96 Commits

Author SHA1 Message Date
Joerg Wunsch
7e4168e0d0 This commit was manufactured by cvs2svn to create tag
'RELEASE_5_6_0'.

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/tags/RELEASE_5_6_0@812 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-27 10:31:34 +00:00
Joerg Wunsch
795b5ded83 Prepare for releasing version 5.6.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@811 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-27 10:31:33 +00:00
Joerg Wunsch
a21d1f3ceb Submitted by Ed Okerson:
* jtagmkII.c (jtagmkII_read_byte): Fix signature reading of
Xmega.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@810 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-27 08:29:30 +00:00
Joerg Wunsch
c5ec274a19 Submitted by Mikael Hermansson:
* avrdude.conf.in (ATxmega256A3): new device.
* stk500v2 (stk500v2_initialize): Enable the AVRISPmkII as a
PDI-capable device for ATxmega parts.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@809 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-26 19:43:55 +00:00
Joerg Wunsch
a824d108c6 Submitted by Lars Immisch:
patch #6750: Arduino support - new programmer-id
* arduino.c: New file, inherits stk500.c.
* arduino.h: New file.
* Makefile.am: Add arduino.c and arduino.h.
* config_gram.y: Add arduino keyword.
* lexer.l: (Ditto.)
* avrdude.conf.in: (Ditto.)
* avrdude.1: Document the new programmer type.
* doc/avrdude.texi: (Ditto.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@808 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-25 09:39:04 +00:00
Joerg Wunsch
a76d845880 Turn all non-const static data into instance data.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@807 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-25 09:20:38 +00:00
Joerg Wunsch
27072552fa Move term.[ch] from the library into the CLI application section, as
it is not useful for anything else but the CLI frontend.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@806 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-25 08:00:14 +00:00
Joerg Wunsch
d32338b5ba Add support for the ATmega1284P.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@805 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-25 07:51:04 +00:00
Joerg Wunsch
efc97346a2 More fixes for Solaris, including fixes for the Sunpro compiler:
* avr.h: Remove stray semicolon.
* configure.ac: Add check for predefined types uint_t and ulong_t.
* confwin.c: Include "avrdude.h" on top to avoid empty translation
unit warning.
* ppwin.c: (Ditto.)
* ser_win32.c: (Ditto.)
* serbb_win32.c: (Ditto.)
* jtagmkII.c (jtagmkII_recv): remove unreachable "return".
* stk500.c (stk500_initialize): (Ditto.)
* par.c: Test for both, __sun__ and __sun to see whether we are
being compiled on Solaris.
* ppi.c: (Ditto.)
* stk500v2.c: Implement the DEBUG and DEBUGRECV macros in a way
that is compatible with the ISO C99 standard.
* usbtiny.c: Only typedef uint_t and ulong_t if they have not
been found already by the autoconf checks.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@804 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-23 22:04:57 +00:00
Joerg Wunsch
71262c2d44 bug #22204: Solaris10/11 Undefiniertes Symbol gethostbyname socket
connect
* configure.ac: Add checks for gethostent() and socket().
While being here, remove some old cruft left from ancient days.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@803 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-23 21:36:04 +00:00
Joerg Wunsch
1d41442054 Bump the %p size so AT&T lex will continue to work.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@802 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-22 21:36:24 +00:00
Joerg Wunsch
822d9bc3f2 (Partially) submitted by John Voltz:
bug #20004: AVRDUDE update (-U) operations do not close files
* fileio.c (fmt_autodetect, fileio): fclose() files.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@801 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-19 10:49:55 +00:00
Joerg Wunsch
9c9c479e37 Replace all but one (very unlikely to trigger) exit(1)
by return -1.  exit(1) from a library function is not going to make
many friends upstream (in particular the day someone uses that as
part of a GUI frontend).


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@800 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-18 20:20:56 +00:00
Joerg Wunsch
d1c90c4ce2 Submitted by Dick Streefland:
patch #6749: make reading from the USBtinyISP programmer more robust

Add code to retry failed communication attempts.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@799 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-18 20:10:32 +00:00
Joerg Wunsch
f7e7ac43be Submitted by Nick Hibma:
bug #22271: usb_reset in usb_libusb.c not necessary in FreeBSD 6.x
* usb_libusb.c (usbdev_close): Do not call usb_reset() on FreeBSD.
It is not necessary there.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@798 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-17 17:09:53 +00:00
Joerg Wunsch
98aa7dbb5a Submitted by Andrew O. Shadoura:
bug #25156: add direct SPI transfer mode
* bitbang.c: Implement direct SPI transfers.
* bitbang.h: (Ditto.)
* par.c: (Ditto.)
* pgm.c: (Ditto.)
* pgm.h: (Ditto.)
* term.c: Add the "spi" and "pgm" commands.
* avrdude.1: Document the changes.
* doc/avrdude.texi: (Ditto.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@797 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-17 15:31:27 +00:00
Joerg Wunsch
39ac828213 Submitted by Limor ("Lady Ada"):
bug #24749: add support for '328p
* avrdude.conf.in (ATmega328P): new device support.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@796 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-17 14:17:53 +00:00
Joerg Wunsch
f913088cdb Submitted by "Womo":
bug #25241: AT90USB162, AT90USB82 device support patch for avrdude-5.5
(also: bug #21745: AT90USBxx2 support)
* avrdude.conf.in (AT90USB162, AT90USB82): new device support.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@795 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-17 13:45:07 +00:00
Joerg Wunsch
9fdeb5444d Submitted by Evangelos Arkalis:
patch #6069: Atmel AT89ISP Cable
* avrdude.conf.in (89isp): new programmer support.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@794 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-17 12:43:05 +00:00
Joerg Wunsch
47660adc4b Submitted by Bob Paddock:
patch #6748: ATTiny88 Config
* avrdude.conf.in (ATtiny88): new device support.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@793 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-16 13:28:55 +00:00
Joerg Wunsch
03d6bcda04 Submitted by Mark Litwack:
patch #6261: avrdude won't use dragon/debugwire to write a file
to eeprom
* jtagmkII.c (jtagmkII_paged_write): when in debugWire mode,
implement a paged write to EEPROM as a series of byte writes.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@792 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-16 12:26:44 +00:00
Joerg Wunsch
f1411fca7e Submitted by Janos Sallai:
patch #6542: paged_load fails on the MIB510 programming board
* stk500.c: Add a workaround for the different signon sequence on
MIB510 programmers.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@791 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-16 10:19:46 +00:00
Joerg Wunsch
abb56b44fb Add the ATmega128RFA1, and document this.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@790 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-05 16:20:29 +00:00
Joerg Wunsch
27ad2caa5b Annual changelog rotation.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@789 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-02-05 16:17:57 +00:00
Joerg Wunsch
6bfb5f1f94 Change the prototype for usleep() to be more Cygwin-friendly.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@788 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-11-19 23:32:30 +00:00
Joerg Wunsch
d70f6c343c Submitted by limor <limor@ladyada.net>
* usbtiny.c (usbtiny_cmd): Replace sizeof() by a fixed constant
4 for the result array, because otherwise it would take the size
of a pointer which miserably fails on 64-bit machines.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@787 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-11-06 09:47:37 +00:00
Joerg Wunsch
e031a67542 patch #6609: Using PCI parallel port cards on Windows
* ppiwin.c (ppi_open): If the port parameter passed from the
-p option is neither lpt1/2/3, try interpreting it directly as
a base address.
* avrdude.1: Document the change.
* doc/avrdude.texi: (Ditto.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@786 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-11-05 20:53:51 +00:00
Joerg Wunsch
cafa88eb9e bug #22882: Erase Cycle Counter does not work for stk500v2
* stk500v2.c (stk500v2_chip_erase,stk500hv_chip_erase): Return
the expected 0 for success rather than a protocol-dependant
number.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@785 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-11-04 13:15:21 +00:00
Joerg Wunsch
889b1f3e48 bug #22883: Chip Erase performed even with no-write flag (-n)
Do not erase the chip if both, -e and -n options have
been specified.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@784 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-11-04 12:10:28 +00:00
Joerg Wunsch
f8f1e6486a Remove garbage from end of signature lines in AT90USB646/647, left
over accidentally from rev 1.131.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@783 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-11-04 11:46:32 +00:00
Joerg Wunsch
d888b1bbb5 bug #24589: AT90USB64* have wrong signature
Uncomment the correct, and delete the wrong signature for
AT90USB646/647.  Alas, the datasheet has never been corrected for
years.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@782 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-11-04 11:02:32 +00:00
Joerg Wunsch
d230a46035 Fix a serious memory corruption that happened when using the JTAG ICE
mkII (or AVR Dragon) in ISP mode.  The wrong set of per-programmer
private data had been allocated (stk500v2 vs. jtagmkII) which was too
small to hold the actual data.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@781 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-10-31 21:26:06 +00:00
Joerg Wunsch
fae57bc0fa This change actually dates back to July 29: add preliminary support
for Xmega programming using the JTAG ICE mkII in JTAG mode.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@780 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-10-31 21:16:46 +00:00
Joerg Wunsch
499b0bec72 * main.c: Remember whether the device initialization worked, and
allow to continue with -F if it failed yet do not attempt to
perform anything on the device itself.  That way, -tF could be
specified for programmers like the STK500/STK600 even without a
device connected, just in order to allow changing parameters on
the programmer itself.
* avrdude.1: Document that possible use of the -F option.
* doc/avrdude.texi: (Ditto.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@779 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-07-29 21:26:55 +00:00
Joerg Wunsch
40e63d4d1a * stk500v2.c (stk600_xprog_paged_write): Fix a fatal miscalculation
of the number of bytes to be written which caused a malloc chunk
corruption.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@778 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-07-29 08:39:15 +00:00
Joerg Wunsch
8ae6321da2 First implementation of ATxmega support. By now, only the
PDI mode of the STK600 is supported.  Single-byte EEPROM
(and flash) updates do not work yet.
* avr.c: "boot" memory is a candidate memory region for paged
operations, besides "flash" and "eeprom".
* avrdude.conf.in: add ATxmega128A1 and ATxmega128A1revD
* avrpart.h: add the AVRPART_HAS_PDI flag (used to distinguish
ATxmega parts from classic AVRs), the nvm_base part field, and
the offset field for a memory region.
* config_gram.y: add "has_pdi", "nvm_base", and "offset"
* lexer.l: (Ditto.)
* main.c: disable auto_erase for ATxmega parts
* stk500v2.c: implement the XPROG functionality, and divert to
this for ATxmega parts
* avrdude.1: Document the changes.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@777 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-07-26 22:53:40 +00:00
Joerg Wunsch
130eda2439 Fix yet another warning:
* ser_avrdoper.c (usbGetReport): remove useless pointer deref


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@776 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-07-26 06:04:30 +00:00
Joerg Wunsch
0ee630eeca Fix a bunch of warnings.
* avr910.c (avr910_paged_load): possible unitialized use of
rd_size
* jtagmkI.c (jtagmkI_initialize): pointer signedness mixup
* jtagmkII.c (jtagmkII_print_parms1): propagate const'ness
of parameter
* usbasp.c (usbasp_transmit): poiner signedness mixup


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@775 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-07-25 21:14:43 +00:00
Joerg Wunsch
fb55e7e383 Contributed by Ville Voipio:
patch #6501: New autotools support for avrdude
* Makefile.am: add @WINDOWS_DIRS@ to SUBDIR
* bootstrap: allow for autconf-2.61 and automake-1.10, too
* configure.ac: fix @WINDOWS_DIRS@ recursion, replace
AC_PROG_CC by AM_PROG_CC_C_O, for esoteric reasons


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@774 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-07-25 21:06:55 +00:00
Joerg Wunsch
39902a7b7b Contributed by Janos Sallai <janos.sallai@vanderbilt.edu>:
patch #6074: added support for crossbow's MIB510 programmer
* avrdude.conf.in: Add entry for mib510.
* stk500.c: Add special hooks to handle the MIB510 programmer.
It mostly talks STK500v1 protocol but has a special hello and
goodbye sequence, and uses a fixed block size of 256 bytes.
* doc/avrdude.texi: Document support for mib510.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@773 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-06-13 21:19:46 +00:00
Joerg Wunsch
5252991341 Contributed by Klaus Leidinger <klaus@mikrocontroller-projekte.de>:
* main.c: Realign verbose messages.
* avrpart.c: (Ditto.)
* avr910.c: Print the device code selected in verbose mode.
* butterfly.c: (Ditto.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@772 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-06-07 21:03:41 +00:00
Joerg Wunsch
85cb696790 Contributed by Klaus Leidinger <klaus@mikrocontroller-projekte.de>:
Add check for buffermode feature, and use it if present.  Can be
turned off using -x no_blockmode.
* avr910.c: Implement buffermode test and usage.
* avrdude.1: Document -x no_blockmode.
* doc/avrdude.texi: (Ditto.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@771 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-06-07 20:55:04 +00:00
Joerg Wunsch
cc4caf1d92 #undef interface for Win32
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@770 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-03-29 22:10:11 +00:00
Joerg Wunsch
d9ce7185a4 Add support for the -x devcode option, and document it.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@769 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-03-24 21:22:04 +00:00
Joerg Wunsch
712282c81d Add initial support for the Atmel STK600, for
"classic" AVRs (AT90, ATtiny, ATmega) in both,
ISP and high-voltage programming modes.
* Makefile.am: Add -lm.
* avrdude.conf.in: Add stk600, stk600pp, and stk600hvsp.
* config_gram.y: Add support for the stk600* keywords.
* lexer.l: (Ditto.)
* pgm.h: Add the "chan" parameter to set_varef().
* stk500.c: (Ditto.)
* serial.h: Add USB endpoint support to struct filedescriptor.
* stk500v2.c: Implement the meat of the STK600 support.
* stk500v2.h: Add new prototypes for stk600*() programmers.
* stk500v2_private.h: Add new constants used in the STK600.
* term.c: Add AREF channel support.
* usb_libusb.c: Automatically determine the correct write
endpoint ID, the STK600 uses 0x83 while all other tools use
0x82.  Propagate the EP to use through struct filedescriptor.
* usbdevs.h: Add the STK600 USB product ID.
* tools/get-stk600-cards.xsl: XSL transformation for
targetboards.xml to obtain the list of socket and routing
card IDs, to be used in stk500v2.c (for displaying the
names).
* tools/get-stk600-devices.xsl: XSL transformation for
targetboards.xml to obtain the table of socket/routing cards
and their respective AVR device support for doc/avrdude.texi.
* avrdude.1: Document all the STK600 stuff.
* doc/avrdude.texi: Ditto.  Added a new chapter for
Programmer Specific Information.

Thanks to Eirik Rasmussen from Atmel Norway for his support in
getting this code running within that short amount of time!


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@768 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-03-14 13:00:08 +00:00
Joerg Wunsch
853080dfeb stk500v2_recv(): Make length computation unsigned so
it cannot accidentally become negative.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@767 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-01-26 08:01:51 +00:00
Joerg Wunsch
e92c22e2a3 ChangeLog rotation for 2007->2008 transition.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@766 81a1dc3b-b13d-400b-aceb-764788c761c2
2008-01-26 07:59:07 +00:00
Joerg Wunsch
948534b2b6 Partially revert the line buffered output change,
and turn stderr into unbuffered output while producing the
progress report.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@765 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-08 22:34:36 +00:00
Joerg Wunsch
89e53f2e3d main.c, pgm.c, pgm.h: Add setup and teardown hooks to the programmer
definition.  If present, call the setup hook immediately after finding
the respective programmer object, and schedule the teardown hook to be
called upon exit.  This allows the programmer implementation to
dynamically allocate private programmer data.

avr910.c, butterfly.c, jtagmkI.c, jtagmkII.c, stk500v2.c, usbasp.c,
usbtiny.c: Convert static programmer data into dynamically allocated
data.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@764 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-07 20:36:12 +00:00
Joerg Wunsch
fa07082d30 Remove the no_show_func_info() calls, as Brian
promised some 4 years ago.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@763 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-06 21:00:33 +00:00
Joerg Wunsch
d3bb347e4f Fix whitespace in previous commit.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@762 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-06 19:42:52 +00:00
Joerg Wunsch
c8c9c6b087 main.c, pgm.c, pgm.h: Add the -x option to pass extended parameters to
the programmer backend.

jtagmkII.c: Implement the extended parameter jtagchain=
to support JTAG daisy-chains.

avrdude.1, doc/avrdude.texi: Document all of the above.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@761 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-06 19:42:16 +00:00
Joerg Wunsch
30a3143cc3 We are post 5.5 now.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@760 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-10-29 23:08:37 +00:00
Joerg Wunsch
2afd3d882e Prepare for releasing avrdude 5.5.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@758 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-10-29 23:00:12 +00:00
Joerg Wunsch
a566b4a888 Submitted by <bikenomad@gmail.com>:
patch #5007: Patch for line-buffering of stdout and stderr


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@757 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-10-29 22:46:45 +00:00
Joerg Wunsch
9693e039cb Submitted by <graceindustries@gmail.com>:
patch #5953: Add AT90CAN64 and AT90CAN32 to avrdude.conf


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@756 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-10-29 22:43:00 +00:00
Joerg Wunsch
7f188d48db Submitted by Wolfgang Moser:
patch #6121: ISP support for the C2N232I device (serial port
bitbanging)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@755 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-10-29 22:37:38 +00:00
Joerg Wunsch
477f1f1049 Submitted by <karl.yerkes@gmail.com>:
patch #6141: accept binary format immediate values

Detect a 0b prefix, and call strtoul() differently in that case.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@754 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-10-29 22:30:59 +00:00
Joerg Wunsch
15d320cbfe bug #21076: -vvvv serial receive prints are empty in Win32 build
In ser_recv(): Drop the essentially unused variable "len", and use the
variable "read" in order to track how many bytes have just been read
in.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@753 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-10-29 21:51:07 +00:00
Joerg Wunsch
83334a1794 bug #21145: atmega329p not recognized
Add definitions for the ATmega329P/3290P.  Same as ATmega329/3290
except of the different signature.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@752 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-10-29 21:45:22 +00:00
Joerg Wunsch
122f2e8ec6 The next release will have bug fixes...
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@751 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-10-29 21:27:46 +00:00
Joerg Wunsch
9858495500 bug #21152: Unable to program atmega324p with avrdude 5.4 and AVRISP
using default configuration file.

Uncomment the (bogus) stk500_devcode lines for the ATmega164P,
ATmega324P, ATmega644, and ATmega644P definitions.  This only affects
users of STK500v1 firmware.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@750 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-10-29 21:24:28 +00:00
Joerg Wunsch
007f4b378d Submitted by <ladyada@gmail.com>:
Patch #6233: Add support for USBtinyISP programmer
* usbtiny.c: New file.
* usbtiny.h: (Ditto.)
* Makefile.am: Include usbtiny into the build.
* avrdude.conf.in: (Ditto.)
* config_gram.y: (Ditto.)
* lexer.l: (Ditto.)
* avrdude.1: Document the usbtiny support.
* doc/avrdude.texi: (Ditto.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@749 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-10-29 18:03:02 +00:00
Joerg Wunsch
f721cc0d53 Forgot to include USBasp into the list of supported programmers.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@748 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-10-29 17:53:58 +00:00
Joerg Wunsch
ff700a8f1a Sort list of supported programmers into
alphabetical order, add all missing programmers.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@747 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-10-29 16:17:01 +00:00
Thomas Fischl
4f47c560ac usbasp.c: Added long addresses to support devices with more than 64kB (bug #20558)
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@746 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-07-24 16:43:25 +00:00
Joerg Wunsch
4f4497f94e Add ChangeLog-2004-2006 to EXTRA_DIST.
Pointed out by Michael Holzt.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@745 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-06-27 20:44:25 +00:00
Joerg Wunsch
e79a210517 We are post-release.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@744 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-05-16 21:54:21 +00:00
Joerg Wunsch
54997a4b27 More release preparation.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@742 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-05-16 21:46:30 +00:00
Joerg Wunsch
ff3368d7d7 Bump version, releasing avrdude-5.4.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@741 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-05-16 21:40:21 +00:00
Joerg Wunsch
b94afc55e9 Fix AVR910 devcodes. It seems that the AVR109 listing refers to
"BOOT"-type code, while the standard codes are different (usually one
below).


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@740 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-05-16 21:29:36 +00:00
Joerg Wunsch
54ad687999 In avr_read() and avr_write(), only use the paged_load and
paged_write backend functions iff the memory area in question has
a page_size != 0.

This is supposed to fix bug #19234: avrdude-5.3.1 segfaults when
stk500v1 tries to program an ATtiny15


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@739 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-05-16 20:15:13 +00:00
Joerg Wunsch
8029f19918 Fall back to avr_{read,write}_byte_default().
Fixes bug #18803: Fuse reading regression in avrdude 5.3.1 with avr910
programmer


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@738 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-05-15 22:00:29 +00:00
Joerg Wunsch
2b024eff77 Rename the ATmega164 and ATmega324 into ATmega164P and ATmega324P,
resp.  Add an entry for the ATmega644P.

Fixes bug #19769: ATmega164p not recognized


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@737 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-05-15 20:39:40 +00:00
Joerg Wunsch
dbb4766f81 In ser_send(), don't select() on the output fd before trying to write
something to the serial line.  That kind of polling isn't very useful
anyway, and it seems it breaks for the Linux CP210x USB<->RS-232
bridge driver which is certainly a bug in the driver, but we can just
avoid that bug alltogether.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@736 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-05-15 20:30:15 +00:00
Joerg Wunsch
6632049d6f Fix the STK500v2 ISP delay parameter for
ATmega640/1280/1281/2560/2561.  Atmel has changed the XML
files after the initial release.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@735 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-05-15 20:25:48 +00:00
Joerg Wunsch
633922546f Style and indentation fixes.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@734 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-05-15 20:23:50 +00:00
Colin O Flynn
35380e1d70 2007-05-01: Colin O'Flynn <coflynn@newae.com>
*Problem in verbose output of previous commit. I hoped to
   have all the verbose changes in a single commit, but that
   won't happen...
  *Main thing is fixed safemode to turn itself off when you can't
   read the fuses anyway. I don't know what I was thinking when
   I made it fail out of programmers that don't support fuse reading.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@733 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-05-02 23:05:21 +00:00
Colin O Flynn
728326c479 2007-05-01 Colin O'Flynn <coflynn@newae.com>
safemode.c: added verbose output


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@732 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-05-02 22:36:04 +00:00
Colin O Flynn
06e4769d2b Colin O'Flynn <coflynn@newae.com>
*stk500generic.c: FIxed bug 19411


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@731 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-03-25 22:43:50 +00:00
Joerg Wunsch
92b95ef36d Add entries for AT90PWM2/3B.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@730 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-02-26 19:52:53 +00:00
Thomas Fischl
7082eecf2a usbasp.c: return error if communication with target isn't possible.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@729 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-02-02 16:27:49 +00:00
Joerg Wunsch
f0ad4dc3aa Remove duplicate definition of token K_WRITEPAGE.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@728 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-02-01 22:07:39 +00:00
Joerg Wunsch
6a9ee90a06 Implement ATmega256x support for butterfly/avr109.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@727 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-01-30 15:47:53 +00:00
Joerg Wunsch
3407d4312a Fix subdir handling. Now finally, "make distcheck" will
include the documentation into the tarball even if the configure had been
run without the --enable-doc.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@726 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-01-30 14:41:57 +00:00
Joerg Wunsch
df256ba7bd safemode.c: Obtain progname from avrdude.h rather than trying to roll our
own (duplicate) copy of it.

other files: Constify char pointers.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@725 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-01-30 13:41:54 +00:00
Joerg Wunsch
2a7aeaa742 More backend/library abstraction and generalization: turn the
list_parts() and list_programmers() functions into general list
iteration functions that call a caller-supplied callback for each
element.  Implement list_parts() and list_programmers() as private
functions in main.c based on that approach.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@724 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-01-29 20:41:47 +00:00
Joerg Wunsch
a3349385d6 Rearrange everything so it is now built into a libavrdude.a library,
and link main.c against that library.

Add AC_PROG_RANLIB to configure.ac as we are building a library now.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@723 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-01-25 20:51:11 +00:00
Joerg Wunsch
6897c7b4a5 Major code cleanup.
- Make all internal functions "static".
- Make sure each module's header and implementation file match.
- Remove all library-like functionality from main.c, so only
  the actual frontend remains in main.c.
- Add C++ brackets to all header files.

That effectively leaves the various module C files as something like
an "avrdude library", with main.c being the currently only frontend
program for that library.  In theory, it should be possible to write
different frontends using the same library backend functions though.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@722 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-01-24 22:43:46 +00:00
Joerg Wunsch
9436ea57d1 Something I always wanted to do: replace all those private "extern"
declarations in each file by a central header file "avrdude.h".


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@721 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-01-24 21:07:54 +00:00
Joerg Wunsch
f2154ce2ea ATmega8: Bump the delay values for flash
and EEPROM, based on the current Atmel XML file.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@720 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-01-13 22:57:14 +00:00
Joerg Wunsch
6aed88281a * configure.ac: Improve the detection of the Win32 HID library,
and the presence of the header ddk/hidsdi.h.  It now works
correctly under Cygwin and several flavours of MinGW.

* Makefile.am: Add new LIBHID pattern.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@719 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-01-12 22:41:05 +00:00
Joerg Wunsch
2e7333d3cc * butterfly.c (butterfly_initialize): when sending the 'T'
command (which is ignored by current AVR109 bootloaders),
send the first reply from the list of supported device
codes back rather than using avrdude.conf's idea about
an AVR910 device code.  Apparently, this solves disagreements
between different versions of at least the ATmega8 AVR910
device code.

Closes bug #18727: Writing flash failed


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@718 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-01-11 20:20:25 +00:00
Joerg Wunsch
8daaa34ba8 Reported by Till Harbaum:
Change HVSP reset timing for ATtiny25/45/85 from
500 microseconds to 1 ms, matching the most recent Atmel XML
specs.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@717 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-01-07 22:36:45 +00:00
Joerg Wunsch
0058fff9d8 ChangeLog rotation.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@716 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-01-07 22:34:21 +00:00
Joerg Wunsch
37ecc60f24 We are post-release (again).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@715 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-22 23:21:53 +00:00
75 changed files with 10231 additions and 3047 deletions

File diff suppressed because it is too large Load Diff

1644
avrdude/ChangeLog-2004-2006 Normal file

File diff suppressed because it is too large Load Diff

364
avrdude/ChangeLog-2007 Normal file
View File

@@ -0,0 +1,364 @@
2007-11-08 Joerg Wunsch <j@uriah.heep.sax.de>
* main.c: Partially revert the line buffered output change,
and turn stderr into unbuffered output while producing the
progress report.
2007-11-07 Joerg Wunsch <j@uriah.heep.sax.de>
* main.c: Add setup and teardown hooks to the programmer
definition. If present, call the setup hook immediately after
finding the respective programmer object, and schedule the
teardown hook to be called upon exit. This allows the
programmer implementation to dynamically allocate private
programmer data.
* pgm.c: (Ditto.)
* pgm.h: (Ditto.)
* avr910.c: Convert static programmer data into dynamically
allocated data.
* butterfly.c: (Ditto.)
* jtagmkI.c: (Ditto.)
* jtagmkII.c: (Ditto.)
* stk500v2.c: (Ditto.)
* usbasp.c: (Ditto.)
* usbtiny.c: (Ditto.)
2007-11-06 Joerg Wunsch <j@uriah.heep.sax.de>
* butterfly.c: Remove the no_show_func_info() calls, as Brian
promised some 4 years ago.
2007-11-06 Joerg Wunsch <j@uriah.heep.sax.de>
* main.c: Add the -x option to pass extended parameters to
the programmer backend.
* pgm.c: (Ditto.)
* pgm.h: (Ditto.)
* jtagmkII.c: Implement the extended parameter jtagchain=
to support JTAG daisy-chains.
* avrdude.1: Document all of the above.
* doc/avrdude.texi: (Ditto.)
2007-10-30 Joerg Wunsch <j@uriah.heep.sax.de>
* configure.ac (AC_INIT): Bump version for post-release.
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
* configure.ac (AC_INIT): Bump version, releasing avrdude-5.5.
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
Submitted by <bikenomad@gmail.com>:
patch #5007: Patch for line-buffering of stdout and stderr
* main.c: call setvbuf() for stdout and stderr.
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
Submitted by <graceindustries@gmail.com>:
patch #5953: Add AT90CAN64 and AT90CAN32 to avrdude.conf
* avrdude.conf.in: Add entry for AT90CAN64 and AT90CAN32.
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
Submitted by Wolfgang Moser:
patch #6121: ISP support for the C2N232I device (serial port
bitbanging)
* avrdude.conf.in: Add entry for c2n232i.
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
Submitted by <karl.yerkes@gmail.com>:
patch #6141: accept binary format immediate values
* fileio.c: Detect a 0b prefix, and call strtoul() differently
in that case.
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
bug #21076: -vvvv serial receive prints are empty in Win32 build
* ser_win32.c (ser_recv): Drop the essentially unused variable
"len", and use the variable "read" in order to track how many
bytes have just been read in.
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
bug #21145: atmega329p not recognized
* avrdude.conf.in: Add definitions for the ATmega329P/3290P.
Same as ATmega329/3290 except of the different signature.
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
bug #21152: Unable to program atmega324p with avrdude 5.4 and AVRISP
using default configuration file.
* avrdude.conf.in: Uncomment the (bogus) stk500_devcode lines for
the ATmega164P, ATmega324P, ATmega644, and ATmega644P definitions.
This only affects users of STK500v1 firmware.
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
Submitted by <ladyada@gmail.com>:
Patch #6233: Add support for USBtinyISP programmer
* usbtiny.c: New file.
* usbtiny.h: (Ditto.)
* Makefile.am: Include usbtiny into the build.
* avrdude.conf.in: (Ditto.)
* config_gram.y: (Ditto.)
* lexer.l: (Ditto.)
* avrdude.1: Document the usbtiny support.
* doc/avrdude.texi: (Ditto.)
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
* doc/avrdude.texi: Sort list of supported programmers into
alphabetical order, add all missing programmers.
2007-07-24 Thomas Fischl <tfischl@gmx.de>
* usbasp.c: Added long addresses to support devices with more
than 64kB flash. Closes bug #20558: Long address problem with
USBasp.
2007-06-27 Joerg Wunsch <j@uriah.heep.sax.de>
* Makefile.am (EXTRA_DIST): Add ChangeLog-2004-2006.
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
* configure.ac (AC_INIT): Bump version for post-release.
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
* configure.ac (AC_INIT): Bump version, releasing avrdude-5.4.
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
* avrdude.conf.in: Fix AVR910 devcodes. It seems that the AVR109
listing refers to "BOOT"-type code, while the standard codes are
different (usually one below).
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
* avr.c (avr_read, avr_write): only use the paged_load and
paged_write backend functions iff the memory area in question has
a page_size != 0.
This is supposed to fix bug #19234: avrdude-5.3.1 segfaults when
stk500v1 tries to program an ATtiny15
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
* avr910.c: Fall back to avr_{read,write}_byte_default(). Fixes
bug #18803: Fuse reading regression in avrdude 5.3.1 with avr910
programmer
2007-05-15 Colin O'Flynn <coflynn@newae.com>
* avrdude.conf.in: Rename the ATmega164 and ATmega324 into
ATmega164P and ATmega324P, resp. Add an entry for the ATmega644P.
Fixes bug #19769: ATmega164p not recognized
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
* ser_posix.c (ser_send): Don't select() on the output fd before
trying to write something to the serial line. That kind of
polling isn't very useful anyway, and it seems it breaks for the
Linux CP210x USB<->RS-232 bridge driver which is certainly a bug
in the driver, but we can just avoid that bug alltogether.
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
* avrdude.conf.in: Fix the STK500v2 ISP delay parameter for
ATmega640/1280/1281/2560/2561. Atmel has changed the XML
files after the initial release.
2007-05-01 Colin O'Flynn <coflynn@newae.com>
* safemode.c: -Oops - bug in verbose output. Fixed.
-Fixed handling of cases where programmer cannot read fuses (AVR910)
* main.c: -Also fixing handling of cases where programmer cannot
read fuses
This should close one or more bugs (18803, 19570)
2007-05-01 Colin O'Flynn <coflynn@newae.com>
* safemode.c: Added verbose output from safemode routines.
2007-03-25 Colin O'Flynn <coflynn@newae.com>
* stk500generic.c: Forgot to close the serial port before trying to
open it again, caused problems on Windows machines.
Closes bug #19411
2007-02-26 Joerg Wunsch <j@uriah.heep.sax.de>
* avrdude.conf.in: Add the AT90PWM2/3B devices.
2007-02-02 Thomas Fischl <tfischl@gmx.de>
* usbasp.c: Changed return value of function usbasp_initialize to stop
avrdude on communication errors between programmer and target.
Closes bug #18581: safemode destroys fuse bits
2007-02-01 Joerg Wunsch <j@uriah.heep.sax.de>
* config_gram.y: Remove duplicate definition of token K_WRITEPAGE
2007-01-30 Joerg Wunsch <j@uriah.heep.sax.de>
* butterfly.c: Implement ATmega256x support for butterfly/avr109.
2007-01-30 Joerg Wunsch <j@uriah.heep.sax.de>
* configure.ac: Fix subdir handling. Now finally, "make
distcheck" will include the documentation into the tarball even if
the configure had been run without the --enable-doc.
2007-01-30 Joerg Wunsch <j@uriah.heep.sax.de>
* safemode.c: Obtain progname from avrdude.h rather than trying to
roll our own (duplicate) copy of it.
* avr910.c: Constify char pointers.
* avrpart.c: (Ditto.)
* avrpart.h: (Ditto.)
* butterfly.c: (Ditto.)
* config.c: (Ditto.)
* config.h: (Ditto.)
* jtagmkI.c: (Ditto.)
* jtagmkII.c: (Ditto.)
* par.c: (Ditto.)
* pgm.c: (Ditto.)
* pgm.h: (Ditto.)
* serbb_posix.c: (Ditto.)
* serbb_win32.c: (Ditto.)
* stk500.c: (Ditto.)
* stk500v2.c: (Ditto.)
* usbasp.c: (Ditto.)
2007-01-29 Joerg Wunsch <j@uriah.heep.sax.de>
* avrpart.c: More backend/library abstraction and generalization:
turn the list_parts() and list_programmers() functions into
general list iteration functions that call a caller-supplied
callback for each element. Implement list_parts() and
list_programmers() as private functions in main.c based on that
approach.
* avrpart.h: (Ditto.)
* main.c: (Ditto.)
* pgm.c: (Ditto.)
* pgm.h: (Ditto.)
2007-01-25 Joerg Wunsch <j@uriah.heep.sax.de>
* Makefile.am: Rearrange everything so it is now built into a
libavrdude.a library, and link main.c against that library.
* configure.ac: Add AC_PROG_RANLIB as we are building a library
now.
2007-01-24 Joerg Wunsch <j@uriah.heep.sax.de>
Major code cleanup.
- Make all internal functions "static".
- Make sure each module's header and implementation file match.
- Remove all library-like functionality from main.c, so only
the actual frontend remains in main.c.
- Add C++ brackets to all header files.
* avr.c: (Ditto.)
* avr.h: (Ditto.)
* avr910.c: (Ditto.)
* avr910.h: (Ditto.)
* avrdude.h: (Ditto.)
* avrpart.c: (Ditto.)
* avrpart.h: (Ditto.)
* bitbang.h: (Ditto.)
* butterfly.h: (Ditto.)
* config.c: (Ditto.)
* config.h: (Ditto.)
* confwin.h: (Ditto.)
* crc16.c: (Ditto.)
* crc16.h: (Ditto.)
* fileio.c: (Ditto.)
* fileio.h: (Ditto.)
* jtagmkI.h: (Ditto.)
* jtagmkII.h: (Ditto.)
* lexer.l: (Ditto.)
* lists.h: (Ditto.)
* main.c: (Ditto.)
* par.h: (Ditto.)
* pgm.c: (Ditto.)
* pgm.h: (Ditto.)
* ppi.c: (Ditto.)
* ppi.h: (Ditto.)
* safemode.h: (Ditto.)
* serbb.h: (Ditto.)
* serial.h: (Ditto.)
* stk500.h: (Ditto.)
* stk500v2.c: (Ditto.)
* stk500v2.h: (Ditto.)
* term.c: (Ditto.)
* term.h: (Ditto.)
* usbasp.h: (Ditto.)
* update.c: New file.
* update.h: New file.
* Makefile.am: Include update.c and update.h.
2007-01-24 Joerg Wunsch <j@uriah.heep.sax.de>
Move all "extern" declarations into a centreal header file.
* Makefile.am: Add new avrdude.h.
* avrdude.h: New file.
* avr.c: Replace private extern decl's by #include "avrdude.h".
* avr910.c: (Ditto.)
* avrpart.c: (Ditto.)
* bitbang.c: (Ditto.)
* butterfly.c: (Ditto.)
* config.c: (Ditto.)
* config_gram.y: (Ditto.)
* fileio.c: (Ditto.)
* jtagmkI.c: (Ditto.)
* jtagmkII.c: (Ditto.)
* lexer.l: (Ditto.)
* main.c: (Ditto.)
* par.c: (Ditto.)
* pgm.c: (Ditto.)
* ppi.c: (Ditto.)
* ppiwin.c: (Ditto.)
* ser_avrdoper.c: (Ditto.)
* ser_posix.c: (Ditto.)
* ser_win32.c: (Ditto.)
* serbb_posix.c: (Ditto.)
* serbb_win32.c: (Ditto.)
* stk500.c: (Ditto.)
* stk500generic.c: (Ditto.)
* stk500v2.c: (Ditto.)
* term.c: (Ditto.)
* usb_libusb.c: (Ditto.)
* usbasp.c: (Ditto.)
2007-01-13 Joerg Wunsch <j@uriah.heep.sax.de>
* avrdude.conf.in (ATmega8): Bump the delay values for flash
and EEPROM, based on the current Atmel XML file.
2007-01-12 Joerg Wunsch <j@uriah.heep.sax.de>
* configure.ac: Improve the detection of the Win32 HID library,
and the presence of the header ddk/hidsdi.h. It now works
correctly under Cygwin and several flavours of MinGW.
* Makefile.am: Add new LIBHID pattern.
2007-01-11 Joerg Wunsch <j@uriah.heep.sax.de>
* butterfly.c (butterfly_initialize): when sending the 'T'
command (which is ignored by current AVR109 bootloaders),
send the first reply from the list of supported device
codes back rather than using avrdude.conf's idea about
an AVR910 device code. Apparently, this solves disagreements
between different versions of at least the ATmega8 AVR910
device code.
Closes bug #18727: Writing flash failed
2007-01-07 Joerg Wunsch <j@uriah.heep.sax.de>
Reported by Till Harbaum:
* avrdude.conf.in (ATtiny25/45/85): Change HVSP reset from
500 microseconds to 1 ms, matching the most recent Atmel XML
specs.

185
avrdude/ChangeLog-2008 Normal file
View File

@@ -0,0 +1,185 @@
2008-11-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
* avrdude.h: Change the prototype for usleep() to be more Cygwin-
friendly.
* ppiwin.c: (Ditto.)
2008-11-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Submitted by limor <limor@ladyada.net>
* usbtiny.c (usbtiny_cmd): Replace sizeof() by a fixed constant
4 for the result array, because otherwise it would take the size
of a pointer which miserably fails on 64-bit machines.
2008-11-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
patch #6609: Using PCI parallel port cards on Windows
* ppiwin.c (ppi_open): If the port parameter passed from the
-p option is neither lpt1/2/3, try interpreting it directly as
a base address.
* avrdude.1: Document the change.
* doc/avrdude.texi: (Ditto.)
2008-11-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
bug #22882: Erase Cycle Counter does not work for stk500v2
* stk500v2.c (stk500v2_chip_erase,stk500hv_chip_erase): Return
the expected 0 for success rather than a protocol-dependant
number.
2008-11-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
bug #22883: Chip Erase performed even with no-write flag (-n)
* main.c: Do not erase the chip if both, -e and -n options have
been specified.
2008-11-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
bug #24589: AT90USB64* have wrong signature
* avrdude.conf.in: Uncomment the correct, and delete the wrong
signature for AT90USB646/647. Alas, the datasheet has never been
corrected for years.
2008-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
* jtagmkII.c: Fix a serious memory corruption that happened when
using the JTAG ICE mkII (or AVR Dragon) in ISP mode. The wrong
set of per-programmer private data had been allocated (stk500v2
vs. jtagmkII) which was too small to hold the actual data.
* jtagmkII.h: (Ditto.)
* stk500v2.c: (Ditto.)
2008-07-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
* jtagmkII.c: Implement Xmega JTAG support.
* jtagmkII_private.h: Add EMULATOR_MODE_JTAG_XMEGA.
2008-07-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
* main.c: Remember whether the device initialization worked, and
allow to continue with -F if it failed yet do not attempt to
perform anything on the device itself. That way, -tF could be
specified for programmers like the STK500/STK600 even without a
device connected, just in order to allow changing parameters on
the programmer itself.
* avrdude.1: Document that possible use of the -F option.
* doc/avrdude.texi: (Ditto.)
2008-07-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
* stk500v2.c (stk600_xprog_paged_write): Fix a fatal miscalculation
of the number of bytes to be written which caused a malloc chunk
corruption.
2008-07-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
First implementation of ATxmega support. By now, only the
PDI mode of the STK600 is supported. Single-byte EEPROM
(and flash) updates do not work yet.
* avr.c: "boot" memory is a candidate memory region for paged
operations, besides "flash" and "eeprom".
* avrdude.conf.in: add ATxmega128A1 and ATxmega128A1revD
* avrpart.h: add the AVRPART_HAS_PDI flag (used to distinguish
ATxmega parts from classic AVRs), the nvm_base part field, and
the offset field for a memory region.
* config_gram.y: add "has_pdi", "nvm_base", and "offset"
* lexer.l: (Ditto.)
* main.c: disable auto_erase for ATxmega parts
* stk500v2.c: implement the XPROG functionality, and divert to
this for ATxmega parts
* avrdude.1: Document the changes.
* doc/avrdude.texi: (Ditto.)
2008-07-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Fix a bunch of warnings.
* avr910.c (avr910_paged_load): possible unitialized use of
rd_size
* jtagmkI.c (jtagmkI_initialize): pointer signedness mixup
* jtagmkII.c (jtagmkII_print_parms1): propagate const'ness
of parameter
* usbasp.c (usbasp_transmit): pointer signedness mixup
* ser_avrdoper.c (usbGetReport): remove useless pointer deref
2008-07-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Contributed by Ville Voipio:
patch #6501: New autotools support for avrdude
* Makefile.am: add @WINDOWS_DIRS@ to SUBDIR
* bootstrap: allow for autconf-2.61 and automake-1.10, too
* configure.ac: fix @WINDOWS_DIRS@ recursion, replace
AC_PROG_CC by AM_PROG_CC_C_O, for esoteric reasons
2008-06-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Contributed by Janos Sallai <janos.sallai@vanderbilt.edu>:
patch #6074: added support for crossbow's MIB510 programmer
* avrdude.conf.in: Add entry for mib510.
* stk500.c: Add special hooks to handle the MIB510 programmer.
It mostly talks STK500v1 protocol but has a special hello and
goodbye sequence, and uses a fixed block size of 256 bytes.
* doc/avrdude.texi: Document support for mib510.
2008-06-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Contributed by Klaus Leidinger <klaus@mikrocontroller-projekte.de>:
* main.c: Realign verbose messages.
* avrpart.c: (Ditto.)
* avr910.c: Print the device code selected in verbose mode.
* butterfly.c: (Ditto.)
2008-06-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Contributed by Klaus Leidinger <klaus@mikrocontroller-projekte.de>:
Add check for buffermode feature, and use it if present. Can be
turned off using -x no_blockmode.
* avr910.c: Implement buffermode test and usage.
* avrdude.1: Document -x no_blockmode.
* doc/avrdude.texi: (Ditto.)
2008-03-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
* usb_libusb.c: #undef interface for Win32
2008-03-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
* avr910.c: Add support for the -x devcode option.
* avrdude.1: Document -x devcode for avr910.
* doc/avrdude.texi: (Ditto.)
2008-03-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Add initial support for the Atmel STK600, for
"classic" AVRs (AT90, ATtiny, ATmega) in both,
ISP and high-voltage programming modes.
* Makefile.am: Add -lm.
* avrdude.conf.in: Add stk600, stk600pp, and stk600hvsp.
* config_gram.y: Add support for the stk600* keywords.
* lexer.l: (Ditto.)
* pgm.h: Add the "chan" parameter to set_varef().
* stk500.c: (Ditto.)
* serial.h: Add USB endpoint support to struct filedescriptor.
* stk500v2.c: Implement the meat of the STK600 support.
* stk500v2.h: Add new prototypes for stk600*() programmers.
* stk500v2_private.h: Add new constants used in the STK600.
* term.c: Add AREF channel support.
* usb_libusb.c: Automatically determine the correct write
endpoint ID, the STK600 uses 0x83 while all other tools use
0x82. Propagate the EP to use through struct filedescriptor.
* usbdevs.h: Add the STK600 USB product ID.
* tools/get-stk600-cards.xsl: XSL transformation for
targetboards.xml to obtain the list of socket and routing
card IDs, to be used in stk500v2.c (for displaying the
names).
* tools/get-stk600-devices.xsl: XSL transformation for
targetboards.xml to obtain the table of socket/routing cards
and their respective AVR device support for doc/avrdude.texi.
* avrdude.1: Document all the STK600 stuff.
* doc/avrdude.texi: Ditto. Added a new chapter for
Programmer Specific Information.
2008-01-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
* stk500v2.c (stk500v2_recv): Make length computation unsigned so
it cannot accidentally become negative.

View File

@@ -26,6 +26,7 @@ EXTRA_DIST = \
ChangeLog-2001 \
ChangeLog-2002 \
ChangeLog-2003 \
ChangeLog-2004-2006 \
avrdude.1 \
avrdude.spec \
bootstrap
@@ -39,18 +40,25 @@ CLEANFILES = \
#DIST_SUBDIRS = doc windows
SUBDIRS = @SUBDIRS_AC@
SUBDIRS += @WINDOWS_DIRS@
DIST_SUBDIRS = @DIST_SUBDIRS_AC@
AM_YFLAGS = -d
avrdude_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
avrdude_CFLAGS = @ENABLE_WARNINGS@
libavrdude_a_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
avrdude_LDADD = @LIBUSB@
avrdude_CFLAGS = @ENABLE_WARNINGS@
libavrdude_a_CFLAGS = @ENABLE_WARNINGS@
avrdude_LDADD = $(top_builddir)/$(noinst_LIBRARIES) @LIBUSB@ @LIBHID@ -lm
bin_PROGRAMS = avrdude
noinst_LIBRARIES = libavrdude.a
# automake thinks these generated files should be in the distribution,
# but this might cause trouble for some users, so we rather don't want
# to have them there.
@@ -66,13 +74,16 @@ dist-hook:
$(distdir)/config_gram.c \
$(distdir)/config_gram.h
avrdude_SOURCES = \
libavrdude_a_SOURCES = \
config_gram.y \
lexer.l \
arduino.h \
arduino.c \
avr.c \
avr.h \
avr910.c \
avr910.h \
avrdude.h \
avrpart.c \
avrpart.h \
bitbang.c \
@@ -97,7 +108,6 @@ avrdude_SOURCES = \
linux_ppdev.h \
lists.c \
lists.h \
main.c \
my_ddk_hidsdi.h \
par.c \
par.h \
@@ -125,12 +135,19 @@ avrdude_SOURCES = \
stk500v2_private.h \
stk500generic.c \
stk500generic.h \
term.c \
term.h \
usbasp.c \
usbasp.h \
usbdevs.h \
usb_libusb.c
usb_libusb.c \
usbtiny.h \
usbtiny.c \
update.h \
update.c
avrdude_SOURCES = \
main.c \
term.c \
term.h
man_MANS = avrdude.1

View File

@@ -5,6 +5,79 @@ Approximate change log for AVRDUDE by version.
(For more detailed changes, see the ChangeLog file.)
----------------------------------------------------------------------
Version 5.6:
* New devices supported:
- AT90USB82
- AT90USB162
- ATtiny88
- ATmega328P
- ATmega1284P
- ATmega128RFA1
- ATxmega128A1 rev D
- ATxmega128A1
- ATxmega256A3
* New programmers supported:
- AT89ISP cable (patch #6069)
- Arduino
* Add support for the -x option to pass extended parameters to the
programmer backend.
* Add support for JTAG daisy-chains, using the -x daisychain=
option.
* Add support for the Atmel STK600 for "classic" AVRs (AT90, ATtiny,
ATmega), using either ISP or high-voltage programming modes.
* Add support for the -x devcode extended parameter to the avr910
programmer, to allow overriding the device code sent to the
programmer.
* Add support for the Crossbow MIB510 programmer (patch #6074, #6542).
* Add support to bootstrap with GNU autoconf 2.61, and automake 1.10,
respectively.
* Add support for ATxmega128A1 (including the revision D engineering
samples) for STK600 and AVRISPmkII tools using PDI
* The option combination -tF now enters terminal mode even if the
device initialization failed, so the user can modify programmer
parameters (like Vtarget).
* Add preliminary support for ATxmega128A1 for the JTAG ICE mkII using
JTAG.
* Add support for direct SPI transfers (bug #25156).
* Bugfixes.
Version 5.5:
* Add support for the USBtinyISP programmer (patch #6233)
* Add support for the C2N232I serial bitbang programmer (patch #6121)
* Bugfixes.
Version 5.4:
* New devices supported:
- AT90PWM2B/AT90PWM3B
* Bugfixes.
* Source code rearranged so that the functionality is now built
into a libavrdude.a library where main.c is currently the only
existing frontend.
* Implement ATmega256x support for butterfly/avr109.
Version 5.3.1:
* Add support for the AVR Dragon (all modes: ISP, JTAG, HVSP, PP,

94
avrdude/arduino.c Normal file
View File

@@ -0,0 +1,94 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2009 Lars Immisch
*
* 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 Arduino programmer
*
* The Arduino programmer is mostly a STK500v1, just the signature bytes
* are read differently.
*/
#include "ac_cfg.h"
#include <stdio.h>
#include <string.h>
#include "avrdude.h"
#include "pgm.h"
#include "stk500_private.h"
#include "stk500.h"
#include "serial.h"
/* read signature bytes - arduino version */
static int arduino_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
{
unsigned char buf[32];
/* Signature byte reads are always 3 bytes. */
if (m->size < 3) {
fprintf(stderr, "%s: memsize too small for sig byte read", progname);
return -1;
}
buf[0] = Cmnd_STK_READ_SIGN;
buf[1] = Sync_CRC_EOP;
serial_send(&pgm->fd, buf, 2);
if (serial_recv(&pgm->fd, buf, 5) < 0)
return -1;
if (buf[0] == Resp_STK_NOSYNC) {
fprintf(stderr, "%s: stk500_cmd(): programmer is out of sync\n",
progname);
return -1;
} else if (buf[0] != Resp_STK_INSYNC) {
fprintf(stderr,
"\n%s: arduino_read_sig_bytes(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
return -2;
}
if (buf[4] != Resp_STK_OK) {
fprintf(stderr,
"\n%s: arduino_read_sig_bytes(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_OK, buf[4]);
return -3;
}
m->buf[0] = buf[1];
m->buf[1] = buf[2];
m->buf[2] = buf[3];
return 3;
}
void arduino_initpgm(PROGRAMMER * pgm)
{
/* This is mostly a STK500; just the signature is read
differently than on real STK500v1 */
stk500_initpgm(pgm);
strcpy(pgm->type, "Arduino");
pgm->read_sig_bytes = arduino_read_sig_bytes;
}

29
avrdude/arduino.h Normal file
View File

@@ -0,0 +1,29 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2009 Lars Immisch
*
* 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 arduino_h__
#define arduino_h__
void arduino_initpgm (PROGRAMMER * pgm);
#endif

View File

@@ -28,23 +28,19 @@
#include <sys/time.h>
#include <time.h>
#include "avrdude.h"
#include "avr.h"
#include "lists.h"
#include "pindefs.h"
#include "ppi.h"
#include "safemode.h"
#include "update.h"
FP_UpdateProgress update_progress;
#define DEBUG 0
extern char * progname;
extern char progbuf[];
extern PROGRAMMER * pgm;
extern int do_cycles;
int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value)
{
@@ -175,8 +171,9 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
*/
memset(buf, 0xff, size);
if ((strcmp(mem->desc, "flash")==0) || (strcmp(mem->desc, "eeprom")==0)) {
if (pgm->paged_load != NULL) {
if ((strcmp(mem->desc, "flash")==0) || (strcmp(mem->desc, "eeprom")==0) ||
(strcmp(mem->desc, "boot")==0)) {
if (pgm->paged_load != NULL && mem->page_size != 0) {
/*
* the programmer supports a paged mode read, perhaps more
* efficiently than we can read it directly, so use its routine
@@ -572,8 +569,9 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
progbuf, wsize);
}
if ((strcmp(m->desc, "flash")==0) || (strcmp(m->desc, "eeprom")==0)) {
if (pgm->paged_write != NULL) {
if ((strcmp(m->desc, "flash")==0) || (strcmp(m->desc, "eeprom")==0) ||
(strcmp(m->desc, "boot")==0)) {
if (pgm->paged_write != NULL && m->page_size != 0) {
/*
* the programmer supports a paged mode write, perhaps more
* efficiently than we can read it directly, so use its routine
@@ -811,3 +809,54 @@ int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p)
return rc;
}
/*
* Report the progress of a read or write operation from/to the
* device.
*
* The first call of report_progress() should look like this (for a write op):
*
* report_progress (0, 1, "Writing");
*
* Then hdr should be passed NULL on subsequent calls while the
* operation is progressing. Once the operation is complete, a final
* call should be made as such to ensure proper termination of the
* progress report:
*
* report_progress (1, 1, NULL);
*
* It would be nice if we could reduce the usage to one and only one
* call for each of start, during and end cases. As things stand now,
* that is not possible and makes maintenance a bit more work.
*/
void report_progress (int completed, int total, char *hdr)
{
static int last = 0;
static double start_time;
int percent = (completed * 100) / total;
struct timeval tv;
double t;
if (update_progress == NULL)
return;
gettimeofday(&tv, NULL);
t = tv.tv_sec + ((double)tv.tv_usec)/1000000;
if (hdr) {
last = 0;
start_time = t;
update_progress (percent, t - start_time, hdr);
}
if (percent > 100)
percent = 100;
if (percent > last) {
last = percent;
update_progress (percent, t - start_time, hdr);
}
if (percent == 100)
last = 0; /* Get ready for next time. */
}

View File

@@ -27,10 +27,15 @@
#include "avrpart.h"
#include "pgm.h"
typedef void (*FP_UpdateProgress)(int percent, double etime, char *hdr);
extern struct avrpart parts[];
extern FP_UpdateProgress update_progress;
#ifdef __cplusplus
extern "C" {
#endif
int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value);
@@ -56,12 +61,16 @@ int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size);
int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles);
int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);;
int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);
int avr_mem_hiaddr(AVRMEM * mem);
int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p);
extern void report_progress (int completed, int total, char *hdr);
void report_progress (int completed, int total, char *hdr);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,6 +1,8 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
* Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
* Copyright 2008 Klaus Leidinger <klaus@mikrocontroller-projekte.de>
*
* 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,19 +32,47 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <sys/time.h>
#include <unistd.h>
#include "avrdude.h"
#include "avr.h"
#include "config.h"
#include "pgm.h"
#include "avr910.h"
#include "serial.h"
extern char * progname;
extern int do_cycles;
extern int ovsigck;
/*
* Private data for this programmer.
*/
struct pdata
{
char has_auto_incr_addr;
unsigned char devcode;
unsigned int buffersize;
unsigned char test_blockmode;
unsigned char use_blockmode;
};
static char has_auto_incr_addr;
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
static void avr910_setup(PROGRAMMER * pgm)
{
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
fprintf(stderr,
"%s: avr910_setup(): Out of memory allocating private data\n",
progname);
exit(1);
}
memset(pgm->cookie, 0, sizeof(struct pdata));
PDATA(pgm)->test_blockmode = 1;
}
static void avr910_teardown(PROGRAMMER * pgm)
{
free(pgm->cookie);
}
static int avr910_send(PROGRAMMER * pgm, char * buf, size_t len)
@@ -166,50 +196,83 @@ static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
/* 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')
avr910_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1);
if (PDATA(pgm)->has_auto_incr_addr == 'Y')
fprintf(stderr, "Programmer supports auto addr increment.\n");
/* Get list of devices that the programmer supports. */
/* Check support for buffered memory access, ignore if not available */
avr910_send(pgm, "t", 1);
fprintf(stderr, "\nProgrammer supports the following devices:\n");
devtype_1st = 0;
while (1) {
if (PDATA(pgm)->test_blockmode == 1) {
avr910_send(pgm, "b", 1);
avr910_recv(pgm, &c, 1);
if (devtype_1st == 0)
devtype_1st = c;
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: %s: selected device is not supported by programmer: %s\n",
progname, ovsigck? "warning": "error", p->id);
if (!ovsigck)
exit(1);
if (c == 'Y') {
avr910_recv(pgm, &c, 1);
PDATA(pgm)->buffersize = (unsigned int)(unsigned char)c<<8;
avr910_recv(pgm, &c, 1);
PDATA(pgm)->buffersize += (unsigned int)(unsigned char)c;
fprintf(stderr,
"Programmer supports buffered memory access with "
"buffersize = %u bytes.\n",
PDATA(pgm)->buffersize);
PDATA(pgm)->use_blockmode = 1;
} else {
PDATA(pgm)->use_blockmode = 0;
}
} else {
PDATA(pgm)->use_blockmode = 0;
}
/* Tell the programmer which part we selected.
If the user forced the selection, use the first device
type that is supported by the programmer. */
if (PDATA(pgm)->devcode == 0) {
/* Get list of devices that the programmer supports. */
avr910_send(pgm, "t", 1);
fprintf(stderr, "\nProgrammer supports the following devices:\n");
devtype_1st = 0;
while (1) {
avr910_recv(pgm, &c, 1);
if (devtype_1st == 0)
devtype_1st = c;
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: %s: selected device is not supported by programmer: %s\n",
progname, ovsigck? "warning": "error", p->id);
if (!ovsigck)
exit(1);
}
/* If the user forced the selection, use the first device
type that is supported by the programmer. */
buf[1] = ovsigck? devtype_1st: p->avr910_devcode;
} else {
/* devcode overridden by -x devcode= option */
buf[1] = (char)(PDATA(pgm)->devcode);
}
/* Tell the programmer which part we selected. */
buf[0] = 'T';
buf[1] = ovsigck? devtype_1st: p->avr910_devcode;
/* buf[1] has been set up above */
avr910_send(pgm, buf, 2);
avr910_vfy_cmd_sent(pgm, "select device");
if (verbose)
fprintf(stderr,
"%s: avr910_devcode selected: 0x%02x\n",
progname, (unsigned)buf[1]);
avr910_enter_prog_mode(pgm);
return 0;
@@ -261,6 +324,55 @@ static int avr910_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
}
static int avr910_parseextparms(PROGRAMMER * pgm, LISTID extparms)
{
LNODEID ln;
const char *extended_param;
int rv = 0;
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
extended_param = ldata(ln);
if (strncmp(extended_param, "devcode=", strlen("devcode=")) == 0) {
int devcode;
if (sscanf(extended_param, "devcode=%i", &devcode) != 1 ||
devcode <= 0 || devcode > 255) {
fprintf(stderr,
"%s: avr910_parseextparms(): invalid devcode '%s'\n",
progname, extended_param);
rv = -1;
continue;
}
if (verbose >= 2) {
fprintf(stderr,
"%s: avr910_parseextparms(): devcode overwritten as 0x%02x\n",
progname, devcode);
}
PDATA(pgm)->devcode = devcode;
continue;
}
if (strncmp(extended_param, "no_blockmode", strlen("no_blockmode")) == 0) {
if (verbose >= 2) {
fprintf(stderr,
"%s: avr910_parseextparms(-x): no testing for Blockmode\n",
progname);
}
PDATA(pgm)->test_blockmode = 0;
continue;
}
fprintf(stderr,
"%s: avr910_parseextparms(): invalid extended parameter '%s'\n",
progname, extended_param);
rv = -1;
}
return rv;
}
static int avr910_open(PROGRAMMER * pgm, char * port)
{
/*
@@ -290,7 +402,7 @@ static void avr910_close(PROGRAMMER * pgm)
}
static void avr910_display(PROGRAMMER * pgm, char * p)
static void avr910_display(PROGRAMMER * pgm, const char * p)
{
return;
}
@@ -328,7 +440,7 @@ static int avr910_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
cmd[0] = 'D';
}
else {
return -1;
return avr_write_byte_default(pgm, p, m, addr, value);
}
cmd[1] = value;
@@ -400,7 +512,7 @@ static int avr910_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
return avr910_read_byte_eeprom(pgm, p, m, addr, value);
}
return -1;
return avr_read_byte_default(pgm, p, m, addr, value);
}
@@ -444,7 +556,7 @@ static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
page_addr = addr;
page_bytes = page_size;
}
else if ((has_auto_incr_addr != 'Y') && ((addr & 0x01) == 0)) {
else if ((PDATA(pgm)->has_auto_incr_addr != 'Y') && ((addr & 0x01) == 0)) {
avr910_set_addr(pgm, addr>>1);
}
@@ -484,7 +596,7 @@ static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
addr++;
if (has_auto_incr_addr != 'Y') {
if (PDATA(pgm)->has_auto_incr_addr != 'Y') {
avr910_set_addr(pgm, addr);
}
@@ -498,15 +610,55 @@ static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
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);
int rval = 0;
if (PDATA(pgm)->use_blockmode == 0) {
if (strcmp(m->desc, "flash") == 0) {
rval = avr910_paged_write_flash(pgm, p, m, page_size, n_bytes);
} else if (strcmp(m->desc, "eeprom") == 0) {
rval = avr910_paged_write_eeprom(pgm, p, m, page_size, n_bytes);
} else {
rval = -2;
}
}
else if (strcmp(m->desc, "eeprom") == 0) {
return avr910_paged_write_eeprom(pgm, p, m, page_size, n_bytes);
}
else {
return -2;
if (PDATA(pgm)->use_blockmode == 1) {
unsigned int addr = 0;
unsigned int max_addr = n_bytes;
char *cmd;
unsigned int blocksize = PDATA(pgm)->buffersize;
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
rval = -2;
if (m->desc[0] == 'e')
blocksize = 1; /* Write to eeprom single bytes only */
avr910_set_addr(pgm, addr);
cmd = malloc(4 + blocksize);
if (!cmd) rval = -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;
avr910_send(pgm, cmd, 4 + blocksize);
avr910_vfy_cmd_sent(pgm, "write block");
addr += blocksize;
report_progress (addr, max_addr, NULL);
} /* while */
free(cmd);
rval = addr;
}
return rval;
}
@@ -514,50 +666,90 @@ static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes)
{
char cmd;
int rd_size;
int rd_size = 1;
unsigned int addr = 0;
unsigned int max_addr;
char buf[2];
int rval=0;
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;
}
if (PDATA(pgm)->use_blockmode == 0) {
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, (char *)&m->buf[addr], 1);
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 {
rval = -2;
}
addr++;
max_addr = n_bytes/rd_size;
if (has_auto_incr_addr != 'Y') {
avr910_set_addr(pgm, addr);
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, (char *)&m->buf[addr], 1);
}
addr++;
if (PDATA(pgm)->has_auto_incr_addr != 'Y') {
avr910_set_addr(pgm, addr);
}
report_progress (addr, max_addr, NULL);
}
report_progress (addr, max_addr, NULL);
rval = addr * rd_size;
}
return addr * rd_size;
if (PDATA(pgm)->use_blockmode == 1) {
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"))
rval = -2;
/* use buffered mode */
char cmd[4];
int blocksize = PDATA(pgm)->buffersize;
cmd[0] = 'g';
cmd[3] = toupper(m->desc[0]);
avr910_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;
avr910_send(pgm, cmd, 4);
avr910_recv(pgm, (char *)&m->buf[addr], blocksize);
addr += blocksize;
report_progress (addr, max_addr, NULL);
}
rval = addr * rd_size;
}
return rval;
}
/* Signature byte reads are always 3 bytes. */
@@ -610,4 +802,8 @@ void avr910_initpgm(PROGRAMMER * pgm)
pgm->paged_load = avr910_paged_load;
pgm->read_sig_bytes = avr910_read_sig_bytes;
pgm->parseextparams = avr910_parseextparms;
pgm->setup = avr910_setup;
pgm->teardown = avr910_teardown;
}

View File

@@ -19,11 +19,19 @@
/* $Id$ */
#ifndef __avr910_h__
#define __avr910_h__
#ifndef avr910_h
#define avr910_h
#include "avrpart.h"
#ifdef __cplusplus
extern "C" {
#endif
void avr910_initpgm (PROGRAMMER * pgm);
#endif /* __avr910_h__ */
#ifdef __cplusplus
}
#endif
#endif /* avr910_h */

View File

@@ -1,6 +1,6 @@
.\"
.\" avrdude - A Downloader/Uploader for AVR device programmers
.\" Copyright (C) 2001, 2002, 2003, 2005, 2006 Joerg Wunsch
.\" Copyright (C) 2001, 2002, 2003, 2005 - 2009 Joerg Wunsch
.\"
.\" 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
@@ -19,7 +19,7 @@
.\"
.\" $Id$
.\"
.Dd DATE October 26, 2006
.Dd DATE November 5, 2008
.Os
.Dt AVRDUDE 1
.Sh NAME
@@ -48,6 +48,7 @@
.Op Fl u
.Op Fl U Ar memtype:op:filename:filefmt
.Op Fl v
.Op Fl x Ar extended_param
.Op Fl V
.Op Fl y
.Op Fl Y
@@ -58,6 +59,7 @@ microcontrollers.
.Nm Avrdude
supports Atmel's STK500 programmer,
Atmel's AVRISP and AVRISP mkII devices,
Atmel's STK600,
Atmel's JTAG ICE (both mkI and mkII, the latter also in ISP mode),
programmers complying to AppNote AVR910 and AVR109 (including the Butterfly),
as well as a simple hard-wired
@@ -105,6 +107,13 @@ Using firmware version 2, high-voltage programming is also supported,
both parallel and serial
(programmer types stk500pp and stk500hvsp).
.Pp
The Arduino (which is very similar to the STK500 1.x) is supported via
its own programmer type specification ``arduino''.
.Pp
Atmel's STK600 programmer is supported in ISP and high-voltage
programming modes, and connects through the USB.
For ATxmega devices, the STK600 is supported in PDI mode.
.Pp
The simple serial programmer described in Atmel's application note
AVR910, and the bootloader described in Atmel's application note
AVR109 (which is also used by the AVR Butterfly evaluation board), are
@@ -127,11 +136,11 @@ frequency, so the
.Fl B Ar bitclock
option might be required to achieve a stable ISP communication.
.Pp
The USBasp ISP adapter is also supported, provided
The USBasp ISP and USBtinyISP adapters are also supported, provided
.Nm avrdude
has been compiled with libusb support.
It features a simple firwmare-only USB implementation, running on
an ATmega8 (or ATmega88).
They both feature simple firwmare-only USB implementations, running on
an ATmega8 (or ATmega88), or ATtiny2313, respectively.
.Pp
Input files can be provided, and output files can be written in
different file formats, such as raw binary files containing the data
@@ -160,7 +169,7 @@ 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
On the STK500 and STK600 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
@@ -197,6 +206,8 @@ m103 ATmega103
m128 ATmega128
m1280 ATmega1280
m1281 ATmega1281
m1284p ATmega1284P
m128rfa1 ATmega128RFA1
m16 ATmega16
m161 ATmega161
m162 ATmega162
@@ -227,6 +238,8 @@ t25 ATtiny25
t26 ATtiny26
t45 ATtiny45
t85 ATtiny85
x128a1 ATxmega128A1
x128a1d ATxmega128A1revD
.TE
.Bl -tag -width "(**) "
.It "(*)"
@@ -281,11 +294,18 @@ option with flash memory is specified,
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.
Auto erase is not used for ATxmega devices as these devices can
use page erase before writing each page so no explicit chip erase
is required.
Note however that any page not affected by the current operation
will retain its previous contents.
.It Fl e
Causes a chip erase to be executed. This will reset the contents of the
flash ROM and EEPROM to the value
.Ql 0xff ,
and is basically a prerequisite command before the flash ROM can be
and clear all lock bits.
Except for ATxmega devices which can use page erase,
it is basically a prerequisite command before the flash ROM can be
reprogrammed again. The only exception would be if the new
contents would exclusively cause bits to be programmed from the value
.Ql 1
@@ -352,6 +372,12 @@ reasonable before continuing. Since it can happen from time to time
that a device has a broken (erased or overwritten) device signature
but is otherwise operating normally, this options is provided to
override the check.
Also, for programmers like the Atmel STK500 and STK600 which can
adjust parameters local to the programming tool (independent of an
actual connection to a target controller), this option can be used
together with
.Fl t
to continue in terminal mode.
.It Fl i Ar delay
For bitbang-type programmers, delay for approximately
.Ar delay
@@ -392,6 +418,14 @@ serial port, the
port is the default. If you need to use a different parallel or
serial port, use this option to specify the alternate port name.
.Pp
On Win32 operating systems, the parallel ports are referred to as lpt1
through lpt3, referring to the addresses 0x378, 0x278, and 0x3BC,
respectively. If the parallel port can be accessed through a different
address, this address can be specified directly, using the common C
language notation (i. e., hexadecimal values are prefixed by
.Ql 0x
).
.Pp
For the JTAG ICE mkII, if
.Nm
has been configured with libusb support,
@@ -578,6 +612,13 @@ does not have a colon in it.
Enable verbose output.
.It Fl V
Disable automatic verify check when uploading data.
.It Fl x Ar extended_param
Pass
.Ar extended_param
to the chosen programmer implementation as an extended parameter.
The interpretation of the extended parameter depends on the
programmer itself.
See below for a list of programmers accepting extended parameters.
.It Fl y
Tells
.Nm
@@ -642,26 +683,38 @@ feature of an AVR part that is not directly supported by
.Nm ,
this command allows you to use it, even though
.Nm
does not implement the command.
does not implement the command. When using direct SPI mode, up to 3 bytes
can be omitted.
.It Ar sig
Display the device signature bytes.
.It Ar spi
Enter direct SPI mode. The
.Em pgmled
pin acts as slave select.
.Em Only supported on parallel bitbang programmers.
.It Ar part
Display the current part settings and parameters. Includes chip
specific information including all memory types supported by the
device, read/write timing, etc.
.It Ar pgm
Return to programming mode (from direct SPI mode).
.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
.Em Only supported on the STK500 and STK600 programmer.
.It Ar varef Oo Ar channel Oc Ar 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.
On the Atmel STK600, two reference voltages are available, which
can be selected by the optional
.Ar channel
argument (either 0 or 1).
.Em Only supported on the STK500 and STK600 programmer.
.It Ar fosc freq Ns Op M Ns \&| Ns k
Set the master oscillator to
.Ar freq
@@ -671,12 +724,12 @@ An optional trailing letter
multiplies by 1E6, a trailing letter
.Ar \&k
by 1E3.
.Em Only supported on the STK500 programmer.
.Em Only supported on the STK500 and STK600 programmer.
.It Ar fosc off
Turn the master oscillator off.
.Em Only supported on the STK500 programmer.
.Em Only supported on the STK500 and STK600 programmer.
.It Ar sck period
.Em STK500 programmer only:
.Em STK500 and STK600 programmer only:
Set the SCK clock period to
.Ar period
microseconds.
@@ -691,7 +744,7 @@ software signs off from the JTAG ICE.
This parameter can also be used on the JTAG ICE mkII to specify the
ISP clock period when operating the ICE in ISP mode.
.It Ar parms
.Em STK500 programmer only:
.Em STK500 and STK600 programmer only:
Display the current voltage and master oscillator parameters.
.Pp
.Em JTAG ICE only:
@@ -744,6 +797,52 @@ be accessed using normal ISP programming.
This sequence is automatically initiated by using the JTAG ICE mkII
or AVR Dragon in ISP mode, when they detect that ISP mode cannot be
entered.
.Ss Programmers accepting extended parameters
.Bl -tag -offset indent -width indent
.It Ar JTAG ICE mkII
.It Ar AVR Dragon
When using the JTAG ICE mkII or AVR Dragon in JTAG mode, the
following extended parameter is accepted:
.Bl -tag -offset indent -width indent
.It Ar jtagchain=UB,UA,BB,BA
Setup the JTAG scan chain for
.Ar UB
units before,
.Ar UA
units after,
.Ar BB
bits before, and
.Ar BA
bits after the target AVR, respectively.
Each AVR unit within the chain shifts by 4 bits.
Other JTAG units might require a different bit shift count.
.El
.It Ar AVR910
.Bl -tag -offset indent -width indent
.It Ar devcode=VALUE
Override the device code selection by using
.Ar VALUE
as the device code.
The programmer is not queried for the list of supported
device codes, and the specified
.Ar VALUE
is not verified but used directly within the
.Ql T
command sent to the programmer.
.Ar VALUE
can be specified using the conventional number notation of the
C programming language.
.El
.Bl -tag -offset indent -width indent
.It Ar no_blockmode
Disables the default checking for block transfer capability.
Use
.Ar no_blockmode
only if your
.Ar AVR910
programmer creates errors during initial sequence.
.El
.El
.Sh FILES
.Bl -tag -offset indent -width /dev/ppi0XXX
.It Pa /dev/ppi0
@@ -815,8 +914,8 @@ Page-mode programming the EEPROM through JTAG (i.e. through an
.Fl U
option) requires a prior chip erase.
This is an inherent feature of the way JTAG EEPROM programming works.
This also applies to the STK500 in parallel programming mode.
This also applies to the STK500 and STK600 in parallel programming mode.
.Pp
The USBasp driver does not offer any option to distinguish multiple
The USBasp and USBtinyISP drivers do not offer any option to distinguish multiple
devices connected simultaneously, so effectively only a single device
is supported.

File diff suppressed because it is too large Load Diff

61
avrdude/avrdude.h Normal file
View File

@@ -0,0 +1,61 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2007 Joerg Wunsch
*
* 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 avrdude_h
#define avrdude_h
extern char * progname; /* name of program, for messages */
extern char progbuf[]; /* spaces same length as progname */
extern int do_cycles; /* track erase-rewrite cycles (-y) */
extern int ovsigck; /* override signature check (-F) */
extern int verbose; /* verbosity level (-v, -vv, ...) */
extern int quell_progress; /* quiteness level (-q, -qq) */
#if defined(WIN32NATIVE)
#include "ac_cfg.h"
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
/* usleep replacements */
/* sleep Windows in ms, Unix usleep in us
#define usleep(us) Sleep((us)<20000?20:us/1000)
#define usleep(us) Sleep(us/1000)
#define ANTIWARP 3
#define usleep(us) Sleep(us/1000*ANTIWARP)
*/
int usleep(unsigned int us);
#if !defined(HAVE_GETTIMEOFDAY)
struct timezone;
int gettimeofday(struct timeval *tv, struct timezone *tz);
#ifdef __cplusplus
}
#endif
#endif /* HAVE_GETTIMEOFDAY */
#endif /* defined(WIN32NATIVE) */
#endif

