116 Commits

Author SHA1 Message Date
Joerg Wunsch
8670e13063 This commit was manufactured by cvs2svn to create tag
'release_4_3_0'.

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/tags/release_4_3_0@404 81a1dc3b-b13d-400b-aceb-764788c761c2
2004-01-27 04:27:19 +00:00
Theodore A. Roth
8aa48a293c * configure.ac: Update copyright year.
(AC_INIT): Set version to 4.3.0.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@403 81a1dc3b-b13d-400b-aceb-764788c761c2
2004-01-27 04:27:18 +00:00
Theodore A. Roth
646cc45b23 * 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.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@402 81a1dc3b-b13d-400b-aceb-764788c761c2
2004-01-26 06:27:41 +00:00
Jan-Hinnerk Reichert
8bfad495f3 * doc/avrdude.texi: get rid of those black boxes marking "overfull hbox"
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@401 81a1dc3b-b13d-400b-aceb-764788c761c2
2004-01-17 19:38:15 +00:00
Jan-Hinnerk Reichert
5a481c813d * doc/avrdude.texi: new appendix "Troubleshooting"
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@400 81a1dc3b-b13d-400b-aceb-764788c761c2
2004-01-17 14:36:47 +00:00
Jan-Hinnerk Reichert
1dfa7127da * avr910.c, avrpart.c, avrpart.h, doc/TODO: Look up devicecode and report device.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@399 81a1dc3b-b13d-400b-aceb-764788c761c2
2004-01-12 22:48:50 +00:00
Jan-Hinnerk Reichert
c7442f9f91 * 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.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@398 81a1dc3b-b13d-400b-aceb-764788c761c2
2004-01-03 18:36:44 +00:00
Jan-Hinnerk Reichert
f77891017e avr910.c: Removed debugging stuff that is no longer needed.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@397 81a1dc3b-b13d-400b-aceb-764788c761c2
2004-01-03 18:18:57 +00:00
Jan-Hinnerk Reichert
95124f0ea8 doc/TODO: Removed two items.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@396 81a1dc3b-b13d-400b-aceb-764788c761c2
2004-01-03 18:14:46 +00:00
Jan-Hinnerk Reichert
357ccfdd21 *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
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@395 81a1dc3b-b13d-400b-aceb-764788c761c2
2004-01-03 18:13:34 +00:00
Jan-Hinnerk Reichert
7b50700c6a *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
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@394 81a1dc3b-b13d-400b-aceb-764788c761c2
2004-01-03 18:04:54 +00:00
Joerg Wunsch
23dc288317 Document my recent -U changes.
Reminded by: Eric

While being here, perform a few style fixes to recent entries as well.

Noticed by: Emacs :-)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@393 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-12-02 18:25:15 +00:00
Eric Weddington
225c4f3b83 *doc/avrdude.texi: Update devices and programmers supported.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@392 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-12-01 19:42:25 +00:00
Eric Weddington
9ebf10ba19 *doc/avrdude.texi: Add missing -D option to user manual.
[This fixes bug #6804]


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@391 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-12-01 19:02:10 +00:00
Jan-Hinnerk Reichert
97aa546db3 Add ChangeLog entries for code cleanup (new file avrpart.c)
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@390 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-11-30 16:56:13 +00:00
Jan-Hinnerk Reichert
59a823acb8 *avrpart.c,main.c: Moved list_parts() and locate_part() from main.c to avrpart.c
*avrpart.h: Added prototypes for list_parts() and locate_part()


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@389 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-11-30 16:49:00 +00:00
Jan-Hinnerk Reichert
6f57db045f *avrpart.c,avr.c: Moved elementary functions on types OPCODE, AVRMEM and AVRPART from avr.c to new file avrpart.c
*avr.h: Removed prototypes for moved functions
*avrpart.h: Added prototypes for functions in avrpart.c
*Makefile.am: Added new file avrpart.c


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@388 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-11-30 16:42:10 +00:00
Brian S. Dean
3674e125f9 Add support for the Atmel Butterfly board which talks to the
Butterfly's supplied bootloader firmware.

Contributed by: Michael Mayer <michael-mayer@gmx.de>


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@387 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-11-30 15:16:48 +00:00
Joerg Wunsch
19d4d87047 Make the -U parser tolerate colons in filenames.
Document the change, including changing one of the texinfo examples
to use a Windows-like filename that contains a space (and thus
requires quoting).

This fixes bug #6764.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@386 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-11-26 22:05:02 +00:00
Jan-Hinnerk Reichert
44617af1ed * ppi.c: Major speed tuning. Since ioctl() is expensive read from shadowregisters where possible.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@385 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-11-22 04:26:50 +00:00
Jan-Hinnerk Reichert
2364219ff2 *ppi.c: Major speed-tuning. Since ioctl() is expensive read from shadow-registers where possible.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@384 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-11-22 03:31:27 +00:00
Jan-Hinnerk Reichert
aeec873e54 *term.c: Add two missing includes to fix compile warnings.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@383 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-11-22 03:25:48 +00:00
Brian S. Dean
7d41abdb6d Config file cleanup and part additions:
* The second poll value for flash is corrected for all devices

  * Delays are corrected for all devices, I have a datasheet for on my
    harddisk

  * mega161 is added

  * avr910_devcode added for all devices except mega64, mega162,
    mega169 and mega8535. Numbers are taken from uisp-source.

Contributed by Jan-Hinnerk Reichert <jan-hinnerk_reichert@hamburg.de>


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@382 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-11-20 04:05:53 +00:00
Eric Weddington
8ef93bad7c * NEWS: Update news from items in ChangeLog.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@381 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-11-19 19:12:38 +00:00
Theodore A. Roth
c11fbbfc07 * avr.c (avr_write_byte_default): Improve polling algorithm to speed up
programming of byte oriented parallel programmers.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@380 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-11-19 18:11:59 +00:00
Brian S. Dean
1ad0277475 Recent updates.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@379 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-11-14 04:52:33 +00:00
Brian S. Dean
06595e3ec3 Add ATmega64 part.
Contributed by Erik Christiansen <erik@dd.nec.com.au>


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@378 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-11-14 04:43:55 +00:00
Joerg Wunsch
aa98d8a24b Add "fuse" and "lock" definitions for the AT90S8535. Actually, this is
stolen from the AT90S8515 since the datasheet says it's the same there.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@377 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-11-08 21:15:42 +00:00
Eric Weddington
f5cb51e1bf * stk500.c (stk500_paged_write): Limit blocks written to no bigger
than memory device size.
	(stk500_paged_write): Send whole block at once.
	(stk500_paged_load): Limit blocks read to no bigger than memory
	device size.
	[Contributed by Bill Somerville <bill@classdesign.com>, this fixes
	bug #5713.]


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@376 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-10-13 21:32:53 +00:00
Eric Weddington
c1e0721545 *avrdude.conf.in: Fix for unterminated character error.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@375 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-10-13 21:20:01 +00:00
Eric Weddington
0a24f1d205 * avrdude.conf.in: Add ATmega8515 definition.
Contributed by: Matthias Weißer <matthias@matwei.de>
	* NEWS: Add note about ATmega8515 definition.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@374 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-10-13 17:53:56 +00:00
Brian S. Dean
4e2677cc5c Add new programmer config: ABCmini Board, contributed by Christian
Catchpole <trio@catchpole.net>.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@373 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-10-02 18:59:47 +00:00
Eric Weddington
9be62d28c3 * doc/TODO: Updated TODO list.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@372 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-09-24 15:34:04 +00:00
Eric Weddington
f72d42b80e * windows/Makefile.am: Correct makefile so loaddrv does not link
to Cygwin DLL.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@371 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-09-22 21:13:57 +00:00
Eric Weddington
08669937dc * doc/avrdude.texi: Minor corrections. Change description of -P
to reference platform dependencies.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@370 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-09-18 18:11:25 +00:00
Eric Weddington
f0808da915 * stk500.c: If writing flash, skip empty pages in paged write.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@369 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-09-16 20:40:13 +00:00
Brian S. Dean
fb9e9ca66a Add ATmega162 part definition.
Contributed by: Stephan Eisvogel <eisvogel@hawo.stw.uni-erlangen.de>


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@368 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-09-08 14:51:28 +00:00
Theodore A. Roth
ddfd0b658c * NEWS: Add 'Current:' header.
* configure.ac (AC_INIT): Add cvs back to version since we're
back in dev cycle (post release).


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@367 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-09-06 18:17:58 +00:00
Theodore A. Roth
d05271766a * NEWS: Update for 4.2.0 release. Add note about read/write of fuses
support for avr910.
* configure.ac (AC_INIT): Set version to 4.2.0.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@365 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-09-06 17:47:16 +00:00
Theodore A. Roth
92059f41a3 * avr.c (avr_read_byte): If pgm->read_byte method fails, retry with
avr_read_byte_default.
* avr.c (avr_write_byte): If pgm->write_byte method fails, retry with
avr_write_byte_default.
* avr910.c (avr910_cmd): Implement using universal command.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@364 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-09-05 16:40:55 +00:00
Theodore A. Roth
ed14409bf9 * ChangeLog: Format cleanups. All indents should be a single tab and
lines should be less than 80 chars including 8 spaces for the tab.
Date should be YYYY-MM-DD not YYYY/MM/DD.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@363 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-09-05 16:25:00 +00:00
Theodore A. Roth
ea652e7b78 * Makefile.am: Change AM_CPPFLAGS to avrdude_CPPFLAGS.
Define avrdude_CFLAGS.
* configure.ac: Set ENABLE_WARNINGS to "-Wall" if using gcc.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@362 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-09-05 04:23:27 +00:00
Brian S. Dean
3bd2da1766 Add an extended example of using the -U option to update the flash,
eeprom, efuse, hfuse, and lfuse on a single command line.  Much of the
output had to be ommitted from the example since the texi commands for
formatting the example don't allow page breaks within the example.  If
someone knows a better way to format it, please feel free to do so.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@361 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-09-04 01:01:40 +00:00
Eric Weddington
d1eb58dbde * doc/avrdude.texi: Add note about privileges needed to load
the giveio driver for Windows.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@360 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-09-02 16:40:06 +00:00
Brian S. Dean
ede8a48d52 Revert to honoring the return code from pgm->pgm_enable() within the
stk500 initialization routine.  However, allow one to use the -F
option to ignore a bad return code from that function.  I think this
still allows what Joerg intended, i.e., providing a way to still get
into terminal mode so that one can recover from setting bad STK500
values which may keep the chip from entering programming mode.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@359 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-31 15:40:59 +00:00
Brian S. Dean
6acb859507 Make a note about the new auto erase default and exceptions.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@358 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-29 23:23:25 +00:00
Brian S. Dean
698769dcca Document auto erase default for -U flash write requests.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@357 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-29 23:19:44 +00:00
Brian S. Dean
1188a0313b Perform an auto erase before programming if the flash memory is
anywhere specified to be written by any of the -U requests.

To remain backward compatible with previous versions, disable this
feature if any of the old-style memory specification operations are
specified (-i, -o).

Implement the -D option to explicitly disable the auto erase default.

Deprecate the old-style memory specification options (-f, -i, -I, -m,
and -o) in favor of the new -U option which allows one to operate on
multiple memories on a single command line.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@356 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-29 23:17:32 +00:00
Brian S. Dean
ae39cd7c57 Add some forgotten entries.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@355 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-29 01:47:47 +00:00
Brian S. Dean
77bc532fd2 Declare size and vsize as 'int'. These represent the size of the AVR
memory read or written (or up to where continuous 0xff begins in the
case of flash memory).  An 'int' should be plenty big enough for that.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@354 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-29 00:14:22 +00:00
Brian S. Dean
ce6e943739 Add entry about "immediate mode."
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@353 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-28 23:42:51 +00:00
Eric Weddington
9560dfe881 * avr910.c:
* fileio.c:
    * main.c:
    * stk500.c:
    More code cleanup to remove warnings.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@352 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-28 23:02:25 +00:00
Brian S. Dean
61c60d3b5b Make a note about -U option.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@351 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-28 18:41:43 +00:00
Brian S. Dean
f2a77c44f0 Fix fuse bit setting example. This closes bug #4027 submitted by
(unknown).


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@350 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-28 14:00:07 +00:00
Brian S. Dean
3c507aee9e Fix placement of local variable - variables must be declared before
any statements within a block.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@349 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-28 13:52:52 +00:00
Theodore A. Roth
964a170f39 * main.c (update_progress_no_tty): Properly terminate progress. Also
fixes stk500 problem where number of bytes written is less than a page.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@348 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-28 05:37:57 +00:00
Theodore A. Roth
d2e0c4eab3 * avrdude.spec.in: Fix broken rpmbuild on RedHat-9.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@347 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-28 04:43:50 +00:00
Eric Weddington
c19d7efe7a * fileio.c:
* main.c:
    * ppiwin.c:
    * ser_posix.c:
    * stk500.c:
    Minor code cleanup to remove warnings.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@346 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-25 15:55:48 +00:00
Brian S. Dean
e603e71c45 Fix example.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@345 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-24 20:53:25 +00:00
Brian S. Dean
e8d5bce16f Document recent enhancements.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@344 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-24 18:40:06 +00:00
Brian S. Dean
b8af1211d8 Update a few programmer entries (descriptions only).
Add the supported programmer list to the manual.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@343 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-24 18:31:08 +00:00
Brian S. Dean
96b8604351 Remove debugging printf.
Update manual to reflect the new -U option.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@342 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-24 18:05:46 +00:00
Brian S. Dean
0d61a7e3f7 Introduce a new option, -U, for performing memory operions. Its
argument is a 4 field string (fields seperated by colons) which
indicate what memory type to operate on, what operation to perform is
(read, write, or verify), the filename to read from, write to, or
verify against, and an optional file format field.  Multple -U options
can be specified to operate on more than one memory at a time with a
single invocation.  For example, to update both the flash and the
eeprom at the same time one can now specify the following:

	avrdude -p -e -U flash:w:main.hex:i -U eeprom:w:eeprom.hex:i


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@341 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-21 04:52:36 +00:00
Brian S. Dean
b4a23dddc0 Timing related fixes for the Windows platform. Several folks have
reported that this patch fixes verify errors on the Windows platform
that are apparently timing related.  Submitted by: Alex Shepherd
<ashepherd@wave.co.nz>, who indicates that this patch was based on
code from the UISP project.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@340 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-20 00:16:27 +00:00
Theodore A. Roth
ca01d072ab * avrdude.1: Document the -q option.
* doc/avrdude.texi: Document the -q option.
Fix some typos left over from pasting in man output.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@339 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-08-01 20:11:21 +00:00
Brian S. Dean
f6a14f4c25 Add elapsed time information to the new progress bar.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@338 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-07-30 23:01:52 +00:00
Theodore A. Roth
f3a6fc6ab0 * avr.c:
* avr.h:
* avr910.c:
* main.c:
* stk500.c:
New progress reporting implementation.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@337 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-07-29 22:08:21 +00:00
Joerg Wunsch
4facd0e3d9 Add support for displaying and changing the various STK500 operational
parameters.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@336 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-07-24 21:26:28 +00:00
Brian S. Dean
17422985b6 Remove carraige returns.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@335 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-07-23 23:44:13 +00:00
Brian S. Dean
6ff0c4a47e Add 'picoweb' programming cable programmer.
Contributed by Rune Christensen <rune.christensen@adslhome.dk>.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@334 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-07-22 01:29:19 +00:00
Brian S. Dean
ede6981133 Add the 'sp12' (Steve Bolt's) programmer.
Submitted by Larry Barello <larryba@barello.net>.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@333 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-06-18 02:47:52 +00:00
Brian S. Dean
3e70d4566f Properly identify the "ALF" programmer.
Extend ATmega8 calibration memory to support all 4 calibration bytes.
Savannah bug #3835.  Submitted by Francisco T. A. Silva
<ftas@geodigitus.com.br>.

Add a few AVR910 programmer device codes.  Savannah bug #3569 - sorry
I can't tell who submitted this to give proper credit.

Add support for the ATtiny12.  Submitted by Pontifex <pontifex@isys.ca>


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@332 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-06-17 21:35:39 +00:00
Brian S. Dean
4446ed3a7d Optimize flash memory handling a little bit by ignoring 0xff data that
resides above the last non-0xff data value in the address space.  Only
do this for flash memory since writing a 0xff to flash is a no-op.
This has the affect of creating smaller output files when dumping
memory contents from flash if the program in flash does not consume
the whole memory space.  It also results in shorter programming times
when avrdude is asked to load a file into flash that has lots of 0xff
filled data past the last non-0xff data value.

I think this is basically where Alexey was going with his s-record
routine, but this should have a similar affect for all the I/O
routines.  The main difference is that Alexey's also optimized 0xff
from the beginning of the address space and was not limited to flash.

I think that these optimizations should be limited to the flash since
it is currently the only memory that treats 0xff as special.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@331 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-05-22 02:33:17 +00:00
Brian S. Dean
e0026ff0fd Make the s-record output routine work like the raw and intel hex
output routines (don't optimize away 0xff data before and after non
0xff data).  Also, fix a bug where the data contents sometimes weren't
written out completely.

Initial bug reported by Tom Harris <TomH@optiscan.com>.  Fixes
provided by Alexey V.Levdikov <tsar@kemford.com>.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@330 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-05-22 00:46:59 +00:00
Theodore A. Roth
1fa0b23de1 * avr910.c (avr910_paged_write_flash): Add code to send the 'm'
command ("issue page write" cmd) for each page.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@329 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-05-14 05:14:32 +00:00
Theodore A. Roth
229481f5ac * avrdude.conf.in: Add pagel and bs2 entries for at90s1200 device.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@328 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-05-14 03:54:17 +00:00
Theodore A. Roth
0b1f5b8a0d * doc/TODO: Add note about avr910 device codes.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@327 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-05-13 21:41:36 +00:00
Eric Weddington
25d2b42f87 Change email address.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@326 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-05-13 18:10:55 +00:00
Brian S. Dean
4e10f943ff fileio.c : Remove superfluous assignment of 'fname'.
main.c : print out '<stdin>' and '<stdout>' instead of '-' when using
         stdio for I/O.

Thanks to Francisco T. A. Silva <ftas@geodigitus.com.br> for catching
this, and the error fixed by the previous commit as well.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@325 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-05-07 22:13:46 +00:00
Brian S. Dean
16d49775d0 Unbreak using stdin/stdout for file input / output.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@324 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-05-07 00:14:03 +00:00
Theodore A. Roth
29658b756a * configure.ac: Check for ncurses library (since it can be a
replacement for termcap.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@323 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-05-05 02:29:28 +00:00
Theodore A. Roth
39dbaf4903 * avrdude.conf.in: Add avr decodes for devices known in avr910
firmware version 2.3.
Add missing stk500 devocde for 2343.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@322 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-05-02 16:23:30 +00:00
Eric Weddington
9baed74e69 Fix for bug #3293. Set correct open mode for raw format for Windows.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@321 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-23 16:36:01 +00:00
Brian S. Dean
8c70fa36ec unbreak '-i' option argument
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@320 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-19 23:31:51 +00:00
Brian S. Dean
83cb042b9e Document -I.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@319 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-19 23:10:00 +00:00
Brian S. Dean
2528839c95 Add a shortcut option, '-I' which is the same as '-i' but defaults the
file format type to 'immediate mode' where the filename is assumed to
be the memory data itself.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@318 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-19 23:06:01 +00:00
Brian S. Dean
57c7412a3c Implement and "immediate mode" for file input - this allows one to
specify byte values on the command line instead of via a file.  This
can be good for specifying fuse bytes and eliminates the need to
create single-byte files or using interactive terminal mode for these
single-byte memories.  Requested by several folks on the mailing list.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@317 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-19 18:41:35 +00:00
Theodore A. Roth
b54f273812 * configure.ac: Add cvs suffix back to version.
* doc/TODO: Add a few items.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@316 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-19 05:26:23 +00:00
Theodore A. Roth
56823c7aa5 * configure.ac: Set version to 4.1.0.
* doc/avrdude.texi: Add note about avr910 programmer type.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@314 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-18 04:41:45 +00:00
Eric Weddington
d6e5083b97 * NEWS: Replace TBD with new release version.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@313 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-17 23:19:58 +00:00
Brian S. Dean
7d5184da75 Change deprecated 'devicecode' to 'stk500_devcode' and remove
extraneous carraige returns.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@312 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-17 22:50:41 +00:00
Eric Weddington
62f2e06711 Change name of pony programmer to pony-stk200 to better describe the hw.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@311 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-17 17:34:01 +00:00
Eric Weddington
bd11e34965 Corrected submitter's name in the ChangeLog.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@310 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-17 16:24:54 +00:00
Eric Weddington
e358fd203a Add ATtiny26 support submitted by Artur Lipowski <LAL@pro.onet.pl>.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@309 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-16 23:00:29 +00:00
Eric Weddington
5fa160a365 Add ATmega8535 support submitted by Alexander <apeter@gmx.de>
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@308 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-16 22:44:55 +00:00
Theodore A. Roth
8513530063 * avr910.c: Reading a 16 bit word in paged load needs to swap the
bytes since the 'R' command returns MSB first and the internal buffer
stores LSB first.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@307 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-09 20:37:28 +00:00
Theodore A. Roth
6c3cb9fbb2 * stk500.c: Don't print out read/write byte progress unless the verbose
option is given.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@306 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-07 17:18:51 +00:00
Theodore A. Roth
d2317147db * avr910.c: Re-add the avr910 byte read/write methods which were
removed in my previous patch. Terminal mode read/writes are broken
without those methods. D'oh!


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@305 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-06 07:10:44 +00:00
Theodore A. Roth
20bf291163 * avr910.c: Refactor to allow probing for auto addr increment. If auto
incr supported by programmer hw, don't send addr for every byte.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@304 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-06 00:47:16 +00:00
Eric Weddington
a58f2c8d66 * confwin.c: Fix bug that allows garbage for non-existent user config filename on Windows.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@303 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-04-03 16:46:47 +00:00
Brian S. Dean
4996510f4c Add the ATmega32 part. This part definition was contributed by:
Daniel Williamson <dannyw@maconmgt.co.uk>
and
	Ruwan Jayanetti <rjayanetti@sri.crossvue.com>

The resulting part definition used was actually somewhat of a merge of
the two submitted definitions.

Thanks for the contributions!


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@302 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-03-29 15:02:07 +00:00
Theodore A. Roth
c3412f1f57 * NEWS: Add note about avr910 support.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@301 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-03-24 23:37:09 +00:00
Eric Weddington
dc21830241 Add ChangeLog and NEWS entry for new Bascom programmer.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@300 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-03-24 23:02:11 +00:00
Theodore A. Roth
191a5a4430 * avr.c (avr_write): Add call to pgm->write_setup() before the write loop.
* avr910.c: Change all show_func_info() calls to no_show_func_info().
Add read/write to/from flash/eeprom memory functionality.
* pgm.c: Initialize pgm->write_setup.
* pgm.h: Add write_setup field to PROGRAMMER structure.
* ser_posix.c: Remove unneeded cast in verbosity code.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@299 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-03-24 07:09:16 +00:00
Theodore A. Roth
ee87b080c3 * ser_posix.c: Limit verbose output to 2 chars.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@298 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-03-24 02:37:33 +00:00
Theodore A. Roth
5bd3b081eb * ser_posix.c: Add verbose level > 3 output for send and recv functions.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@297 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-03-24 01:57:31 +00:00
Theodore A. Roth
6fba5faaf5 * avr.c: Add avr_read_byte_default().
Have avr_read_byte() call pgm->read_byte() or avr_read_byte_default().
Add avr_write_byte_default().
Have avr_write_byte() call pgm->write_byte or avr_write_byte_default().
* pgm.c: Initialize pgm->write_byte and pgm->read_byte.
* pgm.h: Add write_byte and read_byte fields to struct programmer_t.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@296 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-03-23 23:22:50 +00:00
Theodore A. Roth
5d6dace3c3 * avrdude.conf.in: Fix typo for devicecode deprecation comment.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@295 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-03-18 05:49:29 +00:00
Eric Weddington
200283a902 Add Bascom programmer. Submitted by Larry Barello <larryba@barrello.net>
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@294 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-03-17 17:57:55 +00:00
Theodore A. Roth
ea977f6062 * avr.c (avr_read): Use pgm->read_sig_bytes to read signature bytes if
available.
* avr910.c (avr910_vfy_cmd_sent): New function.
(avr910_chip_erase): Add support for chip erase.
(avr910_enter_prog_mode): New function.
(avr910_leave_prog_mode): New function.
(avr910_initialize): Add code to select device type and enter prog mode.
(avr910_close): Leave programming mode before closing serial port.
(avr910_read_sig_bytes): New function.
(avr910_initpgm): Add avr910_read_sig_bytes method to pgm initializer.
* avrdude.conf.in: Add note about deprecating devicecode.
Change all occurences of devicecode to stk500_devcode.
Add avr910_devcode to a few parts for testing.
* avrpart.h (struct avrpart): Change devicecode field to stk500_devcode.
(struct avrpart): Add avr910_devcode field.
* config_gram.y: Add K_STK500_DEVCODE and K_AVR910_DEVCODE tokens.
Generate an error if devicecode is found in the config file.
Handle parsing of avr910_devcode and stk500_devcode.
* lexer.l: Handle parsing of avr910_devcode and stk500_devcode.
* pgm.c: Initialize pgm->read_sig_bytes field.
* pgm.h: Add pgm->read_sig_bytes field.
* stk500.c: Use stk500_devcode instead of devicecode.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@293 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-03-17 06:20:02 +00:00
Theodore A. Roth
a13d87de00 * avrdude.conf.in: Add avr910 and pavr programmers.
* config_gram.y: Add parsing of avr910 programmer.
* lexer.l: Add avr910 token.
* avr910.c: [this is still work in progress]
Add some debug output.
Add probe for programmer presense.
* main.c: Set port to default_serial if programmer type is avr910.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@292 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-03-16 18:19:37 +00:00
Theodore A. Roth
5a74a905b4 * ser_posix.c, ser_win32.c, serial.h:
Change baud from int to long to avoid a 16-bit int overflow.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@291 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-03-13 19:25:27 +00:00
Brian S. Dean
eb551b1d0d Headers needed on FreeBSD.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@290 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-03-13 04:44:46 +00:00
Theodore A. Roth
f0c2dcf820 * Makefile.am (avrdude_SOURCES): Add avr910.[ch], serial.h and
ser_posix.c files.
* avr910.c: New file (stubs for avr910 serial programmer).
* avr910.h: New file.
* ser_posix.c: New file.
* ser_win32.c: New file (just stubs for now).
* serial.h: New file.
* stk500.c: Move all the code for accessing the posix serial ports
into ser_posix. This will make a native win32 port easier and allows
the avr910 programmer to share the serial code.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@289 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-03-13 03:52:19 +00:00
Brian S. Dean
8da3ff76e4 Add Ted, who forgot to add himself.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@288 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-03-13 03:16:53 +00:00
Theodore A. Roth
8f15af9679 * configure.ac (AC_INIT): Set version to 4.0.0cvs since we're done
with 4.0.0 release.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@287 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-03-12 21:37:32 +00:00
38 changed files with 6770 additions and 1940 deletions

View File

@@ -5,5 +5,6 @@ AVRDUDE was written by:
Contributors:
Joerg Wunsch <j@uriah.heep.sax.de>
Eric Weddington <eric@umginc.net>
Eric Weddington <eric@ecentral.com>
Theodore A. Roth <troth@openavr.org>

View File

@@ -1,601 +1,52 @@
2003-03-11 Theodore A. Roth <troth@openavr.org>
2004-01-26 Theodore A. Roth <troth@openavr.org>
* Makefile.am: Add CLEANFILES to remove all files from a make.
* doc/Makefile.am: Ditto
* AVRDUDE 4.3.0 has been released (cvs release tag is "release_4_3_0").
2003-03-11 Theodore A. Roth <troth@openavr.org>
2004-01-26 Theodore A. Roth <troth@openavr.org>
* windows/Makefile.am: Fix uninstall-local rule (forget the $$file
part of the rm command).
* configure.ac: Update copyright year.
(AC_INIT): Set version to 4.3.0.
2003-03-11 Theodore A. Roth <troth@openavr.org>
2004-01-25 Theodore A. Roth <troth@openavr.org>
* 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.
* 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.
2003-03-11 Eric Weddington <eric@umginc.net>
2004-01-17 Jan-Hinnerk Reichert <hinni@despammed.com>
* doc/avrdude.texi:
Add Install and Documentation sections for Windows. Fix typo.
* doc/avrdude.texi: Get rid of those black boxes marking "overfull
hbox".
2003-03-10 Theodore A. Roth <troth@openavr.org>
2004-01-17 Jan-Hinnerk Reichert <hinni@despammed.com>
* Makefile.am: * Makefile.am (EXTRA_DIST): Add CHANGELOG.
* doc/avrdude.texi: New appendix "Troubleshooting".
2003-03-10 Brian S. Dean <bsd@bsdhome.com>
2004-01-12 Jan-Hinnerk Reichert <hinni@despammed.com>
* stk500.c: Disable debugging printf.
* avr910.c, avrpart.c, avrpart.h, doc/TODO:
Look up devicecode and report device.
* configure.ac: Update version number in preparation for release.
2004-01-03 Jan-Hinnerk Reichert <hinni@despammed.com>
2003-03-10 Theodore A. Roth <troth@openavr.org>
* 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.
* 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.
2004-01-03 Jan-Hinnerk Reichert <hinni@despammed.com>
2003-03-10 Brian S. Dean <bsd@bsdhome.com>
* avr910.c: Removed debugging stuff that is no longer needed.
* avrdude.1: Minor man page updates to better reflect reality.
2004-01-03 Jan-Hinnerk Reichert <hinni@despammed.com>
2003-03-10 Joerg Wunsch <j@uriah.heep.sax.de>
* doc/TODO: Removed two items.
* bootstrap:
Export all the AUTO* variables. Hopefully, that way the generated
Makefile might get them correctly.
2004-01-03 Jan-Hinnerk Reichert <hinni@despammed.com>
* bootstrap:
Export ${AUTOCONF} so automake will find it by whatever name it will be
called today.
* 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.
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!

1095
avrdude/ChangeLog-2003 Normal file

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 Theodore A. Roth <troth@openavr.org>
# Copyright (C) 2003, 2004 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,6 +24,7 @@
EXTRA_DIST = \
ChangeLog-2001 \
ChangeLog-2002 \
ChangeLog-2003 \
avrdude.1 \
avrdude.pdf \
avrdude.spec \
@@ -39,7 +40,9 @@ DIST_SUBDIRS = doc windows
AM_YFLAGS = -d
AM_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
avrdude_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
avrdude_CFLAGS = @ENABLE_WARNINGS@
bin_PROGRAMS = avrdude
@@ -48,7 +51,12 @@ 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 \
@@ -67,6 +75,9 @@ 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,18 +6,84 @@ 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 "E. Weddington" <eric@umginc.net>
* Now support Windows - added by "Eric B. Weddington" <eric@ecentral.com>.
* Use 'configure' scripts to tailor the code to the system avrdude
is getting ready to be compiled on - added by "Theodore A. Roth"
<troth@openavr.org>
<troth@openavr.org>.
* Motorola S-Record support - submitted by "Alexey V.Levdikov "
<tsar@kemford.com>
<tsar@kemford.com>.
* Support parallel programming on the STK500. Introduce 'pagel' and
'bs2' keywords to the config file for this purpose.
@@ -233,4 +299,4 @@ Version 1.3.0 :
Version 1.2.2 :
* Initial public release
* Initial public release.

View File

@@ -25,6 +25,8 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include "avr.h"
@@ -43,255 +45,8 @@ extern PROGRAMMER * pgm;
extern int do_cycles;
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)
int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value)
{
unsigned char cmd[4];
unsigned char res[4];
@@ -340,6 +95,53 @@ int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
}
/*
* read a byte of data from the indicated memory region
*/
int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value)
{
int rc;
if (pgm->read_byte) {
rc = pgm->read_byte(pgm, p, mem, addr, value);
if (rc == 0) {
return rc;
}
/* read_byte() method failed, try again with default. */
}
return avr_read_byte_default(pgm, p, mem, addr, value);
}
/*
* Return the number of "interesting" bytes in a memory buffer,
* "interesting" being defined as up to the last non-0xff data
* value. This is useful for determining where to stop when dealing
* with "flash" memory, since writing 0xff to flash is typically a
* no-op. Always return an even number since flash is word addressed.
*/
int avr_mem_hiaddr(AVRMEM * mem)
{
int i, n;
/* return the highest non-0xff address regardless of how much
memory was read */
for (i=mem->size-1; i>0; i--) {
if (mem->buf[i] != 0xff) {
n = i+1;
if (n & 0x01)
return n+1;
else
return n;
}
}
return 0;
}
/*
* Read the entirety of the specified memory type into the
* corresponding buffer of the avrpart pointed to by 'p'. If size =
@@ -355,7 +157,6 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
unsigned char * buf;
AVRMEM * mem;
int rc;
int printed;
mem = avr_locate_mem(p, memtype);
if (mem == NULL) {
@@ -369,6 +170,11 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
size = mem->size;
}
/*
* start with all 0xff
*/
memset(buf, 0xff, size);
if ((strcmp(mem->desc, "flash")==0) || (strcmp(mem->desc, "eeprom")==0)) {
if (pgm->paged_load != NULL) {
/*
@@ -377,16 +183,27 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
* instead
*/
if (mem->paged) {
return pgm->paged_load(pgm, p, mem, mem->page_size, size);
rc = pgm->paged_load(pgm, p, mem, mem->page_size, size);
if (rc < 0)
return rc;
}
else {
return pgm->paged_load(pgm, p, mem, pgm->page_size, size);
rc = pgm->paged_load(pgm, p, mem, pgm->page_size, size);
if (rc < 0)
return rc;
}
if (strcasecmp(mem->desc, "flash") == 0)
return avr_mem_hiaddr(mem);
else
return rc;
}
}
printed = 0;
if (strcmp(mem->desc, "signature") == 0) {
if (pgm->read_sig_bytes) {
return pgm->read_sig_bytes(pgm, p, mem);
}
}
for (i=0; i<size; i++) {
rc = avr_read_byte(pgm, p, mem, i, &rbyte);
@@ -399,19 +216,13 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
return -2;
}
buf[i] = rbyte;
if (verbose) {
if ((i % 16 == 0)||(i == (size-1))) {
printed = 1;
fprintf(stderr, "\r \r%6lu", i);
}
}
report_progress(i, size, NULL);
}
if (printed) {
fprintf(stderr, "\n");
}
return i;
if (strcasecmp(mem->desc, "flash") == 0)
return avr_mem_hiaddr(mem);
else
return i;
}
@@ -451,7 +262,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);
@@ -460,10 +271,7 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
}
/*
* write a byte of data at the specified address
*/
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data)
{
unsigned char cmd[4];
@@ -471,11 +279,14 @@ int avr_write_byte(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) {
/*
@@ -565,13 +376,6 @@ int avr_write_byte(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])) {
@@ -589,6 +393,29 @@ int avr_write_byte(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;
@@ -601,7 +428,6 @@ int avr_write_byte(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",
@@ -648,6 +474,26 @@ int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
}
/*
* write a byte of data at the specified address
*/
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data)
{
int rc;
if (pgm->write_byte) {
rc = pgm->write_byte(pgm, p, mem, addr, data);
if (rc == 0) {
return rc;
}
/* write_byte() method failed, try again with default. */
}
return avr_write_byte_default(pgm, p, mem, addr, data);
}
/*
* Write the whole memory region of the specified memory from the
* corresponding buffer of the avrpart pointed to by 'p'. Write up to
@@ -666,7 +512,6 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
unsigned char data;
int werror;
AVRMEM * m;
int printed;
m = avr_locate_mem(p, memtype);
if (m == NULL) {
@@ -677,7 +522,6 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
pgm->err_led(pgm, OFF);
printed = 0;
werror = 0;
wsize = m->size;
@@ -704,14 +548,14 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
}
}
if (pgm->write_setup) {
pgm->write_setup(pgm, p, m);
}
for (i=0; i<wsize; i++) {
data = m->buf[i];
if (verbose) {
if ((i % 16 == 0)||(i == (wsize-1))) {
fprintf(stderr, "\r \r%6lu", i);
printed = 1;
}
}
report_progress(i, wsize, NULL);
rc = avr_write_byte(pgm, p, m, i, data);
if (rc) {
fprintf(stderr, " ***failed; ");
@@ -744,15 +588,11 @@ 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;
}
@@ -765,36 +605,15 @@ 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;
}
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;
}
}
report_progress (1,1,NULL);
return 0;
}
@@ -805,7 +624,7 @@ int avr_initmem(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)
{
@@ -863,54 +682,37 @@ int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles)
{
AVRMEM * a;
int cycle_count;
unsigned char v1, v2, v3, v4;
unsigned int cycle_count = 0;
unsigned char v1;
int rc;
int i;
a = avr_locate_mem(p, "eeprom");
if (a == NULL) {
return -1;
}
rc = avr_read_byte(pgm, p, a, a->size-4, &v1);
for (i=4; i>0; i--) {
rc = avr_read_byte(pgm, p, a, a->size-i, &v1);
if (rc < 0) {
fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n",
progname, rc);
return -1;
}
rc = avr_read_byte(pgm, p, a, a->size-3, &v2);
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-2, &v3);
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-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;
*cycles = (int) cycle_count;
return 0;
}
@@ -919,214 +721,56 @@ 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, v2, v3, v4;
unsigned char v1;
int rc;
int i;
a = avr_locate_mem(p, "eeprom");
if (a == NULL) {
return -1;
}
v4 = cycles & 0x0ff;
v3 = (cycles & 0x0ff00) >> 8;
v2 = (cycles & 0x0ff0000) >> 16;
v1 = (cycles & 0x0ff000000) >> 24;
for (i=1; i<=4; i++) {
v1 = cycles & 0xff;
cycles = cycles >> 8;
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;
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;
}
}
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)
int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
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;
}
}
int cycles;
int rc;
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);
}
}
}
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;
}
}
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);
}
return rc;
}
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

@@ -33,29 +33,14 @@
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_set_bits(OPCODE * op, unsigned char * cmd);
int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
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,
@@ -64,7 +49,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);
@@ -75,13 +60,17 @@ int avr_initmem(AVRPART * p);
int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size);
void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
int verbose);
void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose);
int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles);
int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);;
int avr_mem_hiaddr(AVRMEM * mem);
int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p);
extern void report_progress (int completed, int total, char *hdr);
#endif

671
avrdude/avr910.c Normal file
View File

@@ -0,0 +1,671 @@
/*
* 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;
}

29
avrdude/avr910.h Normal file
View File

@@ -0,0 +1,29 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* $Id$ */
#ifndef __avr910_h__
#define __avr910_h__
#include "config.h"
void avr910_initpgm (PROGRAMMER * pgm);
#endif /* __avr910_h__ */

View File

@@ -19,7 +19,7 @@
.\"
.\" $Id$
.\"
.Dd DATE January 11, 2002
.Dd DATE November 26, 2003
.Os
.Dt AVRDUDE 1
.Sh NAME
@@ -30,6 +30,7 @@
.Fl p Ar partno
.Op Fl c Ar programmer-id
.Op Fl C Ar config-file
.Op Fl D
.Op Fl e
.Oo Fl E Ar exitspec Ns
.Op \&, Ns Ar exitspec
@@ -41,7 +42,9 @@
.Op Fl o Ar filename
.Op Fl n
.Op Fl P Ar port
.Op Fl q
.Op Fl t
.Op Fl U Ar memtype:op:filename:filefmt
.Op Fl v
.Op Fl V
.Op Fl y
@@ -112,6 +115,9 @@ been code-protected previously, of course) and store the data in a
file. Finally, a ``terminal'' mode is available that allows one to
interactively communicate with the MCU, and to display or program
individual memory cells.
On the STK500 programmer, several operational parameters (target supply
voltage, target Aref voltage, master clock) can be examined and changed
from within terminal mode as well.
.Ss Options
In order to control all the different operation modi, a number of options
need to be specified to
@@ -175,6 +181,19 @@ submit a patch back to the author so that it can be incorporated for
the next version). See the config file, located at
.Pa ${PREFIX}/etc/avrdude.conf ,
which contains a description of the format.
.It Fl D
Disable auto erase for flash. When the
.Fl U
option with flash memory is specified,
.Nm
will perform a chip erase before starting any of the programming
operations, since it generally is a mistake to program the flash
without performing an erase first. This option disables that.
However, to remain backward compatible, the
.Fl i ,
and
.Fl m
options automatically disable the auto erase feature.
.It Fl e
Causes a chip erase to be executed. This will reset the contents of the
flash ROM and EEPROM to the value
@@ -239,8 +258,10 @@ Multiple
.Ar exitspec
arguments can be separated with commas.
.It Fl f Ar format
This option specifies the file format for the input or output files
to be processed.
(Deprecated, use
.Fl U
instead.) This option specifies the file format for the input or
output files to be processed.
.Ar Format
can be one of:
.Bl -tag -width sss
@@ -250,6 +271,10 @@ Intel Hex
Motorola S-record
.It Ar r
raw binary; little-endian byte order, in the case of the flash ROM data
.It Ar m
immediate; actual byte values specified on the command line, seperated
by commas or spaces. This is good for programming fuse bytes without
having to create a single-byte file or enter terminal mode.
.It Ar a
auto detect; valid for input only, and only if the input is not
provided at
@@ -267,15 +292,31 @@ that a device has a broken (erased or overwritten) device signature
but is otherwise operating normally, this options is provided to
override the check.
.It Fl i Ar filename
Specifies the input file to be programmed into the MCU. Can be specified
as
(Deprecated, use
.Fl U
instead.) Specifies the input file to be programmed into the MCU.
Can be specified as
.Ql \&-
to use
.Em stdin
as the input.
.It Fl I Ar data
(Deprecated, use
.Fl U
instead.) Same as specifying
.Fl i
and
.Fl f Ar m
together, i.e., this is a shortcut for using immediate file input mode
where the filename field is used as the data itself. Useful for
programming single byte memories such as fuse bytes without having to
use single byte files or enter interactive terminal mode.
.It Fl m Ar memtype
Specifies which program area of the MCU to read or write; allowable
values depend on the MCU being programmed, but most support at least
(Deprecated, use
.Fl U
instead.) Specifies which program area of the MCU to read or write;
allowable values depend on the MCU being programmed, but most support
at least
.Em eeprom
for the EEPROM, and
.Em flash
@@ -291,8 +332,11 @@ No-write - disables actually writing data to the MCU (useful for debugging
.Nm avrdude
).
.It Fl o Ar filename
Specifies the name of the output file to write, and causes the respective
memory area to be read from the MCU. Can be specified as
(Deprecated, use
.Fl U
instead.) Specifies the name of the output file to write, and causes
the respective memory area to be read from the MCU. Can be specified
as
.Ql \&-
to write to
.Em stdout .
@@ -307,11 +351,49 @@ 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
@@ -385,6 +467,35 @@ does not implement the command.
Display the device signature bytes.
.It Ar part
Display the current part settings.
.It Ar vtarg voltage
Set the target's supply voltage to
.Ar voltage
Volts.
.Em Only supported on the STK500 programmer.
.It Ar varef voltage
Set the adjustable voltage source to
.Ar voltage
Volts.
This voltage is normally used to drive the target's
.Em Aref
input on the STK500.
.Em Only supported on the STK500 programmer.
.It Ar fosc freq Ns Op M Ns \&| Ns k
Set the master oscillator to
.Ar freq
Hz.
An optional trailing letter
.Ar \&M
multiplies by 1E6, a trailing letter
.Ar \&k
by 1E3.
.Em Only supported on the STK500 programmer.
.It Ar fosc off
Turn the master oscillator off.
.Em Only supported on the STK500 programmer.
.It Ar parms
Display the current voltage and master oscillator parameters.
.Em Only supported on the STK500 programmer.
.It Ar \&?
.It Ar help
Give a short on-line summary of the available commands.