View File

@@ -24,12 +24,10 @@
#include <stdlib.h>
#include <string.h>
#include "avrdude.h"
#include "avrpart.h"
#include "pindefs.h"
extern char * progname;
/***
*** Elementary functions dealing with OPCODE structures
***/
@@ -164,7 +162,7 @@ int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data)
}
char * avr_op_str(int op)
static char * avr_op_str(int op)
{
switch (op) {
case AVR_OP_READ : return "READ"; break;
@@ -184,7 +182,7 @@ char * avr_op_str(int op)
}
char * bittype(int type)
static char * bittype(int type)
{
switch (type) {
case AVR_CMDBIT_IGNORE : return "IGNORE"; break;
@@ -287,7 +285,7 @@ AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
}
void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, int type,
int verbose)
{
int i, j;
@@ -436,22 +434,30 @@ AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode)
return NULL;
}
void list_parts(FILE * f, char * prefix, LISTID parts)
/*
* Iterate over the list of avrparts given as "avrparts", and
* call the callback function cb for each entry found. cb is being
* passed the following arguments:
* . the name of the avrpart (for -p)
* . the descriptive text given in the config file
* . the name of the config file this avrpart has been defined in
* . the line number of the config file this avrpart has been defined at
* . the "cookie" passed into walk_avrparts() (opaque client data)
*/
void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie)
{
LNODEID ln1;
AVRPART * p;
for (ln1=lfirst(parts); ln1; ln1=lnext(ln1)) {
for (ln1 = lfirst(avrparts); 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);
cb(p->id, p->desc, p->config_file, p->lineno, cookie);
}
return;
}
char * reset_disp_str(int r)
static char * reset_disp_str(int r)
{
switch (r) {
case RESET_DEDICATED : return "dedicated";
@@ -461,7 +467,7 @@ char * reset_disp_str(int r)
}
char * pin_name(int pinno)
static char * pin_name(int pinno)
{
switch (pinno) {
case PIN_AVR_RESET : return "RESET";
@@ -473,31 +479,31 @@ char * pin_name(int pinno)
}
void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose)
void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose)
{
int i;
char * buf;
char * px;
const 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"
"%sTimeout : %d\n"
"%sStabDelay : %d\n"
"%sCmdexeDelay : %d\n"
"%sSyncLoops : %d\n"
"%sByteDelay : %d\n"
"%sPollIndex : %d\n"
"%sPollValue : 0x%02x\n"
"%sMemory Detail :\n\n",
"%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"
"%sTimeout : %d\n"
"%sStabDelay : %d\n"
"%sCmdexeDelay : %d\n"
"%sSyncLoops : %d\n"
"%sByteDelay : %d\n"
"%sPollIndex : %d\n"
"%sPollValue : 0x%02x\n"
"%sMemory Detail :\n\n",
prefix, p->desc,
prefix, p->chip_erase_delay,
prefix, p->pagel,

View File

@@ -20,16 +20,14 @@
/* $Id$ */
#ifndef __avrpart_h__
#define __avrpart_h__
#ifndef avrpart_h
#define avrpart_h
#include <limits.h>
#include "lists.h"
extern LISTID part_list;
/*
* AVR serial programming instructions
*/
@@ -90,6 +88,7 @@ typedef struct opcode {
#define AVRPART_ALLOWFULLPAGEBITSTREAM 0x0010 /* JTAG ICE mkII param. */
#define AVRPART_ENABLEPAGEPROGRAMMING 0x0020 /* JTAG ICE mkII param. */
#define AVRPART_HAS_DW 0x0040 /* part has a debugWire i/f */
#define AVRPART_HAS_PDI 0x0080 /* part has PDI i/f rather than ISP (ATxmega) */
#define AVR_DESCLEN 64
#define AVR_IDLEN 32
@@ -149,6 +148,7 @@ typedef struct avrpart {
unsigned char rampz; /* JTAG ICE mkII XML file parameter */
unsigned char spmcr; /* JTAG ICE mkII XML file parameter */
unsigned short eecr; /* JTAC ICE mkII XML file parameter */
unsigned int nvm_base; /* Base address of NVM controller in ATxmega devices */
OPCODE * op[AVR_OP_MAX]; /* opcodes */
@@ -164,6 +164,7 @@ typedef struct avrmem {
int size; /* total memory size in bytes */
int page_size; /* size of memory page (if page addressed) */
int num_pages; /* number of pages (if page addressed) */
unsigned int offset; /* offset in IO memory (ATxmega) */
int min_write_delay; /* microseconds */
int max_write_delay; /* microseconds */
int pwroff_after_write; /* after this memory type is written to,
@@ -182,6 +183,10 @@ typedef struct avrmem {
OPCODE * op[AVR_OP_MAX]; /* opcodes */
} AVRMEM;
#ifdef __cplusplus
extern "C" {
#endif
/* Functions for OPCODE structures */
OPCODE * avr_new_opcode(void);
int avr_set_bits(OPCODE * op, unsigned char * cmd);
@@ -194,7 +199,7 @@ 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,
void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, int type,
int verbose);
/* Functions for AVRPART structures */
@@ -202,7 +207,15 @@ 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);
void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose);
typedef void (*walk_avrparts_cb)(const char *name, const char *desc,
const char *cfgname, int cfglineno,
void *cookie);
void walk_avrparts(LISTID programmers, walk_avrparts_cb cb, void *cookie);
#ifdef __cplusplus
}
#endif
#endif /* avrpart_h */