File diff suppressed because it is too large Load Diff

View File

@@ -5,6 +5,8 @@
## @configure_input@
##
%define debug_package %{nil}
Summary: AVRDUDE is software for programming Atmel AVR Microcontrollers.
Name: avrdude
Version: @VERSION@
@@ -43,6 +45,9 @@ make prefix=$RPM_BUILD_ROOT%{_prefix} \
infodir=$RPM_BUILD_ROOT%{_infodir} \
install
rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/%{name}-%{version}
rm -f $RPM_BUILD_ROOT%{_infodir}/dir
%clean
rm -rf $RPM_BUILD_ROOT
@@ -68,11 +73,17 @@ fi
%attr(0644,root,root) %config /etc/avrdude.conf
%files docs
%doc doc/avrdude-html
%doc doc/avrdude-html/*.html
%doc doc/TODO
%doc doc/avrdude.ps
%doc doc/avrdude.pdf
%changelog
* Wed Aug 27 2003 Theodore A. Roth <troth@openavr.org>
[Thanks to Artur Lipowski <LAL@pro.onet.pl>]
- Do not build debug package.
- Remove files not packaged to quell RH9 rpmbuild complaints.
* Wed Mar 05 2003 Theodore A. Roth <troth@openavr.org>
- Add docs sub-package.
- Add %post and %preun scriptlets for handling info files.

523
avrdude/avrpart.c Normal file
View File

@@ -0,0 +1,523 @@
/*
* 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,7 +81,8 @@ typedef struct opcode {
typedef struct avrpart {
char desc[AVR_DESCLEN]; /* long part name */
char id[AVR_IDLEN]; /* short part name */
int devicecode; /* Atmel STK500 device code */
int stk500_devcode; /* stk500 device code */
int avr910_devcode; /* avr910 device code */
int chip_erase_delay; /* microseconds */
unsigned char pagel; /* for parallel programming */
unsigned char bs2; /* for parallel programming */
@@ -115,4 +116,27 @@ 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

641
avrdude/butterfly.c Normal file
View File

@@ -0,0 +1,641 @@
/*
* 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;
}

29
avrdude/butterfly.h Normal file
View File

@@ -0,0 +1,29 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* $Id$ */
#ifndef __butterfly_h__
#define __butterfly_h__
#include "config.h"
void butterfly_initpgm (PROGRAMMER * pgm);
#endif /* __butterfly_h__ */

View File

@@ -33,6 +33,8 @@
#include "ppi.h"
#include "pgm.h"
#include "stk500.h"
#include "avr910.h"
#include "butterfly.h"
#include "avr.h"
extern char * progname;
@@ -63,6 +65,7 @@ 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
@@ -72,6 +75,8 @@ static int parse_cmdbits(OPCODE * op);
%token K_DEFAULT_SERIAL
%token K_DESC
%token K_DEVICECODE
%token K_STK500_DEVCODE
%token K_AVR910_DEVCODE
%token K_EEPROM
%token K_ERRLED
%token K_FLASH
@@ -101,6 +106,8 @@ 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
@@ -284,6 +291,18 @@ 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;
@@ -340,6 +359,12 @@ 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);
@@ -403,7 +428,24 @@ part_parm :
K_DEVICECODE TKN_EQUAL TKN_NUMBER {
{
current_part->devicecode = $3->value.number;
fprintf(stderr,
"%s: error at %s:%d: devicecode is deprecated, use "
"stk500_devcode instead\n",
progname, infile, lineno);
exit(1);
}
} |
K_STK500_DEVCODE TKN_EQUAL TKN_NUMBER {
{
current_part->stk500_devcode = $3->value.number;
free_token($3);
}
} |
K_AVR910_DEVCODE TKN_EQUAL TKN_NUMBER {
{
current_part->avr910_devcode = $3->value.number;
free_token($3);
}
} |

View File