View File

@@ -33,16 +33,13 @@
# include <sys/time.h>
#endif
#include "avrdude.h"
#include "avr.h"
#include "pindefs.h"
#include "pgm.h"
#include "par.h"
#include "serbb.h"
extern char * progname;
extern int do_cycles;
extern int verbose;
static int delay_decrement;
#if !defined(WIN32NATIVE)
@@ -228,6 +225,39 @@ int bitbang_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
return 0;
}
/*
* transmit bytes via SPI and return the results; 'cmd' and
* 'res' must point to data buffers
*/
int bitbang_spi(PROGRAMMER * pgm, unsigned char cmd[],
unsigned char res[], int count)
{
int i;
pgm->setpin(pgm, pgm->pinno[PIN_LED_PGM], 0);
for (i=0; i<count; i++) {
res[i] = bitbang_txrx(pgm, cmd[i]);
}
pgm->setpin(pgm, pgm->pinno[PIN_LED_PGM], 1);
if(verbose >= 2)
{
fprintf(stderr, "bitbang_cmd(): [ ");
for(i = 0; i < count; i++)
fprintf(stderr, "%02X ", cmd[i]);
fprintf(stderr, "] [ ");
for(i = 0; i < count; i++)
{
fprintf(stderr, "%02X ", res[i]);
}
fprintf(stderr, "]\n");
}
return 0;
}
/*
* issue the 'chip erase' command to the AVR device

View File

@@ -22,6 +22,10 @@
#ifndef bitbang_h
#define bitbang_h
#ifdef __cplusplus
extern "C" {
#endif
int bitbang_setpin(int fd, int pin, int value);
int bitbang_getpin(int fd, int pin);
int bitbang_highpulsepin(int fd, int pin);
@@ -35,6 +39,8 @@ int bitbang_pgm_led (PROGRAMMER * pgm, int value);
int bitbang_vfy_led (PROGRAMMER * pgm, int value);
int bitbang_cmd (PROGRAMMER * pgm, unsigned char cmd[4],
unsigned char res[4]);
int bitbang_spi (PROGRAMMER * pgm, unsigned char cmd[],
unsigned char res[], int count);
int bitbang_chip_erase (PROGRAMMER * pgm, AVRPART * p);
int bitbang_program_enable (PROGRAMMER * pgm, AVRPART * p);
void bitbang_powerup (PROGRAMMER * pgm);
@@ -43,4 +49,8 @@ int bitbang_initialize (PROGRAMMER * pgm, AVRPART * p);
void bitbang_disable (PROGRAMMER * pgm);
void bitbang_enable (PROGRAMMER * pgm);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,11 +1,11 @@
#! /bin/sh
# autoconf-2.59 is required
# autoconf-2.59 or 2.61 is known to work
: ${AUTOHEADER="autoheader${AC_VER}"}
: ${AUTOCONF="autoconf${AC_VER}"}
# automake-1.9.x is required
# automake-1.9.x or 1.10 is known to work
: ${ACLOCAL="aclocal${AM_VER}"}
: ${AUTOMAKE="automake${AM_VER}"}
@@ -14,22 +14,20 @@
AUTOCONF_VER=`(${AUTOCONF} --version 2>/dev/null | head -n 1 | \
cut -d ' ' -f 4) 2>/dev/null`
if [ "$AUTOCONF_VER" != "2.59" ]
if [ "$AUTOCONF_VER" != "2.59" -a "$AUTOCONF_VER" != "2.61" ]
then
echo "You need to use autoconf version 2.59."
echo "Warning: This program is tested with autoconf version 2.59 and 2.61."
echo "You are using `${AUTOCONF} --version | head -n 1`."
exit 1
fi
# Verify automake version
AUTOMAKE_VER=`(${AUTOMAKE} --version | head -n 1 | \
cut -d ' ' -f 4 | cut -d '.' -f -2) 2>/dev/null`
if [ "$AUTOMAKE_VER" != "1.9" ]
if [ "$AUTOMAKE_VER" != "1.9" -a "$AUTOMAKE_VER" != "1.10" ]
then
echo "You need to use automake version 1.9."
echo "Warning: This program is tested with automake version 1.9 and 1.10."
echo "You are using `${AUTOMAKE} --version | head -n 1`."
exit 1
fi
export ACLOCAL AUTOHEADER AUTOCONF AUTOMAKE

View File

@@ -1,7 +1,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
* Copyright (C) 2005 Joerg Wunsch <j@uriah.heep.sax.de>
* Copyright (C) 2005, 2007 Joerg Wunsch <j@uriah.heep.sax.de>
*
* 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
@@ -44,31 +44,41 @@
#include <errno.h>
#include <ctype.h>
#include "avrdude.h"
#include "avr.h"
#include "pgm.h"
#include "butterfly.h"
#include "serial.h"
extern char * progname;
extern int do_cycles;
/*
* Private data for this programmer.
*/
struct pdata
{
char has_auto_incr_addr;
unsigned int buffersize;
};
static char has_auto_incr_addr;
static unsigned buffersize = 0;
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
/* 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 void butterfly_setup(PROGRAMMER * pgm)
{
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
fprintf(stderr,
"%s: butterfly_setup(): Out of memory allocating private data\n",
progname);
exit(1);
}
memset(pgm->cookie, 0, sizeof(struct pdata));
}
static void butterfly_teardown(PROGRAMMER * pgm)
{
free(pgm->cookie);
}
static int butterfly_send(PROGRAMMER * pgm, char * buf, size_t len)
{
no_show_func_info();
return serial_send(&pgm->fd, (unsigned char *)buf, len);
}
@@ -77,8 +87,6 @@ static int butterfly_recv(PROGRAMMER * pgm, char * buf, size_t len)
{
int rv;
no_show_func_info();
rv = serial_recv(&pgm->fd, (unsigned char *)buf, len);
if (rv < 0) {
fprintf(stderr,
@@ -92,8 +100,6 @@ static int butterfly_recv(PROGRAMMER * pgm, char * buf, size_t len)
static int butterfly_drain(PROGRAMMER * pgm, int display)
{
no_show_func_info();
return serial_drain(&pgm->fd, display);
}
@@ -113,8 +119,6 @@ static void butterfly_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
static int butterfly_rdy_led(PROGRAMMER * pgm, int value)
{
no_show_func_info();
/* Do nothing. */
return 0;
@@ -123,8 +127,6 @@ static int butterfly_rdy_led(PROGRAMMER * pgm, int value)
static int butterfly_err_led(PROGRAMMER * pgm, int value)
{
no_show_func_info();
/* Do nothing. */
return 0;
@@ -133,8 +135,6 @@ static int butterfly_err_led(PROGRAMMER * pgm, int value)
static int butterfly_pgm_led(PROGRAMMER * pgm, int value)
{
no_show_func_info();
/* Do nothing. */
return 0;
@@ -143,8 +143,6 @@ static int butterfly_pgm_led(PROGRAMMER * pgm, int value)
static int butterfly_vfy_led(PROGRAMMER * pgm, int value)
{
no_show_func_info();
/* Do nothing. */
return 0;
@@ -156,8 +154,6 @@ static int butterfly_vfy_led(PROGRAMMER * pgm, int value)
*/
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");
@@ -184,8 +180,6 @@ static void butterfly_leave_prog_mode(PROGRAMMER * pgm)
*/
static int butterfly_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
no_show_func_info();
return -1;
}
@@ -195,8 +189,6 @@ static int butterfly_program_enable(PROGRAMMER * pgm, AVRPART * p)
*/
static void butterfly_powerup(PROGRAMMER * pgm)
{
no_show_func_info();
/* Do nothing. */
return;
@@ -208,8 +200,6 @@ static void butterfly_powerup(PROGRAMMER * pgm)
*/
static void butterfly_powerdown(PROGRAMMER * pgm)
{
no_show_func_info();
/* Do nothing. */
return;
@@ -226,9 +216,7 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
char hw[2];
char buf[10];
char type;
char c;
no_show_func_info();
char c, devtype_1st;
/*
* Send some ESC to activate butterfly bootloader. This is not needed
@@ -281,8 +269,8 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
/* 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')
butterfly_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1);
if (PDATA(pgm)->has_auto_incr_addr == 'Y')
fprintf(stderr, "Programmer supports auto addr increment.\n");
/* Check support for buffered memory access, abort if not available */
@@ -296,33 +284,48 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
exit(1);
};
butterfly_recv(pgm, &c, 1);
buffersize = (unsigned int)(unsigned char)c<<8;
PDATA(pgm)->buffersize = (unsigned int)(unsigned char)c<<8;
butterfly_recv(pgm, &c, 1);
buffersize += (unsigned int)(unsigned char)c;
PDATA(pgm)->buffersize += (unsigned int)(unsigned char)c;
fprintf(stderr,
"Programmer supports buffered memory access with buffersize=%i bytes.\n",
buffersize);
PDATA(pgm)->buffersize);
/* Get list of devices that the programmer supports. */
butterfly_send(pgm, "t", 1);
fprintf(stderr, "\nProgrammer supports the following devices:\n");
devtype_1st = 0;
while (1) {
butterfly_recv(pgm, &c, 1);
if (devtype_1st == 0)
devtype_1st = c;
if (c == 0)
break;
fprintf(stderr, " Device code: 0x%02x\n", (unsigned int)(unsigned char)c);
};
fprintf(stderr,"\n");
/* Tell the programmer which part we selected. */
/* Tell the programmer which part we selected.
According to the AVR109 code, this is ignored by the bootloader. As
some early versions might not properly ignore it, rather pick up the
first device type as reported above than anything out of avrdude.conf,
so to avoid a potential conflict. There appears to be no general
agreement on AVR910 device IDs beyond the ones from the original
appnote 910. */
buf[0] = 'T';
buf[1] = p->avr910_devcode;
buf[1] = devtype_1st;
butterfly_send(pgm, buf, 2);
butterfly_vfy_cmd_sent(pgm, "select device");
if (verbose)
fprintf(stderr,
"%s: devcode selected: 0x%02x\n",
progname, (unsigned)buf[1]);
butterfly_enter_prog_mode(pgm);
return 0;
@@ -332,8 +335,6 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
static void butterfly_disable(PROGRAMMER * pgm)
{
no_show_func_info();
butterfly_leave_prog_mode(pgm);
return;
@@ -342,16 +343,12 @@ static void butterfly_disable(PROGRAMMER * pgm)
static void butterfly_enable(PROGRAMMER * pgm)
{
no_show_func_info();
return;
}
static int butterfly_open(PROGRAMMER * pgm, char * port)
{
no_show_func_info();
strcpy(pgm->port, port);
/*
* If baudrate was not specified use 19200 Baud
@@ -372,8 +369,6 @@ static int butterfly_open(PROGRAMMER * pgm, char * port)
static void butterfly_close(PROGRAMMER * pgm)
{
no_show_func_info();
/* "exit programmer" */
butterfly_send(pgm, "E", 1);
butterfly_vfy_cmd_sent(pgm, "exit bootloader");
@@ -383,10 +378,8 @@ static void butterfly_close(PROGRAMMER * pgm)
}
static void butterfly_display(PROGRAMMER * pgm, char * p)
static void butterfly_display(PROGRAMMER * pgm, const char * p)
{
no_show_func_info();
return;
}
@@ -404,14 +397,27 @@ static void butterfly_set_addr(PROGRAMMER * pgm, unsigned long addr)
}
static void butterfly_set_extaddr(PROGRAMMER * pgm, unsigned long addr)
{
char cmd[4];
cmd[0] = 'H';
cmd[1] = (addr >> 16) & 0xff;
cmd[2] = (addr >> 8) & 0xff;
cmd[3] = addr & 0xff;
butterfly_send(pgm, cmd, sizeof(cmd));
butterfly_vfy_cmd_sent(pgm, "set extaddr");
}
static int butterfly_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned long addr, unsigned char value)
{
char cmd[6];
int size;
no_show_func_info();
int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
if ((strcmp(m->desc, "flash") == 0) || (strcmp(m->desc, "eeprom") == 0))
{
@@ -427,7 +433,11 @@ static int butterfly_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
size = 6;
return -1;
}
butterfly_set_addr(pgm, addr);
if (use_ext_addr) {
butterfly_set_extaddr(pgm, addr);
} else {
butterfly_set_addr(pgm, addr);
}
}
else if (strcmp(m->desc, "lock") == 0)
{
@@ -451,6 +461,7 @@ static int butterfly_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int cached = 0;
static unsigned char cvalue;
static unsigned long caddr;
int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
if (cached && ((caddr + 1) == addr)) {
*value = cvalue;
@@ -459,7 +470,11 @@ static int butterfly_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
else {
char buf[2];
butterfly_set_addr(pgm, addr >> 1);
if (use_ext_addr) {
butterfly_set_extaddr(pgm, addr >> 1);
} else {
butterfly_set_addr(pgm, addr >> 1);
}
butterfly_send(pgm, "g\000\002F", 4);
@@ -496,8 +511,6 @@ static int butterfly_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
{
char cmd;
no_show_func_info();
if (strcmp(m->desc, "flash") == 0) {
return butterfly_read_byte_flash(pgm, p, m, addr, value);
}
@@ -535,7 +548,8 @@ static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int addr = 0;
unsigned int max_addr = n_bytes;
char *cmd;
unsigned int blocksize = buffersize;
unsigned int blocksize = PDATA(pgm)->buffersize;
int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
return -2;
@@ -543,7 +557,11 @@ static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
if (m->desc[0] == 'e')
blocksize = 1; /* Write to eeprom single bytes only */
butterfly_set_addr(pgm, addr);
if (use_ext_addr) {
butterfly_set_extaddr(pgm, addr);
} else {
butterfly_set_addr(pgm, addr);
}
#if 0
usleep(1000000);
@@ -584,6 +602,7 @@ static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int addr = 0;
unsigned int max_addr = n_bytes;
int rd_size = 1;
int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
/* check parameter syntax: only "flash" or "eeprom" is allowed */
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
@@ -591,12 +610,16 @@ static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
{ /* use buffered mode */
char cmd[4];
int blocksize = buffersize;
int blocksize = PDATA(pgm)->buffersize;
cmd[0] = 'g';
cmd[3] = toupper(m->desc[0]);
butterfly_set_addr(pgm, addr);
if (use_ext_addr) {
butterfly_set_extaddr(pgm, addr);
} else {
butterfly_set_addr(pgm, addr);
}
while (addr < max_addr) {
if ((max_addr - addr) < blocksize) {
blocksize = max_addr - addr;
@@ -622,8 +645,6 @@ static int butterfly_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
{
unsigned char tmp;
no_show_func_info();
if (m->size < 3) {
fprintf(stderr, "%s: memsize too small for sig byte read", progname);
return -1;
@@ -642,8 +663,6 @@ static int butterfly_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
void butterfly_initpgm(PROGRAMMER * pgm)
{
no_show_func_info();
strcpy(pgm->type, "avr910");
/*
@@ -674,4 +693,7 @@ void butterfly_initpgm(PROGRAMMER * pgm)
pgm->paged_load = butterfly_paged_load;
pgm->read_sig_bytes = butterfly_read_sig_bytes;
pgm->setup = butterfly_setup;
pgm->teardown = butterfly_teardown;
}

View File

@@ -19,9 +19,17 @@
/* $Id$ */
#ifndef __butterfly_h__
#define __butterfly_h__
#ifndef butterfly_h
#define butterfly_h
#ifdef __cplusplus
extern "C" {
#endif
void butterfly_initpgm (PROGRAMMER * pgm);
#endif /* __butterfly_h__ */
#ifdef __cplusplus
}
#endif
#endif /* butterfly_h */

View File

@@ -21,11 +21,13 @@
#include "ac_cfg.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "avrdude.h"
#include "avr.h"
#include "config.h"
#include "config_gram.h"
@@ -45,8 +47,10 @@ AVRMEM * current_mem;
LISTID part_list;
LISTID programmers;
int lineno = 0;
char * infile = NULL;
int lineno;
const char * infile;
extern char * yytext;
#define DEBUG 0
@@ -261,14 +265,12 @@ void print_token(TOKEN * tkn)
void pyytext(void)
{
#if DEBUG
extern char * yytext;
fprintf(stderr, "TOKEN: \"%s\"\n", yytext);
#endif
}
char * dup_string(char * str)
char * dup_string(const char * str)
{
char * s;
@@ -281,3 +283,24 @@ char * dup_string(char * str)
return s;
}
int read_config(const char * file)
{
FILE * f;
f = fopen(file, "r");
if (f == NULL) {
fprintf(stderr, "%s: can't open config file \"%s\": %s\n",
progname, file, strerror(errno));
return -1;
}
lineno = 1;
infile = file;
yyin = f;
yyparse();
fclose(f);
return 0;
}

View File

@@ -19,8 +19,8 @@
/* $Id$ */
#ifndef __config_h__
#define __config_h__
#ifndef config_h
#define config_h
#include "lists.h"
#include "pindefs.h"
@@ -49,9 +49,11 @@ extern PROGRAMMER * current_prog;
extern AVRPART * current_part;
extern AVRMEM * current_mem;
extern int lineno;
extern char * infile;
extern const char * infile;
extern LISTID string_list;
extern LISTID number_list;
extern LISTID part_list;
extern LISTID programmers;
extern char default_programmer[];
extern char default_parallel[];
extern char default_serial[];
@@ -66,6 +68,10 @@ extern YYSTYPE yylval;
extern char string_buf[MAX_STR_CONST];
extern char *string_buf_ptr;
#ifdef __cplusplus
extern "C" {
#endif
int yyparse(void);
@@ -89,12 +95,14 @@ TOKEN * keyword(int primary);
void print_token(TOKEN * tkn);
PROGRAMMER * new_programmer(void);
void pyytext(void);
AVRPART * new_part(void);
char * dup_string(const char * str);
AVRPART * dup_part(AVRPART * d);
int read_config(const char * file);
char * dup_string(char * str);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -27,6 +27,8 @@
#include <string.h>
#include <math.h>
#include "avrdude.h"
#include "config.h"
#include "lists.h"
#include "par.h"
@@ -35,11 +37,13 @@
#include "ppi.h"
#include "pgm.h"
#include "stk500.h"
#include "arduino.h"
#include "stk500v2.h"
#include "stk500generic.h"
#include "avr910.h"
#include "butterfly.h"
#include "usbasp.h"
#include "usbtiny.h"
#include "avr.h"
#include "jtagmkI.h"
#include "jtagmkII.h"
@@ -49,8 +53,6 @@
( *(_lasts) = strtok( (_s), (_sep) ) )
#endif
extern char * progname;
int yylex(void);
int yyerror(char * errmsg);
@@ -78,6 +80,7 @@ static int parse_cmdbits(OPCODE * op);
%token K_PAGE_SIZE
%token K_PAGED
%token K_ARDUINO
%token K_BAUDRATE
%token K_BS2
%token K_BUFF
@@ -110,6 +113,8 @@ static int parse_cmdbits(OPCODE * op);
%token K_MISO
%token K_MOSI
%token K_NUM_PAGES
%token K_NVM_BASE
%token K_OFFSET
%token K_PAGEL
%token K_PAR
%token K_PARALLEL
@@ -134,13 +139,16 @@ static int parse_cmdbits(OPCODE * op);
%token K_STK500PP
%token K_STK500V2
%token K_STK500GENERIC
%token K_STK600
%token K_STK600HVSP
%token K_STK600PP
%token K_AVR910
%token K_USBASP
%token K_USBTINY
%token K_BUTTERFLY
%token K_TYPE
%token K_VCC
%token K_VFYLED
%token K_WRITEPAGE
%token K_NO
%token K_YES
@@ -197,6 +205,7 @@ static int parse_cmdbits(OPCODE * op);
%token K_ENABLEPAGEPROGRAMMING /* ? yes for mega256*, mega406 */
%token K_HAS_JTAG /* MCU has JTAG i/f. */
%token K_HAS_DW /* MCU has debugWire i/f. */
%token K_HAS_PDI /* MCU has PDI i/f rather than ISP (ATxmega). */
%token K_IDR /* address of OCD register in IO space */
%token K_RAMPZ /* address of RAMPZ reg. in IO space */
%token K_SPMCR /* address of SPMC[S]R in memory space */
@@ -410,6 +419,30 @@ prog_parm :
}
} |
K_TYPE TKN_EQUAL K_ARDUINO {
{
arduino_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_STK600 {
{
stk600_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_STK600HVSP {
{
stk600hvsp_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_STK600PP {
{
stk600pp_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_AVR910 {
{
avr910_initpgm(current_prog);
@@ -422,6 +455,12 @@ prog_parm :
}
} |
K_TYPE TKN_EQUAL K_USBTINY {
{
usbtiny_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_BUTTERFLY {
{
butterfly_initpgm(current_prog);
@@ -1000,6 +1039,16 @@ part_parm :
free_token($3);
} |
K_HAS_PDI TKN_EQUAL yesno
{
if ($3->primary == K_YES)
current_part->flags |= AVRPART_HAS_PDI;
else if ($3->primary == K_NO)
current_part->flags &= ~AVRPART_HAS_PDI;
free_token($3);
} |
K_ALLOWFULLPAGEBITSTREAM TKN_EQUAL yesno
{
if ($3->primary == K_YES)
@@ -1044,6 +1093,12 @@ part_parm :
free_token($3);
} |
K_NVM_BASE TKN_EQUAL TKN_NUMBER
{
current_part->nvm_base = $3->value.number;
free_token($3);
} |
K_SERIAL TKN_EQUAL yesno
{
if ($3->primary == K_YES)
@@ -1161,6 +1216,12 @@ mem_spec :
free_token($3);
} |
K_OFFSET TKN_EQUAL TKN_NUMBER
{
current_mem->offset = $3->value.number;
free_token($3);
} |
K_MIN_WRITE_DELAY TKN_EQUAL TKN_NUMBER
{
current_mem->min_write_delay = $3->value.number;

View File

@@ -24,7 +24,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57)
AC_INIT(avrdude, 5.3.1, avrdude-dev@nongnu.org)
AC_INIT(avrdude, 5.6, avrdude-dev@nongnu.org)
AC_CANONICAL_BUILD
AC_CANONICAL_HOST
@@ -38,12 +38,15 @@ AM_CONFIG_HEADER(ac_cfg.h)
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_YACC
AM_PROG_LEX
AC_PROG_LEX
AC_PROG_RANLIB
# Checks for libraries.
AC_CHECK_LIB([termcap], [tputs])
AC_CHECK_LIB([ncurses], [tputs])
AC_CHECK_LIB([readline], [readline])
AC_SEARCH_LIBS([gethostent], [nsl])
AC_SEARCH_LIBS([setsockopt], [socket])
AH_TEMPLATE([HAVE_LIBUSB],
[Define if USB support is enabled via libusb])
AC_CHECK_LIB([usb], [usb_get_string_simple], [have_libusb=yes])
@@ -60,16 +63,33 @@ if test x$have_libusb = xyes; then
fi
AC_SUBST(LIBUSB, $LIBUSB)
# Checks for header files.
AC_CHECK_HEADERS([limits.h stdlib.h string.h])
AC_CHECK_HEADERS([fcntl.h sys/ioctl.h sys/time.h termios.h unistd.h])
AC_CHECK_HEADERS([ddk/hidsdi.h],,,[#include <windows.h>
#include <setupapi.h>])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_HEADER_TIME
# Checks for library functions.
AC_CHECK_FUNCS([memset select strcasecmp strdup strerror strncasecmp strtol strtoul gettimeofday])
AC_MSG_CHECKING([for a Win32 HID libray])
SAVED_LIBS="${LIBS}"
case $target in
*-*-mingw32*)
*-*-mingw32* | *-*-cygwin* | *-*-windows*)
LIBHID="-lhid -lsetupapi"
HIDINCLUDE="#include <ddk/hidsdi.h>"
if test $ac_cv_header_ddk_hidsdi_h = yes
then
HIDINCLUDE="#include <ddk/hidsdi.h>"
else
HIDINCLUDE="#include \"my_ddk_hidsdi.h\""
fi
;;
*)
LIBHID="-lhid"
HIDINCLUDE='#include "my_ddk_hidsdi.h"'
LIBHID=""
;;
esac
LIBS="${LIBS} ${LIBHID}"
@@ -96,22 +116,14 @@ else
LIBHID=""
fi
LIBS="${SAVED_LIBS}"
AC_SUBST(LIBHID, $LIBHID)
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([limits.h stdlib.h string.h])
AC_CHECK_HEADERS([fcntl.h sys/ioctl.h sys/time.h termios.h unistd.h])
AC_CHECK_HEADERS([ddk/hidsdi.h],,,[#include <windows.h>
#include <setupapi.h>])
# Check for types
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_HEADER_TIME
# Checks for library functions.
AC_PROG_GCC_TRADITIONAL
AC_FUNC_MALLOC
AC_CHECK_FUNCS([memset select strcasecmp strdup strerror strncasecmp strtol strtoul gettimeofday])
# Solaris has uint_t and ulong_t typedefs in <sys/types.h>, avoid
# the redeclaration in usbtiny.c.
AC_CHECK_TYPES([uint_t], [], [], [#include <sys/types.h>])
AC_CHECK_TYPES([ulong_t], [], [], [#include <sys/types.h>])
# Checks for misc stuff.
@@ -157,14 +169,12 @@ AC_ARG_ENABLE(
esac],
[enabled_parport=yes])
if test "$enabled_doc" = "yes"; then
SUBDIRS_AC='doc @WINDOWS_DIRS@'
DIST_SUBDIRS_AC='doc windows'
else
SUBDIRS_AC='@WINDOWS_DIRS@'
DIST_SUBDIRS_AC='windows'
if test "$enabled_doc" = "yes"; then
SUBDIRS_AC='doc'
else
SUBDIRS_AC=''
fi
AC_SUBST(DOC_INST_DIR, $DOC_INST_DIR)
@@ -232,7 +242,7 @@ export confsubst
case $target in
*-*-mingw32* | *-*-cygwin* | *-*-windows*)
WINDOWS_DIRS="windows"
CFLAGS="-mno-cygwin -DWIN32NATIVE"
CFLAGS="${CFLAGS} -mno-cygwin -DWIN32NATIVE"
LDFLAGS="${LDFLAGS} -static"
;;
esac
@@ -244,11 +254,8 @@ if test "$GCC" = yes; then
fi
AC_SUBST(ENABLE_WARNINGS,$ENABLE_WARNINGS)
if test "$enabled_doc" = "yes"; then
AC_CONFIG_FILES([doc/Makefile])
fi
AC_CONFIG_FILES([
doc/Makefile
windows/Makefile
avrdude.spec
Makefile

View File

@@ -18,6 +18,7 @@
*/
#include "avrdude.h"
#if defined(WIN32NATIVE)

View File

@@ -20,14 +20,19 @@
#if defined(WIN32NATIVE)
#ifndef __confwin_h__
#define __confwin_h__
#ifndef confwin_h
#define confwin_h
#ifdef __cplusplus
extern "C" {
#endif
void win_sys_config_set(char sys_config[PATH_MAX]);
void win_usr_config_set(char usr_config[PATH_MAX]);
#ifdef __cplusplus
}
#endif
#endif
#endif

View File

@@ -5,7 +5,7 @@
#include "crc16.h"
/* CRC16 Definitions */
const unsigned short crc_table[256] = {
static const unsigned short crc_table[256] = {
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,

View File

@@ -1,5 +1,10 @@
#ifndef CRC16_H
#define CRC16_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* Derived from CRC algorithm for JTAG ICE mkII, published in Atmel
* Appnote AVR067. Converted from C++ to C.
@@ -22,4 +27,8 @@ extern int crcverify(const unsigned char* message,
extern void crcappend(unsigned char* message,
unsigned long length);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -30,7 +30,7 @@ For avrdude version @value{VERSION}, @value{UPDATED}.
Copyright @copyright{} 2003, 2005 Brian Dean
Copyright @copyright{} 2006 J@"org Wunsch
Copyright @copyright{} 2006 - 2009 J@"org Wunsch
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -67,7 +67,7 @@ Use @uref{http://savannah.nongnu.org/bugs/?group=avrdude} to report bugs.
Copyright @copyright{} 2003,2005 Brian S. Dean
Copyright @copyright{} 2006 J@"org Wunsch
Copyright @copyright{} 2006 - 2008 J@"org Wunsch
@sp 2
Permission is granted to make and distribute verbatim copies of
@@ -113,6 +113,7 @@ Copyright @copyright{} 2006 J@"org Wunsch
* Command Line Options::
* Terminal Mode Operation::
* Configuration File::
* Programmer Specific Information::
* Platform Dependent Information::
* Troubleshooting::
@end menu
@@ -143,6 +144,7 @@ programming fuse/lock bits, etc.
AVRDUDE supports the following basic programmer types: Atmel's STK500,
Atmel's AVRISP and AVRISP mkII devices,
Atmel's STK600,
Atmel's JTAG ICE (both mkI and mkII, the latter also in ISP mode), appnote
avr910, appnote avr109 (including the AVR Butterfly),
serial bit-bang adapters,
@@ -164,7 +166,10 @@ emulated on top of USB is likely to not work at all, or to work
abysmally slow.
The STK500, JTAG ICE, avr910, and avr109/butterfly use the serial port to communicate with the PC.
The STK500, JTAG ICE, and avr910 contain on-board logic to control the programming of the target
The STK600, JTAG ICE mkII, AVRISP mkII, USBasp, and USBtinyISP
programmers communicate through the USB, using @code{libusb} as a
platform abstraction layer.
The STK500, STK600, JTAG ICE, and avr910 contain on-board logic to control the programming of the target
device.
The avr109 bootloader implements a protocol similar to avr910, but is
actually implemented in the boot area of the target's flash ROM, as
@@ -185,8 +190,10 @@ by AVRDUDE.
For the JTAG ICE mkII, JTAG, debugWire and ISP mode are supported.
See below for the limitations of debugWire.
The Arduino (which is very similar to the STK500 1.x) is supported via
its own programmer type specification ``arduino''.
The AVR Dragon is supported in all modes (ISP, JTAG, HVSP, PP, debugWire).
(High-voltage programming is not yet supported.)
When used in JTAG and debugWire mode, the AVR Dragon behaves similar to a
JTAG ICE mkII, so all device-specific comments for that device
will apply as well.
@@ -197,10 +204,10 @@ In particular, the Dragon starts out with a rather fast ISP clock
frequency, so the @code{-B @var{bitclock}}
option might be required to achieve a stable ISP communication.
The USBasp ISP adapter is also supported, provided AVRDUDE
The USBasp ISP and USBtinyISP adapters are also supported, provided AVRDUDE
has been compiled with libusb support.
It features a simple firwmare-only USB implementation, running on
an ATmega8 (or ATmega88).
They both feature simple firwmare-only USB implementations, running on
an ATmega8 (or ATmega88), or ATtiny2313, respectively.
@menu
@@ -244,13 +251,14 @@ Roth.
@menu
* Option Descriptions::
* Programmers accepting extended parameters::
* Example Command Line Invocations::
@end menu
@c
@c Node
@c
@node Option Descriptions, Example Command Line Invocations, Command Line Options, Command Line Options
@node Option Descriptions, Programmers accepting extended parameters, Command Line Options, Command Line Options
@section Option Descriptions
@noindent
@@ -292,6 +300,8 @@ Currently, the following MCU types are understood:
@item @code{m128} @tab ATmega128
@item @code{m1280} @tab ATmega1280
@item @code{m1281} @tab ATmega1281
@item @code{m1284p} @tab ATmega1284P
@item @code{m128rfa1} @tab ATmega128RFA1
@item @code{m16} @tab ATmega16
@item @code{m161} @tab ATmega161
@item @code{m162} @tab ATmega162
@@ -322,6 +332,8 @@ Currently, the following MCU types are understood:
@item @code{t26} @tab ATtiny26
@item @code{t45} @tab ATtiny45
@item @code{t85} @tab ATtiny85
@item @code{x128a1} @tab ATxmega128A1
@item @code{x128a1d} @tab ATxmega128A1revD
@end multitable
(*) The AT90S2323 and ATtiny22 use the same algorithm.
@@ -363,6 +375,11 @@ ABCmini Board, aka Dick Smith HOTCHIP
@item @code{alf} @tab
Nightshade ALF-PgmAVR,@*
@url{http://nightshade.homeip.net/}
@item @code{arduino}
Arduino board, protocol similar to STK500 1.x
@item @code{atisp} @tab
AT-ISP V1.1 programming cable for AVR-SDK1 from,@*
@url{http://micro-research.co.th/}
@item @code{avr109} @tab
Atmel AppNote AVR109 Boot Loader
@item @code{avr910} @tab
@@ -371,21 +388,30 @@ Atmel Low Cost Serial Programmer
Atmel AppNote AVR911 AVROSP (an alias for avr109)
@item @code{avrisp} @tab
Atmel AVR ISP (an alias for stk500)
@item @code{avrispv2} @tab
Atmel AVR ISP, running a version 2.x firmware (an alias for stk500v2)
@item @code{avrisp2} @tab
Atmel AVR ISP mkII (alias for stk500v2)
@item @code{avrispmkII} @tab
Atmel AVR ISP mkII (alias for stk500v2)
@item @code{avrispmk2} @tab
Atmel AVR ISP mkII (alias for stk500v2)
@item @code{avrispv2} @tab
Atmel AVR ISP, running a version 2.x firmware (an alias for stk500v2)
@item @code{bascom} @tab
Bascom SAMPLE programming cable
@item @code{blaster} @tab
Altera ByteBlaster
@item @code{bsd} @tab
Brian Dean's Programmer,@*
@url{http://www.bsdhome.com/avrdude/}
@item @code{butterfly} @tab
Atmel Butterfly Development Board
@item @code{dt006} @tab
Dontronics DT006
@item @code{c2n232i} @tab
C2N232I, reset=dtr sck=!rts mosi=!txd miso=!cts,@*
@url{http://www.ktverkko.fi/~msmakela/8bit/c2n232/hardware/index.en.html}
@item @code{dapa} @tab
Direct AVR Parallel Access cable
@item @code{dasa} @tab
serial port banging, reset=rts sck=dtr mosi=txd miso=cts
@item @code{dasa3} @tab
serial port banging, reset=!dtr sck=rts mosi=txd miso=cts
@item @code{dragon_dw} @tab
AVR Dragon in debugWire mode
@item @code{dragon_hvsp} @tab
@@ -396,26 +422,36 @@ AVR Dragon in ISP mode
AVR Dragon in JTAG mode
@item @code{dragon_pp} @tab
AVR Dragon in (high-voltage) parallel programming mode
@item @code{frank-stk200} @tab
Frank's STK200 clone, @url{http://electropol.free.fr/spip/spip.php?article15}
@item @code{jtagmkI} @tab
Atmel JTAG ICE mkI, running at 115200 Bd
@item @code{dt006} @tab
Dontronics DT006
@item @code{ere-isp-avr} @tab
ERE ISP-AVR,@*
@url{http://www.ere.co.th/download/sch050713.pdf}
@item @code{frank-stk200}@tab
Frank's STK200 clone,@*
@url{http://electropol.free.fr/spip/spip.php?article15}
@item @code{futurlec} @tab
Futurlec.com programming cable
@item @code{jtag1} @tab
@emph{Same as before.}
Atmel JTAG ICE mkI, running at 115200 Bd
@item @code{jtag1slow} @tab
Atmel JTAG ICE mkI, running at 19200 Bd
@item @code{jtagmkII} @tab
Atmel JTAG ICE mkII (default speed 19200 Bd)
@item @code{jtag2slow} @tab
@emph{Same as before.}
Atmel JTAG ICE mkII (default speed 19200 Bd)
@item @code{jtag2} @tab
Atmel JTAG ICE mkII, running at 115200 Bd
@item @code{jtag2fast} @tab
Atmel JTAG ICE mkII, running at 115200 Bd
@item @code{jtag2} @tab
@emph{Same as before.}
@item @code{jtag2isp} @tab
Atmel JTAG ICE mkII in ISP mode.
@item @code{jtag2dw} @tab
Atmel JTAG ICE mkII in debugWire mode.
@item @code{jtagmkI} @tab
Atmel JTAG ICE mkI, running at 115200 Bd
@item @code{jtagmkII} @tab
Atmel JTAG ICE mkII (default speed 19200 Bd)
@item @code{mib510} @tab
Crossbow MIB510 programming board
@item @code{pavr} @tab
Jason Kyle's pAVR Serial Programmer
@item @code{picoweb} @tab
@@ -423,20 +459,39 @@ Picoweb Programming Cable,@*
@url{http://www.picoweb.net/}
@item @code{pony-stk200} @tab
Pony Prog STK200
@item @code{ponyser} @tab
design ponyprog serial, reset=!txd sck=rts mosi=dtr miso=cts
@item @code{siprog} @tab
Lancos SI-Prog,@*
@url{http://www.lancos.com/siprogsch.html}
@item @code{sp12} @tab
Steve Bolt's Programmer
@item @code{stk200} @tab
STK200
@item @code{stk500} @tab
Atmel STK500, probing for either version 1.x or 2.x firmware
@item @code{stk500v1} @tab
Atmel STK500, running a version 1.x firmware
@item @code{stk500hvsp} @tab
Atmel STK500 in high-voltage serial programming mode(version 2.x firmware only)
@item @code{stk500pp} @tab
Atmel STK500 in parallel programming mode (version 2.xfirmware only)
@item @code{stk500v1} @tab
Atmel STK500, running a version 1.x firmware
@item @code{stk500v2} @tab
Atmel STK500, running a version 2.x firmware
@item @code{stk600} @tab
Atmel STK600 in ISP mode, or in PDI mode for ATxmega devices
@item @code{stk600hvsp} @tab
Atmel STK600 in high-voltage serial programming mode
@item @code{stk600pp} @tab
Atmel STK600 in parallel programming mode
@item @code{usbasp} @tab
USBasp,@*
@url{http://www.fischl.de/usbasp/}
@item @code{usbtiny} @tab
USBtiny simple USB programmer,@*
@url{http://www.ladyada.net/make/usbtinyisp/}
@item @code{xil} @tab
Xilinx JTAG cable
@end multitable
@@ -455,13 +510,18 @@ the method of searching for the configuration file for Windows.
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.
without performing an erase first. This option disables that.
Auto erase is not used for ATxmega devices as these devices can
use page erase before writing each page so no explicit chip erase
is required.
Note however that any page not affected by the current operation
will retain its previous contents.
@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
flash ROM and EEPROM to the value `0xff', and clear all lock bits.
Except for ATxmega devices which can use page erase,
it is basically a
prerequisite command before the flash ROM can be reprogrammed again.
The only exception would be if the new contents would exclusively cause
bits to be programmed from the value `1' to `0'. Note that in order
@@ -510,6 +570,10 @@ the part is reasonable before continuing. Since it can happen from time
to time that a device has a broken (erased or overwritten) device
signature but is otherwise operating normally, this options is provided
to override the check.
Also, for programmers like the Atmel STK500 and STK600 which can
adjust parameters local to the programming tool (independent of an
actual connection to a target controller), this option can be used
together with @option{-t} to continue in terminal mode.
@item -i @var{delay}
For bitbang-type programmers, delay for approximately
@@ -714,6 +778,12 @@ Enable verbose output.
@item -V
Disable automatic verify check when uploading data.
@item -x @var{extended_param}
Pass @var{extended_param} to the chosen programmer implementation as
an extended parameter. The interpretation of the extended parameter
depends on the programmer itself. See below for a list of programmers
accepting extended parameters.
@item -y
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
@@ -741,7 +811,52 @@ should not be used.
@c
@c Node
@c
@node Example Command Line Invocations, , Option Descriptions, Command Line Options
@node Programmers accepting extended parameters, Example Command Line Invocations, Option Descriptions, Command Line Options
@section Programmers accepting extended parameters
@table @code
@item JTAG ICE mkII
@itemx AVR Dragon
When using the JTAG ICE mkII or AVR Dragon in JTAG mode, the
following extended parameter is accepted:
@table @code
@item @samp{jtagchain=UB,UA,BB,BA}
Setup the JTAG scan chain for @var{UB} units before, @var{UA} units
after, @var{BB} bits before, and @var{BA} bits after the target AVR,
respectively.
Each AVR unit within the chain shifts by 4 bits.
Other JTAG units might require a different bit shift count.
@end table
@item AVR910
The AVR910 programmer type accepts the following extended parameter:
@table @code
@item @samp{devcode=VALUE}
Override the device code selection by using @var{VALUE}
as the device code.
The programmer is not queried for the list of supported
device codes, and the specified @var{VALUE}
is not verified but used directly within the
@code{T} command sent to the programmer.
@var{VALUE} can be specified using the conventional number notation of the
C programming language.
@item @samp{no_blockmode}
Disables the default checking for block transfer capability.
Use
@samp{no_blockmode} only if your @samp{AVR910}
programmer creates errors during initial sequence.
@end table
@end table
@page
@c
@c Node
@c
@node Example Command Line Invocations, , Programmers accepting extended parameters, Command Line Options
@section Example Command Line Invocations
@noindent
@@ -957,16 +1072,24 @@ Perform a chip erase.
Send raw instruction codes to the AVR device. If you need access to a
feature of an AVR part that is not directly supported by AVRDUDE, this
command allows you to use it, even though AVRDUDE does not implement the
command.
command. When using direct SPI mode, up to 3 bytes
can be omitted.
@item sig
Display the device signature bytes.
@item spi
Enter direct SPI mode. The @emph{pgmled} pin acts as slave select.
@emph{Only supported on parallel bitbang programmers.}
@item part
Display the current part settings and parameters. Includes chip
specific information including all memory types supported by the
device, read/write timing, etc.
@item pgm
Return to programming mode (from direct SPI mode).
@item ?
@itemx help
Give a short on-line summary of the available commands.
@@ -978,28 +1101,31 @@ Leave terminal mode and thus AVRDUDE.
@noindent
In addition, the following commands are supported on the STK500
programmer:
and STK600 programmer:
@table @code
@item vtarg @var{voltage}
Set the target's supply voltage to @var{voltage} Volts.
@item varef @var{voltage}
@item varef [@var{channel}] @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.
@emph{Aref} input on the STK500 and STK600.
The STK600 offers two reference voltages, which can be
selected by the optional parameter @var{channel} (either
0 or 1).
@item fosc @var{freq}[@var{M}|@var{k}]
@item fosc @var{freq}[@code{M}|@code{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.
An optional trailing letter @code{M}
multiplies by 1E6, a trailing letter @code{k} by 1E3.
@item fosc off
Turn the master oscillator off.
@item sck @var{period}
@emph{STK500 only:}
@emph{STK500 and STK600 only:}
Set the SCK clock period to @var{period} microseconds.
@emph{JTAG ICE only:}
@@ -1011,7 +1137,7 @@ This parameter can also be used on the JTAG ICE mkII to specify the
ISP clock period when operating the ICE in ISP mode.
@item parms
@emph{STK500 only:}
@emph{STK500 and STK600 only:}
Display the current voltage and master oscillator parameters.
@emph{JTAG ICE only:}
@@ -1126,7 +1252,7 @@ avrdude>
@c
@c Node
@c
@node Configuration File, Platform Dependent Information, Terminal Mode Operation, Top
@node Configuration File, Programmer Specific Information, Terminal Mode Operation, Top
@chapter Configuration File
@noindent
@@ -1367,11 +1493,87 @@ functionality does not make sense for these boot loaders.
@end itemize
@c
@c Node
@c
@node Programmer Specific Information, Platform Dependent Information, Configuration File, Top
@chapter Programmer Specific Information
@menu
* Atmel STK600::
@end menu
@c
@c Node
@c
@node Platform Dependent Information, Troubleshooting, Configuration File, Top
@node Atmel STK600, , Programmer Specific Information, Programmer Specific Information
@section Atmel STK600
@c
@c Update the table below by running the tools/get-stk600-devices.xsl
@c XSLT transformation on targetboard.xml as shipped by the latest
@c release of AVR Studio.
@c
The following devices are supported by the respective STK600 routing
and socket card:
@multitable @columnfractions .25 .25 .5
@headitem Routing card @tab Socket card @tab Devices
@item @code{STK600-RC008T-2} @tab @code{STK600-DIP} @tab ATtiny11 ATtiny12 ATtiny13 ATtiny25 ATtiny45 ATtiny85
@item @code{STK600-RC008T-7} @tab @code{STK600-DIP} @tab ATtiny15
@item @code{STK600-RC020T-1} @tab @code{STK600-DIP} @tab ATtiny2313
@item @code{} @tab @code{STK600-TinyX3U} @tab ATtiny43U
@item @code{STK600-RC014T-12} @tab @code{STK600-DIP} @tab ATtiny24 ATtiny44 ATtiny84
@item @code{STK600-RC020T-8} @tab @code{STK600-DIP} @tab ATtiny26 ATtiny261 ATtiny461 ATtiny861
@item @code{STK600-RC020T-23} @tab @code{STK600-SOIC} @tab ATtiny167
@item @code{STK600-RC028T-3} @tab @code{STK600-DIP} @tab ATtiny28
@item @code{STK600-RC028M-6} @tab @code{STK600-DIP} @tab ATtiny48 ATtiny88 ATmega8 ATmega48 ATmega88 ATmega168 ATmega48P ATmega88P ATmega168P ATmega328P
@item @code{STK600-RC040M-4} @tab @code{STK600-DIP} @tab ATmega8515 ATmega162
@item @code{STK600-RC040M-5} @tab @code{STK600-DIP} @tab ATmega8535 ATmega16 ATmega32 ATmega164P ATmega324P ATmega644 ATmega644P ATmega1284P
@item @code{STK600-RC064M-9} @tab @code{STK600-TQFP64} @tab ATmega64 ATmega128 ATmega1281 ATmega2561 AT90CAN32 AT90CAN64 AT90CAN128
@item @code{STK600-RC064M-10} @tab @code{STK600-TQFP64} @tab ATmega165 ATmega165P ATmega169 ATmega169P ATmega325 ATmega325P ATmega329 ATmega329P ATmega645 ATmega649
@item @code{STK600-RC100M-11} @tab @code{STK600-TQFP100} @tab ATmega640 ATmega1280 ATmega2560
@item @code{} @tab @code{STK600-ATMEGA2560} @tab ATmega2560
@item @code{STK600-RC100M-18} @tab @code{STK600-TQFP100} @tab ATmega3250 ATmega3250P ATmega3290 ATmega3290P ATmega6450 ATmega6490
@item @code{STK600-RC32U-20} @tab @code{STK600-TQFP32} @tab AT90USB82 AT90USB162
@item @code{STK600-RC044U-25} @tab @code{STK600-TQFP44} @tab ATmega32U4
@item @code{STK600-RC064U-17} @tab @code{STK600-TQFP64} @tab AT90USB646 AT90USB1286 AT90USB647 AT90USB1287
@item @code{STK600-RCPWM-22} @tab @code{STK600-TQFP32} @tab ATmega32C1 ATmega32M1
@item @code{STK600-RCPWM-19} @tab @code{STK600-SOIC} @tab AT90PWM2 AT90PWM3 AT90PWM2B AT90PWM3B AT90PWM216 AT90PWM316
@item @code{STK600-RC044M-24} @tab @code{STK600-TSSOP44} @tab ATmega32HVB
@item @code{STK600-RC100X-13} @tab @code{STK600-TQFP100} @tab ATxmega128A1 ATxmega128A1_revD ATxmega64A1
@item @code{} @tab @code{STK600-uC3-144} @tab AT32UC3A0512 AT32UC3A0256 AT32UC3A0128
@item @code{STK600-RCuC3B0-21} @tab @code{STK600-TQFP64-2} @tab AT32UC3B0256 AT32UC3B0128 AT32UC3B064
@end multitable
Ensure the correct socket and routing card are mounted @emph{before}
powering on the STK600. While the STK600 firmware ensures the socket
and routing card mounted match each other (using a table stored
internally in nonvolatile memory), it cannot handle the case where a
wrong routing card is used, e. g. the routing card
@code{STK600-RC040M-5} (which is meant for 40-pin DIP AVRs that have
an ADC, with the power supply pins in the center of the package) was
used but an ATmega8515 inserted (which uses the ``industry standard''
pinout with Vcc and GND at opposite corners).
Note that for devices that use the routing card @code{STK600-RC008T-2},
in order to use ISP mode, the jumper for @code{AREF0} must be removed
as it would otherwise block one of the ISP signals. High-voltage
serial programming can be used even with that jumper installed.
The ISP system of the STK600 contains a detection against shortcuts
and other wiring errors. AVRDUDE initiates a connection check before
trying to enter ISP programming mode, and display the result if the
target is not found ready to be ISP programmed.
High-voltage programming requires the target voltage to be set to at
least 4.5 V in order to work. This can be done using
@emph{Terminal Mode}, see @ref{Terminal Mode Operation}.
@c
@c Node
@c
@node Platform Dependent Information, Troubleshooting, Programmer Specific Information, Top
@appendix Platform Dependent Information
@menu
@@ -1695,7 +1897,7 @@ Windows serial port device names such as: com1, com2, etc.
@subsubsection Parallel Ports
@noindent
AVRDUDE will only accept 3 Windows parallel port names: lpt1, lpt2, or
AVRDUDE will accept 3 Windows parallel port names: lpt1, lpt2, or
lpt3. Each of these names corresponds to a fixed parallel port base
address:
@@ -1716,6 +1918,9 @@ using a laptop, you might have to use lpt3 instead of lpt1. Select the
name of the port the corresponds to the base address of the parallel
port that you want.
If the parallel port can be accessed through a different
address, this address can be specified directly, using the common C
language notation (i. e., hexadecimal values are prefixed by @code{0x}).
@c
@c Node
@@ -1886,7 +2091,7 @@ programming works, and is documented that way in the Atmel AVR
datasheets.
In order to successfully program the EEPROM that way, a prior chip
erase (with the EESAVE fuse unprogrammed) is required.
This also applies to the STK500 in high-voltage programming mode.
This also applies to the STK500 and STK600 in high-voltage programming mode.
@item
Problem: How do I turn off the @var{DWEN} fuse?
@@ -1932,12 +2137,12 @@ The pin mapping for the JTAG-to-ISP adapter is:
@end multitable
@item
Problem: Multiple USBasp programmers connected simultaneously are not
Problem: Multiple USBasp or USBtinyISP programmers connected simultaneously are not
found.
Solution: none at this time. The simplicity of the USBasp programmer
Solution: none at this time. The simplicity of these programmers
doesn't offer a method to distinguish multiple programmers that are
connected simultaneously, so effectively only one USBasp is supported.
connected simultaneously, so effectively only one of them is supported.
@item
Problem: I cannot do @dots{} when the target is in debugWire mode.

View File

@@ -28,6 +28,7 @@
#include <errno.h>
#include <ctype.h>
#include "avrdude.h"
#include "avr.h"
#include "fileio.h"
@@ -46,42 +47,38 @@ struct ihexrec {
};
extern char * progname;
extern char progbuf[];
extern int quell_progress;
int b2ihex(unsigned char * inbuf, int bufsize,
static int b2ihex(unsigned char * inbuf, int bufsize,
int recsize, int startaddr,
char * outfile, FILE * outf);
int ihex2b(char * infile, FILE * inf,
static int ihex2b(char * infile, FILE * inf,
unsigned char * outbuf, int bufsize);
int b2srec(unsigned char * inbuf, int bufsize,
static int b2srec(unsigned char * inbuf, int bufsize,
int recsize, int startaddr,
char * outfile, FILE * outf);
int srec2b(char * infile, FILE * inf,
static int srec2b(char * infile, FILE * inf,
unsigned char * outbuf, int bufsize);
int ihex_readrec(struct ihexrec * ihex, char * rec);
static int ihex_readrec(struct ihexrec * ihex, char * rec);
int srec_readrec(struct ihexrec * srec, char * rec);
static int srec_readrec(struct ihexrec * srec, char * rec);
int fileio_rbin(struct fioparms * fio,
static int fileio_rbin(struct fioparms * fio,
char * filename, FILE * f, unsigned char * buf, int size);
int fileio_ihex(struct fioparms * fio,
static int fileio_ihex(struct fioparms * fio,
char * filename, FILE * f, unsigned char * buf, int size);
int fileio_srec(struct fioparms * fio,
static int fileio_srec(struct fioparms * fio,
char * filename, FILE * f, unsigned char * buf, int size);
int fileio_num(struct fioparms * fio,
static int fileio_num(struct fioparms * fio,
char * filename, FILE * f, unsigned char * buf, int size,
FILEFMT fmt);
int fmt_autodetect(char * fname);
static int fmt_autodetect(char * fname);
@@ -98,7 +95,7 @@ char * fmtstr(FILEFMT format)
int b2ihex(unsigned char * inbuf, int bufsize,
static int b2ihex(unsigned char * inbuf, int bufsize,
int recsize, int startaddr,
char * outfile, FILE * outf)
{
@@ -176,7 +173,7 @@ int b2ihex(unsigned char * inbuf, int bufsize,
}
int ihex_readrec(struct ihexrec * ihex, char * rec)
static int ihex_readrec(struct ihexrec * ihex, char * rec)
{
int i, j;
char buf[8];
@@ -265,7 +262,7 @@ int ihex_readrec(struct ihexrec * ihex, char * rec)
*
* */
int ihex2b(char * infile, FILE * inf,
static int ihex2b(char * infile, FILE * inf,
unsigned char * outbuf, int bufsize)
{
char buffer [ MAX_LINE_LEN ];
@@ -360,7 +357,7 @@ int ihex2b(char * infile, FILE * inf,
}
int b2srec(unsigned char * inbuf, int bufsize,
static int b2srec(unsigned char * inbuf, int bufsize,
int recsize, int startaddr,
char * outfile, FILE * outf)
{
@@ -466,7 +463,7 @@ int b2srec(unsigned char * inbuf, int bufsize,
}
int srec_readrec(struct ihexrec * srec, char * rec)
static int srec_readrec(struct ihexrec * srec, char * rec)
{
int i, j;
char buf[8];
@@ -542,7 +539,7 @@ int srec_readrec(struct ihexrec * srec, char * rec)
}
int srec2b(char * infile, FILE * inf,
static int srec2b(char * infile, FILE * inf,
unsigned char * outbuf, int bufsize)
{
char buffer [ MAX_LINE_LEN ];
@@ -702,7 +699,7 @@ static char *itoa_simple(int n, char *buf, int base)
int fileio_rbin(struct fioparms * fio,
static int fileio_rbin(struct fioparms * fio,
char * filename, FILE * f, unsigned char * buf, int size)
{
int rc;
@@ -732,7 +729,7 @@ int fileio_rbin(struct fioparms * fio,
}
int fileio_imm(struct fioparms * fio,
static int fileio_imm(struct fioparms * fio,
char * filename, FILE * f, unsigned char * buf, int size)
{
int rc = 0;
@@ -746,6 +743,10 @@ int fileio_imm(struct fioparms * fio,
p = strtok(filename, " ,");
while (p != NULL && loc < size) {
b = strtoul(p, &e, 0);
/* check for binary formated (0b10101001) strings */
b = (strncmp (p, "0b", 2))?
strtoul (p, &e, 0):
strtoul (p + 2, &e, 2);
if (*e != 0) {
fprintf(stderr,
"%s: invalid byte value (%s) specified for immediate mode\n",
@@ -775,7 +776,7 @@ int fileio_imm(struct fioparms * fio,
}
int fileio_ihex(struct fioparms * fio,
static int fileio_ihex(struct fioparms * fio,
char * filename, FILE * f, unsigned char * buf, int size)
{
int rc;
@@ -805,7 +806,7 @@ int fileio_ihex(struct fioparms * fio,
}
int fileio_srec(struct fioparms * fio,
static int fileio_srec(struct fioparms * fio,
char * filename, FILE * f, unsigned char * buf, int size)
{
int rc;
@@ -836,7 +837,7 @@ int fileio_srec(struct fioparms * fio,
}
int fileio_num(struct fioparms * fio,
static int fileio_num(struct fioparms * fio,
char * filename, FILE * f, unsigned char * buf, int size,
FILEFMT fmt)
{
@@ -939,7 +940,7 @@ int fileio_setparms(int op, struct fioparms * fp)
int fmt_autodetect(char * fname)
static int fmt_autodetect(char * fname)
{
FILE * f;
unsigned char buf[MAX_LINE_LEN];
@@ -968,8 +969,10 @@ int fmt_autodetect(char * fname)
break;
}
}
if (found)
if (found) {
fclose(f);
return FMT_RBIN;
}
/* check for lines that look like intel hex */
if ((buf[0] == ':') && (len >= 11)) {
@@ -980,8 +983,10 @@ int fmt_autodetect(char * fname)
break;
}
}
if (found)
if (found) {
fclose(f);
return FMT_IHEX;
}
}
/* check for lines that look like motorola s-record */
@@ -993,11 +998,14 @@ int fmt_autodetect(char * fname)
break;
}
}
if (found)
if (found) {
fclose(f);
return FMT_SREC;
}
}
}
fclose(f);
return -1;
}
@@ -1142,7 +1150,9 @@ int fileio(int op, char * filename, FILEFMT format,
rc = avr_mem_hiaddr(mem);
}
}
if (format != FMT_IMM) {
fclose(f);
}
return rc;
}

View File

@@ -19,8 +19,8 @@
/* $Id$ */
#ifndef __fileio_h__
#define __fileio_h__
#ifndef fileio_h
#define fileio_h
typedef enum {
FMT_AUTO,
@@ -47,11 +47,19 @@ enum {
FIO_WRITE
};
#ifdef __cplusplus
extern "C" {
#endif
char * fmtstr(FILEFMT format);
int fileio_setparms(int op, struct fioparms * fp);
int fileio(int op, char * filename, FILEFMT format,
int fileio(int op, char * filename, FILEFMT format,
struct avrpart * p, char * memtype, int size);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2005 Joerg Wunsch <j@uriah.heep.sax.de>
* Copyright (C) 2005, 2007 Joerg Wunsch <j@uriah.heep.sax.de>
*
* 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
@@ -33,34 +33,37 @@
#include <sys/time.h>
#include <time.h>
#include "avrdude.h"
#include "avr.h"
#include "crc16.h"
#include "pgm.h"
#include "jtagmkI_private.h"
#include "serial.h"
extern int verbose;
extern char * progname;
extern int do_cycles;
/*
* XXX There should really be a programmer-specific private data
* pointer in struct PROGRAMMER.
* Private data for this programmer.
*/
static int initial_baudrate;
struct pdata
{
int initial_baudrate;
/*
* See jtagmkI_read_byte() for an explanation of the flash and
* EEPROM page caches.
*/
static unsigned char *flash_pagecache;
static unsigned long flash_pageaddr;
static unsigned int flash_pagesize;
/*
* See jtagmkI_read_byte() for an explanation of the flash and
* EEPROM page caches.
*/
unsigned char *flash_pagecache;
unsigned long flash_pageaddr;
unsigned int flash_pagesize;
static unsigned char *eeprom_pagecache;
static unsigned long eeprom_pageaddr;
static unsigned int eeprom_pagesize;
unsigned char *eeprom_pagecache;
unsigned long eeprom_pageaddr;
unsigned int eeprom_pagesize;
int prog_enabled; /* Cached value of PROGRAMMING status. */
};
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
static int prog_enabled; /* Cached value of PROGRAMMING status. */
/*
* The OCDEN fuse is bit 7 of the high fuse (hfuse). In order to
* perform memory operations on MTYPE_SPM and MTYPE_EEPROM, OCDEN
@@ -102,10 +105,27 @@ static int jtagmkI_getparm(PROGRAMMER * pgm, unsigned char parm,
unsigned char * value);
static int jtagmkI_setparm(PROGRAMMER * pgm, unsigned char parm,
unsigned char value);
static void jtagmkI_print_parms1(PROGRAMMER * pgm, char * p);
static void jtagmkI_print_parms1(PROGRAMMER * pgm, const char * p);
static int jtagmkI_resync(PROGRAMMER *pgm, int maxtries, int signon);
static void jtagmkI_setup(PROGRAMMER * pgm)
{
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
fprintf(stderr,
"%s: jtagmkI_setup(): Out of memory allocating private data\n",
progname);
exit(1);
}
memset(pgm->cookie, 0, sizeof(struct pdata));
}
static void jtagmkI_teardown(PROGRAMMER * pgm)
{
free(pgm->cookie);
}
static void
u32_to_b3(unsigned char *b, unsigned long l)
{
@@ -383,10 +403,10 @@ static void jtagmkI_set_devdescr(PROGRAMMER * pgm, AVRPART * p)
for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
m = ldata(ln);
if (strcmp(m->desc, "flash") == 0) {
flash_pagesize = m->page_size;
u16_to_b2(sendbuf.dd.uiFlashPageSize, flash_pagesize);
PDATA(pgm)->flash_pagesize = m->page_size;
u16_to_b2(sendbuf.dd.uiFlashPageSize, PDATA(pgm)->flash_pagesize);
} else if (strcmp(m->desc, "eeprom") == 0) {
sendbuf.dd.ucEepromPageSize = eeprom_pagesize = m->page_size;
sendbuf.dd.ucEepromPageSize = PDATA(pgm)->eeprom_pagesize = m->page_size;
}
}
@@ -450,7 +470,7 @@ static int jtagmkI_program_enable(PROGRAMMER * pgm)
{
unsigned char buf[1], resp[2];
if (prog_enabled)
if (PDATA(pgm)->prog_enabled)
return 0;
buf[0] = CMD_ENTER_PROGMODE;
@@ -474,7 +494,7 @@ static int jtagmkI_program_enable(PROGRAMMER * pgm)
fprintf(stderr, "OK\n");
}
prog_enabled = 1;
PDATA(pgm)->prog_enabled = 1;
return 0;
}
@@ -483,7 +503,7 @@ static int jtagmkI_program_disable(PROGRAMMER * pgm)
{
unsigned char buf[1], resp[2];
if (!prog_enabled)
if (!PDATA(pgm)->prog_enabled)
return 0;
if (pgm->fd.ifd != -1) {
@@ -508,7 +528,7 @@ static int jtagmkI_program_disable(PROGRAMMER * pgm)
fprintf(stderr, "OK\n");
}
}
prog_enabled = 0;
PDATA(pgm)->prog_enabled = 0;
return 0;
}
@@ -530,7 +550,7 @@ static unsigned char jtagmkI_get_baud(long baud)
static int jtagmkI_initialize(PROGRAMMER * pgm, AVRPART * p)
{
AVRMEM hfuse;
char cmd[1], resp[5];
unsigned char cmd[1], resp[5];
unsigned char b;
if (!(p->flags & AVRPART_HAS_JTAG)) {
@@ -541,7 +561,7 @@ static int jtagmkI_initialize(PROGRAMMER * pgm, AVRPART * p)
jtagmkI_drain(pgm, 0);
if ((serdev->flags & SERDEV_FL_CANSETSPEED) && initial_baudrate != pgm->baudrate) {
if ((serdev->flags & SERDEV_FL_CANSETSPEED) && PDATA(pgm)->initial_baudrate != pgm->baudrate) {
if ((b = jtagmkI_get_baud(pgm->baudrate)) == 0) {
fprintf(stderr, "%s: jtagmkI_initialize(): unsupported baudrate %d\n",
progname, pgm->baudrate);
@@ -551,7 +571,7 @@ static int jtagmkI_initialize(PROGRAMMER * pgm, AVRPART * p)
"trying to set baudrate to %d\n",
progname, pgm->baudrate);
if (jtagmkI_setparm(pgm, PARM_BITRATE, b) == 0) {
initial_baudrate = pgm->baudrate; /* don't adjust again later */
PDATA(pgm)->initial_baudrate = pgm->baudrate; /* don't adjust again later */
serial_setspeed(&pgm->fd, pgm->baudrate);
}
}
@@ -586,24 +606,24 @@ static int jtagmkI_initialize(PROGRAMMER * pgm, AVRPART * p)
*/
jtagmkI_set_devdescr(pgm, p);
jtagmkI_setparm(pgm, PARM_FLASH_PAGESIZE_LOW, flash_pagesize & 0xff);
jtagmkI_setparm(pgm, PARM_FLASH_PAGESIZE_HIGH, flash_pagesize >> 8);
jtagmkI_setparm(pgm, PARM_EEPROM_PAGESIZE, eeprom_pagesize & 0xff);
jtagmkI_setparm(pgm, PARM_FLASH_PAGESIZE_LOW, PDATA(pgm)->flash_pagesize & 0xff);
jtagmkI_setparm(pgm, PARM_FLASH_PAGESIZE_HIGH, PDATA(pgm)->flash_pagesize >> 8);
jtagmkI_setparm(pgm, PARM_EEPROM_PAGESIZE, PDATA(pgm)->eeprom_pagesize & 0xff);
free(flash_pagecache);
free(eeprom_pagecache);
if ((flash_pagecache = malloc(flash_pagesize)) == NULL) {
free(PDATA(pgm)->flash_pagecache);
free(PDATA(pgm)->eeprom_pagecache);
if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) {
fprintf(stderr, "%s: jtagmkI_initialize(): Out of memory\n",
progname);
return -1;
}
if ((eeprom_pagecache = malloc(eeprom_pagesize)) == NULL) {
if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
fprintf(stderr, "%s: jtagmkI_initialize(): Out of memory\n",
progname);
free(flash_pagecache);
free(PDATA(pgm)->flash_pagecache);
return -1;
}
flash_pageaddr = eeprom_pageaddr = (unsigned long)-1L;
PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
if (jtagmkI_reset(pgm) < 0)
return -1;
@@ -624,10 +644,10 @@ static int jtagmkI_initialize(PROGRAMMER * pgm, AVRPART * p)
static void jtagmkI_disable(PROGRAMMER * pgm)
{
free(flash_pagecache);
flash_pagecache = NULL;
free(eeprom_pagecache);
eeprom_pagecache = NULL;
free(PDATA(pgm)->flash_pagecache);
PDATA(pgm)->flash_pagecache = NULL;
free(PDATA(pgm)->eeprom_pagecache);
PDATA(pgm)->eeprom_pagecache = NULL;
(void)jtagmkI_program_disable(pgm);
}
@@ -646,7 +666,7 @@ static int jtagmkI_open(PROGRAMMER * pgm, char * port)
fprintf(stderr, "%s: jtagmkI_open()\n", progname);
strcpy(pgm->port, port);
initial_baudrate = -1L;
PDATA(pgm)->initial_baudrate = -1L;
for (i = 0; i < sizeof(baudtab) / sizeof(baudtab[0]); i++) {
if (verbose >= 2)
@@ -661,7 +681,7 @@ static int jtagmkI_open(PROGRAMMER * pgm, char * port)
jtagmkI_drain(pgm, 0);
if (jtagmkI_getsync(pgm) == 0) {
initial_baudrate = baudtab[i].baud;
PDATA(pgm)->initial_baudrate = baudtab[i].baud;
if (verbose >= 2)
fprintf(stderr, "%s: jtagmkI_open(): succeeded\n", progname);
return 0;
@@ -691,15 +711,15 @@ static void jtagmkI_close(PROGRAMMER * pgm)
* appears to make AVR Studio happier when it is about to access the
* ICE later on.
*/
if ((serdev->flags & SERDEV_FL_CANSETSPEED) && initial_baudrate != pgm->baudrate) {
if ((b = jtagmkI_get_baud(initial_baudrate)) == 0) {
if ((serdev->flags & SERDEV_FL_CANSETSPEED) && PDATA(pgm)->initial_baudrate != pgm->baudrate) {
if ((b = jtagmkI_get_baud(PDATA(pgm)->initial_baudrate)) == 0) {
fprintf(stderr, "%s: jtagmkI_close(): unsupported baudrate %d\n",
progname, initial_baudrate);
progname, PDATA(pgm)->initial_baudrate);
} else {
if (verbose >= 2)
fprintf(stderr, "%s: jtagmkI_close(): "
"trying to set baudrate to %d\n",
progname, initial_baudrate);
progname, PDATA(pgm)->initial_baudrate);
if (jtagmkI_setparm(pgm, PARM_BITRATE, b) == 0) {
serial_setspeed(&pgm->fd, pgm->baudrate);
}
@@ -748,13 +768,13 @@ static int jtagmkI_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
cmd[0] = CMD_WRITE_MEM;
if (strcmp(m->desc, "flash") == 0) {
cmd[1] = MTYPE_FLASH_PAGE;
flash_pageaddr = (unsigned long)-1L;
page_size = flash_pagesize;
PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
page_size = PDATA(pgm)->flash_pagesize;
is_flash = 1;
} else if (strcmp(m->desc, "eeprom") == 0) {
cmd[1] = MTYPE_EEPROM_PAGE;
eeprom_pageaddr = (unsigned long)-1L;
page_size = eeprom_pagesize;
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
page_size = PDATA(pgm)->eeprom_pagesize;
}
datacmd[0] = CMD_DATA;
@@ -970,15 +990,15 @@ static int jtagmkI_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
cmd[1] = MTYPE_FLASH_PAGE;
pagesize = mem->page_size;
paddr = addr & ~(pagesize - 1);
paddr_ptr = &flash_pageaddr;
cache_ptr = flash_pagecache;
paddr_ptr = &PDATA(pgm)->flash_pageaddr;
cache_ptr = PDATA(pgm)->flash_pagecache;
is_flash = 1;
} else if (strcmp(mem->desc, "eeprom") == 0) {
cmd[1] = MTYPE_EEPROM_PAGE;
pagesize = mem->page_size;
paddr = addr & ~(pagesize - 1);
paddr_ptr = &eeprom_pageaddr;
cache_ptr = eeprom_pagecache;
paddr_ptr = &PDATA(pgm)->eeprom_pageaddr;
cache_ptr = PDATA(pgm)->eeprom_pagecache;
} else if (strcmp(mem->desc, "lfuse") == 0) {
cmd[1] = MTYPE_FUSE_BITS;
addr = 0;
@@ -1080,11 +1100,11 @@ static int jtagmkI_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
if (strcmp(mem->desc, "flash") == 0) {
cmd[1] = MTYPE_SPM;
need_progmode = 0;
flash_pageaddr = (unsigned long)-1L;
PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
} else if (strcmp(mem->desc, "eeprom") == 0) {
cmd[1] = MTYPE_EEPROM;
need_progmode = 0;
eeprom_pageaddr = (unsigned long)-1L;
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
} else if (strcmp(mem->desc, "lfuse") == 0) {
cmd[1] = MTYPE_FUSE_BITS;
addr = 0;
@@ -1282,7 +1302,7 @@ static int jtagmkI_setparm(PROGRAMMER * pgm, unsigned char parm,
}
static void jtagmkI_display(PROGRAMMER * pgm, char * p)
static void jtagmkI_display(PROGRAMMER * pgm, const char * p)
{
unsigned char hw, fw;
@@ -1300,7 +1320,7 @@ static void jtagmkI_display(PROGRAMMER * pgm, char * p)
}
static void jtagmkI_print_parms1(PROGRAMMER * pgm, char * p)
static void jtagmkI_print_parms1(PROGRAMMER * pgm, const char * p)
{
unsigned char vtarget, jtag_clock;
const char *clkstr;
@@ -1376,5 +1396,7 @@ void jtagmkI_initpgm(PROGRAMMER * pgm)
pgm->paged_load = jtagmkI_paged_load;
pgm->print_parms = jtagmkI_print_parms;
pgm->set_sck_period = jtagmkI_set_sck_period;
pgm->setup = jtagmkI_setup;
pgm->teardown = jtagmkI_teardown;
pgm->page_size = 256;
}

View File

@@ -22,7 +22,15 @@
#ifndef jtagmkI_h
#define jtagmkI_h
#ifdef __cplusplus
extern "C" {
#endif
void jtagmkI_initpgm (PROGRAMMER * pgm);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2005,2006 Joerg Wunsch <j@uriah.heep.sax.de>
* Copyright (C) 2005-2007 Joerg Wunsch <j@uriah.heep.sax.de>
*
* Derived from stk500 code which is:
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
@@ -41,6 +41,7 @@
#include <sys/time.h>
#include <time.h>
#include "avrdude.h"
#include "avr.h"
#include "crc16.h"
#include "pgm.h"
@@ -50,30 +51,37 @@
#include "usbdevs.h"
extern int verbose;
extern char * progname;
extern int do_cycles;
/*
* XXX There should really be a programmer-specific private data
* pointer in struct PROGRAMMER.
* Private data for this programmer.
*/
static unsigned short command_sequence; /* Next cmd seqno to issue. */
struct pdata
{
unsigned short command_sequence; /* Next cmd seqno to issue. */
/*
* See jtagmkII_read_byte() for an explanation of the flash and
* EEPROM page caches.
*/
static unsigned char *flash_pagecache;
static unsigned long flash_pageaddr;
static unsigned int flash_pagesize;
/*
* See jtagmkII_read_byte() for an explanation of the flash and
* EEPROM page caches.
*/
unsigned char *flash_pagecache;
unsigned long flash_pageaddr;
unsigned int flash_pagesize;
static unsigned char *eeprom_pagecache;
static unsigned long eeprom_pageaddr;
static unsigned int eeprom_pagesize;
unsigned char *eeprom_pagecache;
unsigned long eeprom_pageaddr;
unsigned int eeprom_pagesize;
int prog_enabled; /* Cached value of PROGRAMMING status. */
unsigned char serno[6]; /* JTAG ICE serial number. */
/* JTAG chain stuff */
unsigned char jtagchain[4];
/* The length of the device descriptor is firmware-dependent. */
size_t device_descriptor_length;
};
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
static int prog_enabled; /* Cached value of PROGRAMMING status. */
static unsigned char serno[6]; /* JTAG ICE serial number. */
/*
* The OCDEN fuse is bit 7 of the high fuse (hfuse). In order to
* perform memory operations on MTYPE_SPM and MTYPE_EEPROM, OCDEN
@@ -112,9 +120,6 @@ static struct {
*/
#define PGM_FL_IS_DW (0x0001)
/* The length of the device descriptor is firmware-dependent. */
static size_t device_descriptor_length;
static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value);
static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
@@ -123,7 +128,24 @@ static int jtagmkII_reset(PROGRAMMER * pgm, unsigned char flags);
static int jtagmkII_set_sck_period(PROGRAMMER * pgm, double v);
static int jtagmkII_setparm(PROGRAMMER * pgm, unsigned char parm,
unsigned char * value);
static void jtagmkII_print_parms1(PROGRAMMER * pgm, char * p);
static void jtagmkII_print_parms1(PROGRAMMER * pgm, const char * p);
void jtagmkII_setup(PROGRAMMER * pgm)
{
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
fprintf(stderr,
"%s: jtagmkII_setup(): Out of memory allocating private data\n",
progname);
exit(1);
}
memset(pgm->cookie, 0, sizeof(struct pdata));
}
void jtagmkII_teardown(PROGRAMMER * pgm)
{
free(pgm->cookie);
}
static unsigned long
b4_to_u32(unsigned char *b)
@@ -239,6 +261,7 @@ static void jtagmkII_prmsg(PROGRAMMER * pgm, unsigned char * data, size_t len)
case EMULATOR_MODE_JTAG: fprintf(stderr, ": JTAG"); break;
case EMULATOR_MODE_HV: fprintf(stderr, ": HVSP/PP"); break;
case EMULATOR_MODE_SPI: fprintf(stderr, ": SPI"); break;
case EMULATOR_MODE_JTAG_XMEGA: fprintf(stderr, ": JTAG/Xmega"); break;
}
putc('\n', stderr);
break;
@@ -352,7 +375,7 @@ int jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
}
buf[0] = MESSAGE_START;
u16_to_b2(buf + 1, command_sequence);
u16_to_b2(buf + 1, PDATA(pgm)->command_sequence);
u32_to_b4(buf + 3, len);
buf[7] = TOKEN;
memcpy(buf + 8, data, len);
@@ -548,10 +571,10 @@ int jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg) {
if (verbose >= 3)
fprintf(stderr, "%s: jtagmkII_recv(): "
"Got message seqno %d (command_sequence == %d)\n",
progname, r_seqno, command_sequence);
if (r_seqno == command_sequence) {
if (++command_sequence == 0xffff)
command_sequence = 0;
progname, r_seqno, PDATA(pgm)->command_sequence);
if (r_seqno == PDATA(pgm)->command_sequence) {
if (++(PDATA(pgm)->command_sequence) == 0xffff)
PDATA(pgm)->command_sequence = 0;
/*
* We move the payload to the beginning of the buffer, to make
* the job easier for the caller. We have to return the
@@ -568,11 +591,10 @@ int jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg) {
if (verbose >= 2)
fprintf(stderr, "%s: jtagmkII_recv(): "
"got wrong sequence number, %u != %u\n",
progname, r_seqno, command_sequence);
progname, r_seqno, PDATA(pgm)->command_sequence);
}
free(*msg);
}
return 0;
}
@@ -610,7 +632,7 @@ int jtagmkII_getsync(PROGRAMMER * pgm, int mode) {
if ((c = resp[0]) == RSP_SIGN_ON) {
fwver = ((unsigned)resp[8] << 8) | (unsigned)resp[7];
hwver = (unsigned)resp[9];
memcpy(serno, resp + 10, 6);
memcpy(PDATA(pgm)->serno, resp + 10, 6);
if (verbose >= 1 && status > 17) {
fprintf(stderr, "JTAG ICE mkII sign-on message:\n");
fprintf(stderr, "Communications protocol version: %u\n",
@@ -631,7 +653,7 @@ int jtagmkII_getsync(PROGRAMMER * pgm, int mode) {
(unsigned)resp[9]);
fprintf(stderr, "Serial number: "
"%02x:%02x:%02x:%02x:%02x:%02x\n",
serno[0], serno[1], serno[2], serno[3], serno[4], serno[5]);
PDATA(pgm)->serno[0], PDATA(pgm)->serno[1], PDATA(pgm)->serno[2], PDATA(pgm)->serno[3], PDATA(pgm)->serno[4], PDATA(pgm)->serno[5]);
resp[status - 1] = '\0';
fprintf(stderr, "Device ID: %s\n",
resp + 16);
@@ -655,7 +677,7 @@ int jtagmkII_getsync(PROGRAMMER * pgm, int mode) {
return -1;
}
device_descriptor_length = sizeof(struct device_descriptor);
PDATA(pgm)->device_descriptor_length = sizeof(struct device_descriptor);
/*
* There's no official documentation from Atmel about what firmware
* revision matches what device descriptor length. The algorithm
@@ -667,20 +689,20 @@ int jtagmkII_getsync(PROGRAMMER * pgm, int mode) {
*/
#define FWVER(maj, min) ((maj << 8) | (min))
if (hwver == 0 && fwver < FWVER(3, 16)) {
device_descriptor_length -= 2;
PDATA(pgm)->device_descriptor_length -= 2;
fprintf(stderr,
"%s: jtagmkII_getsync(): "
"S_MCU firmware version might be too old to work correctly\n",
progname);
} else if (hwver == 0 && fwver < FWVER(4, 0)) {
device_descriptor_length -= 2;
PDATA(pgm)->device_descriptor_length -= 2;
}
if (verbose >= 2 && mode != EMULATOR_MODE_SPI)
fprintf(stderr,
"%s: jtagmkII_getsync(): Using a %zu-byte device descriptor\n",
progname, device_descriptor_length);
progname, PDATA(pgm)->device_descriptor_length);
if (mode == EMULATOR_MODE_SPI || mode == EMULATOR_MODE_HV) {
device_descriptor_length = 0;
PDATA(pgm)->device_descriptor_length = 0;
if (hwver == 0 && fwver < FWVER(4, 14)) {
fprintf(stderr,
"%s: jtagmkII_getsync(): ISP functionality requires firmware "
@@ -842,25 +864,27 @@ static void jtagmkII_set_devdescr(PROGRAMMER * pgm, AVRPART * p)
for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
m = ldata(ln);
if (strcmp(m->desc, "flash") == 0) {
flash_pagesize = m->page_size;
PDATA(pgm)->flash_pagesize = m->page_size;
u32_to_b4(sendbuf.dd.ulFlashSize, m->size);
u16_to_b2(sendbuf.dd.uiFlashPageSize, flash_pagesize);
u16_to_b2(sendbuf.dd.uiFlashpages, m->size / flash_pagesize);
u16_to_b2(sendbuf.dd.uiFlashPageSize, PDATA(pgm)->flash_pagesize);
u16_to_b2(sendbuf.dd.uiFlashpages, m->size / PDATA(pgm)->flash_pagesize);
if (p->flags & AVRPART_HAS_DW) {
memcpy(sendbuf.dd.ucFlashInst, p->flash_instr, FLASH_INSTR_SIZE);
memcpy(sendbuf.dd.ucEepromInst, p->eeprom_instr, EEPROM_INSTR_SIZE);
}
} else if (strcmp(m->desc, "eeprom") == 0) {
sendbuf.dd.ucEepromPageSize = eeprom_pagesize = m->page_size;
sendbuf.dd.ucEepromPageSize = PDATA(pgm)->eeprom_pagesize = m->page_size;
}
}
sendbuf.dd.ucCacheType =
(p->flags & AVRPART_HAS_PDI)? 0x02 /* ATxmega */: 0x00;
if (verbose >= 2)
fprintf(stderr, "%s: jtagmkII_set_devdescr(): "
"Sending set device descriptor command: ",
progname);
jtagmkII_send(pgm, (unsigned char *)&sendbuf,
device_descriptor_length + sizeof(unsigned char));
PDATA(pgm)->device_descriptor_length + sizeof(unsigned char));
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
@@ -951,7 +975,7 @@ static int jtagmkII_program_enable(PROGRAMMER * pgm)
int status;
unsigned char buf[1], *resp, c;
if (prog_enabled)
if (PDATA(pgm)->prog_enabled)
return 0;
buf[0] = CMND_ENTER_PROGMODE;
@@ -988,7 +1012,7 @@ static int jtagmkII_program_enable(PROGRAMMER * pgm)
return -1;
}
prog_enabled = 1;
PDATA(pgm)->prog_enabled = 1;
return 0;
}
@@ -997,7 +1021,7 @@ static int jtagmkII_program_disable(PROGRAMMER * pgm)
int status;
unsigned char buf[1], *resp, c;
if (!prog_enabled)
if (!PDATA(pgm)->prog_enabled)
return 0;
buf[0] = CMND_LEAVE_PROGMODE;
@@ -1032,7 +1056,7 @@ static int jtagmkII_program_disable(PROGRAMMER * pgm)
return -1;
}
prog_enabled = 0;
PDATA(pgm)->prog_enabled = 0;
(void)jtagmkII_reset(pgm, 0x01);
return 0;
@@ -1111,25 +1135,38 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
return -1;
}
if (jtagmkII_setparm(pgm, PAR_DAISY_CHAIN_INFO, PDATA(pgm)->jtagchain) < 0) {
fprintf(stderr, "%s: jtagmkII_initialize(): Failed to setup JTAG chain\n",
progname);
return -1;
}
/*
* Must set the device descriptor before entering programming mode.
*/
jtagmkII_set_devdescr(pgm, p);
/*
* If this is an ATxmega device, change the emulator mode from JTAG
* to JTAG_XMEGA.
*/
if (!(pgm->flag & PGM_FL_IS_DW) &&
(p->flags & AVRPART_HAS_PDI))
jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG_XMEGA);
free(flash_pagecache);
free(eeprom_pagecache);
if ((flash_pagecache = malloc(flash_pagesize)) == NULL) {
free(PDATA(pgm)->flash_pagecache);
free(PDATA(pgm)->eeprom_pagecache);
if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) {
fprintf(stderr, "%s: jtagmkII_initialize(): Out of memory\n",
progname);
return -1;
}
if ((eeprom_pagecache = malloc(eeprom_pagesize)) == NULL) {
if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
fprintf(stderr, "%s: jtagmkII_initialize(): Out of memory\n",
progname);
free(flash_pagecache);
free(PDATA(pgm)->flash_pagecache);
return -1;
}
flash_pageaddr = eeprom_pageaddr = (unsigned long)-1L;
PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
if (jtagmkII_reset(pgm, 0x01) < 0)
return -1;
@@ -1152,10 +1189,10 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
static void jtagmkII_disable(PROGRAMMER * pgm)
{
free(flash_pagecache);
flash_pagecache = NULL;
free(eeprom_pagecache);
eeprom_pagecache = NULL;
free(PDATA(pgm)->flash_pagecache);
PDATA(pgm)->flash_pagecache = NULL;
free(PDATA(pgm)->eeprom_pagecache);
PDATA(pgm)->eeprom_pagecache = NULL;
if (!(pgm->flag & PGM_FL_IS_DW))
(void)jtagmkII_program_disable(pgm);
@@ -1166,6 +1203,49 @@ static void jtagmkII_enable(PROGRAMMER * pgm)
return;
}
static int jtagmkII_parseextparms(PROGRAMMER * pgm, LISTID extparms)
{
LNODEID ln;
const char *extended_param;
int rv = 0;
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
extended_param = ldata(ln);
if (strncmp(extended_param, "jtagchain=", strlen("jtagchain=")) == 0) {
unsigned int ub, ua, bb, ba;
if (sscanf(extended_param, "jtagchain=%u,%u,%u,%u", &ub, &ua, &bb, &ba)
!= 4) {
fprintf(stderr,
"%s: jtagmkII_parseextparms(): invalid JTAG chain '%s'\n",
progname, extended_param);
rv = -1;
continue;
}
if (verbose >= 2) {
fprintf(stderr,
"%s: jtagmkII_parseextparms(): JTAG chain parsed as:\n"
"%s %u units before, %u units after, %u bits before, %u bits after\n",
progname,
progbuf, ub, ua, bb, ba);
}
PDATA(pgm)->jtagchain[0] = ub;
PDATA(pgm)->jtagchain[1] = ua;
PDATA(pgm)->jtagchain[2] = bb;
PDATA(pgm)->jtagchain[3] = ba;
continue;
}
fprintf(stderr,
"%s: jtagmkII_parseextparms(): invalid extended parameter '%s'\n",
progname, extended_param);
rv = -1;
}
return rv;
}
static int jtagmkII_open(PROGRAMMER * pgm, char * port)
{
@@ -1355,7 +1435,7 @@ void jtagmkII_close(PROGRAMMER * pgm)
if (verbose >= 2)
fprintf(stderr, "%s: jtagmkII_close()\n", progname);
if (device_descriptor_length) {
if (PDATA(pgm)->device_descriptor_length) {
/* When in JTAG mode, restart target. */
buf[0] = CMND_GO;
if (verbose >= 2)
@@ -1450,16 +1530,28 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
cmd[0] = CMND_WRITE_MEMORY;
if (strcmp(m->desc, "flash") == 0) {
cmd[1] = MTYPE_FLASH_PAGE;
flash_pageaddr = (unsigned long)-1L;
page_size = flash_pagesize;
PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
page_size = PDATA(pgm)->flash_pagesize;
} else if (strcmp(m->desc, "eeprom") == 0) {
cmd[1] = MTYPE_EEPROM_PAGE;
eeprom_pageaddr = (unsigned long)-1L;
page_size = eeprom_pagesize;
if (pgm->flag & PGM_FL_IS_DW) {
/*
* jtagmkII_paged_write() to EEPROM attempted while in
* DW mode. Use jtagmkII_write_byte() instead.
*/
for (addr = 0; addr < n_bytes; addr++) {
status = jtagmkII_write_byte(pgm, p, m, addr, m->buf[addr]);
report_progress(addr, n_bytes, NULL);
if (status < 0) {
free(cmd);
return -1;
}
}
free(cmd);
return -1;
return n_bytes;
}
cmd[1] = MTYPE_EEPROM_PAGE;
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
page_size = PDATA(pgm)->eeprom_pagesize;
}
serial_recv_timeout = 100;
@@ -1658,8 +1750,8 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
cmd[1] = MTYPE_FLASH_PAGE;
pagesize = mem->page_size;
paddr = addr & ~(pagesize - 1);
paddr_ptr = &flash_pageaddr;
cache_ptr = flash_pagecache;
paddr_ptr = &PDATA(pgm)->flash_pageaddr;
cache_ptr = PDATA(pgm)->flash_pagecache;
} else if (strcmp(mem->desc, "eeprom") == 0) {
if (pgm->flag & PGM_FL_IS_DW) {
/* debugWire cannot use page access for EEPROM */
@@ -1668,8 +1760,8 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
cmd[1] = MTYPE_EEPROM_PAGE;
pagesize = mem->page_size;
paddr = addr & ~(pagesize - 1);
paddr_ptr = &eeprom_pageaddr;
cache_ptr = eeprom_pagecache;
paddr_ptr = &PDATA(pgm)->eeprom_pageaddr;
cache_ptr = PDATA(pgm)->eeprom_pagecache;
}
} else if (strcmp(mem->desc, "lfuse") == 0) {
cmd[1] = MTYPE_FUSE_BITS;
@@ -1724,6 +1816,11 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
}
return 0;
}
else if (mem->offset != 0) {
cmd[1] = MTYPE_SRAM;
addr += mem->offset;
}
}
/*
@@ -1827,13 +1924,13 @@ static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
if (strcmp(mem->desc, "flash") == 0) {
cmd[1] = MTYPE_SPM;
need_progmode = 0;
flash_pageaddr = (unsigned long)-1L;
PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1;
} else if (strcmp(mem->desc, "eeprom") == 0) {
cmd[1] = MTYPE_EEPROM;
need_progmode = 0;
eeprom_pageaddr = (unsigned long)-1L;
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
} else if (strcmp(mem->desc, "lfuse") == 0) {
cmd[1] = MTYPE_FUSE_BITS;
addr = 0;
@@ -2029,6 +2126,7 @@ static int jtagmkII_setparm(PROGRAMMER * pgm, unsigned char parm,
case PAR_OCD_VTARGET: size = 2; break;
case PAR_OCD_JTAG_CLK: size = 1; break;
case PAR_TIMERS_RUNNING: size = 1; break;
case PAR_DAISY_CHAIN_INFO: size = 4; break;
default:
fprintf(stderr, "%s: jtagmkII_setparm(): unknown parameter 0x%02x\n",
progname, parm);
@@ -2073,7 +2171,7 @@ static int jtagmkII_setparm(PROGRAMMER * pgm, unsigned char parm,
}
static void jtagmkII_display(PROGRAMMER * pgm, char * p)
static void jtagmkII_display(PROGRAMMER * pgm, const char * p)
{
unsigned char hw[4], fw[4];
@@ -2086,7 +2184,7 @@ static void jtagmkII_display(PROGRAMMER * pgm, char * p)
fprintf(stderr, "%sS_MCU hardware version: %d\n", p, hw[1]);
fprintf(stderr, "%sS_MCU firmware version: %d.%02d\n", p, fw[3], fw[2]);
fprintf(stderr, "%sSerial number: %02x:%02x:%02x:%02x:%02x:%02x\n",
p, serno[0], serno[1], serno[2], serno[3], serno[4], serno[5]);
p, PDATA(pgm)->serno[0], PDATA(pgm)->serno[1], PDATA(pgm)->serno[2], PDATA(pgm)->serno[3], PDATA(pgm)->serno[4], PDATA(pgm)->serno[5]);
jtagmkII_print_parms1(pgm, p);
@@ -2094,7 +2192,7 @@ static void jtagmkII_display(PROGRAMMER * pgm, char * p)
}
static void jtagmkII_print_parms1(PROGRAMMER * pgm, char * p)
static void jtagmkII_print_parms1(PROGRAMMER * pgm, const char * p)
{
unsigned char vtarget[4], jtag_clock[4];
char clkbuf[20];
@@ -2163,6 +2261,9 @@ void jtagmkII_initpgm(PROGRAMMER * pgm)
pgm->paged_load = jtagmkII_paged_load;
pgm->print_parms = jtagmkII_print_parms;
pgm->set_sck_period = jtagmkII_set_sck_period;
pgm->parseextparams = jtagmkII_parseextparms;
pgm->setup = jtagmkII_setup;
pgm->teardown = jtagmkII_teardown;
pgm->page_size = 256;
}
@@ -2191,6 +2292,8 @@ void jtagmkII_dw_initpgm(PROGRAMMER * pgm)
pgm->paged_write = jtagmkII_paged_write;
pgm->paged_load = jtagmkII_paged_load;
pgm->print_parms = jtagmkII_print_parms;
pgm->setup = jtagmkII_setup;
pgm->teardown = jtagmkII_teardown;
pgm->page_size = 256;
pgm->flag = PGM_FL_IS_DW;
}
@@ -2221,6 +2324,9 @@ void jtagmkII_dragon_initpgm(PROGRAMMER * pgm)
pgm->paged_load = jtagmkII_paged_load;
pgm->print_parms = jtagmkII_print_parms;
pgm->set_sck_period = jtagmkII_set_sck_period;
pgm->parseextparams = jtagmkII_parseextparms;
pgm->setup = jtagmkII_setup;
pgm->teardown = jtagmkII_teardown;
pgm->page_size = 256;
}
@@ -2249,6 +2355,8 @@ void jtagmkII_dragon_dw_initpgm(PROGRAMMER * pgm)
pgm->paged_write = jtagmkII_paged_write;
pgm->paged_load = jtagmkII_paged_load;
pgm->print_parms = jtagmkII_print_parms;
pgm->setup = jtagmkII_setup;
pgm->teardown = jtagmkII_teardown;
pgm->page_size = 256;
pgm->flag = PGM_FL_IS_DW;
}

View File

@@ -22,6 +22,10 @@
#ifndef jtagmkII_h
#define jtagmkII_h
#ifdef __cplusplus
extern "C" {
#endif
int jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len);
int jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg);
void jtagmkII_close(PROGRAMMER * pgm);
@@ -34,5 +38,17 @@ void jtagmkII_dw_initpgm (PROGRAMMER * pgm);
void jtagmkII_dragon_initpgm (PROGRAMMER * pgm);
void jtagmkII_dragon_dw_initpgm (PROGRAMMER * pgm);
/*
* These functions are referenced from stk500v2.c for JTAG ICE mkII
* and AVR Dragon programmers running in one of the STK500v2
* modi.
*/
void jtagmkII_setup(PROGRAMMER * pgm);
void jtagmkII_teardown(PROGRAMMER * pgm);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -179,6 +179,7 @@
# define EMULATOR_MODE_JTAG 0x01
# define EMULATOR_MODE_HV 0x02 /* HVSP or PP mode of AVR Dragon */
# define EMULATOR_MODE_SPI 0x03
# define EMULATOR_MODE_JTAG_XMEGA 0x05
#define PAR_IREG 0x04
#define PAR_BAUD_RATE 0x05
# define PAR_BAUD_2400 0x01

View File

@@ -29,15 +29,12 @@
#include <sys/types.h>
#include <sys/stat.h>
#include "avrdude.h"
#include "config.h"
#include "config_gram.h"
#include "lists.h"
extern int lineno;
extern char * infile;
void pyytext(void);
#define YY_NO_UNPUT
%}
@@ -53,7 +50,7 @@ SIGN [+-]
/* Bump resources for classic lex. */
%e2000
%p5000
%p10000
%n1000
%%
@@ -120,9 +117,11 @@ SIGN [+-]
exit(1); }
allowfullpagebitstream { yylval=NULL; return K_ALLOWFULLPAGEBITSTREAM; }
arduino { yylval=NULL; return K_ARDUINO; }
avr910 { yylval=NULL; return K_AVR910; }
avr910_devcode { yylval=NULL; return K_AVR910_DEVCODE; }
usbasp { yylval=NULL; return K_USBASP; }
usbtiny { yylval=NULL; return K_USBTINY; }
bank_size { yylval=NULL; return K_PAGE_SIZE; }
banked { yylval=NULL; return K_PAGED; }
baudrate { yylval=NULL; return K_BAUDRATE; }
@@ -147,6 +146,7 @@ errled { yylval=NULL; return K_ERRLED; }
flash { yylval=NULL; return K_FLASH; }
has_jtag { yylval=NULL; return K_HAS_JTAG; }
has_debugwire { yylval=NULL; return K_HAS_DW; }
has_pdi { yylval=NULL; return K_HAS_PDI; }
id { yylval=NULL; return K_ID; }
idr { yylval=NULL; return K_IDR; }
jtagmki { yylval=NULL; return K_JTAG_MKI; }
@@ -160,6 +160,8 @@ miso { yylval=NULL; return K_MISO; }
mosi { yylval=NULL; return K_MOSI; }
num_banks { yylval=NULL; return K_NUM_PAGES; }
num_pages { yylval=NULL; return K_NUM_PAGES; }
nvm_base { yylval=NULL; return K_NVM_BASE; }
offset { yylval=NULL; return K_OFFSET; }
page_size { yylval=NULL; return K_PAGE_SIZE; }
paged { yylval=NULL; return K_PAGED; }
pagel { yylval=NULL; return K_PAGEL; }
@@ -185,6 +187,9 @@ stk500pp { yylval=NULL; return K_STK500PP; }
stk500v2 { yylval=NULL; return K_STK500V2; }
stk500generic { yylval=NULL; return K_STK500GENERIC; }
stk500_devcode { yylval=NULL; return K_STK500_DEVCODE; }
stk600 { yylval=NULL; return K_STK600; }
stk600hvsp { yylval=NULL; return K_STK600HVSP; }
stk600pp { yylval=NULL; return K_STK600PP; }
type { yylval=NULL; return K_TYPE; }
vcc { yylval=NULL; return K_VCC; }
vfyled { yylval=NULL; return K_VFYLED; }

View File

@@ -28,8 +28,8 @@
Author : Brian Dean
Date : 10 January, 1990
----------------------------------------------------------------------*/
#ifndef __lists_h__
#define __lists_h__
#ifndef lists_h
#define lists_h
#include <stdio.h>
@@ -67,6 +67,10 @@ typedef void * LNODEID;
#define LISTRMV(l,d) lrmv_d(l,d) /* remove from end of the list */
#ifdef __cplusplus
extern "C" {
#endif
/* .................... Function Prototypes .................... */
LISTID lcreat ( void * liststruct, int poolsize );
@@ -104,4 +108,8 @@ void * lsrch ( LISTID lid, void * p, int (*compare)(void *p1,void *p2));
int lprint ( FILE * f, LISTID lid );
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,6 +1,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2005 Brian S. Dean <bsd@bsdhome.com>
* Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
*
* 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
@@ -53,49 +54,42 @@
#include "pindefs.h"
#include "term.h"
#include "safemode.h"
enum {
DEVICE_READ,
DEVICE_WRITE,
DEVICE_VERIFY
};
typedef struct update_t {
char * memtype;
int op;
char * filename;
int format;
} UPDATE;
#include "update.h"
/* Get VERSION from ac_cfg.h */
char * version = VERSION;
int verbose; /* verbose output */
int quell_progress; /* un-verebose output */
int ovsigck; /* 1=override sig check, 0=don't */
char * progname;
char progbuf[PATH_MAX]; /* temporary buffer of spaces the same
length as progname; used for lining up
multiline messages */
PROGRAMMER * pgm = NULL;
struct list_walk_cookie
{
FILE *f;
const char *prefix;
};
LISTID updates;
static LISTID updates;
static LISTID extended_params;
static PROGRAMMER * pgm;
/*
* global options
*/
int do_cycles; /* track erase-rewrite cycles */
int do_cycles; /* track erase-rewrite cycles */
int verbose; /* verbose output */
int quell_progress; /* un-verebose output */
int ovsigck; /* 1=override sig check, 0=don't */
/*
* usage message
*/
void usage(void)
static void usage(void)
{
fprintf(stderr,
"Usage: %s [options]\n"
@@ -122,6 +116,7 @@ void usage(void)
" fuses should be changed back.\n"
" -t Enter terminal mode.\n"
" -E <exitspec>[,<exitspec>] List programmer exit specifications.\n"
" -x <extended_param> Pass <extended_param> to programmer.\n"
" -y Count # erase cycles in EEPROM.\n"
" -Y <number> Initialize erase cycle # in EEPROM.\n"
" -v Verbose output. -v -v for more.\n"
@@ -132,135 +127,6 @@ void usage(void)
}
int read_config(char * file)
{
FILE * f;
f = fopen(file, "r");
if (f == NULL) {
fprintf(stderr, "%s: can't open config file \"%s\": %s\n",
progname, file, strerror(errno));
return -1;
}
lineno = 1;
infile = file;
yyin = f;
yyparse();
fclose(f);
return 0;
}
void programmer_display(char * p)
{
fprintf(stderr, "%sProgrammer Type : %s\n", p, pgm->type);
fprintf(stderr, "%sDescription : %s\n", p, pgm->desc);
pgm->display(pgm, p);
}
PROGRAMMER * locate_programmer(LISTID programmers, char * configid)
{
LNODEID ln1, ln2;
PROGRAMMER * p = NULL;
char * id;
int found;
found = 0;
for (ln1=lfirst(programmers); ln1 && !found; ln1=lnext(ln1)) {
p = ldata(ln1);
for (ln2=lfirst(p->id); ln2 && !found; ln2=lnext(ln2)) {
id = ldata(ln2);
if (strcasecmp(configid, id) == 0)
found = 1;
}
}
if (found)
return p;
return NULL;
}
void list_programmers(FILE * f, char * prefix, LISTID programmers)
{
LNODEID ln1;
PROGRAMMER * p;
for (ln1=lfirst(programmers); ln1; ln1=lnext(ln1)) {
p = ldata(ln1);
fprintf(f, "%s%-8s = %-30s [%s:%d]\n",
prefix, (char *)ldata(lfirst(p->id)), p->desc,
p->config_file, p->lineno);
}
return;
}
typedef void (*FP_UpdateProgress)(int percent, double etime, char *hdr);
static FP_UpdateProgress update_progress;
/*
* Report the progress of a read or write operation from/to the
* device.
*
* The first call of report_progress() should look like this (for a write op):
*
* report_progress (0, 1, "Writing");
*
* Then hdr should be passed NULL on subsequent calls while the
* operation is progressing. Once the operation is complete, a final
* call should be made as such to ensure proper termination of the
* progress report:
*
* report_progress (1, 1, NULL);
*
* It would be nice if we could reduce the usage to one and only one
* call for each of start, during and end cases. As things stand now,
* that is not possible and makes maintenance a bit more work.
*/
void report_progress (int completed, int total, char *hdr)
{
static int last = 0;
static double start_time;
int percent = (completed * 100) / total;
struct timeval tv;
double t;
if (update_progress == NULL)
return;
gettimeofday(&tv, NULL);
t = tv.tv_sec + ((double)tv.tv_usec)/1000000;
if (hdr) {
last = 0;
start_time = t;
update_progress (percent, t - start_time, hdr);
}
if (percent > 100)
percent = 100;
if (percent > last) {
last = percent;
update_progress (percent, t - start_time, hdr);
}
if (percent == 100)
last = 0; /* Get ready for next time. */
}
static void update_progress_tty (int percent, double etime, char *hdr)
{
static char hashes[51];
@@ -268,6 +134,8 @@ static void update_progress_tty (int percent, double etime, char *hdr)
static int last = 0;
int i;
setvbuf(stderr, (char*)NULL, _IONBF, 0);
hashes[50] = 0;
memset (hashes, ' ', 50);
@@ -290,6 +158,8 @@ static void update_progress_tty (int percent, double etime, char *hdr)
last = 1;
fprintf (stderr, "\n\n");
}
setvbuf(stderr, (char*)NULL, _IOLBF, 0);
}
static void update_progress_no_tty (int percent, double etime, char *hdr)
@@ -298,6 +168,8 @@ static void update_progress_no_tty (int percent, double etime, char *hdr)
static int last = 0;
int cnt = (percent>>1)*2;
setvbuf(stderr, (char*)NULL, _IONBF, 0);
if (hdr) {
fprintf (stderr, "\n%s | ", hdr);
last = 0;
@@ -317,352 +189,55 @@ static void update_progress_no_tty (int percent, double etime, char *hdr)
}
else
last = (percent>>1)*2; /* Make last a multiple of 2. */
setvbuf(stderr, (char*)NULL, _IOLBF, 0);
}
UPDATE * parse_op(char * s)
static void list_programmers_callback(const char *name, const char *desc,
const char *cfgname, int cfglineno,
void *cookie)
{
char buf[1024];
char * p, * cp, c;
UPDATE * upd;
int i;
size_t fnlen;
struct list_walk_cookie *c = (struct list_walk_cookie *)cookie;
upd = (UPDATE *)malloc(sizeof(UPDATE));
if (upd == NULL) {
fprintf(stderr, "%s: out of memory\n", progname);
exit(1);
}
i = 0;
p = s;
while ((i < (sizeof(buf)-1) && *p && (*p != ':')))
buf[i++] = *p++;
if (*p != ':') {
upd->memtype = (char *)malloc(strlen("flash")+1);
if (upd->memtype == NULL) {
outofmem:
fprintf(stderr, "%s: out of memory\n", progname);
exit(1);
}
strcpy(upd->memtype, "flash");
upd->op = DEVICE_WRITE;
upd->filename = (char *)malloc(strlen(buf) + 1);
if (upd->filename == NULL)
goto outofmem;
strcpy(upd->filename, buf);
upd->format = FMT_AUTO;
return upd;
}
buf[i] = 0;
upd->memtype = (char *)malloc(strlen(buf)+1);
if (upd->memtype == NULL) {
fprintf(stderr, "%s: out of memory\n", progname);
exit(1);
}
strcpy(upd->memtype, buf);
p++;
if (*p == 'r') {
upd->op = DEVICE_READ;
}
else if (*p == 'w') {
upd->op = DEVICE_WRITE;
}
else if (*p == 'v') {
upd->op = DEVICE_VERIFY;
}
else {
fprintf(stderr, "%s: invalid I/O mode '%c' in update specification\n",
progname, *p);
fprintf(stderr,
" allowed values are:\n"
" r = read device\n"
" w = write device\n"
" v = verify device\n");
free(upd->memtype);
free(upd);
return NULL;
}
p++;
if (*p != ':') {
fprintf(stderr, "%s: invalid update specification\n", progname);
free(upd->memtype);
free(upd);
return NULL;
}
p++;
/*
* Now, parse the filename component. Instead of looking for the
* leftmost possible colon delimiter, we look for the rightmost one.
* If we found one, we do have a trailing :format specifier, and
* process it. Otherwise, the remainder of the string is our file
* name component. That way, the file name itself is allowed to
* contain a colon itself (e. g. C:/some/file.hex), except the
* optional format specifier becomes mandatory then.
*/
cp = p;
p = strrchr(cp, ':');
if (p == NULL) {
upd->format = FMT_AUTO;
fnlen = strlen(cp);
upd->filename = (char *)malloc(fnlen + 1);
} else {
fnlen = p - cp;
upd->filename = (char *)malloc(fnlen +1);
c = *++p;
if (c && p[1])
/* More than one char - force failure below. */
c = '?';
switch (c) {
case 'a': upd->format = FMT_AUTO; break;
case 's': upd->format = FMT_SREC; break;
case 'i': upd->format = FMT_IHEX; break;
case 'r': upd->format = FMT_RBIN; break;
case 'm': upd->format = FMT_IMM; break;
case 'b': upd->format = FMT_BIN; break;
case 'd': upd->format = FMT_DEC; break;
case 'h': upd->format = FMT_HEX; break;
case 'o': upd->format = FMT_OCT; break;
default:
fprintf(stderr, "%s: invalid file format '%s' in update specifier\n",
progname, p);
free(upd->memtype);
free(upd);
return NULL;
}
}
if (upd->filename == NULL) {
fprintf(stderr, "%s: out of memory\n", progname);
free(upd->memtype);
free(upd);
return NULL;
}
memcpy(upd->filename, cp, fnlen);
upd->filename[fnlen] = 0;
return upd;
fprintf(c->f, "%s%-8s = %-30s [%s:%d]\n",
c->prefix, name, desc, cfgname, cfglineno);
}
UPDATE * dup_update(UPDATE * upd)
static void list_programmers(FILE * f, const char *prefix, LISTID programmers)
{
UPDATE * u;
struct list_walk_cookie c;
u = (UPDATE *)malloc(sizeof(UPDATE));
if (u == NULL) {
fprintf(stderr, "%s: out of memory\n", progname);
exit(1);
}
c.f = f;
c.prefix = prefix;
memcpy(u, upd, sizeof(UPDATE));
u->memtype = strdup(upd->memtype);
u->filename = strdup(upd->filename);
return u;
walk_programmers(programmers, list_programmers_callback, &c);
}
UPDATE * new_update(int op, char * memtype, int filefmt, char * filename)
static void list_avrparts_callback(const char *name, const char *desc,
const char *cfgname, int cfglineno,
void *cookie)
{
UPDATE * u;
struct list_walk_cookie *c = (struct list_walk_cookie *)cookie;
u = (UPDATE *)malloc(sizeof(UPDATE));
if (u == NULL) {
fprintf(stderr, "%s: out of memory\n", progname);
exit(1);
}
u->memtype = strdup(memtype);
u->filename = strdup(filename);
u->op = op;
u->format = filefmt;
return u;
fprintf(c->f, "%s%-4s = %-15s [%s:%d]\n",
c->prefix, name, desc, cfgname, cfglineno);
}
int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite,
int verify)
static void list_parts(FILE * f, const char *prefix, LISTID avrparts)
{
struct avrpart * v;
AVRMEM * mem;
int size, vsize;
int rc;
struct list_walk_cookie c;
mem = avr_locate_mem(p, upd->memtype);
if (mem == NULL) {
fprintf(stderr, "\"%s\" memory type not defined for part \"%s\"\n",
upd->memtype, p->desc);
return -1;
}
c.f = f;
c.prefix = prefix;
if (upd->op == DEVICE_READ) {
/*
* read out the specified device memory and write it to a file
*/
if (quell_progress < 2) {
fprintf(stderr, "%s: reading %s memory:\n",
progname, mem->desc);
}
report_progress(0,1,"Reading");
rc = avr_read(pgm, p, upd->memtype, 0, 1);
if (rc < 0) {
fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
progname, mem->desc, rc);
return -1;
}
report_progress(1,1,NULL);
size = rc;
if (quell_progress < 2) {
fprintf(stderr,
"%s: writing output file \"%s\"\n",
progname,
strcmp(upd->filename, "-")==0 ? "<stdout>" : upd->filename);
}
rc = fileio(FIO_WRITE, upd->filename, upd->format, p, upd->memtype, size);
if (rc < 0) {
fprintf(stderr, "%s: write to file '%s' failed\n",
progname, upd->filename);
return -1;
}
}
else if (upd->op == DEVICE_WRITE) {
/*
* write the selected device memory using data from a file; first
* read the data from the specified file
*/
if (quell_progress < 2) {
fprintf(stderr,
"%s: reading input file \"%s\"\n",
progname,
strcmp(upd->filename, "-")==0 ? "<stdin>" : upd->filename);
}
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
if (rc < 0) {
fprintf(stderr, "%s: write to file '%s' failed\n",
progname, upd->filename);
return -1;
}
size = rc;
/*
* write the buffer contents to the selected memory type
*/
if (quell_progress < 2) {
fprintf(stderr, "%s: writing %s (%d bytes):\n",
progname, mem->desc, size);
}
if (!nowrite) {
report_progress(0,1,"Writing");
rc = avr_write(pgm, p, upd->memtype, size, 1);
report_progress(1,1,NULL);
}
else {
/*
* test mode, don't actually write to the chip, output the buffer
* to stdout in intel hex instead
*/
rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, upd->memtype, size);
}
if (rc < 0) {
fprintf(stderr, "%s: failed to write %s memory, rc=%d\n",
progname, mem->desc, rc);
return -1;
}
vsize = rc;
if (quell_progress < 2) {
fprintf(stderr, "%s: %d bytes of %s written\n", progname,
vsize, mem->desc);
}
}
else if (upd->op == DEVICE_VERIFY) {
/*
* verify that the in memory file (p->mem[AVR_M_FLASH|AVR_M_EEPROM])
* is the same as what is on the chip
*/
pgm->vfy_led(pgm, ON);
v = avr_dup_part(p);
if (quell_progress < 2) {
fprintf(stderr, "%s: verifying %s memory against %s:\n",
progname, mem->desc, upd->filename);
fprintf(stderr, "%s: load data %s data from input file %s:\n",
progname, mem->desc, upd->filename);
}
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
if (rc < 0) {
fprintf(stderr, "%s: read from file '%s' failed\n",
progname, upd->filename);
return -1;
}
size = rc;
if (quell_progress < 2) {
fprintf(stderr, "%s: input file %s contains %d bytes\n",
progname, upd->filename, size);
fprintf(stderr, "%s: reading on-chip %s data:\n",
progname, mem->desc);
}
report_progress (0,1,"Reading");
rc = avr_read(pgm, v, upd->memtype, size, 1);
if (rc < 0) {
fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
progname, mem->desc, rc);
pgm->err_led(pgm, ON);
return -1;
}
report_progress (1,1,NULL);
if (quell_progress < 2) {
fprintf(stderr, "%s: verifying ...\n", progname);
}
rc = avr_verify(p, v, upd->memtype, size);
if (rc < 0) {
fprintf(stderr, "%s: verification error; content mismatch\n",
progname);
pgm->err_led(pgm, ON);
return -1;
}
if (quell_progress < 2) {
fprintf(stderr, "%s: %d bytes of %s verified\n",
progname, rc, mem->desc);
}
pgm->vfy_led(pgm, OFF);
}
else {
fprintf(stderr, "%s: invalid update operation (%d) requested\n",
progname, upd->op);
return -1;
}
return 0;
walk_avrparts(avrparts, list_avrparts_callback, &c);
}
static void exithook(void)
{
if (pgm->teardown)
pgm->teardown(pgm);
}
/*
* main routine
@@ -681,6 +256,7 @@ int main(int argc, char * argv [])
UPDATE * upd;
LNODEID * ln;
/* options / operating mode variables */
int erase; /* 1=erase chip, 0=don't */
int calibrate; /* 1=calibrate RC oscillator, 0=don't */
@@ -703,6 +279,7 @@ int main(int argc, char * argv [])
int ispdelay; /* Specify the delay for ISP clock */
int safemode; /* Enable safemode, 1=safemode on, 0=normal */
int silentsafe; /* Don't ask about fuses, 1=silent, 0=normal */
int init_ok; /* Device initialization worked well */
unsigned char safemode_lfuse = 0xff;
unsigned char safemode_hfuse = 0xff;
unsigned char safemode_efuse = 0xff;
@@ -715,6 +292,13 @@ int main(int argc, char * argv [])
char * homedir;
#endif
/*
* Set line buffering for file descriptors so we see stdout and stderr
* properly interleaved.
*/
setvbuf(stdout, (char*)NULL, _IOLBF, 0);
setvbuf(stderr, (char*)NULL, _IOLBF, 0);
progname = strrchr(argv[0],'/');
#if defined (WIN32NATIVE)
@@ -738,6 +322,12 @@ int main(int argc, char * argv [])
exit(1);
}
extended_params = lcreat(NULL, 0);
if (extended_params == NULL) {
fprintf(stderr, "%s: cannot initialize extended parameter list\n", progname);
exit(1);
}
partdesc = NULL;
port = default_parallel;
erase = 0;
@@ -760,7 +350,7 @@ int main(int argc, char * argv [])
ispdelay = 0;
safemode = 1; /* Safemode on by default */
silentsafe = 0; /* Ask by default */
if (isatty(STDIN_FILENO) == 0)
safemode = 0; /* Turn off safemode if this isn't a terminal */
@@ -808,7 +398,7 @@ int main(int argc, char * argv [])
/*
* process command line arguments
*/
while ((ch = getopt(argc,argv,"?b:B:c:C:DeE:Fi:np:OP:qstU:uvVyY:")) != -1) {
while ((ch = getopt(argc,argv,"?b:B:c:C:DeE:Fi:np:OP:qstU:uvVx:yY:")) != -1) {
switch (ch) {
case 'b': /* override default programmer baud rate */
@@ -920,6 +510,10 @@ int main(int argc, char * argv [])
verify = 0;
break;
case 'x':
ladd(extended_params, optarg);
break;
case 'y':
do_cycles = 1;
break;
@@ -1059,6 +653,29 @@ int main(int argc, char * argv [])
exit(1);
}
if (pgm->setup) {
pgm->setup(pgm);
}
if (pgm->teardown) {
atexit(exithook);
}
if (lsize(extended_params) > 0) {
if (pgm->parseextparams == NULL) {
fprintf(stderr,
"%s: WARNING: Programmer doesn't support extended parameters,"
" -x option(s) ignored\n",
progname);
} else {
if (pgm->parseextparams(pgm, extended_params) < 0) {
fprintf(stderr,
"%s: Error parsing extended parameter list\n",
progname);
exit(1);
}
}
}
if ((strcmp(pgm->type, "STK500") == 0) ||
(strcmp(pgm->type, "avr910") == 0) ||
(strcmp(pgm->type, "STK500V2") == 0) ||
@@ -1125,20 +742,26 @@ int main(int argc, char * argv [])
}
if (verbose) {
fprintf(stderr, "%sUsing Port : %s\n", progbuf, port);
fprintf(stderr, "%sUsing Programmer : %s\n", progbuf, programmer);
fprintf(stderr, "%sUsing Port : %s\n", progbuf, port);
fprintf(stderr, "%sUsing Programmer : %s\n", progbuf, programmer);
if ((strcmp(pgm->type, "avr910") == 0)) {
fprintf(stderr, "%savr910_devcode (avrdude.conf) : ", progbuf);
if(p->avr910_devcode)fprintf(stderr, "0x%x\n", p->avr910_devcode);
else fprintf(stderr, "none\n");
}
}
if (baudrate != 0) {
if (verbose) {
fprintf(stderr, "%sOverriding Baud Rate : %d\n", progbuf, baudrate);
fprintf(stderr, "%sOverriding Baud Rate : %d\n", progbuf, baudrate);
}
pgm->baudrate = baudrate;
}
if (bitclock != 0.0) {
if (verbose) {
fprintf(stderr, "%sSetting bit clk period: %.1f\n", progbuf, bitclock);
fprintf(stderr, "%sSetting bit clk period : %.1f\n", progbuf, bitclock);
}
pgm->bitclock = bitclock * 1e-6;
@@ -1146,7 +769,7 @@ int main(int argc, char * argv [])
if (ispdelay != 0) {
if (verbose) {
fprintf(stderr, "%sSetting isp clock delay: %3i\n", progbuf, ispdelay);
fprintf(stderr, "%sSetting isp clock delay : %3i\n", progbuf, ispdelay);
}
pgm->ispdelay = ispdelay;
}
@@ -1176,7 +799,7 @@ int main(int argc, char * argv [])
if (verbose) {
avr_display(stderr, p, progbuf, verbose);
fprintf(stderr, "\n");
programmer_display(progbuf);
programmer_display(pgm, progbuf);
}
if (quell_progress < 2) {
@@ -1201,8 +824,8 @@ int main(int argc, char * argv [])
/*
* initialize the chip in preperation for accepting commands
*/
rc = pgm->initialize(pgm, p);
if (rc < 0) {
init_ok = (rc = pgm->initialize(pgm, p)) >= 0;
if (!init_ok) {
fprintf(stderr, "%s: initialization failed, rc=%d\n", progname, rc);
if (!ovsigck) {
fprintf(stderr, "%sDouble check connections and try again, "
@@ -1229,12 +852,14 @@ int main(int argc, char * argv [])
* against 0xffffff / 0x000000 should ensure that the signature bytes
* are valid.
*/
rc = avr_signature(pgm, p);
if (rc != 0) {
fprintf(stderr, "%s: error reading signature data, rc=%d\n",
progname, rc);
exitrc = 1;
goto main_exit;
if (init_ok) {
rc = avr_signature(pgm, p);
if (rc != 0) {
fprintf(stderr, "%s: error reading signature data, rc=%d\n",
progname, rc);
exitrc = 1;
goto main_exit;
}
}
sig = avr_locate_mem(p, "signature");
@@ -1295,25 +920,50 @@ int main(int argc, char * argv [])
}
}
if (safemode == 1) {
if (init_ok && safemode == 1) {
/* If safemode is enabled, go ahead and read the current low, high,
and extended fuse bytes as needed */
if (safemode_readfuses(&safemode_lfuse, &safemode_hfuse,
&safemode_efuse, &safemode_fuse, pgm, p, verbose) != 0) {
fprintf(stderr, "%s: safemode: To protect your AVR the programming "
"will be aborted\n",
progname);
exitrc = 1;
goto main_exit;
}
rc = safemode_readfuses(&safemode_lfuse, &safemode_hfuse,
&safemode_efuse, &safemode_fuse, pgm, p, verbose);
//Save the fuses as default
safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
if (rc != 0) {
//Check if the programmer just doesn't support reading
if (rc == -5)
{
if (verbose > 0)
{
fprintf(stderr, "%s: safemode: Fuse reading not support by programmer.\n"
" Safemode disabled.\n", progname);
}
safemode = 0;
}
else
{
fprintf(stderr, "%s: safemode: To protect your AVR the programming "
"will be aborted\n",
progname);
exitrc = 1;
goto main_exit;
}
}
else {
//Save the fuses as default
safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
}
}
if ((p->flags & AVRPART_HAS_PDI) != 0) {
/*
* This is an ATxmega which can page erase, so no auto erase is
* needed.
*/
auto_erase = 0;
}
if ((erase == 0) && (auto_erase == 1)) {
AVRMEM * m;
@@ -1342,7 +992,8 @@ int main(int argc, char * argv [])
*
* The cycle count will be displayed anytime it will be changed later.
*/
if ((set_cycles == -1) && ((erase == 0) || (do_cycles == 0))) {
if (init_ok &&
(set_cycles == -1) && ((erase == 0) || (do_cycles == 0))) {
/*
* see if the cycle count in the last four bytes of eeprom seems
* reasonable
@@ -1358,7 +1009,7 @@ int main(int argc, char * argv [])
}
}
if (set_cycles != -1) {
if (init_ok && set_cycles != -1) {
rc = avr_get_cycle_count(pgm, p, &cycles);
if (rc == 0) {
/*
@@ -1381,25 +1032,39 @@ int main(int argc, char * argv [])
}
if (erase) {
if (init_ok && erase) {
/*
* erase the chip's flash and eeprom memories, this is required
* before the chip can accept new programming
*/
if (quell_progress < 2) {
fprintf(stderr, "%s: erasing chip\n", progname);
if (nowrite) {
fprintf(stderr,
"%s: conflicting -e and -n options specified, NOT erasing chip\n",
progname);
} else {
if (quell_progress < 2) {
fprintf(stderr, "%s: erasing chip\n", progname);
}
avr_chip_erase(pgm, p);
}
avr_chip_erase(pgm, p);
}
if (terminal) {
/*
* terminal mode
*/
*/
exitrc = terminal_mode(pgm, p);
}
if (!init_ok) {
/*
* If we came here by the -tF options, bail out now.
*/
exitrc = 1;
goto main_exit;
}
for (ln=lfirst(updates); ln; ln=lnext(ln)) {
upd = ldata(ln);

View File

@@ -32,20 +32,17 @@
# include "freebsd_ppi.h"
#elif defined(__linux__)
# include "linux_ppdev.h"
#elif defined(__sun__) && defined(__svr4__) /* Solaris */
#elif defined(__sun__) || defined(__sun) /* Solaris */
# include "solaris_ecpp.h"
#endif
#include "avrdude.h"
#include "avr.h"
#include "pindefs.h"
#include "pgm.h"
#include "ppi.h"
#include "bitbang.h"
extern char * progname;
extern int do_cycles;
extern int verbose;
#if HAVE_PARPORT
struct ppipins_t {
@@ -324,7 +321,7 @@ static void par_close(PROGRAMMER * pgm)
pgm->fd.ifd = -1;
}
static void par_display(PROGRAMMER * pgm, char * p)
static void par_display(PROGRAMMER * pgm, const char * p)
{
char vccpins[64];
char buffpins[64];
@@ -419,6 +416,7 @@ void par_initpgm(PROGRAMMER * pgm)
pgm->program_enable = bitbang_program_enable;
pgm->chip_erase = bitbang_chip_erase;
pgm->cmd = bitbang_cmd;
pgm->spi = bitbang_spi;
pgm->open = par_open;
pgm->close = par_close;
pgm->setpin = par_setpin;

View File

@@ -19,11 +19,17 @@
/* $Id$ */
#ifndef __par_h__
#define __par_h__
#ifndef par_h
#define par_h
#ifdef __cplusplus
extern "C" {
#endif
void par_initpgm (PROGRAMMER * pgm);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,6 +1,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
*
* 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
@@ -25,17 +26,16 @@
#include <stdlib.h>
#include <string.h>
#include "avrdude.h"
#include "pgm.h"
extern char * progname;
static int pgm_default_2 (struct programmer_t *, AVRPART *);
static int pgm_default_3 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value);
static void pgm_default_4 (struct programmer_t *);
static int pgm_default_5 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data);
static void pgm_default_6 (struct programmer_t *, char *);
static void pgm_default_6 (struct programmer_t *, const char *);
static int pgm_default_open (struct programmer_t *pgm, char * name)
@@ -118,6 +118,7 @@ PROGRAMMER * pgm_new(void)
* assigned before they are called
*/
pgm->cmd = NULL;
pgm->spi = NULL;
pgm->paged_write = NULL;
pgm->paged_load = NULL;
pgm->write_setup = NULL;
@@ -126,6 +127,9 @@ PROGRAMMER * pgm_new(void)
pgm->set_varef = NULL;
pgm->set_fosc = NULL;
pgm->perform_osccal = NULL;
pgm->parseextparams = NULL;
pgm->setup = NULL;
pgm->teardown = NULL;
return pgm;
}
@@ -162,9 +166,62 @@ static int pgm_default_5 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
return -1;
}
static void pgm_default_6 (struct programmer_t * pgm, char * p)
static void pgm_default_6 (struct programmer_t * pgm, const char * p)
{
pgm_default();
}
void programmer_display(PROGRAMMER * pgm, const char * p)
{
fprintf(stderr, "%sProgrammer Type : %s\n", p, pgm->type);
fprintf(stderr, "%sDescription : %s\n", p, pgm->desc);
pgm->display(pgm, p);
}
PROGRAMMER * locate_programmer(LISTID programmers, const char * configid)
{
LNODEID ln1, ln2;
PROGRAMMER * p = NULL;
const char * id;
int found;
found = 0;
for (ln1=lfirst(programmers); ln1 && !found; ln1=lnext(ln1)) {
p = ldata(ln1);
for (ln2=lfirst(p->id); ln2 && !found; ln2=lnext(ln2)) {
id = ldata(ln2);
if (strcasecmp(configid, id) == 0)
found = 1;
}
}
if (found)
return p;
return NULL;
}
/*
* Iterate over the list of programmers given as "programmers", and
* call the callback function cb for each entry found. cb is being
* passed the following arguments:
* . the name of the programmer (for -c)
* . the descriptive text given in the config file
* . the name of the config file this programmer has been defined in
* . the line number of the config file this programmer has been defined at
* . the "cookie" passed into walk_programmers() (opaque client data)
*/
void walk_programmers(LISTID programmers, walk_programmers_cb cb, void *cookie)
{
LNODEID ln1;
PROGRAMMER * p;
for (ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) {
p = ldata(ln1);
cb((char *)ldata(lfirst(p->id)), p->desc, p->config_file, p->lineno, cookie);
}
}

View File

@@ -1,6 +1,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
*
* 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
@@ -19,8 +20,8 @@
/* $Id$ */
#ifndef __pgm_h__
#define __pgm_h__
#ifndef pgm_h
#define pgm_h
#include <limits.h>
@@ -36,8 +37,6 @@
#define PGM_PORTLEN PATH_MAX
#define PGM_TYPELEN 32
extern LISTID programmers;
typedef enum {
EXIT_VCC_UNSPEC,
EXIT_VCC_ENABLED,
@@ -70,7 +69,7 @@ typedef struct programmer_t {
int (*pgm_led) (struct programmer_t * pgm, int value);
int (*vfy_led) (struct programmer_t * pgm, int value);
int (*initialize) (struct programmer_t * pgm, AVRPART * p);
void (*display) (struct programmer_t * pgm, char * p);
void (*display) (struct programmer_t * pgm, const char * p);
void (*enable) (struct programmer_t * pgm);
void (*disable) (struct programmer_t * pgm);
void (*powerup) (struct programmer_t * pgm);
@@ -79,6 +78,8 @@ typedef struct programmer_t {
int (*chip_erase) (struct programmer_t * pgm, AVRPART * p);
int (*cmd) (struct programmer_t * pgm, unsigned char cmd[4],
unsigned char res[4]);
int (*spi) (struct programmer_t * pgm, unsigned char cmd[],
unsigned char res[], int count);
int (*open) (struct programmer_t * pgm, char * port);
void (*close) (struct programmer_t * pgm);
int (*paged_write) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
@@ -93,7 +94,7 @@ typedef struct programmer_t {
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_varef) (struct programmer_t * pgm, unsigned int chan, double v);
int (*set_fosc) (struct programmer_t * pgm, double v);
int (*set_sck_period) (struct programmer_t * pgm, double v);
int (*setpin) (struct programmer_t * pgm, int pin, int value);
@@ -101,34 +102,31 @@ typedef struct programmer_t {
int (*highpulsepin) (struct programmer_t * pgm, int pin);
int (*parseexitspecs) (struct programmer_t * pgm, char *s);
int (*perform_osccal) (struct programmer_t * pgm);
int (*parseextparams) (struct programmer_t * pgm, LISTID xparams);
void (*setup) (struct programmer_t * pgm);
void (*teardown) (struct programmer_t * pgm);
char config_file[PATH_MAX]; /* config file where defined */
int lineno; /* config file line number */
void *cookie; /* for private use by the programmer */
char flag; /* for private use of the programmer */
} PROGRAMMER;
#ifdef __cplusplus
extern "C" {
#endif
PROGRAMMER * pgm_new(void);
#if defined(WIN32NATIVE)
void programmer_display(PROGRAMMER * pgm, const char * p);
PROGRAMMER * locate_programmer(LISTID programmers, const char * configid);
#include "ac_cfg.h"
#include <windows.h>
/* usleep replacements */
/* sleep Windows in ms, Unix usleep in us
#define usleep(us) Sleep((us)<20000?20:us/1000)
#define usleep(us) Sleep(us/1000)
#define ANTIWARP 3
#define usleep(us) Sleep(us/1000*ANTIWARP)
*/
void usleep(unsigned long us);
#if !defined(HAVE_GETTIMEOFDAY)
struct timezone;
int gettimeofday(struct timeval *tv, struct timezone *tz);
#endif /* HAVE_GETTIMEOFDAY */
#endif /* __win32native_h */
typedef void (*walk_programmers_cb)(const char *name, const char *desc,
const char *cfgname, int cfglineno,
void *cookie);
void walk_programmers(LISTID programmers, walk_programmers_cb cb, void *cookie);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -37,24 +37,24 @@
# include "freebsd_ppi.h"
#elif defined(__linux__)
# include "linux_ppdev.h"
#elif defined(__sun__) && defined(__svr4__) /* Solaris */
#elif defined(__sun__) || defined(__sun) /* Solaris */
# include "solaris_ecpp.h"
#endif
#include "avrdude.h"
#include "avr.h"
#include "pindefs.h"
#include "pgm.h"
#include "ppi.h"
extern char * progname;
enum {
PPI_READ,
PPI_WRITE,
PPI_SHADOWREAD
};
int ppi_shadow_access(union filedescriptor *fdp, int reg, unsigned char *v, unsigned char action)
static int ppi_shadow_access(union filedescriptor *fdp, int reg,
unsigned char *v, unsigned char action)
{
static unsigned char shadow[3];
int shadow_num;

View File

@@ -19,8 +19,8 @@
/* $Id$ */
#ifndef __ppi_h__
#define __ppi_h__
#ifndef ppi_h
#define ppi_h
/*
* PPI registers
@@ -31,7 +31,9 @@ enum {
PPISTATUS
};
#ifdef __cplusplus
extern "C" {
#endif
int ppi_get (union filedescriptor *fdp, int reg, int bit);
@@ -49,6 +51,10 @@ void ppi_open (char * port, union filedescriptor *fdp);
void ppi_close (union filedescriptor *fdp);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -2,6 +2,7 @@
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003, 2004, 2006
* Eric B. Weddington <eweddington@cso.atmel.com>
* Copyright 2008, Joerg Wunsch
*
* 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
@@ -31,6 +32,7 @@ reg = register as defined in an enum in ppi.h. This must be converted
#include "ac_cfg.h"
#include "avrdude.h"
#if defined (WIN32NATIVE)
@@ -43,13 +45,10 @@ reg = register as defined in an enum in ppi.h. This must be converted
#include <windows.h>
#include <sys/time.h>
#include <windows.h>
#include "serial.h"
#include "ppi.h"
extern char *progname;
#define DEVICE_LPT1 "lpt1"
#define DEVICE_LPT2 "lpt2"
#define DEVICE_LPT3 "lpt3"
@@ -109,6 +108,24 @@ void ppi_open(char *port, union filedescriptor *fdp)
break;
}
}
if(fd == -1)
{
/*
* Supplied port name did not match any of the pre-defined
* names. Try interpreting it as a numeric
* (hexadecimal/decimal/octal) address.
*/
char *cp;
fd = strtol(port, &cp, 0);
if(*port == '\0' || *cp != '\0')
{
fprintf(stderr,
"%s: port name \"%s\" is neither lpt1/2/3 nor valid number\n",
progname, port);
fd = -1;
}
}
if(fd < 0)
{
fprintf(stderr, "%s: can't open device \"%s\"\n\n", progname, port);
@@ -357,7 +374,7 @@ int gettimeofday(struct timeval *tv, struct timezone *unused){
#endif
void usleep(unsigned long us)
int usleep(unsigned int us)
{
int has_highperf;
LARGE_INTEGER freq,start,stop,loopend;
@@ -390,6 +407,8 @@ void usleep(unsigned long us)
}
DEBUG_DisplayTimingInfo(start, stop, freq, us, has_highperf);
return 0;
}
#endif

View File

@@ -2,7 +2,7 @@
* avrdude - A Downloader/Uploader for AVR device programmers
* avrdude is Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
*
* This file: Copyright (C) 2005 Colin O'Flynn <coflynn@newae.com>
* This file: Copyright (C) 2005-2007 Colin O'Flynn <coflynn@newae.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
@@ -23,13 +23,12 @@
#include <stdio.h>
#include "ac_cfg.h"
#include "avrdude.h"
#include "avr.h"
#include "pgm.h"
#include "safemode.h"
/* This value from ac_cfg.h */
char * progname = PACKAGE_NAME;
/*
* Writes the specified fuse in fusename (can be "lfuse", "hfuse", or
* "efuse") and verifies it. Will try up to tries amount of times
@@ -87,6 +86,7 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
unsigned char value;
unsigned char fusegood = 0;
unsigned char allowfuseread = 1;
unsigned char safemode_lfuse;
unsigned char safemode_hfuse;
unsigned char safemode_efuse;
@@ -107,17 +107,29 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
fusegood = 0; /* By default fuse is a failure */
if(pgm->read_byte(pgm, p, m, 0, &safemode_fuse) != 0)
{
safemode_fuse = 1 + value; //failed - ensure they differ
allowfuseread = 0;
}
if (verbose > 2)
{
fprintf(stderr, "%s: safemode read 1, fuse value: %x\n",progname, safemode_fuse);
}
if(pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
value = 1 + safemode_fuse; //failed - ensure they differ
allowfuseread = 0;
}
if (verbose > 2)
{
fprintf(stderr, "%s: safemode read 2, fuse value: %x\n",progname, value);
}
if (value == safemode_fuse) {
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
value = 1 + safemode_fuse;
allowfuseread = 0;
}
if (verbose > 2)
{
fprintf(stderr, "%s: safemode read 3, fuse value: %x\n",progname, value);
}
if (value == safemode_fuse)
{
fusegood = 1; /* Fuse read OK three times */
@@ -125,6 +137,12 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
}
}
//Programmer does not allow fuse reading.... no point trying anymore
if (allowfuseread == 0)
{
return -5;
}
if (fusegood == 0) {
fprintf(stderr,
"%s: safemode: Verify error - unable to read fuse properly. "
@@ -144,23 +162,42 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
fusegood = 0; /* By default fuse is a failure */
if (pgm->read_byte(pgm, p, m, 0, &safemode_lfuse) != 0)
{
safemode_lfuse = 1 + value;
allowfuseread = 0;
}
if (verbose > 2)
{
fprintf(stderr, "%s: safemode read 1, lfuse value: %x\n",progname, safemode_lfuse);
}
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
value = safemode_lfuse + 1;
allowfuseread = 0;
}
if (verbose > 2)
{
fprintf(stderr, "%s: safemode read 2, lfuse value: %x\n",progname, value);
}
if (value == safemode_lfuse) {
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
value = safemode_lfuse + 1;
allowfuseread = 0;
}
if (verbose > 2)
{
fprintf(stderr, "%s: safemode read 3, lfuse value: %x\n",progname, value);
}
if (value == safemode_lfuse){
fusegood = 1; /* Fuse read OK three times */
}
}
}
//Programmer does not allow fuse reading.... no point trying anymore
if (allowfuseread == 0)
{
return -5;
}
if (fusegood == 0) {
fprintf(stderr,
"%s: safemode: Verify error - unable to read lfuse properly. "
@@ -179,23 +216,41 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
fusegood = 0; /* By default fuse is a failure */
if (pgm->read_byte(pgm, p, m, 0, &safemode_hfuse) != 0)
{
safemode_hfuse = value + 1;
allowfuseread = 0;
}
if (verbose > 2)
{
fprintf(stderr, "%s: safemode read 1, hfuse value: %x\n",progname, safemode_hfuse);
}
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
value = safemode_hfuse + 1;
allowfuseread = 0;
}
if (verbose > 2)
{
fprintf(stderr, "%s: safemode read 2, hfuse value: %x\n",progname, value);
}
if (value == safemode_hfuse) {
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
value = safemode_hfuse + 1;
allowfuseread = 0;
}
if (verbose > 2)
{
fprintf(stderr, "%s: safemode read 3, hfuse value: %x\n",progname, value);
}
if (value == safemode_hfuse){
fusegood = 1; /* Fuse read OK three times */
}
}
}
//Programmer does not allow fuse reading.... no point trying anymore
if (allowfuseread == 0)
{
return -5;
}
if (fusegood == 0) {
fprintf(stderr,
"%s: safemode: Verify error - unable to read hfuse properly. "
@@ -214,23 +269,41 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
fusegood = 0; /* By default fuse is a failure */
if (pgm->read_byte(pgm, p, m, 0, &safemode_efuse) != 0)
{
safemode_efuse = value + 1;
allowfuseread = 0;
}
if (verbose > 2)
{
fprintf(stderr, "%s: safemode read 1, efuse value: %x\n",progname, safemode_efuse);
}
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
value = safemode_efuse + 1;
allowfuseread = 0;
}
if (verbose > 2)
{
fprintf(stderr, "%s: safemode read 2, efuse value: %x\n",progname, value);
}
if (value == safemode_efuse) {
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
value = safemode_efuse + 1;
allowfuseread = 0;
}
if (verbose > 2)
{
fprintf(stderr, "%s: safemode read 3, efuse value: %x\n",progname, value);
}
if (value == safemode_efuse){
fusegood = 1; /* Fuse read OK three times */
}
}
}
//Programmer does not allow fuse reading.... no point trying anymore
if (allowfuseread == 0)
{
return -5;
}
if (fusegood == 0) {
fprintf(stderr,
"%s: safemode: Verify error - unable to read efuse properly. "

View File

@@ -20,9 +20,13 @@
*/
#ifndef __safemode_h__
#define __safemode_h__
#ifndef safemode_h
#define safemode_h
#ifdef __cplusplus
extern "C" {
#endif
/* Writes the specified fuse in fusename (can be "lfuse", "hfuse", or "efuse") and verifies it. Will try up to tries
amount of times before giving up */
int safemode_writefuse (unsigned char fuse, char * fusename, PROGRAMMER * pgm, AVRPART * p, int tries, int verbose);
@@ -36,4 +40,8 @@ pointed to be lfuse, hfuse, and efuse. This allows you to change the fuse bits i
if user requests fuse bits are changed, the requested value is now verified */
int safemode_memfuses (int save, unsigned char * lfuse, unsigned char * hfuse, unsigned char * efuse, unsigned char * fuse);
#endif //__safemode_h
#ifdef __cplusplus
}
#endif
#endif /* safemode_h */

View File

@@ -32,6 +32,7 @@
#include <stdio.h>
#include <string.h>
#include "avrdude.h"
#include "serial.h"
/* ------------------------------------------------------------------------ */
@@ -53,9 +54,6 @@
#define USB_VENDOR_ID 0x16c0
#define USB_PRODUCT_ID 0x05df
extern char *progname;
extern int verbose;
static int reportDataSizes[4] = {13, 29, 61, 125};
static unsigned char avrdoperRxBuffer[280]; /* buffer for receive data */
@@ -427,7 +425,7 @@ static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNum
*len = bytesReceived;
if(!usesReportIDs){
buffer[-1] = reportNumber; /* add dummy report ID */
*len++;
len++;
}
return 0;
}

View File

@@ -42,11 +42,9 @@
#include <termios.h>
#include <unistd.h>
#include "avrdude.h"
#include "serial.h"
extern char *progname;
extern int verbose;
long serial_recv_timeout = 5000; /* ms */
struct baud_mapping {
@@ -273,8 +271,6 @@ static void ser_close(union filedescriptor *fd)
static int ser_send(union filedescriptor *fd, unsigned char * buf, size_t buflen)
{
struct timeval timeout, to2;
fd_set wfds;
int nfds;
int rc;
unsigned char * p = buf;
size_t len = buflen;
@@ -308,29 +304,6 @@ static int ser_send(union filedescriptor *fd, unsigned char * buf, size_t buflen
to2 = timeout;
while (len) {
reselect:
FD_ZERO(&wfds);
FD_SET(fd->ifd, &wfds);
nfds = select(fd->ifd + 1, NULL, &wfds, NULL, &to2);
if (nfds == 0) {
if (verbose >= 1)
fprintf(stderr,
"%s: ser_send(): programmer is not responding\n",
progname);
exit(1);
}
else if (nfds == -1) {
if (errno == EINTR || errno == EAGAIN) {
goto reselect;
}
else {
fprintf(stderr, "%s: ser_send(): select(): %s\n",
progname, strerror(errno));
exit(1);
}
}
rc = write(fd->ifd, p, (len > 1024) ? 1024 : len);
if (rc < 0) {
fprintf(stderr, "%s: ser_send(): write error: %s\n",

View File

@@ -24,15 +24,15 @@
* Native Win32 serial interface for avrdude.
*/
#include "avrdude.h"
#if defined(WIN32NATIVE)
#include <windows.h>
#include <stdio.h>
#include <ctype.h> /* for isprint */
#include "serial.h"
extern char *progname;
extern int verbose;
#include "serial.h"
long serial_recv_timeout = 5000; /* ms */
@@ -246,7 +246,6 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
{
unsigned char c;
unsigned char * p = buf;
size_t len = 0;
DWORD read;
HANDLE hComPort=(HANDLE)fd->pfd;
@@ -283,7 +282,7 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
{
fprintf(stderr, "%s: Recv: ", progname);
while (len) {
while (read) {
c = *p;
if (isprint(c)) {
fprintf(stderr, "%c ", c);
@@ -294,7 +293,7 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
fprintf(stderr, "[%02x] ", c);
p++;
len--;
read--;
}
fprintf(stderr, "\n");
}

View File

@@ -22,11 +22,15 @@
#ifndef serbb_h
#define serbb_h
#ifdef __cplusplus
extern "C" {
#endif
void serbb_initpgm (PROGRAMMER * pgm);
int serbb_setpin(int fd, int pin, int value);
int serbb_getpin(int fd, int pin);
int serbb_highpulsepin(int fd, int pin);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -37,6 +37,7 @@
#include <sys/ioctl.h>
#include <termios.h>
#include "avrdude.h"
#include "avr.h"
#include "pindefs.h"
#include "pgm.h"
@@ -44,8 +45,7 @@
#undef DEBUG
extern char *progname;
struct termios oldmode;
static struct termios oldmode;
/*
serial port/pin mapping
@@ -190,7 +190,7 @@ static int serbb_highpulsepin(PROGRAMMER * pgm, int pin)
static void serbb_display(PROGRAMMER *pgm, char *p)
static void serbb_display(PROGRAMMER *pgm, const char *p)
{
/* MAYBE */
}

View File

@@ -24,6 +24,8 @@
* Win32 serial bitbanging interface for avrdude.
*/
#include "avrdude.h"
#if defined(WIN32NATIVE)
@@ -37,9 +39,6 @@
#include "pgm.h"
#include "bitbang.h"
extern char *progname;
extern int verbose;
/* cached status lines */
static int dtr, rts, txd;
@@ -239,7 +238,7 @@ static int serbb_highpulsepin(PROGRAMMER * pgm, int pin)
}
static void serbb_display(PROGRAMMER *pgm, char *p)
static void serbb_display(PROGRAMMER *pgm, const char *p)
{
/* MAYBE */
}

View File

@@ -27,14 +27,19 @@
The target file will be selected at configure time. */
#ifndef __serial_h__
#define __serial_h__
#ifndef serial_h
#define serial_h
extern long serial_recv_timeout;
union filedescriptor
{
int ifd;
void *pfd;
struct
{
void *handle;
int ep;
} usb;
};
struct serial_device
@@ -65,4 +70,4 @@ extern struct serial_device avrdoper_serdev;
#define serial_recv (serdev->recv)
#define serial_drain (serdev->drain)
#endif /* __serial_h__ */
#endif /* serial_h */

View File

@@ -1,6 +1,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2008 Joerg Wunsch
*
* 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
@@ -36,6 +37,7 @@
#include <errno.h>
#include <unistd.h>
#include "avrdude.h"
#include "avr.h"
#include "pgm.h"
#include "stk500_private.h"
@@ -43,14 +45,9 @@
#define STK500_XTAL 7372800U
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 void stk500_print_parms1(PROGRAMMER * pgm, const char * p);
static int stk500_is_page_empty(unsigned int address, int page_size,
const unsigned char *buf);
@@ -334,6 +331,77 @@ static int stk500_set_extended_parms(PROGRAMMER * pgm, int n,
return -1;
}
/*
* Crossbow MIB510 initialization and shutdown. Use cmd = 1 to
* initialize, cmd = 0 to close.
*/
static int mib510_isp(PROGRAMMER * pgm, unsigned char cmd)
{
unsigned char buf[9];
int tries = 0;
buf[0] = 0xaa;
buf[1] = 0x55;
buf[2] = 0x55;
buf[3] = 0xaa;
buf[4] = 0x17;
buf[5] = 0x51;
buf[6] = 0x31;
buf[7] = 0x13;
buf[8] = cmd;
retry:
tries++;
stk500_send(pgm, buf, 9);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
fprintf(stderr, "%s: mib510_isp(): can't get into sync\n",
progname);
return -1;
}
if (stk500_getsync(pgm) < 0)
return -1;
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
fprintf(stderr,
"%s: mib510_isp(): protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
return -1;
}
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_OK) {
return 0;
}
else if (buf[0] == Resp_STK_NODEVICE) {
fprintf(stderr, "%s: mib510_isp(): no device\n",
progname);
return -1;
}
if (buf[0] == Resp_STK_FAILED)
{
fprintf(stderr,
"%s: mib510_isp(): command %d failed\n",
progname, cmd);
return -1;
}
fprintf(stderr, "%s: mib510_isp(): unknown response=0x%02x\n",
progname, buf[0]);
return -1;
}
/*
* initialize the AVR device and prepare it to accept commands
@@ -345,13 +413,18 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
int tries;
unsigned maj, min;
int rc;
int n_extparms = 3;
int n_extparms;
stk500_getparm(pgm, Parm_STK_SW_MAJOR, &maj);
stk500_getparm(pgm, Parm_STK_SW_MINOR, &min);
if ((maj > 1) || ((maj == 1) && (min > 10)))
// MIB510 does not need extparams
if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0)
n_extparms = 0;
else if ((maj > 1) || ((maj == 1) && (min > 10)))
n_extparms = 4;
else
n_extparms = 3;
tries = 0;
@@ -466,7 +539,6 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
if (stk500_getsync(pgm) < 0)
return -1;
goto retry;
return -1;
}
else if (buf[0] != Resp_STK_INSYNC) {
fprintf(stderr,
@@ -592,6 +664,11 @@ static int stk500_open(PROGRAMMER * pgm, char * port)
*/
stk500_drain(pgm, 0);
// MIB510 init
if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0 &&
mib510_isp(pgm, 1) != 0)
return -1;
if (stk500_getsync(pgm) < 0)
return -1;
@@ -601,6 +678,10 @@ static int stk500_open(PROGRAMMER * pgm, char * port)
static void stk500_close(PROGRAMMER * pgm)
{
// MIB510 close
if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0)
(void)mib510_isp(pgm, 0);
serial_close(&pgm->fd);
pgm->fd.ifd = -1;
}
@@ -670,7 +751,13 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int flash;
if (page_size == 0) {
page_size = 128;
// MIB510 uses page size of 256 bytes
if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0) {
page_size = 256;
}
else {
page_size = 128;
}
}
if (strcmp(m->desc, "flash") == 0) {
@@ -715,7 +802,9 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
for (addr = 0; addr < n; addr += page_size) {
report_progress (addr, n_bytes, NULL);
if (addr + page_size > n_bytes) {
// MIB510 uses fixed blocks size of 256 bytes
if ((strcmp(ldata(lfirst(pgm->id)), "mib510") != 0) &&
(addr + page_size > n_bytes)) {
block_size = n_bytes % page_size;
}
else {
@@ -836,7 +925,9 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
for (addr = 0; addr < n; addr += page_size) {
report_progress (addr, n_bytes, NULL);
if (addr + page_size > n_bytes) {
// MIB510 uses fixed blocks size of 256 bytes
if ((strcmp(ldata(lfirst(pgm->id)), "mib510") != 0) &&
(addr + page_size > n_bytes)) {
block_size = n_bytes % page_size;
}
else {
@@ -879,7 +970,9 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] != Resp_STK_OK) {
if(strcmp(ldata(lfirst(pgm->id)), "mib510") == 0) {
if (buf[0] != Resp_STK_INSYNC) {
fprintf(stderr,
"\n%s: stk500_paged_load(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
@@ -887,6 +980,16 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
return -5;
}
}
else {
if (buf[0] != Resp_STK_OK) {
fprintf(stderr,
"\n%s: stk500_paged_load(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_OK, buf[0]);
return -5;
}
}
}
return n_bytes;
}
@@ -917,7 +1020,8 @@ static int stk500_set_vtarget(PROGRAMMER * pgm, double v)
}
static int stk500_set_varef(PROGRAMMER * pgm, double v)
static int stk500_set_varef(PROGRAMMER * pgm, unsigned int chan /* unused */,
double v)
{
unsigned uaref, utarg;
@@ -1141,7 +1245,7 @@ static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value)
}
static void stk500_display(PROGRAMMER * pgm, char * p)
static void stk500_display(PROGRAMMER * pgm, const char * p)
{
unsigned maj, min, hdw, topcard;
@@ -1172,7 +1276,7 @@ static void stk500_display(PROGRAMMER * pgm, char * p)
}
static void stk500_print_parms1(PROGRAMMER * pgm, char * p)
static void stk500_print_parms1(PROGRAMMER * pgm, const char * p)
{
unsigned vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration;

View File

@@ -19,11 +19,19 @@
/* $Id$ */
#ifndef __stk500_h__
#define __stk500_h__
#ifndef stk500_h
#define stk500_h
#ifdef __cplusplus
extern "C" {
#endif
void stk500_initpgm (PROGRAMMER * pgm);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -32,12 +32,11 @@
#include <stdio.h>
#include <string.h>
#include "avrdude.h"
#include "pgm.h"
#include "stk500.h"
#include "stk500v2.h"
extern char *progname;
static int stk500generic_open(PROGRAMMER * pgm, char * port)
{
stk500_initpgm(pgm);
@@ -49,6 +48,8 @@ static int stk500generic_open(PROGRAMMER * pgm, char * port)
return 0;
}
pgm->close(pgm);
stk500v2_initpgm(pgm);
if (pgm->open(pgm, port) >= 0)
{

File diff suppressed because it is too large Load Diff

View File

@@ -20,8 +20,12 @@
/* $Id$ */
#ifndef stk500v2_h__
#define stk500v2_h__
#ifndef stk500v2_h
#define stk500v2_h
#ifdef __cplusplus
extern "C" {
#endif
void stk500v2_initpgm (PROGRAMMER * pgm);
void stk500hvsp_initpgm (PROGRAMMER * pgm);
@@ -30,6 +34,13 @@ void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm);
void stk500v2_dragon_hvsp_initpgm(PROGRAMMER * pgm);
void stk500v2_dragon_isp_initpgm(PROGRAMMER * pgm);
void stk500v2_dragon_pp_initpgm(PROGRAMMER * pgm);
void stk600_initpgm (PROGRAMMER * pgm);
void stk600hvsp_initpgm (PROGRAMMER * pgm);
void stk600pp_initpgm (PROGRAMMER * pgm);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -23,6 +23,9 @@
#define CMD_OSCCAL 0x05
#define CMD_LOAD_ADDRESS 0x06
#define CMD_FIRMWARE_UPGRADE 0x07
#define CMD_CHECK_TARGET_CONNECTION 0x0D
#define CMD_LOAD_RC_ID_TABLE 0x0E
#define CMD_LOAD_EC_ID_TABLE 0x0F
// *****************[ STK ISP command constants ]******************************
@@ -75,6 +78,27 @@
#define CMD_READ_LOCK_HVSP 0x3A
#define CMD_READ_SIGNATURE_HVSP 0x3B
#define CMD_READ_OSCCAL_HVSP 0x3C
// These two are redefined since 0x30/0x31 collide
// with the STK600 bootloader.
#define CMD_ENTER_PROGMODE_HVSP_STK600 0x3D
#define CMD_LEAVE_PROGMODE_HVSP_STK600 0x3E
// *** XPROG command constants ***
#define CMD_XPROG 0x50
#define CMD_XPROG_SETMODE 0x51
// *** AVR32 JTAG Programming command ***
#define CMD_JTAG_AVR32 0x80
#define CMD_ENTER_PROGMODE_JTAG_AVR32 0x81
#define CMD_LEAVE_PROGMODE_JTAG_AVR32 0x82
// *** AVR JTAG Programming command ***
#define CMD_JTAG_AVR 0x90
// *****************[ STK test command constants ]***************************
@@ -110,24 +134,136 @@
#define STATUS_CMD_FAILED 0xC0
#define STATUS_CKSUM_ERROR 0xC1
#define STATUS_CMD_UNKNOWN 0xC9
#define STATUS_CMD_ILLEGAL_PARAMETER 0xCA
// Status
#define STATUS_CONN_FAIL_MOSI 0x01
#define STATUS_CONN_FAIL_RST 0x02
#define STATUS_CONN_FAIL_SCK 0x04
#define STATUS_TGT_NOT_DETECTED 0x00
#define STATUS_ISP_READY 0x10
#define STATUS_TGT_REVERSE_INSERTED 0x20
// hw_status
// Bits in status variable
// Bit 0-3: Slave MCU
// Bit 4-7: Master MCU
#define STATUS_AREF_ERROR 0
// Set to '1' if AREF is short circuited
#define STATUS_VTG_ERROR 4
// Set to '1' if VTG is short circuited
#define STATUS_RC_CARD_ERROR 5
// Set to '1' if board id changes when board is powered
#define STATUS_PROGMODE 6
// Set to '1' if board is in programming mode
#define STATUS_POWER_SURGE 7
// Set to '1' if board draws excessive current
// *****************[ STK parameter constants ]***************************
#define PARAM_BUILD_NUMBER_LOW 0x80
#define PARAM_BUILD_NUMBER_HIGH 0x81
#define PARAM_BUILD_NUMBER_LOW 0x80 /* ??? */
#define PARAM_BUILD_NUMBER_HIGH 0x81 /* ??? */
#define PARAM_HW_VER 0x90
#define PARAM_SW_MAJOR 0x91
#define PARAM_SW_MINOR 0x92
#define PARAM_VTARGET 0x94
#define PARAM_VADJUST 0x95
#define PARAM_OSC_PSCALE 0x96
#define PARAM_OSC_CMATCH 0x97
#define PARAM_SCK_DURATION 0x98
#define PARAM_TOPCARD_DETECT 0x9A
#define PARAM_STATUS 0x9C
#define PARAM_DATA 0x9D
#define PARAM_RESET_POLARITY 0x9E
#define PARAM_VADJUST 0x95 /* STK500 only */
#define PARAM_OSC_PSCALE 0x96 /* STK500 only */
#define PARAM_OSC_CMATCH 0x97 /* STK500 only */
#define PARAM_SCK_DURATION 0x98 /* STK500 only */
#define PARAM_TOPCARD_DETECT 0x9A /* STK500 only */
#define PARAM_STATUS 0x9C /* STK500 only */
#define PARAM_DATA 0x9D /* STK500 only */
#define PARAM_RESET_POLARITY 0x9E /* STK500 only, and STK600 FW
* version <= 2.0.3 */
#define PARAM_CONTROLLER_INIT 0x9F
/* STK600 parameters */
#define PARAM_STATUS_TGT_CONN 0xA1
#define PARAM_DISCHARGEDELAY 0xA4
#define PARAM_SOCKETCARD_ID 0xA5
#define PARAM_ROUTINGCARD_ID 0xA6
#define PARAM_EXPCARD_ID 0xA7
#define PARAM_SW_MAJOR_SLAVE1 0xA8
#define PARAM_SW_MINOR_SLAVE1 0xA9
#define PARAM_SW_MAJOR_SLAVE2 0xAA
#define PARAM_SW_MINOR_SLAVE2 0xAB
#define PARAM_BOARD_ID_STATUS 0xAD
#define PARAM_RESET 0xB4
#define PARAM_JTAG_ALLOW_FULL_PAGE_STREAM 0x50
#define PARAM_JTAG_EEPROM_PAGE_SIZE 0x52
#define PARAM_JTAG_DAISY_BITS_BEFORE 0x53
#define PARAM_JTAG_DAISY_BITS_AFTER 0x54
#define PARAM_JTAG_DAISY_UNITS_BEFORE 0x55
#define PARAM_JTAG_DAISY_UNITS_AFTER 0x56
// *** Parameter constants for 2 byte values ***
#define PARAM2_SCK_DURATION 0xC0
#define PARAM2_CLOCK_CONF 0xC1
#define PARAM2_AREF0 0xC2
#define PARAM2_AREF1 0xC3
#define PARAM2_JTAG_FLASH_SIZE_H 0xC5
#define PARAM2_JTAG_FLASH_SIZE_L 0xC6
#define PARAM2_JTAG_FLASH_PAGE_SIZE 0xC7
#define PARAM2_RC_ID_TABLE_REV 0xC8
#define PARAM2_EC_ID_TABLE_REV 0xC9
/* STK600 XPROG section */
// XPROG commands
#define XPRG_CMD_ENTER_PROGMODE 0x01
#define XPRG_CMD_LEAVE_PROGMODE 0x02
#define XPRG_CMD_ERASE 0x03
#define XPRG_CMD_WRITE_MEM 0x04
#define XPRG_CMD_READ_MEM 0x05
#define XPRG_CMD_CRC 0x06
#define XPRG_CMD_SET_PARAM 0x07
// Memory types
#define XPRG_MEM_TYPE_APPL 1
#define XPRG_MEM_TYPE_BOOT 2
#define XPRG_MEM_TYPE_EEPROM 3
#define XPRG_MEM_TYPE_FUSE 4
#define XPRG_MEM_TYPE_LOCKBITS 5
#define XPRG_MEM_TYPE_USERSIG 6
#define XPRG_MEM_TYPE_FACTORY_CALIBRATION 7
// Erase types
#define XPRG_ERASE_CHIP 1
#define XPRG_ERASE_APP 2
#define XPRG_ERASE_BOOT 3
#define XPRG_ERASE_EEPROM 4
#define XPRG_ERASE_APP_PAGE 5
#define XPRG_ERASE_BOOT_PAGE 6
#define XPRG_ERASE_EEPROM_PAGE 7
#define XPRG_ERASE_USERSIG 8
// Write mode flags
#define XPRG_MEM_WRITE_ERASE 0
#define XPRG_MEM_WRITE_WRITE 1
// CRC types
#define XPRG_CRC_APP 1
#define XPRG_CRC_BOOT 2
#define XPRG_CRC_FLASH 3
// Error codes
#define XPRG_ERR_OK 0
#define XPRG_ERR_FAILED 1
#define XPRG_ERR_COLLISION 2
#define XPRG_ERR_TIMEOUT 3
// XPROG parameters of different sizes
// 4-byte address
#define XPRG_PARAM_NVMBASE 0x01
// 2-byte page size
#define XPRG_PARAM_EEPPAGESIZE 0x02
// *****************[ STK answer constants ]***************************
#define ANSWER_CKSUM_ERROR 0xB0

View File

@@ -34,6 +34,7 @@
#endif
#endif
#include "avrdude.h"
#include "avr.h"
#include "config.h"
#include "lists.h"
@@ -41,12 +42,6 @@
#include "pindefs.h"
#include "ppi.h"
extern char * progname;
extern char progbuf[];
extern PROGRAMMER * pgm;
struct command {
char * name;
int (*func)(PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
@@ -54,32 +49,50 @@ struct command {
};
int cmd_dump (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
static int cmd_dump (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
int cmd_write (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
static int cmd_write (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
int cmd_erase (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
static int cmd_erase (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
int cmd_sig (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
static int cmd_sig (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
int cmd_part (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
static int cmd_part (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
int cmd_help (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
static int cmd_help (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
int cmd_quit (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
static int cmd_quit (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
int cmd_send (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
static int cmd_send (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
int cmd_parms (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
static int cmd_parms (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
int cmd_vtarg (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
static int cmd_vtarg (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
int cmd_varef (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
static int cmd_varef (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
int cmd_fosc (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
static int cmd_fosc (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
int cmd_sck (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
static int cmd_sck (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
static int cmd_spi (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
static int cmd_pgm (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
struct command cmd[] = {
{ "dump", cmd_dump, "dump memory : %s <memtype> <addr> <N-Bytes>" },
@@ -94,6 +107,8 @@ struct command cmd[] = {
{ "varef", cmd_varef, "set <V[aref]> (STK500 only)" },
{ "fosc", cmd_fosc, "set <oscillator frequency> (STK500 only)" },
{ "sck", cmd_sck, "set <SCK period> (STK500 only)" },
{ "spi", cmd_spi, "enter direct SPI mode" },
{ "pgm", cmd_pgm, "return to programming mode" },
{ "help", cmd_help, "help" },
{ "?", cmd_help, "help" },
{ "quit", cmd_quit, "quit" }
@@ -103,9 +118,9 @@ struct command cmd[] = {
static int spi_mode = 0;
int nexttok(char * buf, char ** tok, char ** next)
static int nexttok(char * buf, char ** tok, char ** next)
{
char * q, * n;
@@ -134,7 +149,7 @@ int nexttok(char * buf, char ** tok, char ** next)
}
int hexdump_line(char * buffer, unsigned char * p, int n, int pad)
static int hexdump_line(char * buffer, unsigned char * p, int n, int pad)
{
char * hexdata = "0123456789abcdef";
char * b;
@@ -166,7 +181,7 @@ int hexdump_line(char * buffer, unsigned char * p, int n, int pad)
}
int chardump_line(char * buffer, unsigned char * p, int n, int pad)
static int chardump_line(char * buffer, unsigned char * p, int n, int pad)
{
int i;
char b [ 128 ];
@@ -189,7 +204,7 @@ int chardump_line(char * buffer, unsigned char * p, int n, int pad)
}
int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len)
static int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len)
{
int addr;
int i, n;
@@ -216,7 +231,8 @@ int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len)
}
int cmd_dump(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
static char prevmem[128] = {0};
char * e;
@@ -315,7 +331,8 @@ int cmd_dump(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
}
int cmd_write(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
char * e;
int len, maxsize;
@@ -420,7 +437,8 @@ int cmd_write(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
}
int cmd_send(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
static int cmd_send(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
unsigned char cmd[4], res[4];
char * e;
@@ -434,8 +452,18 @@ int cmd_send(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
return -1;
}
if (argc != 5) {
fprintf(stderr, "Usage: send <byte1> <byte2> <byte3> <byte4>\n");
if (spi_mode && (pgm->spi == NULL)) {
fprintf(stderr,
"The %s programmer does not support direct SPI transfers.\n",
pgm->type);
return -1;
}
if ((argc > 5) || ((argc < 5) && (!spi_mode))) {
fprintf(stderr, spi_mode?
"Usage: send <byte1> [<byte2> [<byte3> [<byte4>]]]\n":
"Usage: send <byte1> <byte2> <byte3> <byte4>\n");
return -1;
}
@@ -454,7 +482,10 @@ int cmd_send(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
pgm->err_led(pgm, OFF);
pgm->cmd(pgm, cmd, res);
if (spi_mode)
pgm->spi(pgm, cmd, res, argc-1);
else
pgm->cmd(pgm, cmd, res);
/*
* display results
@@ -470,7 +501,8 @@ int cmd_send(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
}
int cmd_erase(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
static int cmd_erase(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
fprintf(stderr, "%s: erasing chip\n", progname);
pgm->chip_erase(pgm, p);
@@ -478,7 +510,8 @@ int cmd_erase(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
}
int cmd_part(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
static int cmd_part(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
fprintf(stdout, "\n");
avr_display(stdout, p, "", 0);
@@ -488,7 +521,8 @@ int cmd_part(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
}
int cmd_sig(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
static int cmd_sig(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
int i;
int rc;
@@ -517,13 +551,15 @@ int cmd_sig(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
}
int cmd_quit(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
static int cmd_quit(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
return 1;
}
int cmd_parms(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
static int cmd_parms(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
if (pgm->print_parms == NULL) {
fprintf(stderr,
@@ -538,7 +574,8 @@ int cmd_parms(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
}
int cmd_vtarg(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
static int cmd_vtarg(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
int rc;
double v;
@@ -568,7 +605,8 @@ int cmd_vtarg(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
}
int cmd_fosc(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
static int cmd_fosc(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
int rc;
double v;
@@ -607,7 +645,8 @@ int cmd_fosc(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
}
int cmd_sck(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
static int cmd_sck(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
int rc;
double v;
@@ -639,28 +678,46 @@ int cmd_sck(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
}
int cmd_varef(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
static int cmd_varef(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
int rc;
unsigned int chan;
double v;
char *endp;
if (argc != 2) {
fprintf(stderr, "Usage: varef <value>\n");
if (argc != 2 && argc != 3) {
fprintf(stderr, "Usage: varef [channel] <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 (argc == 2) {
chan = 0;
v = strtod(argv[1], &endp);
if (endp == argv[1]) {
fprintf(stderr, "%s (varef): can't parse voltage \"%s\"\n",
progname, argv[1]);
return -1;
}
} else {
chan = strtoul(argv[1], &endp, 10);
if (endp == argv[1]) {
fprintf(stderr, "%s (varef): can't parse channel \"%s\"\n",
progname, argv[1]);
return -1;
}
v = strtod(argv[2], &endp);
if (endp == argv[2]) {
fprintf(stderr, "%s (varef): can't parse voltage \"%s\"\n",
progname, argv[2]);
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) {
if ((rc = pgm->set_varef(pgm, chan, v)) != 0) {
fprintf(stderr, "%s (varef): failed to set V[aref] (rc = %d)\n",
progname, rc);
return -3;
@@ -669,7 +726,8 @@ int cmd_varef(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
}
int cmd_help(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
static int cmd_help(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
int i;
@@ -686,8 +744,24 @@ int cmd_help(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
return 0;
}
static int cmd_spi(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1);
spi_mode = 1;
return 0;
}
int tokenize(char * s, char *** argv)
static int cmd_pgm(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 0);
spi_mode = 0;
pgm->initialize(pgm, p);
return 0;
}
static int tokenize(char * s, char *** argv)
{
int i, n, l, nargs, offset;
int len, slen;
@@ -764,7 +838,8 @@ int tokenize(char * s, char *** argv)
}
int do_cmd(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
static int do_cmd(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
int i;
int hold;

View File

@@ -19,13 +19,21 @@
/* $Id$ */
#ifndef __term_h__
#define __term_h__
#ifndef term_h
#define term_h
#include "avr.h"
#include "pgm.h"
#ifdef __cplusplus
extern "C" {
#endif
int terminal_mode(PROGRAMMER * pgm, struct avrpart * p);
char * terminal_get_input(const char *prompt);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding='ISO-8859-1' ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--
* Copyright (c) 2008 Joerg Wunsch
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*
* $Id$
-->
<!--
* Extract STK600 routing and socket card information out of
* targetboards.xml.
*
* Run this like:
*
* xsltproc -param what "'RC'" \
* tools/get-stk600-cards.xsl targetboard.xml | sort -u
*
* xsltproc -param what "'SC'" \
* tools/get-stk600-cards.xsl targetboard.xml | sort -u
*
* and copy&paste the results into the respective tables.
-->
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:if test="$what = 'RC'">
<xsl:for-each select="/STK600/ROUTING/CARD">
<xsl:if test="RC_NAME != ''">
<xsl:text> { </xsl:text>
<xsl:value-of select="RC_ID" />
<xsl:text>, &#034;</xsl:text>
<xsl:value-of select="RC_NAME" />
<xsl:text>&#034; },&#010;</xsl:text>
</xsl:if>
</xsl:for-each> <!-- All cards -->
</xsl:if> <!-- Routing cards -->
<xsl:if test="$what = 'SC'">
<xsl:for-each select="/STK600/ROUTING/CARD">
<xsl:if test="SC_NAME != ''">
<xsl:text> { </xsl:text>
<xsl:value-of select="SC_ID" />
<xsl:text>, &#034;</xsl:text>
<xsl:value-of select="SC_NAME" />
<xsl:text>&#034; },&#010;</xsl:text>
</xsl:if>
</xsl:for-each> <!-- All cards -->
</xsl:if> <!-- Socket cards -->
</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding='ISO-8859-1' ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--
* Copyright (c) 2008 Joerg Wunsch
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*
* $Id$
-->
<!--
* Extract STK600 device support out of
* targetboards.xml.
*
* Run this like:
*
* xsltproc \
* tools/get-stk600-devices.xsl targetboard.xml
*
* and copy&paste the results into the respective table.
-->
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:text>@multitable @columnfractions .15 .15 .6&#010;</xsl:text>
<xsl:text>Routing card @tab Socket card @tab Devices&#010;</xsl:text>
<xsl:for-each select="/STK600/ROUTING/CARD">
<xsl:text>@item @code{</xsl:text>
<xsl:value-of select="RC_NAME" />
<xsl:text>} @tab @code{</xsl:text>
<xsl:value-of select="SC_NAME" />
<xsl:text>} @tab</xsl:text>
<xsl:for-each select="TARGET">
<xsl:text> </xsl:text>
<xsl:value-of select="NAME" />
</xsl:for-each>
<xsl:text>&#010;</xsl:text>
</xsl:for-each> <!-- All cards -->
<xsl:text>@end multitable&#010;</xsl:text>
</xsl:template>
</xsl:stylesheet>

373
avrdude/update.c Normal file
View File

@@ -0,0 +1,373 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2005 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2007 Joerg Wunsch
*
* 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 <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include "avrdude.h"
#include "avr.h"
#include "config.h"
#include "confwin.h"
#include "fileio.h"
#include "update.h"
UPDATE * parse_op(char * s)
{
char buf[1024];
char * p, * cp, c;
UPDATE * upd;
int i;
size_t fnlen;
upd = (UPDATE *)malloc(sizeof(UPDATE));
if (upd == NULL) {
fprintf(stderr, "%s: out of memory\n", progname);
exit(1);
}
i = 0;
p = s;
while ((i < (sizeof(buf)-1) && *p && (*p != ':')))
buf[i++] = *p++;
if (*p != ':') {
upd->memtype = (char *)malloc(strlen("flash")+1);
if (upd->memtype == NULL) {
outofmem:
fprintf(stderr, "%s: out of memory\n", progname);
exit(1);
}
strcpy(upd->memtype, "flash");
upd->op = DEVICE_WRITE;
upd->filename = (char *)malloc(strlen(buf) + 1);
if (upd->filename == NULL)
goto outofmem;
strcpy(upd->filename, buf);
upd->format = FMT_AUTO;
return upd;
}
buf[i] = 0;
upd->memtype = (char *)malloc(strlen(buf)+1);
if (upd->memtype == NULL) {
fprintf(stderr, "%s: out of memory\n", progname);
exit(1);
}
strcpy(upd->memtype, buf);
p++;
if (*p == 'r') {
upd->op = DEVICE_READ;
}
else if (*p == 'w') {
upd->op = DEVICE_WRITE;
}
else if (*p == 'v') {
upd->op = DEVICE_VERIFY;
}
else {
fprintf(stderr, "%s: invalid I/O mode '%c' in update specification\n",
progname, *p);
fprintf(stderr,
" allowed values are:\n"
" r = read device\n"
" w = write device\n"
" v = verify device\n");
free(upd->memtype);
free(upd);
return NULL;
}
p++;
if (*p != ':') {
fprintf(stderr, "%s: invalid update specification\n", progname);
free(upd->memtype);
free(upd);
return NULL;
}
p++;
/*
* Now, parse the filename component. Instead of looking for the
* leftmost possible colon delimiter, we look for the rightmost one.
* If we found one, we do have a trailing :format specifier, and
* process it. Otherwise, the remainder of the string is our file
* name component. That way, the file name itself is allowed to
* contain a colon itself (e. g. C:/some/file.hex), except the
* optional format specifier becomes mandatory then.
*/
cp = p;
p = strrchr(cp, ':');
if (p == NULL) {
upd->format = FMT_AUTO;
fnlen = strlen(cp);
upd->filename = (char *)malloc(fnlen + 1);
} else {
fnlen = p - cp;
upd->filename = (char *)malloc(fnlen +1);
c = *++p;
if (c && p[1])
/* More than one char - force failure below. */
c = '?';
switch (c) {
case 'a': upd->format = FMT_AUTO; break;
case 's': upd->format = FMT_SREC; break;
case 'i': upd->format = FMT_IHEX; break;
case 'r': upd->format = FMT_RBIN; break;
case 'm': upd->format = FMT_IMM; break;
case 'b': upd->format = FMT_BIN; break;
case 'd': upd->format = FMT_DEC; break;
case 'h': upd->format = FMT_HEX; break;
case 'o': upd->format = FMT_OCT; break;
default:
fprintf(stderr, "%s: invalid file format '%s' in update specifier\n",
progname, p);
free(upd->memtype);
free(upd);
return NULL;
}
}
if (upd->filename == NULL) {
fprintf(stderr, "%s: out of memory\n", progname);
free(upd->memtype);
free(upd);
return NULL;
}
memcpy(upd->filename, cp, fnlen);
upd->filename[fnlen] = 0;
return upd;
}
UPDATE * dup_update(UPDATE * upd)
{
UPDATE * u;
u = (UPDATE *)malloc(sizeof(UPDATE));
if (u == NULL) {
fprintf(stderr, "%s: out of memory\n", progname);
exit(1);
}
memcpy(u, upd, sizeof(UPDATE));
u->memtype = strdup(upd->memtype);
u->filename = strdup(upd->filename);
return u;
}
UPDATE * new_update(int op, char * memtype, int filefmt, char * filename)
{
UPDATE * u;
u = (UPDATE *)malloc(sizeof(UPDATE));
if (u == NULL) {
fprintf(stderr, "%s: out of memory\n", progname);
exit(1);
}
u->memtype = strdup(memtype);
u->filename = strdup(filename);
u->op = op;
u->format = filefmt;
return u;
}
int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite,
int verify)
{
struct avrpart * v;
AVRMEM * mem;
int size, vsize;
int rc;
mem = avr_locate_mem(p, upd->memtype);
if (mem == NULL) {
fprintf(stderr, "\"%s\" memory type not defined for part \"%s\"\n",
upd->memtype, p->desc);
return -1;
}
if (upd->op == DEVICE_READ) {
/*
* read out the specified device memory and write it to a file
*/
if (quell_progress < 2) {
fprintf(stderr, "%s: reading %s memory:\n",
progname, mem->desc);
}
report_progress(0,1,"Reading");
rc = avr_read(pgm, p, upd->memtype, 0, 1);
if (rc < 0) {
fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
progname, mem->desc, rc);
return -1;
}
report_progress(1,1,NULL);
size = rc;
if (quell_progress < 2) {
fprintf(stderr,
"%s: writing output file \"%s\"\n",
progname,
strcmp(upd->filename, "-")==0 ? "<stdout>" : upd->filename);
}
rc = fileio(FIO_WRITE, upd->filename, upd->format, p, upd->memtype, size);
if (rc < 0) {
fprintf(stderr, "%s: write to file '%s' failed\n",
progname, upd->filename);
return -1;
}
}
else if (upd->op == DEVICE_WRITE) {
/*
* write the selected device memory using data from a file; first
* read the data from the specified file
*/
if (quell_progress < 2) {
fprintf(stderr,
"%s: reading input file \"%s\"\n",
progname,
strcmp(upd->filename, "-")==0 ? "<stdin>" : upd->filename);
}
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
if (rc < 0) {
fprintf(stderr, "%s: write to file '%s' failed\n",
progname, upd->filename);
return -1;
}
size = rc;
/*
* write the buffer contents to the selected memory type
*/
if (quell_progress < 2) {
fprintf(stderr, "%s: writing %s (%d bytes):\n",
progname, mem->desc, size);
}
if (!nowrite) {
report_progress(0,1,"Writing");
rc = avr_write(pgm, p, upd->memtype, size, 1);
report_progress(1,1,NULL);
}
else {
/*
* test mode, don't actually write to the chip, output the buffer
* to stdout in intel hex instead
*/
rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, upd->memtype, size);
}
if (rc < 0) {
fprintf(stderr, "%s: failed to write %s memory, rc=%d\n",
progname, mem->desc, rc);
return -1;
}
vsize = rc;
if (quell_progress < 2) {
fprintf(stderr, "%s: %d bytes of %s written\n", progname,
vsize, mem->desc);
}
}
else if (upd->op == DEVICE_VERIFY) {
/*
* verify that the in memory file (p->mem[AVR_M_FLASH|AVR_M_EEPROM])
* is the same as what is on the chip
*/
pgm->vfy_led(pgm, ON);
v = avr_dup_part(p);
if (quell_progress < 2) {
fprintf(stderr, "%s: verifying %s memory against %s:\n",
progname, mem->desc, upd->filename);
fprintf(stderr, "%s: load data %s data from input file %s:\n",
progname, mem->desc, upd->filename);
}
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
if (rc < 0) {
fprintf(stderr, "%s: read from file '%s' failed\n",
progname, upd->filename);
return -1;
}
size = rc;
if (quell_progress < 2) {
fprintf(stderr, "%s: input file %s contains %d bytes\n",
progname, upd->filename, size);
fprintf(stderr, "%s: reading on-chip %s data:\n",
progname, mem->desc);
}
report_progress (0,1,"Reading");
rc = avr_read(pgm, v, upd->memtype, size, 1);
if (rc < 0) {
fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
progname, mem->desc, rc);
pgm->err_led(pgm, ON);
return -1;
}
report_progress (1,1,NULL);
if (quell_progress < 2) {
fprintf(stderr, "%s: verifying ...\n", progname);
}
rc = avr_verify(p, v, upd->memtype, size);
if (rc < 0) {
fprintf(stderr, "%s: verification error; content mismatch\n",
progname);
pgm->err_led(pgm, ON);
return -1;
}
if (quell_progress < 2) {
fprintf(stderr, "%s: %d bytes of %s verified\n",
progname, rc, mem->desc);
}
pgm->vfy_led(pgm, OFF);
}
else {
fprintf(stderr, "%s: invalid update operation (%d) requested\n",
progname, upd->op);
return -1;
}
return 0;
}

55
avrdude/update.h Normal file
View File

@@ -0,0 +1,55 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2005 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2007 Joerg Wunsch
*
* 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 update_h
#define update_h
enum {
DEVICE_READ,
DEVICE_WRITE,
DEVICE_VERIFY
};
typedef struct update_t {
char * memtype;
int op;
char * filename;
int format;
} UPDATE;
#ifdef __cplusplus
extern "C" {
#endif
extern UPDATE * parse_op(char * s);
extern UPDATE * dup_update(UPDATE * upd);
extern UPDATE * new_update(int op, char * memtype, int filefmt,
char * filename);
extern int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd,
int nowrite, int verify);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -38,11 +38,14 @@
#include <usb.h>
#include "avrdude.h"
#include "serial.h"
#include "usbdevs.h"
extern char *progname;
extern int verbose;
#if defined(WIN32NATIVE)
/* someone has defined "interface" to "struct" in Cygwin */
# undef interface
#endif
static char usbbuf[USBDEV_MAX_XFER];
static int buflen = -1, bufptr;
@@ -61,6 +64,7 @@ static void usbdev_open(char * port, long baud, union filedescriptor *fd)
struct usb_device *dev;
usb_dev_handle *udev;
char *serno, *cp2;
int i;
size_t x;
/*
@@ -189,7 +193,33 @@ static void usbdev_open(char * port, long baud, union filedescriptor *fd)
goto trynext;
}
fd->pfd = udev;
fd->usb.handle = udev;
fd->usb.ep = -1;
/* Try finding out what our read endpoint is. */
for (i = 0; i < dev->config[0].interface[0].altsetting[0].bNumEndpoints; i++)
{
int possible_ep = dev->config[0].interface[0].altsetting[0].
endpoint[i].bEndpointAddress;
if ((possible_ep & USB_ENDPOINT_DIR_MASK) != 0)
{
if (verbose > 1)
{
fprintf(stderr,
"%s: usbdev_open(): using read endpoint 0x%02x\n",
progname, possible_ep);
}
fd->usb.ep = possible_ep;
break;
}
}
if (fd->usb.ep == -1)
{
fprintf(stderr,
"%s: usbdev_open(): cannot find a read endpoint, using 0x%02x\n",
progname, USBDEV_BULK_EP_READ);
fd->usb.ep = USBDEV_BULK_EP_READ;
}
return;
}
trynext:
@@ -205,15 +235,18 @@ static void usbdev_open(char * port, long baud, union filedescriptor *fd)
static void usbdev_close(union filedescriptor *fd)
{
usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
(void)usb_release_interface(udev, usb_interface);
#if defined(__FreeBSD__)
/*
* Without this reset, the AVRISP mkII seems to stall the second
* time we try to connect to it.
* time we try to connect to it. This is not necessary on
* FreeBSD.
*/
usb_reset(udev);
#endif
usb_close(udev);
}
@@ -221,7 +254,7 @@ static void usbdev_close(union filedescriptor *fd)
static int usbdev_send(union filedescriptor *fd, unsigned char *bp, size_t mlen)
{
usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
int rv;
int i = mlen;
unsigned char * p = bp;
@@ -278,11 +311,11 @@ static int usbdev_send(union filedescriptor *fd, unsigned char *bp, size_t mlen)
* empty and more data are requested.
*/
static int
usb_fill_buf(usb_dev_handle *udev)
usb_fill_buf(usb_dev_handle *udev, int ep)
{
int rv;
rv = usb_bulk_read(udev, USBDEV_BULK_EP_READ, usbbuf, USBDEV_MAX_XFER, 5000);
rv = usb_bulk_read(udev, ep, usbbuf, USBDEV_MAX_XFER, 5000);
if (rv < 0)
{
if (verbose > 1)
@@ -299,7 +332,7 @@ usb_fill_buf(usb_dev_handle *udev)
static int usbdev_recv(union filedescriptor *fd, unsigned char *buf, size_t nbytes)
{
usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
int i, amnt;
unsigned char * p = buf;
@@ -307,7 +340,7 @@ static int usbdev_recv(union filedescriptor *fd, unsigned char *buf, size_t nbyt
{
if (buflen <= bufptr)
{
if (usb_fill_buf(udev) < 0)
if (usb_fill_buf(udev, fd->usb.ep) < 0)
return -1;
}
amnt = buflen - bufptr > nbytes? nbytes: buflen - bufptr;
@@ -351,7 +384,7 @@ static int usbdev_recv(union filedescriptor *fd, unsigned char *buf, size_t nbyt
*/
static int usbdev_recv_frame(union filedescriptor *fd, unsigned char *buf, size_t nbytes)
{
usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
int rv, n;
int i;
unsigned char * p = buf;
@@ -359,7 +392,7 @@ static int usbdev_recv_frame(union filedescriptor *fd, unsigned char *buf, size_
n = 0;
do
{
rv = usb_bulk_read(udev, USBDEV_BULK_EP_READ, usbbuf,
rv = usb_bulk_read(udev, fd->usb.ep, usbbuf,
USBDEV_MAX_XFER, 10000);
if (rv < 0)
{
@@ -408,11 +441,11 @@ static int usbdev_recv_frame(union filedescriptor *fd, unsigned char *buf, size_
static int usbdev_drain(union filedescriptor *fd, int display)
{
usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
int rv;
do {
rv = usb_bulk_read(udev, USBDEV_BULK_EP_READ, usbbuf, USBDEV_MAX_XFER, 100);
rv = usb_bulk_read(udev, fd->usb.ep, usbbuf, USBDEV_MAX_XFER, 100);
if (rv > 0 && verbose >= 4)
fprintf(stderr, "%s: usbdev_drain(): flushed %d characters\n",
progname, rv);

View File

@@ -1,6 +1,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2006 Thomas Fischl
* Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
*
* 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
@@ -33,6 +34,7 @@
#include <sys/time.h>
#include <unistd.h>
#include "avrdude.h"
#include "avr.h"
#include "pgm.h"
#include "usbasp.h"
@@ -40,25 +42,47 @@
#ifdef HAVE_LIBUSB
#include <usb.h>
extern int verbose;
extern char * progname;
extern int do_cycles;
/*
* Private data for this programmer.
*/
struct pdata
{
usb_dev_handle *usbhandle;
};
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
static void usbasp_setup(PROGRAMMER * pgm)
{
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
fprintf(stderr,
"%s: usbasp_setup(): Out of memory allocating private data\n",
progname);
exit(1);
}
memset(pgm->cookie, 0, sizeof(struct pdata));
}
static void usbasp_teardown(PROGRAMMER * pgm)
{
free(pgm->cookie);
}
static usb_dev_handle *usbhandle;
/*
* wrapper for usb_control_msg call
*/
static int usbasp_transmit(unsigned char receive, unsigned char functionid,
static int usbasp_transmit(PROGRAMMER * pgm,
unsigned char receive, unsigned char functionid,
unsigned char send[4], unsigned char * buffer, int buffersize)
{
int nbytes;
nbytes = usb_control_msg(usbhandle,
nbytes = usb_control_msg(PDATA(pgm)->usbhandle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | (receive << 7),
functionid,
(send[1] << 8) | send[0],
(send[3] << 8) | send[2],
buffer, buffersize,
(char *)buffer, buffersize,
5000);
if(nbytes < 0){
fprintf(stderr, "%s: error: usbasp_transmit: %s\n", progname, usb_strerror());
@@ -161,11 +185,11 @@ static int usbasp_open(PROGRAMMER * pgm, char * port)
{
usb_init();
if (usbOpenDevice(&usbhandle, USBASP_SHARED_VID, "www.fischl.de",
if (usbOpenDevice(&PDATA(pgm)->usbhandle, USBASP_SHARED_VID, "www.fischl.de",
USBASP_SHARED_PID, "USBasp") != 0) {
/* check if device with old VID/PID is available */
if (usbOpenDevice(&usbhandle, USBASP_OLD_VID, "www.fischl.de",
if (usbOpenDevice(&PDATA(pgm)->usbhandle, USBASP_OLD_VID, "www.fischl.de",
USBASP_OLD_PID, "USBasp") != 0) {
/* no USBasp found */
@@ -193,9 +217,9 @@ static void usbasp_close(PROGRAMMER * pgm)
{
unsigned char temp[4];
memset(temp, 0, sizeof(temp));
usbasp_transmit(1, USBASP_FUNC_DISCONNECT, temp, temp, sizeof(temp));
usbasp_transmit(pgm, 1, USBASP_FUNC_DISCONNECT, temp, temp, sizeof(temp));
usb_close(usbhandle);
usb_close(PDATA(pgm)->usbhandle);
}
@@ -204,12 +228,11 @@ static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p)
unsigned char temp[4];
memset(temp, 0, sizeof(temp));
usbasp_transmit(1, USBASP_FUNC_CONNECT, temp, temp, sizeof(temp));
usbasp_transmit(pgm, 1, USBASP_FUNC_CONNECT, temp, temp, sizeof(temp));
usleep(100000);
pgm->program_enable(pgm, p);
return 0;
return pgm->program_enable(pgm, p);
}
static void usbasp_disable(PROGRAMMER * pgm)
@@ -226,7 +249,7 @@ static void usbasp_enable(PROGRAMMER * pgm)
return;
}
static void usbasp_display(PROGRAMMER * pgm, char * p)
static void usbasp_display(PROGRAMMER * pgm, const char * p)
{
return;
}
@@ -236,7 +259,7 @@ static int usbasp_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
unsigned char res[4])
{
int nbytes =
usbasp_transmit(1, USBASP_FUNC_TRANSMIT, cmd, res, sizeof(res));
usbasp_transmit(pgm, 1, USBASP_FUNC_TRANSMIT, cmd, res, sizeof(res));
if(nbytes != 4){
fprintf(stderr, "%s: error: wrong responds size\n",
@@ -258,7 +281,7 @@ static int usbasp_program_enable(PROGRAMMER * pgm, AVRPART * p)
cmd[0] = 0;
int nbytes =
usbasp_transmit(1, USBASP_FUNC_ENABLEPROG, cmd, res, sizeof(res));
usbasp_transmit(pgm, 1, USBASP_FUNC_ENABLEPROG, cmd, res, sizeof(res));
if ((nbytes != 1) | (res[0] != 0)) {
fprintf(stderr, "%s: error: programm enable: target doesn't answer. %x \n",
@@ -320,10 +343,24 @@ static int usbasp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
wbytes = 0;
}
/* set address (new mode) - if firmware on usbasp support newmode, then they use address from this command */
unsigned char temp[4];
memset(temp, 0, sizeof(temp));
cmd[0] = address & 0xFF;
cmd[1] = address >> 8;
cmd[2] = address >> 16;
cmd[3] = address >> 24;
usbasp_transmit(pgm, 1, USBASP_FUNC_SETLONGADDRESS, cmd, temp, sizeof(temp));
/* send command with address (compatibility mode) - if firmware on
usbasp doesn't support newmode, then they use address from this */
cmd[0] = address & 0xFF;
cmd[1] = address >> 8;
// for compatibility - previous version of usbasp.c doesn't initialize this fields (firmware ignore it)
cmd[2] = 0;
cmd[3] = 0;
n = usbasp_transmit(1, function, cmd, buffer, blocksize);
n = usbasp_transmit(pgm, 1, function, cmd, buffer, blocksize);
if (n != blocksize) {
fprintf(stderr, "%s: error: wrong reading bytes %x\n",
@@ -370,13 +407,26 @@ static int usbasp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
blockflags |= USBASP_BLOCKFLAG_LAST;
}
/* set address (new mode) - if firmware on usbasp support newmode, then
they use address from this command */
unsigned char temp[4];
memset(temp, 0, sizeof(temp));
cmd[0] = address & 0xFF;
cmd[1] = address >> 8;
cmd[2] = address >> 16;
cmd[3] = address >> 24;
usbasp_transmit(pgm, 1, USBASP_FUNC_SETLONGADDRESS, cmd, temp, sizeof(temp));
/* normal command - firmware what support newmode - use address from previous command,
firmware what doesn't support newmode - ignore previous command and use address from this command */
cmd[0] = address & 0xFF;
cmd[1] = address >> 8;
cmd[2] = page_size & 0xFF;
cmd[3] = (blockflags & 0x0F) + ((page_size & 0xF00) >> 4); //TP: Mega128 fix
blockflags = 0;
n = usbasp_transmit(0, function, cmd, buffer, blocksize);
n = usbasp_transmit(pgm, 0, function, cmd, buffer, blocksize);
if (n != blocksize) {
fprintf(stderr, "%s: error: wrong count at writing %x\n",
@@ -420,14 +470,14 @@ void usbasp_initpgm(PROGRAMMER * pgm)
pgm->paged_write = usbasp_paged_write;
pgm->paged_load = usbasp_paged_load;
pgm->setup = usbasp_setup;
pgm->teardown = usbasp_teardown;
}
#else /* HAVE_LIBUSB */
extern char * progname;
static int usbasp_nousb_open (struct programmer_t *pgm, char * name)
{
fprintf(stderr, "%s: error: no usb support. please compile again with libusb installed.\n",

View File

@@ -39,6 +39,7 @@
#define USBASP_FUNC_WRITEFLASH 6
#define USBASP_FUNC_READEEPROM 7
#define USBASP_FUNC_WRITEEEPROM 8
#define USBASP_FUNC_SETLONGADDRESS 9
#define USBASP_BLOCKFLAG_FIRST 1
#define USBASP_BLOCKFLAG_LAST 2
@@ -50,6 +51,14 @@
#define USB_ERROR_ACCESS 2
#define USB_ERROR_IO 3
#ifdef __cplusplus
extern "C" {
#endif
void usbasp_initpgm (PROGRAMMER * pgm);
#ifdef __cplusplus
}
#endif
#endif /* usbasp_h */

View File

@@ -29,6 +29,7 @@
#define USB_VENDOR_ATMEL 1003
#define USB_DEVICE_JTAGICEMKII 0x2103
#define USB_DEVICE_AVRISPMKII 0x2104
#define USB_DEVICE_STK600 0x2106
#define USB_DEVICE_AVRDRAGON 0x2107
/*

552
avrdude/usbtiny.c Normal file
View File

@@ -0,0 +1,552 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2007 Dick Streefland, adapted for 5.4 by Limor Fried
*
* 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
*/
/*
* Driver for "usbtiny"-type programmers
* Please see http://www.xs4all.nl/~dicks/avr/usbtiny/
* and http://www.ladyada.net/make/usbtinyisp/
* For example schematics and detailed documentation
*/
#include "ac_cfg.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <unistd.h>
#include "avrdude.h"
#include "avr.h"
#include "pgm.h"
#include "usbtiny.h"
#if defined(HAVE_LIBUSB) // we use LIBUSB to talk to the board
#include <usb.h>
#ifndef HAVE_UINT_T
typedef unsigned int uint_t;
#endif
#ifndef HAVE_ULONG_T
typedef unsigned long ulong_t;
#endif
extern int avr_write_byte_default ( PROGRAMMER* pgm, AVRPART* p,
AVRMEM* mem, ulong_t addr,
unsigned char data );
/*
* Private data for this programmer.
*/
struct pdata
{
usb_dev_handle *usb_handle;
int sck_period;
int chunk_size;
int retries;
};
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
// ----------------------------------------------------------------------
static void usbtiny_setup(PROGRAMMER * pgm)
{
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
fprintf(stderr,
"%s: usbtiny_setup(): Out of memory allocating private data\n",
progname);
exit(1);
}
memset(pgm->cookie, 0, sizeof(struct pdata));
}
static void usbtiny_teardown(PROGRAMMER * pgm)
{
free(pgm->cookie);
}
// Wrapper for simple usb_control_msg messages
static int usb_control (PROGRAMMER * pgm,
unsigned int requestid, unsigned int val, unsigned int index )
{
int nbytes;
nbytes = usb_control_msg( PDATA(pgm)->usb_handle,
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
requestid,
val, index, // 2 bytes each of data
NULL, 0, // no data buffer in control messge
USB_TIMEOUT ); // default timeout
if(nbytes < 0){
fprintf(stderr, "\n%s: error: usbtiny_transmit: %s\n", progname, usb_strerror());
return -1;
}
return nbytes;
}
// Wrapper for simple usb_control_msg messages to receive data from programmer
static int usb_in (PROGRAMMER * pgm,
unsigned int requestid, unsigned int val, unsigned int index,
unsigned char* buffer, int buflen, int bitclk )
{
int nbytes;
int timeout;
int i;
// calculate the amout of time we expect the process to take by
// figuring the bit-clock time and buffer size and adding to the standard USB timeout.
timeout = USB_TIMEOUT + (buflen * bitclk) / 1000;
for (i = 0; i < 10; i++) {
nbytes = usb_control_msg( PDATA(pgm)->usb_handle,
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
requestid,
val, index,
(char *)buffer, buflen,
timeout);
if (nbytes == buflen) {
return nbytes;
}
PDATA(pgm)->retries++;
}
fprintf(stderr, "\n%s: error: usbtiny_receive: %s (expected %d, got %d)\n",
progname, usb_strerror(), buflen, nbytes);
return -1;
}
// Report the number of retries, and reset the counter.
static void check_retries (PROGRAMMER * pgm, const char* operation)
{
if (PDATA(pgm)->retries > 0 && quell_progress < 2) {
printf("%s: %d retries during %s\n", progname,
PDATA(pgm)->retries, operation);
}
PDATA(pgm)->retries = 0;
}
// Wrapper for simple usb_control_msg messages to send data to programmer
static int usb_out (PROGRAMMER * pgm,
unsigned int requestid, unsigned int val, unsigned int index,
unsigned char* buffer, int buflen, int bitclk )
{
int nbytes;
int timeout;
// calculate the amout of time we expect the process to take by
// figuring the bit-clock time and buffer size and adding to the standard USB timeout.
timeout = USB_TIMEOUT + (buflen * bitclk) / 1000;
nbytes = usb_control_msg( PDATA(pgm)->usb_handle,
USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
requestid,
val, index,
(char *)buffer, buflen,
timeout);
if (nbytes != buflen) {
fprintf(stderr, "\n%s: error: usbtiny_send: %s (expected %d, got %d)\n",
progname, usb_strerror(), buflen, nbytes);
return -1;
}
return nbytes;
}
// Sometimes we just need to know the SPI command for the part to perform
// a function. Here we wrap this request for an operation so that we
// can just specify the part and operation and it'll do the right stuff
// to get the information from AvrDude and send to the USBtiny
static int usbtiny_avr_op (PROGRAMMER * pgm, AVRPART * p,
int op,
unsigned char res[4])
{
unsigned char cmd[4];
if (p->op[op] == NULL) {
fprintf( stderr, "Operation %d not defined for this chip!\n", op );
return -1;
}
memset(cmd, 0, sizeof(cmd));
avr_set_bits(p->op[op], cmd);
return pgm->cmd(pgm, cmd, res);
}
// ----------------------------------------------------------------------
/* Find a device with the correct VID/PID match for USBtiny */
static int usbtiny_open(PROGRAMMER* pgm, char* name)
{
struct usb_bus *bus;
struct usb_device *dev = 0;
usb_init(); // initialize the libusb system
usb_find_busses(); // have libusb scan all the usb busses available
usb_find_devices(); // have libusb scan all the usb devices available
PDATA(pgm)->usb_handle = NULL;
// now we iterate through all the busses and devices
for ( bus = usb_busses; bus; bus = bus->next ) {
for ( dev = bus->devices; dev; dev = dev->next ) {
if (dev->descriptor.idVendor == USBTINY_VENDOR
&& dev->descriptor.idProduct == USBTINY_PRODUCT ) { // found match?
PDATA(pgm)->usb_handle = usb_open(dev); // attempt to connect to device
// wrong permissions or something?
if (!PDATA(pgm)->usb_handle) {
fprintf(stderr, "%s: Warning: cannot open USB device: %s\n",
progname, usb_strerror());
continue;
}
}
}
}
if (!PDATA(pgm)->usb_handle) {
fprintf( stderr, "%s: Error: Could not find USBtiny device (0x%x/0x%x)\n",
progname, USBTINY_VENDOR, USBTINY_PRODUCT );
return -1;
}
return 0; // If we got here, we must have found a good USB device
}
/* Clean up the handle for the usbtiny */
static void usbtiny_close ( PROGRAMMER* pgm )
{
if (! PDATA(pgm)->usb_handle) {
return; // not a valid handle, bail!
}
usb_close(PDATA(pgm)->usb_handle); // ask libusb to clean up
PDATA(pgm)->usb_handle = NULL;
}
/* A simple calculator function determines the maximum size of data we can
shove through a USB connection without getting errors */
static void usbtiny_set_chunk_size (PROGRAMMER * pgm, int period)
{
PDATA(pgm)->chunk_size = CHUNK_SIZE; // start with the maximum (default)
while (PDATA(pgm)->chunk_size > 8 && period > 16) {
// Reduce the chunk size for a slow SCK to reduce
// the maximum time of a single USB transfer.
PDATA(pgm)->chunk_size >>= 1;
period >>= 1;
}
}
/* Given a SCK bit-clock speed (in useconds) we verify its an OK speed and tell the
USBtiny to update itself to the new frequency */
static int usbtiny_set_sck_period (PROGRAMMER *pgm, double v)
{
PDATA(pgm)->sck_period = (int)(v * 1e6 + 0.5); // convert from us to 'int', the 0.5 is for rounding up
// Make sure its not 0, as that will confuse the usbtiny
if (PDATA(pgm)->sck_period < SCK_MIN)
PDATA(pgm)->sck_period = SCK_MIN;
// We can't go slower, due to the byte-size of the clock variable
if (PDATA(pgm)->sck_period > SCK_MAX)
PDATA(pgm)->sck_period = SCK_MAX;
if (verbose) {
printf( "%s: Setting SCK period to %d usec\n", progname,
PDATA(pgm)->sck_period );
}
// send the command to the usbtiny device.
// MEME: for at90's fix resetstate?
if (usb_control(pgm, USBTINY_POWERUP, PDATA(pgm)->sck_period, RESET_LOW) < 0)
return -1;
// with the new speed, we'll have to update how much data we send per usb transfer
usbtiny_set_chunk_size(pgm, PDATA(pgm)->sck_period);
return 0;
}
static int usbtiny_initialize (PROGRAMMER *pgm, AVRPART *p )
{
unsigned char res[4]; // store the response from usbtinyisp
// Check for bit-clock and tell the usbtiny to adjust itself
if (pgm->bitclock > 0.0) {
// -B option specified: convert to valid range for sck_period
usbtiny_set_sck_period(pgm, pgm->bitclock);
} else {
// -B option not specified: use default
PDATA(pgm)->sck_period = SCK_DEFAULT;
if (verbose) {
printf( "%s: Using SCK period of %d usec\n",
progname, PDATA(pgm)->sck_period );
}
if (usb_control(pgm, USBTINY_POWERUP,
PDATA(pgm)->sck_period, RESET_LOW ) < 0)
return -1;
usbtiny_set_chunk_size(pgm, PDATA(pgm)->sck_period);
}
// Let the device wake up.
usleep(50000);
// Attempt to use the underlying avrdude methods to connect (MEME: is this kosher?)
if (! usbtiny_avr_op(pgm, p, AVR_OP_PGM_ENABLE, res)) {
// no response, RESET and try again
if (usb_control(pgm, USBTINY_POWERUP,
PDATA(pgm)->sck_period, RESET_HIGH) < 0 ||
usb_control(pgm, USBTINY_POWERUP,
PDATA(pgm)->sck_period, RESET_LOW) < 0)
return -1;
usleep(50000);
if ( ! usbtiny_avr_op( pgm, p, AVR_OP_PGM_ENABLE, res)) {
// give up
return -1;
}
}
return 0;
}
/* Tell the USBtiny to release the output pins, etc */
static void usbtiny_powerdown(PROGRAMMER * pgm)
{
if (!PDATA(pgm)->usb_handle) {
return; // wasn't connected in the first place
}
usb_control(pgm, USBTINY_POWERDOWN, 0, 0); // Send USB control command to device
}
/* Send a 4-byte SPI command to the USBtinyISP for execution
This procedure is used by higher-level Avrdude procedures */
static int usbtiny_cmd(PROGRAMMER * pgm, unsigned char cmd[4], unsigned char res[4])
{
int nbytes;
// Make sure its empty so we don't read previous calls if it fails
memset(res, '\0', 4 );
nbytes = usb_in( pgm, USBTINY_SPI,
(cmd[1] << 8) | cmd[0], // convert to 16-bit words
(cmd[3] << 8) | cmd[2], // "
res, 4, 8 * PDATA(pgm)->sck_period );
if (nbytes < 0)
return -1;
check_retries(pgm, "SPI command");
if (verbose > 1) {
// print out the data we sent and received
printf( "CMD: [%02x %02x %02x %02x] [%02x %02x %02x %02x]\n",
cmd[0], cmd[1], cmd[2], cmd[3],
res[0], res[1], res[2], res[3] );
}
return ((nbytes == 4) && // should have read 4 bytes
res[2] == cmd[1]); // AVR's do a delayed-echo thing
}
/* Send the chip-erase command */
static int usbtiny_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
unsigned char res[4];
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
fprintf(stderr, "Chip erase instruction not defined for part \"%s\"\n",
p->desc);
return -1;
}
// get the command for erasing this chip and transmit to avrdude
if (! usbtiny_avr_op( pgm, p, AVR_OP_CHIP_ERASE, res )) {
return -1;
}
usleep( p->chip_erase_delay );
// prepare for further instruction
pgm->initialize(pgm, p);
return 0;
}
// These are required functions but don't actually do anything
static void usbtiny_enable ( PROGRAMMER* pgm ) {}
static void usbtiny_disable ( PROGRAMMER* pgm ) {}
/* To speed up programming and reading, we do a 'chunked' read.
* We request just the data itself and the USBtiny uses the SPI function
* given to read in the data. Much faster than sending a 4-byte SPI request
* per byte
*/
static int usbtiny_paged_load (PROGRAMMER * pgm, AVRPART * p, AVRMEM* m,
int page_size, int n_bytes )
{
int i;
int chunk;
int function;
// First determine what we're doing
if (strcmp( m->desc, "flash" ) == 0) {
function = USBTINY_FLASH_READ;
} else {
function = USBTINY_EEPROM_READ;
}
for (i = 0; i < n_bytes; i += chunk) {
chunk = PDATA(pgm)->chunk_size; // start with the maximum chunk size possible
// If we want to xmit less than a chunk, thats OK
if (chunk > n_bytes-i)
chunk = n_bytes - i;
// Send the chunk of data to the USBtiny with the function we want
// to perform
if (usb_in(pgm,
function, // EEPROM or flash
0, // delay between SPI commands
i, // index
m->buf + i, // pointer to where we store data
chunk, // number of bytes
32 * PDATA(pgm)->sck_period) // each byte gets turned into a 4-byte SPI cmd
< 0) {
// usb_in() multiplies this per byte.
return -1;
}
// Tell avrdude how we're doing to provide user feedback
report_progress(i + chunk, n_bytes, NULL );
}
check_retries(pgm, "read");
return n_bytes;
}
/* To speed up programming and reading, we do a 'chunked' write.
* We send just the data itself and the USBtiny uses the SPI function
* given to write the data. Much faster than sending a 4-byte SPI request
* per byte.
*/
static int usbtiny_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes)
{
int i;
int chunk; // Size of data to write at once
int next;
int function; // which SPI command to use
int delay; // delay required between SPI commands
// First determine what we're doing
if (strcmp( m->desc, "flash" ) == 0) {
function = USBTINY_FLASH_WRITE;
} else {
function = USBTINY_EEPROM_WRITE;
}
delay = 0;
if (! m->paged) {
// Does this chip not support paged writes?
i = (m->readback[1] << 8) | m->readback[0];
if (usb_control(pgm, USBTINY_POLL_BYTES, i, 0 ) < 0)
return -1;
delay = m->max_write_delay;
}
for (i=0; i < n_bytes; i=next) {
// start with the max chunk size
chunk = PDATA(pgm)->chunk_size;
// we can only write a page at a time anyways
if (m->paged && chunk > page_size)
chunk = page_size;
// if there's less data remaining than one chunk
if (chunk > n_bytes-i)
chunk = n_bytes - i;
if (usb_out(pgm,
function, // Flash or EEPROM
delay, // How much to wait between each byte
i, // Index of data
m->buf + i, // Pointer to data
chunk, // Number of bytes to write
32 * PDATA(pgm)->sck_period + delay // each byte gets turned into a
// 4-byte SPI cmd usb_out() multiplies
// this per byte. Then add the cmd-delay
) < 0) {
return -1;
}
next = i + chunk; // Calculate what address we're at now
if (m->paged
&& ((next % page_size) == 0 || next == n_bytes) ) {
// If we're at a page boundary, send the SPI command to flush it.
avr_write_page(pgm, p, m, (unsigned long) i);
}
report_progress( next, n_bytes, NULL );
}
return n_bytes;
}
extern void usbtiny_initpgm ( PROGRAMMER* pgm )
{
strcpy(pgm->type, "USBtiny");
/* Mandatory Functions */
pgm->initialize = usbtiny_initialize;
pgm->enable = usbtiny_enable;
pgm->disable = usbtiny_disable;
pgm->program_enable = NULL;
pgm->chip_erase = usbtiny_chip_erase;
pgm->cmd = usbtiny_cmd;
pgm->open = usbtiny_open;
pgm->close = usbtiny_close;
pgm->read_byte = avr_read_byte_default;
pgm->write_byte = avr_write_byte_default;
/* Optional Functions */
pgm->powerup = NULL;
pgm->powerdown = usbtiny_powerdown;
pgm->paged_load = usbtiny_paged_load;
pgm->paged_write = usbtiny_paged_write;
pgm->set_sck_period = usbtiny_set_sck_period;
pgm->setup = usbtiny_setup;
pgm->teardown = usbtiny_teardown;
}
#else /* !HAVE_LIBUSB */
// Give a proper error if we were not compiled with libusb
static int usbtiny_nousb_open(struct programmer_t *pgm, char * name)
{
fprintf(stderr, "%s: error: no usb support. Please compile again with libusb installed.\n",
progname);
return -1;
}
void usbtiny_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "usbtiny");
pgm->open = usbtiny_nousb_open;
}
#endif /* HAVE_LIBUSB */

76
avrdude/usbtiny.h Normal file
View File

@@ -0,0 +1,76 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2007 Limor Fried
*
* 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
*/
#ifndef usbtiny_h
#define usbtiny_h
#include "avrpart.h"
// these are specifically assigned to USBtiny,
// if you need your own VID and PIDs you can get them for cheap from
// www.mecanique.co.uk so please don't reuse these. Thanks!
#define USBTINY_VENDOR 0x1781
#define USBTINY_PRODUCT 0x0C9F
// Generic requests to the USBtiny
#define USBTINY_ECHO 0 // echo test
#define USBTINY_READ 1 // read byte (wIndex:address)
#define USBTINY_WRITE 2 // write byte (wIndex:address, wValue:value)
#define USBTINY_CLR 3 // clear bit (wIndex:address, wValue:bitno)
#define USBTINY_SET 4 // set bit (wIndex:address, wValue:bitno)
// Programming requests
#define USBTINY_POWERUP 5 // apply power (wValue:SCK-period, wIndex:RESET)
#define USBTINY_POWERDOWN 6 // remove power from chip
#define USBTINY_SPI 7 // issue SPI command (wValue:c1c0, wIndex:c3c2)
#define USBTINY_POLL_BYTES 8 // set poll bytes for write (wValue:p1p2)
#define USBTINY_FLASH_READ 9 // read flash (wIndex:address)
#define USBTINY_FLASH_WRITE 10 // write flash (wIndex:address, wValue:timeout)
#define USBTINY_EEPROM_READ 11 // read eeprom (wIndex:address)
#define USBTINY_EEPROM_WRITE 12 // write eeprom (wIndex:address, wValue:timeout)
// Flags to indicate how to set RESET on power up
#define RESET_LOW 0
#define RESET_HIGH 1
// The SCK speed can be set by avrdude, to allow programming of slow-clocked parts
#define SCK_MIN 1 // usec delay (target clock >= 4 MHz)
#define SCK_MAX 250 // usec (target clock >= 16 KHz)
#define SCK_DEFAULT 10 // usec (target clock >= 0.4 MHz)
// How much data, max, do we want to send in one USB packet?
#define CHUNK_SIZE 128 // must be power of 2 less than 256
// The default USB Timeout
#define USB_TIMEOUT 500 // msec
#ifdef __cplusplus
extern "C" {
#endif
void usbtiny_initpgm (PROGRAMMER * pgm);
#ifdef __cplusplus
}
#endif
#endif /* usbtiny_h */