@@ -1,6 +1,6 @@
#
# avrdude - A Downloader/Uploader for AVR device programmers
# Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
# Copyright (C) 2003, 2004 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.0.0, avrdude-dev@nongnu.org)
AC_INIT(avrdude, 4.3.0, avrdude-dev@nongnu.org)
AC_CANONICAL_BUILD
AC_CANONICAL_HOST
@@ -42,6 +42,7 @@ AM_PROG_LEX
# Checks for libraries.
AC_CHECK_LIB([termcap], [tputs])
AC_CHECK_LIB([ncurses], [tputs])
AC_CHECK_LIB([readline], [readline])
# Checks for header files.
@@ -124,6 +125,12 @@ case $target in
esac
AC_SUBST(WINDOWS_DIRS,$WINDOWS_DIRS)
# If we are compiling with gcc, enable all warning and make warnings errors.
if test "$GCC" = yes; then
ENABLE_WARNINGS="-Wall"
fi
AC_SUBST(ENABLE_WARNINGS,$ENABLE_WARNINGS)
AC_CONFIG_FILES([
doc/Makefile
windows/Makefile

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003 Eric B. Weddington <eric@umginc.net> or <eric@ecentral.com>
* Copyright (C) 2003 Eric B. Weddington <eric@ecentral.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,6 +30,8 @@ static char *filename;
void win_sys_config_set(char sys_config[PATH_MAX])
{
sys_config[0] = 0;
/* Use Windows API call to search for the Windows default system config file.*/
SearchPath(NULL, "avrdude.conf", NULL, PATH_MAX, sys_config, &filename);
return;
@@ -38,6 +40,8 @@ void win_sys_config_set(char sys_config[PATH_MAX])
void win_usr_config_set(char usr_config[PATH_MAX])
{
usr_config[0] = 0;
/* Use Windows API call to search for the Windows default user config file. */
SearchPath(NULL, "avrdude.rc", NULL, PATH_MAX, usr_config, &filename);
return;

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003 Eric B. Weddington <eric@umginc.net> or <eric@ecentral.com>
* Copyright (C) 2003 Eric B. Weddington <eric@ecentral.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -1,11 +1,22 @@
General:
- Man page needs updated for avr910 info.
- Website needs to link to docs:
http://savannah.nongnu.org/download/avrdude/doc/avrdude-html/
Windows:
- Use Windows API for stk500 serial port communications on Windows port.
This might remove dependency on Cygwin.
- [Windows Port] Use Windows API for serial port communications (ser_win32.c).
(In Progress)
- Add ability to find all parallel port names available and base addresses
of available ports.
- 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.

View File

@@ -5,6 +5,7 @@
@setfilename avrdude.info
@settitle AVRDUDE
@finalout
@include version.texi
@@ -97,10 +98,11 @@ 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::
* Platform Dependent Information::
* Troubleshooting::
@end menu
@c
@@ -127,17 +129,24 @@ from the contents of a file, while interactive mode is useful for
exploring memory contents, modifing individual bytes of eeprom,
programming fuse/lock bits, etc.
AVRDUDE supports two basic programmer types: Atmel's STK500 and the PPI
(parallel port interface). PPI represents a class of simple programmers
where the programming lines are directly connected to the PC parallel
port, while the STK500 uses the serial port to communicate with the PC
AVRDUDE supports three basic programmer types: Atmel's STK500, appnote
avr910 and the PPI (parallel port interface). PPI represents a class
of simple programmers where the programming lines are directly
connected to the PC parallel port. Several pin configurations exist
for several variations of the PPI programmers, and AVRDUDE can be be
configured to work with them by either specifying the appropriate
programmer on the command line or by creating a new entry in its
configuration file. All that's usually required for a new entry is to
tell AVRDUDE which pins to use for each programming function.
The STK500 and avr910 use the serial port to communicate with the PC
and contains on-board logic to control the programming of the target
device. Several pin configurations exist for several variations of the
PPI programmers, and AVRDUDE can be be configured to work with them by
either specifying the appropriate programmer on the command line or by
creating a new entry in its configuration file. All that's usually
required for a new entry is to tell AVRDUDE which pins to use for each
programming function.
device. The fundamental difference between the two types lies in the
protocol used to control the programmer. The 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.
@menu
* History::
@@ -147,7 +156,7 @@ programming function.
@c Node
@c
@node History, , Introduction, Introduction
@section History
@section History and Credits
AVRDUDE was written by Brian S. Dean under the name of AVRPROG to run on
the FreeBSD Operating System. Brian renamed the software to be called
@@ -179,8 +188,8 @@ Roth.
@cindex options
@menu
* Option Descriptions::
* Example Command Line Invocations::
* Option Descriptions::
* Example Command Line Invocations::
@end menu
@c
@@ -204,7 +213,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
@@ -212,9 +221,6 @@ datasheet so that you can enter the programming specifications.
Currently, the following MCU types are understood:
@table @code
@itemx t15
ATtiny15
@itemx 1200
AT90S1200
@@ -242,24 +248,51 @@ 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 m128
ATMEGA128
@itemx m32
ATMEGA32
@itemx m103
ATMEGA103
@itemx m16
ATMEGA16
@itemx m64
ATMEGA64
@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.
@@ -268,12 +301,61 @@ ATMEGA8
Specify the programmer to be used. AVRDUDE knows about several common
programmers. Use this option to specify which one to use. The
@var{programmer-id} parameter is the programmer's id listed in the
configuration file. Specify -c ? to list all programmers in the
configuration file. Specify -c ? to list all programmers in the
configuration file. If you have a programmer that is unknown to
AVRDUDE, and the programmer is controlled via the PC parallel port,
there's a good chance that it can be easily added to the configuration
file without any code changes to AVRDUDE. Simply copy an existing entry
and change the pin definitions to match that of the unknown programmer.
Currently, the following programmer ids are understood and supported:
@table @code
@itemx 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
@@ -285,12 +367,20 @@ 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 pro- grammed from the value `1' to `0'. Note that in order
bits to be programmed from the value `1' to `0'. Note that in order
to reprogram EERPOM cells, no explicit prior chip erase is required
since the MCU provides an auto-erase cycle in that case before
programming the cell.
@@ -299,12 +389,12 @@ programming the cell.
@item -E @var{exitspec}[,@dots{}]
By default, AVRDUDE leaves the parallel port in the same state at exit
as it has been found at startup. This option modifies the state of the
`/RESET' and `Vcc' lines the par- allel port is left at, according to
`/RESET' and `Vcc' lines the parallel port is left at, according to
the exitspec arguments provided, as follows:
@table @code
@itemx reset
The `/RESET' signal will be left activated at pro- gram exit, that is it
The `/RESET' signal will be left activated at program exit, that is it
will be held low, in order to keep the MCU in reset state afterwards.
Note in particular that the programming algorithm for the AT90S1200
device mandates that the `/RESET' signal is active before powering up
@@ -317,12 +407,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 paral- lel port down at
This option will pull the `Vcc' pins of the parallel port down at
program exit.
@end table
@@ -332,7 +422,7 @@ Multiple @var{exitspec} arguments can be separated with commas.
@item -f @var{format}
This option specifies the file format for the input or out- put files to
This option specifies the file format for the input or output files to
be processed. Format can be one of:
@table @code
@@ -345,6 +435,16 @@ Motorola S-record
@itemx r
raw binary; little-endian byte order, in the case of the flash ROM data
@itemx m
immediate mode; actual byte values specified on the command line,
seperated by commas or spaces in place of the @var{filename} field of
the @option{-i}, @option{-o}, or @option{-U} options. This is useful
for programming fuse bytes without having to create a single-byte file
or enter terminal mode. If the number specified begins with @code{0x},
it is treated as a hex value. If the number otherwise begins with a
leading zero (@code{0}) it is treated as octal. Otherwise, the value is
treated as decimal.
@itemx a
auto detect; valid for input only, and only if the input is not provided
at stdin.
@@ -383,17 +483,50 @@ 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. 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.
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.
@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.
@@ -405,14 +538,14 @@ Tells AVRDUDE to use the last four bytes of the connected parts' EEPROM
memory to track the number of times the device has been erased. When
this option is used and the @option{-e} flag is specified to generate a
chip erase, the previous counter will be saved before the chip erase, it
is then incremented, and written back after the erase cycle com- pletes.
is then incremented, and written back after the erase cycle completes.
Presumably, the device would only be erased just before being
programmed, and thus, this can be utilized to give an indication of how
many erase-rewrite cycles the part has undergone. Since the FLASH
memory can only endure a finite number of erase-rewrite cycles, one can
use this option to track when a part is nearing the limit. The typ-
ical limit for Atmel AVR FLASH is 1000 cycles. Of course, if the
application needs the last four bytes of EEPROM mem- ory, this option
use this option to track when a part is nearing the limit. The typical
limit for Atmel AVR FLASH is 1000 cycles. Of course, if the
application needs the last four bytes of EEPROM memory, this option
should not be used.
@item -Y @var{cycles}
@@ -430,28 +563,64 @@ should not be used.
@section Example Command Line Invocations
@noindent
Download the file @code{m128diag.hex} to the ATmega128 chip using the
Download the file @code{diag.hex} to the ATmega128 chip using the
STK500 programmer connected to the default serial port:
@example
@cartouche
% avrdude -p m128 -c stk500 -y -e -i m128diag.hex
% avrdude -p m128 -c stk500 -e -U flash:w:diag.hex
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.03s
avrdude: Device signature = 0x1e9702
avrdude: erasing chip
avrdude: erase-rewrite cycle count is now 52
avrdude: done.
avrdude: reading input file "m128diag.hex"
avrdude: input file m128diag.hex auto detected as Intel Hex
avrdude: writing flash (18130 bytes):
18175
avrdude: 18176 bytes of flash written
avrdude: verifying flash memory against m128diag.hex:
avrdude: performing op: 1, flash, 0, diag.hex
avrdude: reading input file "diag.hex"
avrdude: input file diag.hex auto detected as Intel Hex
avrdude: writing flash (19278 bytes):
Writing | ################################################## | 100% 7.60s
avrdude: 19456 bytes of flash written
avrdude: verifying flash memory against diag.hex:
avrdude: load data flash data from input file diag.hex:
avrdude: input file diag.hex auto detected as Intel Hex
avrdude: input file diag.hex contains 19278 bytes
avrdude: reading on-chip flash data:
18175
Reading | ################################################## | 100% 6.83s
avrdude: verifying ...
avrdude: 18176 bytes of flash verified
avrdude: 19278 bytes of flash verified
avrdude done. Thank you.
%
@end cartouche
@end example
@noindent
Upload the flash memory from the ATmega128 connected to the STK500
programmer and save it in raw binary format in the file named
@code{c:/diag flash.bin}:
@example
@cartouche
% avrdude -p m128 -c stk500 -U flash:r:"c:/diag flash.bin":r
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.03s
avrdude: Device signature = 0x1e9702
avrdude: reading flash memory:
Reading | ################################################## | 100% 46.10s
avrdude: writing output file "c:/diag flash.bin"
avrdude done. Thank you.
@@ -460,20 +629,46 @@ avrdude done. Thank you.
@end example
@noindent
Upload the flash memory from the ATmega128 connected to the STK500
programmer and save it in raw binary format in the file named
@code{m128diag.flash}:
Using the default programmer, download the file @code{diag.hex} to
flash, @code{eeprom.hex} to EEPROM, and set the Extended, High, and Low
fuse bytes to 0xff, 0x89, and 0x2e respectively:
@example
@cartouche
% avrdude -p m128 -c stk500 -f r -o m128diag.flash
% avrdude -p m128 -U flash:w:diag.hex \
> -U eeprom:w:eeprom.hex \
> -U efuse:w:0xff:m \
> -U hfuse:w:0x89:m \
> -U lfuse:w:0x2e:m
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.03s
avrdude: Device signature = 0x1e9702
avrdude: current erase-rewrite cycle count is 52 (if being tracked)
avrdude: reading flash memory:
131071
avrdude: writing output file "m128diag.flash"
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "diag.hex"
avrdude: input file diag.hex auto detected as Intel Hex
avrdude: writing flash (19278 bytes):
Writing | ################################################## | 100% 7.60s
avrdude: 19456 bytes of flash written
avrdude: verifying flash memory against diag.hex:
avrdude: load data flash data from input file diag.hex:
avrdude: input file diag.hex auto detected as Intel Hex
avrdude: input file diag.hex contains 19278 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 6.84s
avrdude: verifying ...
avrdude: 19278 bytes of flash verified
[ ... other memory status output skipped for brevity ... ]
avrdude done. Thank you.
@@ -482,6 +677,7 @@ avrdude done. Thank you.
@end example
@c
@c Node
@c
@@ -548,6 +744,33 @@ Leave terminal mode and thus AVRDUDE.
@end table
@noindent
In addition, the following commands are supported on the STK500
programmer:
@table @code
@item vtarg @var{voltage}
Set the target's supply voltage to @var{voltage} Volts.
@item varef @var{voltage}
Set the adjustable voltage source to @var{voltage} Volts.
This voltage is normally used to drive the target's
@emph{Aref} input on the STK500.
@item fosc @var{freq}[@var{M}|@var{k}]
Set the master oscillator to @var{freq} Hz.
An optional trailing letter @var{M}
multiplies by 1E6, a trailing letter @var{k} by 1E3.
@item fosc off
Turn the master oscillator off.
@item parms
Display the current voltage and master oscillator parameters.
@end table
@c
@c Node
@c
@@ -614,8 +837,8 @@ avrdude>
@noindent
Program the fuse bits of an ATmega128 (disable M103 compatibility,
enable high speed external crystal, enable brown-out detection). First
display the factory defaults, then reprogram:
enable high speed external crystal, enable brown-out detection, slowly
rising power). First display the factory defaults, then reprogram:
@example
@cartouche
@@ -642,8 +865,8 @@ avrdude> w efuse 0 0xff
avrdude> w hfuse 0 0x89
>>> w hfuse 0 0x89
avrdude> w lfuse 0 0x2e
>>> w lfuse 0 0x2e
avrdude> w lfuse 0 0x2f
>>> w lfuse 0 0x2f
avrdude>
@end cartouche
@@ -719,17 +942,18 @@ 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
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
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
;
@end example
@@ -776,7 +1000,7 @@ part
@end example
@menu
* Instruction Format::
* Instruction Format::
@end menu
@c
@@ -824,7 +1048,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",
@@ -844,7 +1068,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 are obtained from the software section (@code{avr061.zip} of
and is 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}.
@@ -879,12 +1103,12 @@ problem with the at90s4433/2333's; see the at90s4433 errata at:
@c
@c Node
@c
@node Platform Dependent Information, , Configuration File, Top
@node Platform Dependent Information, Troubleshooting, Configuration File, Top
@appendix Platform Dependent Information
@menu
* Unix::
* Windows::
* Unix::
* Windows::
@end menu
@c
@@ -1269,6 +1493,8 @@ means that after the first time install_giveio is executed, you should
be able to subsequently execute the batch file from any directory and have
it successfully start the driver.
Note that you must have administrator privilege to load the giveio driver.
@c
@c Node
@c
@@ -1318,4 +1544,55 @@ 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,11 +360,10 @@ int b2srec(unsigned char * inbuf, int bufsize,
char * outfile, FILE * outf)
{
unsigned char * buf;
unsigned int nextaddr, stopaddr;
unsigned int nextaddr;
int n, nbytes, addr_width;
int i;
unsigned char cksum;
unsigned char startf, stopf ,emptyf;
char * tmpl=0;
@@ -373,39 +372,11 @@ int b2srec(unsigned char * inbuf, int bufsize,
progname, recsize);
return -1;
}
nextaddr = startaddr;
buf = inbuf;
nextaddr = 0;
stopaddr = 0;
startf = 0;
stopf = 0;
nbytes = 0;
/* search for ranges of 'real' data */
for (i=startaddr; i<bufsize; i++) {
if (buf[i] == 0xff) {
if (startf == 0)
continue;
else if (stopf == 0) {
stopf = 1;
stopaddr = i;
}
}
else {
if (startf == 0) {
startf = 1;
nextaddr = i;
while (nextaddr % recsize != 0)
nextaddr --;
}
else if (stopf == 1) {
stopf = 0;
stopaddr = bufsize;
}
}
}
nbytes = i;
bufsize = stopaddr - nextaddr;
addr_width = 0;
while (bufsize) {
@@ -435,34 +406,23 @@ int b2srec(unsigned char * inbuf, int bufsize,
return -1;
}
/* skip the lines filled with 0xff */
emptyf = 1;
fprintf(outf, tmpl, n + addr_width + 1, nextaddr);
cksum += n + addr_width + 1;
for (i=addr_width; i>0; i--)
cksum += (nextaddr >> (i-1) * 8) & 0xff;
for (i=nextaddr; i<nextaddr + n; i++) {
if (buf[i] != 0xff) {
emptyf=0;
break;
}
fprintf(outf, "%02X", buf[i]);
cksum += buf[i];
}
if (emptyf != 1) {
fprintf(outf, tmpl, n + addr_width + 1, nextaddr);
cksum += n + addr_width + 1;
for (i=addr_width; i>0; i--)
cksum += (nextaddr >> (i-1) * 8) & 0xff;
for (i=nextaddr; i<nextaddr + n; i++) {
fprintf(outf, "%02X", buf[i]);
cksum += buf[i];
}
cksum = 0xff - cksum;
fprintf(outf, "%02X\n", cksum);
}
cksum = 0xff - cksum;
fprintf(outf, "%02X\n", cksum);
nextaddr += n;
nbytes +=n;
}
/* advance to next 'recsize' bytes */
@@ -728,6 +688,49 @@ int fileio_rbin(struct fioparms * fio,
}
int fileio_imm(struct fioparms * fio,
char * filename, FILE * f, unsigned char * buf, int size)
{
int rc = 0;
char * e, * p;
unsigned long b;
int loc;
switch (fio->op) {
case FIO_READ:
loc = 0;
p = strtok(filename, " ,");
while (p != NULL && loc < size) {
b = strtoul(p, &e, 0);
if (*e != 0) {
fprintf(stderr,
"%s: invalid byte value (%s) specified for immediate mode\n",
progname, p);
return -1;
}
buf[loc++] = b;
p = strtok(NULL, " ,");
rc = loc;
}
break;
default:
fprintf(stderr, "%s: fileio: invalid operation=%d\n",
progname, fio->op);
return -1;
}
if (rc < 0 || (fio->op == FIO_WRITE && rc < size)) {
fprintf(stderr,
"%s: %s error %s %s: %s; %s %d of the expected %d bytes\n",
progname, fio->iodesc, fio->dir, filename, strerror(errno),
fio->rw, rc, size);
return -1;
}
return rc;
}
int fileio_ihex(struct fioparms * fio,
char * filename, FILE * f, unsigned char * buf, int size)
{
@@ -892,8 +895,8 @@ int fileio(int op, char * filename, FILEFMT format,
char * fname;
unsigned char * buf;
struct fioparms fio;
int i;
AVRMEM * mem;
int using_stdio;
mem = avr_locate_mem(p, memtype);
if (mem == NULL) {
@@ -907,6 +910,33 @@ int fileio(int op, char * filename, FILEFMT format,
if (rc < 0)
return -1;
#if defined(__CYGWIN__)
/* Open Raw Binary format in binary mode on Windows.*/
if(format == FMT_RBIN)
{
if(fio.op == FIO_READ)
{
fio.mode = "rb";
}
if(fio.op == FIO_WRITE)
{
fio.mode = "wb";
}
}
#endif
/* point at the requested memory buffer */
buf = mem->buf;
if (fio.op == FIO_READ)
size = mem->size;
if (fio.op == FIO_READ) {
/* 0xff fill unspecified memory */
memset(buf, 0xff, size);
}
using_stdio = 0;
if (strcmp(filename, "-")==0) {
if (fio.op == FIO_READ) {
fname = "<stdin>";
@@ -916,30 +946,22 @@ int fileio(int op, char * filename, FILEFMT format,
fname = "<stdout>";
f = stdout;
}
using_stdio = 1;
}
else {
fname = filename;
f = fopen(fname, fio.mode);
if (f == NULL) {
fprintf(stderr, "%s: can't open %s file %s: %s\n",
progname, fio.iodesc, fname, strerror(errno));
return -1;
}
}
/* point at the requested memory buffer */
buf = mem->buf;
if (fio.op == FIO_READ)
size = mem->size;
if (fio.op == FIO_READ) {
/* 0xff fill unspecified memory */
for (i=0; i<size; i++) {
buf[i] = 0xff;
}
f = NULL;
}
if (format == FMT_AUTO) {
if (using_stdio) {
fprintf(stderr,
"%s: can't auto detect file format when using stdin/out.\n"
" Please specify a file format using the -f option and try again.\n",
progname);
exit(1);
}
format = fmt_autodetect(fname);
if (format < 0) {
fprintf(stderr,
@@ -952,6 +974,17 @@ int fileio(int op, char * filename, FILEFMT format,
progname, fio.iodesc, fname, fmtstr(format));
}
if (format != FMT_IMM) {
if (!using_stdio) {
f = fopen(fname, fio.mode);
if (f == NULL) {
fprintf(stderr, "%s: can't open %s file %s: %s\n",
progname, fio.iodesc, fname, strerror(errno));
return -1;
}
}
}
switch (format) {
case FMT_IHEX:
rc = fileio_ihex(&fio, fname, f, buf, size);
@@ -965,12 +998,26 @@ int fileio(int op, char * filename, FILEFMT format,
rc = fileio_rbin(&fio, fname, f, buf, size);
break;
case FMT_IMM:
rc = fileio_imm(&fio, fname, f, buf, size);
break;
default:
fprintf(stderr, "%s: invalid %s file format: %d\n",
progname, fio.iodesc, format);
return -1;
}
if (rc > 0) {
if ((op == FIO_READ) && (strcasecmp(mem->desc, "flash") == 0)) {
/*
* if we are reading flash, just mark the size as being the
* highest non-0xff byte
*/
rc = avr_mem_hiaddr(mem);
}
}
return rc;
}

View File

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

View File

@@ -117,6 +117,7 @@ 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; }
@@ -125,6 +126,8 @@ default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
devicecode { yylval=NULL; return K_DEVICECODE; }
stk500_devcode { yylval=NULL; return K_STK500_DEVCODE; }
avr910_devcode { yylval=NULL; return K_AVR910_DEVCODE; }
eeprom { yylval=NULL; return K_EEPROM; }
errled { yylval=NULL; return K_ERRLED; }
flash { yylval=NULL; return K_FLASH; }
@@ -152,6 +155,8 @@ 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,8 +319,6 @@ 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",
@@ -328,19 +326,6 @@ 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));
@@ -352,16 +337,6 @@ 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,6 +57,7 @@ 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;
@@ -89,6 +90,13 @@ PROGRAMMER * pgm_new(void)
*/
pgm->paged_write = NULL;
pgm->paged_load = NULL;
pgm->write_setup = NULL;
pgm->write_byte = NULL;
pgm->read_byte = NULL;
pgm->read_sig_bytes = NULL;
pgm->set_vtarget = NULL;
pgm->set_varef = NULL;
pgm->set_fosc = NULL;
return pgm;
}

View File

@@ -42,6 +42,7 @@ 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);
@@ -66,6 +67,16 @@ typedef struct programmer_t {
int page_size, int n_bytes);
int (*paged_load) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes);
void (*write_setup) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
int (*write_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
unsigned long addr, unsigned char value);
int (*read_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
unsigned long addr, unsigned char * value);
int (*read_sig_bytes) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
void (*print_parms) (struct programmer_t * pgm);
int (*set_vtarget) (struct programmer_t * pgm, double v);
int (*set_varef) (struct programmer_t * pgm, double v);
int (*set_fosc) (struct programmer_t * pgm, double v);
char config_file[PATH_MAX]; /* config file where defined */
int lineno; /* config file line number */
} PROGRAMMER;

View File

@@ -43,24 +43,33 @@
extern char * progname;
/*
* 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)
enum {
PPI_READ,
PPI_WRITE,
PPI_SHADOWREAD
};
int ppi_shadow_access(int fd, int reg, unsigned char *v, unsigned char action)
{
static unsigned char shadow[3];
int shadow_num;
unsigned long set, get;
switch (reg) {
case PPIDATA:
*set = PPISDATA;
*get = PPIGDATA;
set = PPISDATA;
get = PPIGDATA;
shadow_num = 0;
break;
case PPICTRL:
*set = PPISCTRL;
*get = PPIGCTRL;
set = PPISCTRL;
get = PPIGCTRL;
shadow_num = 1;
break;
case PPISTATUS:
*set = PPISSTATUS;
*get = PPIGSTATUS;
set = PPISSTATUS;
get = PPIGSTATUS;
shadow_num = 2;
break;
default:
fprintf(stderr, "%s: avr_set(): invalid register=%d\n",
@@ -69,27 +78,37 @@ static int ppi_getops(int reg, unsigned long * get, unsigned long * set)
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_getops(reg, &get, &set);
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
v |= bit;
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
if (rc)
return -1;
ioctl(fd, get, &v);
v |= bit;
ioctl(fd, set, &v);
return 0;
}
@@ -100,17 +119,15 @@ 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_getops(reg, &get, &set);
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
v &= ~bit;
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
if (rc)
return -1;
ioctl(fd, get, &v);
v &= ~bit;
ioctl(fd, set, &v);
return 0;
}
@@ -121,16 +138,14 @@ 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_getops(reg, &get, &set);
rc = ppi_shadow_access(fd, reg, &v, PPI_READ);
v &= bit;
if (rc)
return -1;
ioctl(fd, get, &v);
v &= bit;
return v; /* v == bit */
}
@@ -140,17 +155,15 @@ 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_getops(reg, &get, &set);
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
v ^= bit;
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
if (rc)
return -1;
ioctl(fd, get, &v);
v ^= bit;
ioctl(fd, set, &v);
return 0;
}
@@ -161,16 +174,14 @@ 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_getops(reg, &get, &set);
rc = ppi_shadow_access(fd, reg, &v, PPI_READ);
if (rc)
return -1;
ioctl(fd, get, &v);
return (int)v;
return v; /* v == bit */
}
/*
@@ -179,16 +190,14 @@ 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;
rc = ppi_getops(reg, &get, &set);
v = val;
rc = ppi_shadow_access(fd, reg, &v, PPI_WRITE);
if (rc)
return -1;
v = val;
ioctl(fd, set, &v);
return 0;
}
@@ -196,6 +205,7 @@ 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) {
@@ -204,6 +214,14 @@ 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@umginc.net> or <eric@ecentral.com>
* Copyright (C) 2003 Eric B. Weddington <eric@ecentral.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -39,6 +39,8 @@ reg = register as defined in an enum in ppi.h. This must be converted
#include <string.h>
#include <unistd.h>
#include <windows.h>
#include <sys/time.h>
#include <w32api/windows.h>
#include "ppi.h"
@@ -315,6 +317,78 @@ static void outb(unsigned char value, unsigned short port)
return;
}
/* These two functions usecPerfDelay and usleep are based on code from the
* uisp project and are a replacement for the cygwin usleep library
* function which seems to not delay for the correct time
*/
BOOL usecPerfDelay(long t)
{
static BOOL perf_counter_checked = FALSE;
static BOOL use_perf_counter = FALSE;
static LARGE_INTEGER freq ;
if (! perf_counter_checked) {
if (QueryPerformanceFrequency(&freq)){
use_perf_counter = TRUE;
}
perf_counter_checked = TRUE;
}
if (! use_perf_counter)
return FALSE;
else {
LARGE_INTEGER now;
LARGE_INTEGER finish;
QueryPerformanceCounter(&now);
finish.QuadPart = now.QuadPart + (t * freq.QuadPart) / 1000000;
do {
QueryPerformanceCounter(&now);
} while (now.QuadPart < finish.QuadPart);
return TRUE;
}
}
/*
WARNING WARNING This function replaces the standard usleep() library function
because it doesn't appear to delay for the correct time.
*/
#ifndef MIN_SLEEP_USEC
#define MIN_SLEEP_USEC 20000
#endif
unsigned usleep( unsigned int uSeconds )
{
struct timeval t1, t2;
struct timespec nanoDelay ;
if (usecPerfDelay(uSeconds))
return(0);
gettimeofday(&t1, NULL);
if( uSeconds > MIN_SLEEP_USEC )
{
nanoDelay.tv_sec = uSeconds / 1000000UL;
nanoDelay.tv_nsec = (uSeconds / 1000000UL) * 1000 ;
nanosleep( &nanoDelay, NULL ) ;
}
/* loop for the remaining time */
t2.tv_sec = uSeconds / 1000000UL;
t2.tv_usec = uSeconds % 1000000UL;
timeradd(&t1, &t2, &t1);
do {
gettimeofday(&t2, NULL);
} while (timercmp(&t2, &t1, <));
return(0);
}
#endif

352
avrdude/ser_posix.c Normal file
View File

@@ -0,0 +1,352 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* $Id$ */
/*
* Posix serial interface for avrdude.
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
extern char *progname;
extern int verbose;
struct baud_mapping {
long baud;
speed_t speed;
};
/* There are a lot more baud rates we could handle, but what's the point? */
static struct baud_mapping baud_lookup_table [] = {
{ 1200, B1200 },
{ 2400, B2400 },
{ 4800, B4800 },
{ 9600, B9600 },
{ 19200, B19200 },
{ 38400, B38400 },
{ 57600, B57600 },
{ 115200, B115200 },
{ 230400, B230400 },
{ 0, 0 } /* Terminator. */
};
static speed_t serial_baud_lookup(long baud)
{
struct baud_mapping *map = baud_lookup_table;
while (map->baud) {
if (map->baud == baud)
return map->speed;
map++;
}
fprintf(stderr, "%s: serial_baud_lookup(): unknown baud rate: %ld",
progname, baud);
exit(1);
}
static int serial_setattr(int fd, long baud)
{
int rc;
struct termios termios;
speed_t speed = serial_baud_lookup (baud);
if (!isatty(fd))
return -1;
/*
* initialize terminal modes
*/
rc = tcgetattr(fd, &termios);
if (rc < 0) {
fprintf(stderr, "%s: serial_setattr(): tcgetattr() failed, %s",
progname, strerror(errno));
return -errno;
}
termios.c_iflag = 0;
termios.c_oflag = 0;
termios.c_cflag = 0;
termios.c_cflag |= (CS8 | CREAD | CLOCAL);
termios.c_lflag = 0;
termios.c_cc[VMIN] = 1;
termios.c_cc[VTIME] = 0;
cfsetospeed(&termios, speed);
cfsetispeed(&termios, speed);
rc = tcsetattr(fd, TCSANOW, &termios);
if (rc < 0) {
fprintf(stderr, "%s: serial_setattr(): tcsetattr() failed, %s",
progname, strerror(errno));
return -errno;
}
return 0;
}
int serial_open(char * port, int baud)
{
int rc;
int fd;
/*
* open the serial port
*/
fd = open(port, O_RDWR | O_NOCTTY /*| O_NONBLOCK*/);
if (fd < 0) {
fprintf(stderr, "%s: serial_open(): can't open device \"%s\": %s\n",
progname, port, strerror(errno));
exit(1);
}
/*
* set serial line attributes
*/
rc = serial_setattr(fd, baud);
if (rc) {
fprintf(stderr,
"%s: serial_open(): can't set attributes for device \"%s\"\n",
progname, port);
exit(1);
}
return fd;
}
void serial_close(int fd)
{
/* FIXME: Should really restore the terminal to original state here. */
close(fd);
}
int serial_send(int fd, char * buf, size_t buflen)
{
struct timeval timeout;
fd_set wfds;
int nfds;
int rc;
char * p = buf;
size_t len = buflen;
if (!len)
return 0;
if (verbose > 3)
{
fprintf(stderr, "%s: Send: ", progname);
while (buflen) {
unsigned char c = *buf;
if (isprint(c)) {
fprintf(stderr, "%c ", c);
}
else {
fprintf(stderr, ". ");
}
fprintf(stderr, "[%02x] ", c);
buf++;
buflen--;
}
fprintf(stderr, "\n");
}
timeout.tv_sec = 0;
timeout.tv_usec = 500000;
while (len) {
FD_ZERO(&wfds);
FD_SET(fd, &wfds);
reselect:
nfds = select(fd+1, NULL, &wfds, NULL, &timeout);
if (nfds == 0) {
fprintf(stderr,
"%s: serial_send(): programmer is not responding\n",
progname);
exit(1);
}
else if (nfds == -1) {
if (errno == EINTR) {
goto reselect;
}
else {
fprintf(stderr, "%s: serial_send(): select(): %s\n",
progname, strerror(errno));
exit(1);
}
}
rc = write(fd, p, 1);
if (rc < 0) {
fprintf(stderr, "%s: serial_send(): write error: %s\n",
progname, strerror(errno));
exit(1);
}
p++;
len--;
}
return 0;
}
int serial_recv(int fd, char * buf, size_t buflen)
{
struct timeval timeout;
fd_set rfds;
int nfds;
int rc;
char * p = buf;
size_t len = 0;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
while (len < buflen) {
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
reselect:
nfds = select(fd+1, &rfds, NULL, NULL, &timeout);
if (nfds == 0) {
fprintf(stderr,
"%s: serial_recv(): programmer is not responding\n",
progname);
exit(1);
}
else if (nfds == -1) {
if (errno == EINTR) {
goto reselect;
}
else {
fprintf(stderr, "%s: serial_recv(): select(): %s\n",
progname, strerror(errno));
exit(1);
}
}
rc = read(fd, p, 1);
if (rc < 0) {
fprintf(stderr, "%s: serial_recv(): read error: %s\n",
progname, strerror(errno));
exit(1);
}
p++;
len++;
}
p = buf;
if (verbose > 3)
{
fprintf(stderr, "%s: Recv: ", progname);
while (len) {
unsigned char c = *p;
if (isprint(c)) {
fprintf(stderr, "%c ", c);
}
else {
fprintf(stderr, ". ");
}
fprintf(stderr, "[%02x] ", c);
p++;
len--;
}
fprintf(stderr, "\n");
}
return 0;
}
int serial_drain(int fd, int display)
{
struct timeval timeout;
fd_set rfds;
int nfds;
int rc;
unsigned char buf;
timeout.tv_sec = 0;
timeout.tv_usec = 250000;
if (display) {
fprintf(stderr, "drain>");
}
while (1) {
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
reselect:
nfds = select(fd+1, &rfds, NULL, NULL, &timeout);
if (nfds == 0) {
if (display) {
fprintf(stderr, "<drain\n");
}
break;
}
else if (nfds == -1) {
if (errno == EINTR) {
goto reselect;
}
else {
fprintf(stderr, "%s: serial_drain(): select(): %s\n",
progname, strerror(errno));
exit(1);
}
}
rc = read(fd, &buf, 1);
if (rc < 0) {
fprintf(stderr, "%s: serial_drain(): read error: %s\n",
progname, strerror(errno));
exit(1);
}
if (display) {
fprintf(stderr, "%02x ", buf);
}
}
return 0;
}

60
avrdude/ser_win32.c Normal file
View File

@@ -0,0 +1,60 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* $Id$ */
/*
* Native Win32 serial interface for avrdude.
*/
#include "serial.h"
extern char *progname;
#if 0
int serial_open(char * port, long baud)
{
return fd;
}
void serial_close(int fd)
{
}
int serial_send(int fd, char * buf, size_t buflen)
{
return 0;
}
int serial_recv(int fd, char * buf, size_t buflen)
{
return 0;
}
int serial_drain(int fd, int display)
{
return 0;
}
#endif

42
avrdude/serial.h Normal file
View File

@@ -0,0 +1,42 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* $Id$ */
/* This is the API for the generic serial interface. The implementations are
actually provided by the target dependant files:
ser_posix.c : posix serial interface.
ser_win32.c : native win32 serial interface.
The target file will be selected at configure time. */
#ifndef __serial_h__
#define __serial_h__
#include "config.h"
extern int serial_open(char * port, long baud);
extern void serial_close(int fd);
extern int serial_send(int fd, char * buf, size_t buflen);
extern int serial_recv(int fd, char * buf, size_t buflen);
extern int serial_drain(int fd, int display);
#endif /* __serial_h__ */

View File

@@ -33,171 +33,42 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <termios.h>
#include <sys/time.h>
#include <unistd.h>
#include "avr.h"
#include "pgm.h"
#include "stk500_private.h"
#include "serial.h"
extern int verbose;
extern char * progname;
extern int do_cycles;
static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value);
static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value);
static void stk500_print_parms1(PROGRAMMER * pgm, char * p);
static int stk500_is_page_empty(unsigned int address, int page_size,
const unsigned char *buf);
static int stk500_send(PROGRAMMER * pgm, char * buf, int buflen)
static int stk500_send(PROGRAMMER * pgm, char * buf, size_t len)
{
struct timeval timeout;
fd_set wfds;
int nfds;
int rc;
if (!buflen)
return 0;
timeout.tv_sec = 0;
timeout.tv_usec = 500000;
while (buflen) {
FD_ZERO(&wfds);
FD_SET(pgm->fd, &wfds);
reselect:
nfds = select(pgm->fd+1, NULL, &wfds, NULL, &timeout);
if (nfds == 0) {
fprintf(stderr,
"%s: stk500_send(): programmer is not responding on %s\n",
progname, pgm->port);
exit(1);
}
else if (nfds == -1) {
if (errno == EINTR) {
goto reselect;
}
else {
fprintf(stderr, "%s: stk500_send(): select(): %s\n",
progname, strerror(errno));
exit(1);
}
}
rc = write(pgm->fd, buf, 1);
if (rc < 0) {
fprintf(stderr, "%s: stk500_send(): write error: %s\n",
progname, strerror(errno));
exit(1);
}
buf++;
buflen--;
}
return 0;
return serial_send(pgm->fd, buf, len);
}
static int stk500_recv(PROGRAMMER * pgm, char * buf, int n)
static int stk500_recv(PROGRAMMER * pgm, char * buf, size_t len)
{
struct timeval timeout;
fd_set rfds;
int nfds;
int rc;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
while (n) {
FD_ZERO(&rfds);
FD_SET(pgm->fd, &rfds);
reselect:
nfds = select(pgm->fd+1, &rfds, NULL, NULL, &timeout);
if (nfds == 0) {
fprintf(stderr,
"%s: stk500_recv(): programmer is not responding on %s\n",
progname, pgm->port);
exit(1);
}
else if (nfds == -1) {
if (errno == EINTR) {
goto reselect;
}
else {
fprintf(stderr, "%s: stk500_recv(): select(): %s\n",
progname, strerror(errno));
exit(1);
}
}
rc = read(pgm->fd, buf, 1);
if (rc < 0) {
fprintf(stderr, "%s: stk500_recv(): read error: %s\n",
progname, strerror(errno));
exit(1);
}
buf++;
n--;
}
return 0;
return serial_recv(pgm->fd, buf, len);
}
static int stk500_drain(PROGRAMMER * pgm, int display)
{
struct timeval timeout;
fd_set rfds;
int nfds;
int rc;
unsigned char buf;
timeout.tv_sec = 0;
timeout.tv_usec = 250000;
if (display) {
fprintf(stderr, "drain>");
}
while (1) {
FD_ZERO(&rfds);
FD_SET(pgm->fd, &rfds);
reselect:
nfds = select(pgm->fd+1, &rfds, NULL, NULL, &timeout);
if (nfds == 0) {
if (display) {
fprintf(stderr, "<drain\n");
}
return 0;
}
else if (nfds == -1) {
if (errno == EINTR) {
goto reselect;
}
else {
fprintf(stderr, "%s: stk500_drain(): select(): %s\n",
progname, strerror(errno));
exit(1);
}
}
rc = read(pgm->fd, &buf, 1);
if (rc < 0) {
fprintf(stderr, "%s: stk500_drain(): read error: %s\n",
progname, strerror(errno));
exit(1);
}
if (display) {
fprintf(stderr, "%02x ", buf);
}
}
return serial_drain(pgm->fd, display);
}
@@ -300,8 +171,6 @@ 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",
@@ -309,19 +178,6 @@ 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));
@@ -333,16 +189,6 @@ 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;
}
@@ -518,7 +364,7 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
*/
buf[0] = Cmnd_STK_SET_DEVICE;
buf[1] = p->devicecode;
buf[1] = p->stk500_devcode;
buf[2] = 0; /* device revision */
if ((p->flags & AVRPART_SERIALOK) && (p->flags & AVRPART_PARALLELOK))
@@ -739,72 +585,10 @@ static void stk500_enable(PROGRAMMER * pgm)
}
static int stk500_setattr(int fd)
{
int rc;
struct termios termios;
if (!isatty(fd))
return -1;
/*
* initialize terminal modes
*/
rc = tcgetattr(fd, &termios);
if (rc < 0) {
fprintf(stderr, "%s: stk500_setattr(): tcgetattr() failed, %s",
progname, strerror(errno));
return -errno;
}
termios.c_iflag = 0;
termios.c_oflag = 0;
termios.c_cflag = 0;
termios.c_cflag |= (CS8 | CREAD | CLOCAL);
termios.c_lflag = 0;
termios.c_cc[VMIN] = 1;
termios.c_cc[VTIME] = 0;
cfsetospeed(&termios, B115200);
cfsetispeed(&termios, B115200);
rc = tcsetattr(fd, TCSANOW, &termios);
if (rc < 0) {
fprintf(stderr, "%s: stk500_setattr(): tcsetattr() failed, %s",
progname, strerror(errno));
return -errno;
}
return 0;
}
static void stk500_open(PROGRAMMER * pgm, char * port)
{
int rc;
strcpy(pgm->port, port);
/*
* open the serial port
*/
pgm->fd = open(port, O_RDWR | O_NOCTTY /*| O_NONBLOCK*/);
if (pgm->fd < 0) {
fprintf(stderr, "%s: stk500_open(): can't open device \"%s\": %s\n",
progname, port, strerror(errno));
exit(1);
}
/*
* set serial line attributes
*/
rc = stk500_setattr(pgm->fd);
if (rc) {
fprintf(stderr,
"%s: stk500_open(): can't set attributes for device \"%s\"\n",
progname, port);
exit(1);
}
pgm->fd = serial_open(port, 115200);
/*
* drain any extraneous input
@@ -819,7 +603,7 @@ static void stk500_open(PROGRAMMER * pgm, char * port)
static void stk500_close(PROGRAMMER * pgm)
{
close(pgm->fd);
serial_close(pgm->fd);
pgm->fd = -1;
}
@@ -878,9 +662,10 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int memtype;
unsigned int addr;
int a_div;
int i;
int block_size;
int tries;
unsigned int n;
int flash;
if (page_size == 0) {
page_size = 128;
@@ -888,9 +673,11 @@ 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;
@@ -924,20 +711,33 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
#endif
for (addr = 0; addr < n; addr += page_size) {
fprintf(stderr, "\r \r%6u", addr);
report_progress (addr, n_bytes, NULL);
if (addr + page_size > n_bytes) {
block_size = n_bytes % page_size;
}
else {
block_size = page_size;
}
/* Only skip on empty page if programming flash. */
if (flash) {
if (stk500_is_page_empty(addr, block_size, m->buf)) {
continue;
}
}
tries = 0;
retry:
tries++;
stk500_loadaddr(pgm, addr/a_div);
buf[0] = Cmnd_STK_PROG_PAGE;
buf[1] = (page_size >> 8) & 0xff;
buf[2] = page_size & 0xff;
buf[1] = (block_size >> 8) & 0xff;
buf[2] = block_size & 0xff;
buf[3] = memtype;
stk500_send(pgm, buf, 4);
for (i=0; i<page_size; i++) {
buf[0] = m->buf[addr + i];
stk500_send(pgm, buf, 1);
}
stk500_send(pgm, &m->buf[addr], block_size);
buf[0] = Sync_CRC_EOP;
stk500_send(pgm, buf, 1);
@@ -968,12 +768,24 @@ 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;
return n_bytes;
}
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)
@@ -984,6 +796,7 @@ 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';
@@ -1014,14 +827,22 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
}
for (addr = 0; addr < n; addr += page_size) {
fprintf(stderr, "\r \r%6u", addr);
report_progress (addr, n_bytes, NULL);
if (addr + page_size > n_bytes) {
block_size = n_bytes % page_size;
}
else {
block_size = page_size;
}
tries = 0;
retry:
tries++;
stk500_loadaddr(pgm, addr/a_div);
buf[0] = Cmnd_STK_READ_PAGE;
buf[1] = (page_size >> 8) & 0xff;
buf[2] = page_size & 0xff;
buf[1] = (block_size >> 8) & 0xff;
buf[2] = block_size & 0xff;
buf[3] = memtype;
buf[4] = Sync_CRC_EOP;
stk500_send(pgm, buf, 5);
@@ -1044,7 +865,7 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
return -4;
}
stk500_recv(pgm, &m->buf[addr], page_size);
stk500_recv(pgm, &m->buf[addr], block_size);
stk500_recv(pgm, buf, 1);
if (buf[0] != Resp_STK_OK) {
@@ -1055,10 +876,108 @@ 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;
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;
}
@@ -1118,21 +1037,141 @@ static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
}
static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value)
{
unsigned char buf[16];
int tries = 0;
retry:
tries++;
buf[0] = Cmnd_STK_SET_PARAMETER;
buf[1] = parm;
buf[2] = value;
buf[3] = Sync_CRC_EOP;
stk500_send(pgm, buf, 4);
stk500_recv(pgm, buf, 1);
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
fprintf(stderr, "\n%s: stk500_setparm(): can't get into sync\n",
progname);
return -1;
}
stk500_getsync(pgm);
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
fprintf(stderr,
"\n%s: stk500_setparm(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
return -2;
}
stk500_recv(pgm, buf, 1);
if (buf[0] == Resp_STK_OK)
return 0;
parm = buf[0]; /* if not STK_OK, we've been echoed parm here */
stk500_recv(pgm, buf, 1);
if (buf[0] == Resp_STK_FAILED) {
fprintf(stderr,
"\n%s: stk500_setparm(): parameter 0x%02x failed\n",
progname, parm);
return -3;
}
else {
fprintf(stderr,
"\n%s: stk500_setparm(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
return -3;
}
}
static void stk500_display(PROGRAMMER * pgm, char * p)
{
unsigned maj, min, hdw;
unsigned maj, min, hdw, topcard;
stk500_getparm(pgm, Parm_STK_HW_VER, &hdw);
stk500_getparm(pgm, Parm_STK_SW_MAJOR, &maj);
stk500_getparm(pgm, Parm_STK_SW_MINOR, &min);
stk500_getparm(pgm, Param_STK500_TOPCARD_DETECT, &topcard);
fprintf(stderr, "%sHardware Version: %d\n", p, hdw);
fprintf(stderr, "%sFirmware Version: %d.%d\n", p, maj, min);
if (topcard < 3) {
const char *n = "Unknown";
switch (topcard) {
case 1:
n = "STK502";
break;
case 2:
n = "STK501";
break;
}
fprintf(stderr, "%sTopcard : %s\n", p, n);
}
stk500_print_parms1(pgm, p);
return;
}
static void stk500_print_parms1(PROGRAMMER * pgm, char * p)
{
unsigned vtarget, vadjust, osc_pscale, osc_cmatch;
stk500_getparm(pgm, Parm_STK_VTARGET, &vtarget);
stk500_getparm(pgm, Parm_STK_VADJUST, &vadjust);
stk500_getparm(pgm, Parm_STK_OSC_PSCALE, &osc_pscale);
stk500_getparm(pgm, Parm_STK_OSC_CMATCH, &osc_cmatch);
fprintf(stderr, "%sVtarget : %.1f V\n", p, vtarget / 10.0);
fprintf(stderr, "%sVaref : %.1f V\n", p, vadjust / 10.0);
fprintf(stderr, "%sOscillator : ", p);
if (osc_pscale == 0)
fprintf(stderr, "Off\n");
else {
int prescale = 1;
double f = 3.6864e6;
const char *unit;
switch (osc_pscale) {
case 2: prescale = 8; break;
case 3: prescale = 32; break;
case 4: prescale = 64; break;
case 5: prescale = 128; break;
case 6: prescale = 256; break;
case 7: prescale = 1024; break;
}
f /= prescale;
f /= (osc_cmatch + 1);
if (f > 1e6) {
f /= 1e6;
unit = "MHz";
} else if (f > 1e3) {
f /= 1000;
unit = "kHz";
} else
unit = "Hz";
fprintf(stderr, "%.3f %s\n", f, unit);
}
return;
}
static void stk500_print_parms(PROGRAMMER * pgm)
{
stk500_print_parms1(pgm, "");
}
void stk500_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "STK500");
@@ -1163,7 +1202,9 @@ void stk500_initpgm(PROGRAMMER * pgm)
*/
pgm->paged_write = stk500_paged_write;
pgm->paged_load = stk500_paged_load;
pgm->print_parms = stk500_print_parms;
pgm->set_vtarget = stk500_set_vtarget;
pgm->set_varef = stk500_set_varef;
pgm->set_fosc = stk500_set_fosc;
pgm->page_size = 256;
}

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,6 +21,8 @@
#include "ac_cfg.h"
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
@@ -66,6 +68,14 @@ int cmd_quit (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
int cmd_send (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
int cmd_parms (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
int cmd_vtarg (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
int cmd_varef (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
int cmd_fosc (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
struct command cmd[] = {
{ "dump", cmd_dump, "dump memory : %s <memtype> <addr> <N-Bytes>" },
@@ -75,6 +85,10 @@ struct command cmd[] = {
{ "sig", cmd_sig, "display device signature bytes" },
{ "part", cmd_part, "display the current part information" },
{ "send", cmd_send, "send a raw command : %s <b1> <b2> <b3> <b4>" },
{ "parms", cmd_parms, "display adjustable parameters (STK500 only)" },
{ "vtarg", cmd_vtarg, "set <V[target]> (STK500 only)" },
{ "varef", cmd_varef, "set <V[aref]> (STK500 only)" },
{ "fosc", cmd_fosc, "set <oscillator frequency> (STK500 only)" },
{ "help", cmd_help, "help" },
{ "?", cmd_help, "help" },
{ "quit", cmd_quit, "quit" }
@@ -497,6 +511,120 @@ int cmd_quit(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
}
int cmd_parms(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
{
if (pgm->print_parms == NULL) {
fprintf(stderr,
"%s (parms): the %s programmer does not support "
"adjustable parameters\n",
progname, pgm->type);
return -1;
}
pgm->print_parms(pgm);
return 0;
}
int cmd_vtarg(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
{
int rc;
double v;
char *endp;
if (argc != 2) {
fprintf(stderr, "Usage: vtarg <value>\n");
return -1;
}
v = strtod(argv[1], &endp);
if (endp == argv[1]) {
fprintf(stderr, "%s (vtarg): can't parse voltage \"%s\"\n",
progname, argv[1]);
return -1;
}
if (pgm->set_vtarget == NULL) {
fprintf(stderr, "%s (vtarg): the %s programmer cannot set V[target]\n",
progname, pgm->type);
return -2;
}
if ((rc = pgm->set_vtarget(pgm, v)) != 0) {
fprintf(stderr, "%s (vtarg): failed to set V[target] (rc = %d)\n",
progname, rc);
return -3;
}
return 0;
}
int cmd_fosc(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
{
int rc;
double v;
char *endp;
if (argc != 2) {
fprintf(stderr, "Usage: fosc <value>[M|k] | off\n");
return -1;
}
v = strtod(argv[1], &endp);
if (endp == argv[1]) {
if (strcmp(argv[1], "off") == 0)
v = 0.0;
else {
fprintf(stderr, "%s (fosc): can't parse frequency \"%s\"\n",
progname, argv[1]);
return -1;
}
}
if (*endp == 'm' || *endp == 'M')
v *= 1e6;
else if (*endp == 'k' || *endp == 'K')
v *= 1e3;
if (pgm->set_fosc == NULL) {
fprintf(stderr,
"%s (fosc): the %s programmer cannot set oscillator frequency\n",
progname, pgm->type);
return -2;
}
if ((rc = pgm->set_fosc(pgm, v)) != 0) {
fprintf(stderr, "%s (fosc): failed to set oscillator_frequency (rc = %d)\n",
progname, rc);
return -3;
}
return 0;
}
int cmd_varef(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
{
int rc;
double v;
char *endp;
if (argc != 2) {
fprintf(stderr, "Usage: varef <value>\n");
return -1;
}
v = strtod(argv[1], &endp);
if (endp == argv[1]) {
fprintf(stderr, "%s (varef): can't parse voltage \"%s\"\n",
progname, argv[1]);
return -1;
}
if (pgm->set_varef == NULL) {
fprintf(stderr, "%s (varef): the %s programmer cannot set V[aref]\n",
progname, pgm->type);
return -2;
}
if ((rc = pgm->set_varef(pgm, v)) != 0) {
fprintf(stderr, "%s (varef): failed to set V[aref] (rc = %d)\n",
progname, rc);
return -3;
}
return 0;
}
int cmd_help(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
{
int i;

View File

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