223 Commits

Author SHA1 Message Date
Joerg Wunsch
eb61d895a5 This commit was manufactured by cvs2svn to create tag
'RELEASE_5_5_0'.

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/tags/RELEASE_5_5_0@759 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-10-29 23:00:13 +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
Joerg Wunsch
1fc0d26959 Actually bump version to 5.3.1 now.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@713 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-22 22:55:33 +00:00
Joerg Wunsch
c59ed7097e * configure.ac (AC_INIT): Bump version to 5.3.1.
* avrdude.conf.in (frank-stk200): Fix syntax error.
* ser_avrdoper.c: Make #ifdef for Win32/libhid
consistent with the initial check: use the HID driver
only iff found, otherwise use libusb.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@712 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-22 22:52:34 +00:00
Joerg Wunsch
ba82e4bb01 We are now post release 5.3.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@711 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-21 22:48:14 +00:00
Joerg Wunsch
b2c5030890 Cosmetic: mention the current changes are now for 5.3.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@709 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-21 22:40:06 +00:00
Joerg Wunsch
1652c1b781 Mention frank-stk200 in the docs.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@708 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-21 22:05:56 +00:00
Joerg Wunsch
22fe8cd1e1 Bump version to 5.3, ready to release.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@707 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-21 22:01:30 +00:00
Joerg Wunsch
9749ffcd75 Submitted by Vince VG:
* avrdude.conf.in (frank-stk200): New programmer added.
Closes patch #5502: one other programmer


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@706 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-21 21:44:14 +00:00
Joerg Wunsch
ac95d249d6 In usbOpenDevice(), clear the error code when returning successfully.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@705 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-21 21:21:14 +00:00
Joerg Wunsch
f239ffa1d1 Submitted by Christian Starkjohann:
patch #5507: Support for AVR-Doper USB programmer in HID mode

* configure.ac: Add hooks to detect the Win32 HID library,
as well as the existence of <ddk/hidsdi.h>.
* Makefile.am: Add new files.
* my_ddk_hidsdi.h: (New file.)
* ser_avrdoper.c: (New file.)
* serial.h: Add declaration for avrdoper_serdev.
* stk500v2.c: Add hook to divert to the AVR Doper code.
* avrdude.1: Document the AVR Doper support.
* doc/avrdude.texi: (Ditto.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@704 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-20 23:43:34 +00:00
Joerg Wunsch
ef04ad29bf Submitted by ivanv at netman.ru
Fix length for single-byte write operations.
Closes bug #18527 JTAG ICE: fuse bits have been writen incorrectly


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@703 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-15 15:42:44 +00:00
Joerg Wunsch
a1afb8ea4a In jtagmkII_paged_write(), remove a debugging
usleep(1000000) that accidentally crept in in rev 1.19.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@702 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-11 16:48:52 +00:00
Joerg Wunsch
631f057984 In ser_open(), do fill in fdp->ifd before already
using it in ser_setspeed().


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@701 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-11 16:02:45 +00:00
Joerg Wunsch
dfe36d084b Sigh, fix yet another printf() format warning (on 64-bit architectures).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@700 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-11 15:33:19 +00:00
Joerg Wunsch
7abd4c5bb2 In jtagmkI_close(), revert baud rate to the initial
value in case we had changed it.

Fixes bug #18262: JTAGMKI/JTAG1 Reset Bug


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@699 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-11 15:15:50 +00:00
Colin O Flynn
f25cf95909 Colin O'Flynn <coflynn@newae.com>
* safemode.c: Stop ignoring return values!
      Closes bug #18339


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@698 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-11 14:41:59 +00:00
Joerg Wunsch
10eb9c7f5c Submitted by Nick Lott:
Fix signature for ATmega8515.

Closes bug #18348: ATMEGA8515 Signature is wrong in avrdude.conf


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@697 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-11 14:23:46 +00:00
Joerg Wunsch
08f272851c Actually return the number of bytes read or written in avr_read() or
avr_write(), respectively, in case the paged_load()/paged_write()
methods succeeded, rather than only 0.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@696 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-11 14:06:52 +00:00
Joerg Wunsch
35a87b9b6f Fix a bug introduced in rev. 1.69, when implementing the
fallback from each programmer's paged_load() or paged_write()
method, respectively.  The return value needs to be checked for
being greater or equal than 0 rather equal to 0 in order to
assume the operation has been successful.

Fixes bug #18489: avrdude is too slow (20 byte/s)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@695 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-11 14:01:54 +00:00
Joerg Wunsch
ab86a7d09b Make the code compile warning-free:
- declare a dummy "struct timezone" for some Win32 systems (MinGW)
- fix a few printf() argument types
- get rid off the prevailing "all filedescriptors are of type int"
  attitude

The last item required a large sweep across the code, in order to
replace all "int fd"s by "struct filedescriptor *fd"s, and pass
pointers (as we cannot pass a union directly).  In return, the
code is now supposed to be fully 64-bit safe, rather than relying
on a 64-bit pointer being converted to a (32-bit) int and back
to a pointer as we did previously.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@694 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-11 12:47:35 +00:00
Joerg Wunsch
fa205ce214 Implement EEPROM access through debugWire.
* jtagmkII.c: Extend the jtagmkII_read_byte() and
jtagmkII_write_byte() methods to handle EEPROM through
debugWire.

* avrpart.h: Implement the "flash instruction" parameter.
* config_gram.y: (Ditto.)
* lexer.l: (Ditto.)
* avrdude.conf.in: (Ditto.)

* avrdude.1: Document the EEPROM access through dW.
* doc/avrdude.texi: (Ditto.)

* tools/get-dw-params.xsl: Extend to extract the flash
instruction field.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@693 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-11-23 07:07:06 +00:00
Joerg Wunsch
7d1d5424d2 In avr_read() and avr_write(), if the paged access returns a
failure, fall back to byte access.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@692 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-11-23 07:02:22 +00:00
Joerg Wunsch
a473be7683 In jtagmkII_read_byte() and jtagmkII_write_byte(), return an error
upon failure now that the upper layers won't fall back to the cmd()
method anymore in that case.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@691 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-11-21 16:13:08 +00:00
Joerg Wunsch
84e401d795 Add debugWire entries for all devices where dW is known to exist
(according to the XML files).

Add an XSL stylesheet to extract the dW
parameters from the XML files.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@690 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-11-21 11:56:26 +00:00
Joerg Wunsch
17ac6b9989 Mention our debugWire support.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@689 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-11-21 11:19:10 +00:00
Joerg Wunsch
4108e10380 Implement debugWire programming support. Several limitations are
imposed by debugWire itself, so effectively, only flash ROM can be
read and written.

Currently, the required changes to avrdude.conf.in are only present
for the ATtiny44.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@688 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-11-20 23:23:37 +00:00
Joerg Wunsch
71cd3f3dd1 jtagmkI_close(): remove two unused variables.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@687 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-11-20 22:07:25 +00:00
Joerg Wunsch
47bc86120d Fix date of last changelog entry (copy&paste-o).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@686 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-11-20 21:35:26 +00:00
Joerg Wunsch
22879832f1 Add the default read_byte() and write_byte() methods here, too. Forgot
to commit these files in previous commit.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@685 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-11-20 15:08:13 +00:00
Joerg Wunsch
a4fa4ea9fc Replace the fallback of avr_read_byte() and avr_write_byte() to
avr_read_byte_default() and avr_write_byte_default (resp.) by directly
calling the latter functions from within all programmers that don't
implement their own read_byte()/write_byte() methods.  In turn, make the
read_byte() and write_byte() methods mandatory, and the cmd() method
(direct ISP command) optional instead (it's effectively mandatory for
any programmer using avr_read_byte_default()/avr_write_byte_default()
though).  Remove all the pointless cmd() method stubs from those programmers
that don't need it.

Eliminate avr_read_byte() as it was now completely identical to
pgm->read_byte().


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@684 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-11-20 15:04:09 +00:00
Joerg Wunsch
074b7a0868 Avoid sending a CMD_RESET when leaving programming mode, and CMD_GO
when closing the connection.  They cause the activity LED on the ICE
to continue to flicker, and are not necessary anyway (the target
starts to run by itself when leaving programmng mode).

This is a partial fix for bug #18262: JTAGMKI/JTAG1 Reset Bug


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@683 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-11-13 21:14:28 +00:00
Colin O Flynn
1da689ac37 * avrdude.conf.in: Add read support for lockbits on Tiny2313 device.
Applies patch #5538


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@682 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-11-12 16:11:55 +00:00
Joerg Wunsch
c02384d670 Add signatures for ATmega325/3250/645/6450.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@681 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-11-09 23:06:55 +00:00
Joerg Wunsch
45d7a727cd Preserve ${LDFLAGS} inherited from environment for Win32 environments.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@680 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-11-08 12:37:05 +00:00
Joerg Wunsch
d11d70ea6c Don't pretend --enable-doc were the default.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@679 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-11-07 20:32:41 +00:00
Joerg Wunsch
885333687c Fix the width of the efuse memory area for a number of AVRs.
Closes bug #18182: Wrong setting of eFuse configuration for
mega640/1280/1281/2560/2561 in avrdude 5.2


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@678 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-11-02 21:02:41 +00:00
Joerg Wunsch
197dc966e9 Implement and document HVSP and PP modes for the AVR Dragon.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@677 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-11-01 21:47:25 +00:00
Joerg Wunsch
25e7980b28 Implement a flags field in struct serdev, and populate it with a flag
that indicates whether the underlying communication can dynamically
change its speed or not.  This flag is set for true serial
communication but clear for USB communication.  Don't try to adjust
the speed when talking over a communication channel that doesn't
support it.  (The Dragon does not even support the respective
parameter.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@676 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-10-27 08:45:47 +00:00
Joerg Wunsch
38c5d278aa Add support for the AVR Dragon (JTAG and ISP mode).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@675 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-10-26 21:14:10 +00:00
Joerg Wunsch
f2d7a52f51 This is post-release 5.2 now.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@674 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-10-09 14:57:18 +00:00
Joerg Wunsch
79ce8f34bf Bump version for release 5.2.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@672 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-10-09 14:47:29 +00:00
Joerg Wunsch
2ccc76a66d Submitted by John Voltz: add AVR053 oscillator calibration.
* main.c: Add the -O option.
* pgm.c: Add the hook for the perform_osccal() method.
* pgm.h: (Ditto.)
* stk500v2.c: Implement perform_osccal().
* avrdude.1: Document the -O option.
* doc/avrdude.texi: (Ditto.)
Partially closes bug #17487: AVR RC oscillator calibration
routine not supported (feature request)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@671 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-10-09 14:34:24 +00:00
Joerg Wunsch
6b8fa85a0b Submitted by freckle@sf.net:
* stk500.c (stk500_paged_write): Send the command and the data
payload within a single write().
patch #5025: Improve stk500.c robustness

Submitted by Matthias Ringwald:
* stk500.c (stk500_open): do not flush the serial line after
getting in sync with the programmer.
patch #5293: stk500.c: no drain after sync (-> allow BTnode
Bootloader to work on cygwin)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@670 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-10-09 09:56:10 +00:00
Joerg Wunsch
8c215d1da5 Make the private prototype for gettimeofday() only visible if the
autoconfiguration figured out we need it.  The private implementation
has already been protected that way.

This should finally really fix bug #17884: another gettimeofday
conflict under win32/cygwin


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@669 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-30 20:48:17 +00:00
Joerg Wunsch
860aea6e04 The return type of gettimeofday() is actually int' not void'.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@668 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-30 19:36:22 +00:00
Joerg Wunsch
0353e3ade9 Fix prototype for gettimeofday().
Closes bug #17884: another gettimeofday conflict under win32/cygwin


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@667 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-29 20:52:32 +00:00
Joerg Wunsch
f39e957354 Submitted by Thomas Fischl (initially):
Add the CoreFoundation and IOKit framework linker flags on MacOS X
when configuring for USB support.

patch #4685: Libusb on MacOS X: detection and additional includes

Thanks to Matthias Ringwald for testing the reworked patch.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@666 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-24 13:35:40 +00:00
Joerg Wunsch
b8d0a34c44 * avr910.c: As there is a lot of ambiguity about the AVR910
device codes, allow the user to override the device code
verification with the -F option.
* main.c: Make ovsigck a global variable.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@665 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-20 21:32:18 +00:00
Joerg Wunsch
0734c16f98 Sync NEWS with latest changes.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@664 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-19 22:33:53 +00:00
Joerg Wunsch
73f657ac41 Add the "stk500generic" programmer that auto-probes for STK500
either firmware version 1 or 2.
* Makefile.am (avrdude_SOURCES): add the new files
stk500generic.c and stk500generic.h.
* avrdude.conf.in: Add the stk500generic programmer type, and
change the "stk500" entry to point to this programmer.
* config_gram.y: Add the stk500generic keyword.
* lexer.l: (Ditto.)
* stk500.c: Change the stk500v1 code to not call exit()
prematurely when failing to open the programmer, but instead
return an error status.
* stk500generic.c: (New file.) Stub programmer implementation.
Probe for either stk500v1 or stk500v2, and adjust the current pgm
appropriately.
* stk500generic.h: (New file.) Declare the public interface(s)
of stk500generic.c.
* doc/avrdude.texi: Document the changed behaviour of stk500.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@663 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-19 22:27:30 +00:00
Joerg Wunsch
2e86c833ce Various fixes for ancient processors and their capabilities. For the
AT90S1200 and the AT90S8515, fuse bit handling via ISP, and lock bit
reading via ISP are not supported at all.  For the AT90S4414 (small
brother of the AT90S8515), add the ability to write the lock bits, and
add a definition for the fuse bits (usable for HV programming).  For
the AT90S2313, add the "fuse" memory range, so it's available for HV
programming.

Resolves bug #17796: avrdude will not program or verify lockbits with
Atmel STK protocol programmers


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@662 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-18 21:48:36 +00:00
Joerg Wunsch
f3dfeb6ecf Submitted by Thomas Fischl:
* usbasp.c: Check for USBasp with new as well as old VID/PID
pair, warn the user about upgrading the firmware in case an
old one has been found.
* usbasp.h: Add new VID/PID.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@661 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-17 20:35:36 +00:00
Joerg Wunsch
8e5f9c7e1b Fix some mistakes for the ATtinyX61 family:
. high fuse has 8 bits
. there is an extended fuse (just one bit)
. the calibration area is only 1 byte


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@660 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-15 21:41:29 +00:00
Joerg Wunsch
af4f648cf5 More texinfo incompatibilities to avoid: replace @headitem by @item
and @strong{}


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@659 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-14 20:07:14 +00:00
Joerg Wunsch
4f9cd863b8 Not all texinfo versions understand indicateurl{}, so resort to url{}.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@658 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-14 20:00:55 +00:00
Joerg Wunsch
84ed521326 Convert some of the tables to multitables
in order to beautify the result.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@657 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-12 12:01:34 +00:00
Joerg Wunsch
c788c75014 Contributed by Thomas Fischl: add support for USBasp.
patch #4686: Add support for USBasp, a simple USB programmer
* usbasp.c: New file, implement the USBasp driver.
* usbasp.h: New file, interface declarations for USBasp.
* Makefile.am: Wire the new files into the build.
* avrdude.conf.in: Add the usbasp programmer entry.
* config_gram.y: Add the usbasp token.
* lexer.l: (Ditto.)
* avrdude.1: Document the USBasp programmer.
* doc/avrdude.texi: (Ditto.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@656 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-10 20:41:00 +00:00
Joerg Wunsch
c4e4fa62c3 Implement -U filename as a shorthand for -U flash:w:filename:a.
This has once been suggested by Brian Dean.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@655 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-08 21:52:45 +00:00
Joerg Wunsch
16c7a11538 Implement numerical output formats for decimal, hexadecimal, octal,
and binary numbers.

Closes bug #16129: more output formats for fuse bits (avrdude
enhancement request)

* fileio.c: Implement fileio_num() and the itoa_simple() helper function.
* fileio.h: Add new file formats to FILEFMT.
* main.c: Parse the new file formats.
* avrdude.1: Document all this.
* doc/avrdude.texi: (Ditto.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@654 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-08 21:28:24 +00:00
Joerg Wunsch
ac7bf0624c Hide two debug/trace statements behind "verbose".
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@653 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-08 21:10:05 +00:00
Joerg Wunsch
6e45624477 CPP statements start in column #1.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@652 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-08 19:46:45 +00:00
Joerg Wunsch
4bc635da8c Describe how to disable the DWEN fuse.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@651 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-07 20:42:01 +00:00
Joerg Wunsch
3318df48ed Translate numerical response codes to strings.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@650 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-07 19:57:59 +00:00
Joerg Wunsch
f615f8cbad Fix a broken indentation.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@649 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-07 19:37:41 +00:00
Joerg Wunsch
3b69ebd4e9 The avr109 programmer type no longer chokes on a wrong avr910 device
ID, so remove that description.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@648 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-07 19:34:17 +00:00
Joerg Wunsch
9a2971fb35 When failing to start in ISP mode, try debugWire instead. This
requires the user to eventually restart AVRDUE from scratch then.

jtagmkII_reset() had to get a second parameter in order to record
the reset mode.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@647 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-06 22:37:30 +00:00
Joerg Wunsch
66fa9f0689 In stk500v2_jtagmkII_open(), when the ICE synchronization failed,
still call the close method so we sign off correctly from the ICE:


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@646 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-06 22:33:59 +00:00
Joerg Wunsch
1abf521ee3 jtagmkII_open() is not needed externally.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@645 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-06 22:30:00 +00:00
Joerg Wunsch
8962bec663 Fix the maxsize comparision in stk500v2_jtagmkII_recv(), it was off
by one.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@644 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-06 22:29:27 +00:00
Joerg Wunsch
d973ae28e3 Add support for the JTAG ICE mkII in ISP mode.
* avrdude.conf.in (jtag2isp): New programmer entry.
* config_gram.y: Add K_JTAG_MKII_ISP.
* jtagmkII.c: Restructure and export some more functions.
* jtagmkII.h: Declare exported functions.
* jtagmkII_private.h: Prepare file to be included in stk500v2.c.
* lexer.l: Add jtagmkii_isp token.
* stk500v2.c: Implement glue to jtagmkII.c.
* stk500v2.h: Declare stk500v2_jtagmkII_initpgm().
* avrdude.1: Document the new programmer support.
* doc/avrdude.texi: (Ditto.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@643 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-06 20:06:07 +00:00
Joerg Wunsch
4074a28682 Add date and time of compilation to the verbose greeting message.
Idea taken from patch #3172: Adds date and time of compile to usage
message


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@642 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-01 21:15:03 +00:00
Joerg Wunsch
cba56a46fe Contributed by <avrdude@zevv.nl> as
patch #4372: Better synchronization for stk500

Sync three times, and drop any noise inbetween.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@641 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-01 21:00:36 +00:00
Joerg Wunsch
82a9e3cd60 Add entries for the ATtiny261/461/861 devices.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@640 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-01 20:48:04 +00:00
Joerg Wunsch
74f8cf9dd5 Remove unused variable.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@639 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-01 10:06:53 +00:00
Joerg Wunsch
1c121a456a * butterfly.c: Remove the device support decision based on
the old AVR910 device codes; we've got signature verification
now so better rely on that.

* avr910.c: Revert the signature bytes returned, as it already
happened in butterfly.c.  This closes bug #14998: Signature Bytes
read in wrong order (avr910 mode)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@638 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-09-01 10:03:12 +00:00
Joerg Wunsch
c71e4d3674 Submitted by Wim Lewis.
Improve error handling.

patch #4923: Better error reporting for serial-bitbang programmers


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@637 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-31 22:07:39 +00:00
Joerg Wunsch
54b633cace Introduce a "stk500v1" entry, so we can switch the default "stk500" to
"stk500v2" some day.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@636 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-31 21:19:58 +00:00
Joerg Wunsch
6eeab88fd4 The major part of this change has been contributed by
<andyw@pobox.com>.

Implements patch #4635: Add support for terminal/console servers for
serial programmers

* ser_posix.c: Add net_open(), and divert to it for net:host:port.
* ser_win32.c: Recognize net:host:port, and bail out.
* avrdude.1: Document the net:host:port connection option.
* doc/avrdude.texi: (Ditto.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@635 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-31 20:52:47 +00:00
Joerg Wunsch
fc87fe433a Fix for bug #16627: Butterfly programmer does not reset after programming
Wait for the device's response after sending an "E" command.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@634 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-31 11:02:25 +00:00
Joerg Wunsch
5dbc32c73e Tentative fix for bug #16156: Problem with Si-Prog
Disable reset before closing.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@633 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-31 10:55:20 +00:00
Joerg Wunsch
fa5465b63f Rewrite the serbb code so the pin numbering matches the
DB9 connector, and fix some related bugs in serbb_posix.c.

Closes bug #16265: dasa2 does not work under posix

* avrdude.conf.in: New serbb pin numbering; added "siprog"
as an alias for "ponyser".
* serbb_posix.c: New pin numbering, fix some confusion.
* serbb_win32.c: New pin numbering.

The generic and Posix-related parts of these changes have
been contributed by Hanns-Konrad Unger


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@632 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-30 14:09:58 +00:00
Joerg Wunsch
6460235802 Rewrite the serbb code so the pin numbering matches the
DB9 connector, and fix some related bugs in serbb_posix.c.
Closes bug #16265: dasa2 does not work under posix

* avrdude.conf.in: New serbb pin numbering; added "siprog"
as an alias for "ponyser".
* serbb_posix.c: New pin numbering, fix some confusion.
* serbb_win32.c: New pin numbering.

The generic and Posix-related parts of these changes have
been contributed by Hanns-Konrad Unger


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@631 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-30 14:08:37 +00:00
Joerg Wunsch
4b97ebc9ad Contributed by the anonymous developer of patch #5096:
Add an entry for the Altera byteblaster.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@630 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-30 05:13:15 +00:00
Joerg Wunsch
00791df09d Rework the exit specs so they actually work again. It should be
possible to extend them for other programmers than PPI now (serbb,
stk500*).

* pgm.h: Keep the exit specs in an abstract form inside struct
programmer_t.  (Should be moved out into some programmer-specific
structure.)  Rename the getexitspecs() method into
parseexitspecs().
* main.c: Move the exit specs stuff out to the programmer
implementation.
* par.c: Implement the new exit spec handling.  Everything is now
done using the generic abstraction layer.

Closes bug #16443: No disable Resetsignal at the end of
Programming Session

Obviates need for patch #5057: quick and dirty Hack to unset Reset
after Programming


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@629 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-29 23:12:15 +00:00
Joerg Wunsch
9473243b2c This patch has been contributed by an anonymous developer
via the patch tracking system.

patch #5096: Allow VCC and BUFF to be any pin in parallel mode

* config_gram.y: Release the restriction to PPIDATA pins.
* par.c: Rework the code to introduce a function par_setmany()
that builds on top of par_setpin(), and use that function for the
PPI_AVR_VCC and PPI_AVR_BUFF pin collections.  This also abstracts
the polarity of these signals appropriately.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@628 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-29 21:39:26 +00:00
Joerg Wunsch
8a833f921e Contributed by Ned Konz:
Open the serial port with O_NONBLOCK, and save and restore the port
state before exiting.

patch #5008: Patch for (5.1) ser_posix.c for O_NONBLOCK open and
restoring serial port state on close

Closes bug #12622: avrdude hangs on macosx/darwin with PL-2303
usb-to-serial and Butterfly


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@627 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-28 21:17:01 +00:00
Joerg Wunsch
ca1ed48a5e Move the bitbang prerequisite checks out from
main() into their own bitbang_check_prerequisites().


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@626 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-23 21:06:28 +00:00
Joerg Wunsch
d54f7a4fdb So finally, also ignore the Makefile.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@625 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-23 15:02:07 +00:00
Joerg Wunsch
879dd88de5 Two more things to ignore by CVS.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@624 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-23 15:01:04 +00:00
Joerg Wunsch
291c0515b9 Make CVS ignore all generated files.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@623 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-23 15:00:11 +00:00
Joerg Wunsch
fc2bb33bb6 * avrdude.conf.in: Add page mode parameters for all "eeprom" memory
definitions that are organized in pages.

* avr.c (avr_write_byte_default): Consider using the loadpage
instructions only if the respective memory is marked "paged".

Closes bug #17199: EEPROM fails verification on ATmega645 with
pony-stk200 hardware
Closes bug #16849: EEPROM write fails for AT90USB1287 with mode 0x41
Closes bug #15146: stk500v2_paged_write: loadpage instruction not
defined for part


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@622 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-22 22:05:19 +00:00
Joerg Wunsch
1ac704aa18 Change "avrispmk2" into "avrisp2" (in the description of the -d
option) as that is the programmer actually supported by
avrdude.conf.in.

Closes bug #15677: documentation mentions wrong programmer-id "avrispmk2"


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@621 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-22 20:01:25 +00:00
Joerg Wunsch
7c00e9ce8d Fix various AVR910 device codes. Add the code tables from both,
AVR910 and AVR109.  Change avr910_devcode of the ATtiny2313 to 0x5e
(ATtiny26).

Closes bug #16671: Tiny2313 avr910_devcode is bad
Closes bug #15826: avr910 device type for ATmega8 wrong


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@620 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-21 21:00:45 +00:00
Joerg Wunsch
1066d7cbb2 Add (rather conservative) write delay timing values to the *fuse and
lock memory spaces of all devices where they have been missing.  Add
the lock memory space to the ATmega48 section.

Closes bug #14920: tiny2313 fuses and AVRDUDE 5.0
Closes bug #15751: atmega48: no lock bits defined


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@619 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-21 20:19:35 +00:00
Joerg Wunsch
656a37122e Fix the size of the calibration memory space for ATtiny13, ATmega64,
ATmega16, ATmega32, ATmega8535, ATtiny25, ATtiny45, ATtiny85.

Closes bug #17383: Wrong calibration section in avrdude.conf...


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@618 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-21 19:43:05 +00:00
Joerg Wunsch
c4770ee293 Correct the pagesize of the ATmega324 from 256 to 128.
This closes bug #16410: ATMega164/324/644 cannot be programmed


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@617 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-21 19:09:32 +00:00
Joerg Wunsch
13ae062376 * configure.ac: Check for gettimeofday().
* ppiwin.c (gettimeofday): Define gettimeofday() replacement
only if !defined(HAVE_GETTIMEOFDAY); use correct protype.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@616 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-20 06:49:11 +00:00
Joerg Wunsch
fafd64f35d Some more STK500 vs. AVRISP cleanup: don't announce STK500-only
parameters on AVRISPs.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@615 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-19 21:02:45 +00:00
Joerg Wunsch
3f6708683a Minor cosmetic changes: STK500 firmware version numbers are M.NN, so
always display the minor number as two digits.  Examine the response
to the sign-on command to see which programmer hardware we are talking
to, and then restrict the STK500 topcard display to devices detected
as STK500.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@614 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-18 21:23:34 +00:00
Joerg Wunsch
be32054156 Add a dist-hook, and make it remove lexer.c, config_gram.c, and
config_gram.h from the source distribution archive.  These files are
supposed to be generated on the target system.

Closes bug #15536: avrdude-5.1 compilation fails on Gentoo/amd64


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@613 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-18 20:10:20 +00:00
Joerg Wunsch
8e64e0b3ca (AC_CHECK_LIB[usb]) Fix the generation of HAVE_LIBUSB in ac_cfg.h.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@612 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-17 22:44:34 +00:00
Joerg Wunsch
de999a4df4 Unreverse the argument order for CMD_CHIP_ERASE_HVSP; Atmel says
AVR068 is right, and stk500.exe is wrong.  (This reverts rev 1.19)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@611 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-17 16:01:34 +00:00
Joerg Wunsch
1c27d0b72c Submitted by Neil Davey:
patch #4539: Ability to control the bit clock (usleep) delay
for ppi interface
* bitbang.c: Implement bitbang_delay() and its calibration.
* bitbang.h: Declare bitbang_delay().
* main.c: Add the ispdelay option (-i).
* pgm.h (struct programmer_t): Add the ispdelay parameter.
* par.c: Add calls to bitbang_delay() when requested.
* serbb_posix.c: (Ditto.)
* serbb_win32.c: (Ditto.)
* avrdude.1: Document the new -i option.
* doc/avrdude.texi: (Ditto.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@610 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-17 15:06:20 +00:00
Joerg Wunsch
72b22aa078 Submitted by <chris@awaretechs.com>:
* avrdude.conf.in (ATmega48, ATmega88, ATmega168): patch #5100:
mega88 EEPROM support (extended for ATmega48 and ATmega168 - jw).


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@609 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-14 22:00:47 +00:00
Joerg Wunsch
cf07755f50 Submitted by <eolson@mit.edu>:
* stk500v2.c (stk500v2_open): patch #5273: Emit error message
if user requests usb and no libusb support


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@608 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-14 21:30:04 +00:00
Joerg Wunsch
2ff1624077 Beautify: replace indentation spaces by TABs,
remove trailing white space.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@607 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-14 05:16:56 +00:00
Joerg Wunsch
9243abcf3b Update most important recent additions.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@606 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-13 22:34:42 +00:00
Joerg Wunsch
9a055d4128 Add HVSP/PP mode parameters for all AVRs.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@605 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-13 22:26:45 +00:00
Joerg Wunsch
29daef32db Pretty-print the control stack argument.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@604 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-13 21:57:52 +00:00
Joerg Wunsch
e860b3091f New file, extract high-voltage programming parameters from Atmel XML
files, and produce an avrdude.conf[.in] snippet.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@603 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-13 21:10:13 +00:00
Joerg Wunsch
75bf98f073 * configure.ac (AC_CHECK_LIB([usb]): implement a private LIBUSB
macro to add this library to, to prevent it from being
automatically linked to all binaries.  This should fix the Win32
build of loaddrv.
* Makefile.am (avrdude_LDADD): add LIBUSB here.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@602 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-11 16:00:12 +00:00
Eric Weddington
3745f482d9 Patch #4780. Provide support for mega325, mega3250, mega645, mega6450.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@601 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-10 17:31:56 +00:00
Joerg Wunsch
f638a4caab Reverse the argument order for
CMD_CHIP_ERASE_HVSP; AVR068 and stk500.exe differ here.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@600 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-10 15:41:19 +00:00
Joerg Wunsch
4cf622cbf9 ATtiny11: fix the HVSP control stack,
add delay values required for flash and EEPROM.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@599 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-10 15:40:33 +00:00
Joerg Wunsch
688e194b10 stk500v2_program_enable(): Fix a typo (synchloops vs. synchcycles).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@598 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-09 19:56:48 +00:00
Joerg Wunsch
bb60925d96 Add parallel programming definitions for the ATmega8/48/88/168.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@597 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-08-04 20:49:00 +00:00
Joerg Wunsch
e663123831 Add the ATtiny11, an HVSP-only device.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@596 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-07-22 20:21:38 +00:00
Joerg Wunsch
6ed65069bf Implement STK500 (v2) HVSP mode.
* stk500v2.c: Add new functions for HVSP support.
* stk500v2.h: Add prototype for the stk500hvsp programmer.
* avrpart.h: Add fields to struct avrpart for new features.
* config_gram.y: Extend the configuration syntax for new
features required for HVSP support.
* lexer.l: (Ditto.)
* avrdude.conf.in: Add HVSP support for ATtiny13 and
ATtiny45 as an example.
* avrdude.1: Document stk500hvsp.
* doc/avrdude.texi: (Ditto.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@595 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-07-21 21:53:49 +00:00
Joerg Wunsch
e2e97bca93 Print the very verbose memory details only in debug level > 4.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@594 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-07-21 21:51:13 +00:00
Joerg Wunsch
c8c576ff35 Document the stk500pp support.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@593 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-07-19 21:34:34 +00:00
Joerg Wunsch
c814037d98 Document the new PP mode parameters.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@592 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-07-19 21:28:14 +00:00
Joerg Wunsch
4d5a479c86 Add more parameters for PP mode.
Fix the non-paged write operations for old AVRs.

In avrdude.conf.in, use the new PP mode parameters; add PP mode
definitions for AT90S8515.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@591 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-07-19 21:25:08 +00:00
Joerg Wunsch
2d146130a6 Hide stk500v2_set_sck_period_mk2() behind an #if defined(HAVE_LIBUSB)
as it is only used there (for the AVRISP mkII).


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@590 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-07-19 21:19:42 +00:00
Joerg Wunsch
a8a9ed2ca1 Fix all bugs in the stk500pp implementation.
Eliminate pagebuf, and use stack-allocated buffers instead.  The
pagesize of all current AVRs is at most 256 only anyway, and this is
unlikely to change with the STK500v2 protocol.  The previous pagebuf
implementation suffered from some possible buffer overrun.

In stk500pp_write_page(), do always write full pages, rather than
attempting to write a partial last page which did not get written at
all.  Fill the remaining bytes with 0xff.

For (paged) write operations, correctly synthesize the mode byte.
This mode byte is very different from the ISP mode byte (sigh).

In stk500pp_read_byte(), when performing read operations on paged
memory, start reading at the previous page boundary rather than the
current address.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@589 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-07-17 21:25:59 +00:00
Joerg Wunsch
285ae1ab31 Use mem->desc in place of upd->memtype in more places to
give the full name of the respective memory area, instead of
the (possibly abbreviated) name the user typed in the -U option.

(Previous attempt in rev 1.110 was obviously not complete.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@588 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-07-17 19:58:50 +00:00
Joerg Wunsch
a8e190bd30 First stab at an implementation of the STK500 parallel programming
feature (v2 firmware only), named "stk500pp".  Still not yet
complete: EEPROM writes not working, documentation missing, only
ATmega16 parameters available in avrdude.conf.in, some parameters
not yet implemented.

* avrdude.conf.in: Add sample parameters for PP mode to ATmega16.
* avrpart.h: Add the parallel programming control parameters.
* avrpart.c: (Ditto.)
* config_gram.y: Add stk500pp configuration grammar.
* lexer.l: Add stk500pp token recognition.
* stk500v2.h: Add declaration for stk500pp_initpgm().
* stk500v2.c: Add stk500pp implementation.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@587 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-07-16 21:30:14 +00:00
Joerg Wunsch
f76b51b554 Fix the signatures for the ATmega164/324 devices.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@586 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-07-11 21:05:33 +00:00
Joerg Wunsch
51770e1a4b Enter the signatures for the ATmega164/324/644 devices.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@585 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-07-10 20:24:27 +00:00
Joerg Wunsch
a71e6218b8 Implement extended addressing needed for the ATmega256x devices.
Document ATmega256x support.  Also document Solaris port defaults
in avrdude.texi.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@584 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-05-25 14:38:08 +00:00
Joerg Wunsch
7f81f23269 Fix date in last commit.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@583 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-05-23 22:37:17 +00:00
Joerg Wunsch
ed1637d25c Mention ATmega256x support.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@582 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-05-23 22:28:43 +00:00
Joerg Wunsch
56ef0aafe8 Start implementing support for ATmega256x;
jtag2 and bitbang programmers are working, stk500v2
still needs to be done.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@581 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-05-23 22:27:43 +00:00
Joerg Wunsch
4d4b87df15 Fix syntax error in previous commit (missing semicolon).
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@580 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-04-21 12:50:17 +00:00
Joerg Wunsch
e20799eefe Contributed by Julius Luukko <Julius.Luukko@lut.fi>:
Add the "ere-isp-avr" programmer.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@579 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-04-18 15:32:01 +00:00
Joerg Wunsch
06a5af36ba Contributed by Bram Daams:
Add the "atisp" programmer entry that makes use of negated signals.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@578 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-04-14 12:18:39 +00:00
Joerg Wunsch
cee67f5f4b Add logic to handle inverted signals for parallel ports as well, using
a tilde in avrdude.conf.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@577 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-04-13 20:10:55 +00:00
Joerg Wunsch
bbe2807089 Add support for AT90USB646/647/1286/1287.
The 64 KB devices are actually guessed, as the datasheet and XML
files obviously contain a number of errors there.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@576 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-03-28 20:35:21 +00:00
Joerg Wunsch
b17ff40a09 Cosmetical changes: items are indented by one hard tab.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@575 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-03-28 19:37:54 +00:00
Colin O Flynn
db16162922 Colin O'Flynn - March 23, 2006 - <coflynn@newae.com>
Contributed by Wim Lewis, fix a few typos (patch #4987)
    *avrdude.1: Typo fix


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@574 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-03-24 02:49:09 +00:00
Colin O Flynn
cb4000d7d3 2006-02-27 Colin O'Flynn <coflynn@newae.com>
Contributed by Wim Lewis, add support for checking device
        signatures in detail (patch #4924 and #4925)
    * avrdude.conf.in: Add signatures
    * avrpart.c: Set default signature
    * avrpart.h: Variable for signature
    * config_gram.y: More signature reading
    * lexer.l: Define that signatures exist
    * main.c: Read signatures and check them against hardware


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@573 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-02-27 17:18:42 +00:00
Joerg Wunsch
d7bddada25 Fixed paged flash write operations for AT90PWMx devices
(error in datasheet).


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@572 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-02-21 21:17:08 +00:00
Joerg Wunsch
df364f59c3 This is now post-release.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@571 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-01-23 21:04:13 +00:00
Joerg Wunsch
cd07291aae Pre-release mode.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@569 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-01-23 20:53:59 +00:00
Colin O Flynn
ede97a0ed2 * main.c, stk500v2.c: Added patch 4804 from eolson@mit.edu
Which stops sck from being writtend needlessly


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@568 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-01-17 21:11:39 +00:00
Colin O Flynn
caec621eaa *avrdude.conf.in : Added bs2 and pagel to m162, patch 4766
CVS  ----------------------------------------------------------------------


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@567 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-01-17 21:01:25 +00:00
Colin O Flynn
c23519f392 Colin O'Flynn <coflynn@newae.com>
* main.c: Fixed a typo in safemode variable names, fixed bug 15113


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@566 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-01-17 20:17:43 +00:00
Joerg Wunsch
4cbcbe84ec Replace David's email address by his full name in the copyrights.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@565 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-01-12 23:24:35 +00:00
Joerg Wunsch
fddb673ee8 Contributed by dcm@mit.edu: add support for the
AVRISP mkII device. (Savannah patch #4789.)
* serial.h: Declare usb_serdev_frame device descriptor.
* stk500v2.c: Implementation of the AVRISP mkII handling.
* usb_libusb.c: Add USB handling for short-frame delimited
AVRISP mkII USB protocol; add distinction of different
devices in usbdev_open().
* jtagmkII.c: Tell usbdev_open() to search for the JTAG ICE mkII.
* usbdevs.h: (New file.)
* Makefile.am: Add usbdevs.h, as well as some other forgotten
files "make distcheck" complained about.
* avrdude.conf.in: Add more aliases for the AVRISP mkII.
* avrdude.1: Document how to use the AVRISP mkII.
* doc/avrdude.texi: (Ditto.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@564 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-01-12 23:13:50 +00:00
Joerg Wunsch
b561874f07 Add EEPROM page instructions for the
ATmega169 so it will work for STK500v2.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@563 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-01-12 20:56:43 +00:00
Joerg Wunsch
5e68193a6c Add support for ATtiny24/44/84.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@562 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-12-16 22:39:39 +00:00
Colin O Flynn
d9866f6219 *avrdude.conf.in: added support for m162 using stk500v2
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@561 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-12-07 19:19:20 +00:00
Joerg Wunsch
645961163d Fix the number of significant bits for the efuse memory in
ATmega48/88/168; the datasheet is a bit off here as well.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@560 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-12-01 19:55:17 +00:00
Joerg Wunsch
e9750a7712 Document the JTAG ICE mkI support.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@559 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-29 22:58:04 +00:00
Joerg Wunsch
0b197a6c6f Submitted by Galen Seitz:
patch #4459: Fix for rpm package builds
* avrdude.spec.in: update the RPM spec file:
  - Default to enable-doc=yes during configure.
  - Move info file to docs package.
  - Make building of docs package conditional.  Basic
    idea copied from avr-gcc.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@558 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-29 20:28:51 +00:00
Joerg Wunsch
70fdf3082e Submitted by someone who thinks he's called "Daper":
Fix bug #15013: Wrong use of PPICLAIM (kernel: ppdev0: claim the
port first)

* par.c: don't claim/release here (thus win_ppdev.h not needed
anymore)
* ppi.c: claim/release here.
* freebsd_ppi.h: ppi_claim/ppi_release now take an fd as parameter.
* solaris_ecpp.h: (Ditto.)
* linux_ppdev.h: (Ditto.)  (Also add copyright.)
* win_ppdev.h: Not needed anymore, remove.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@557 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-29 20:20:22 +00:00
Joerg Wunsch
e58b699f41 Fix the size of a response array.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@556 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-28 21:11:18 +00:00
Joerg Wunsch
6b379d8842 Improve the communication startup with the ICE in particular after a
powerup.  Ideas taken from AVaRICE.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@555 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-28 20:46:21 +00:00
Joerg Wunsch
6fa8db276f Enable parport access on x86_64 Linux and amd64 FreeBSD systems.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@554 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-28 09:47:23 +00:00
Joerg Wunsch
7f7974ce25 Add a forgotten newline at EOF.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@553 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-27 21:20:48 +00:00
Joerg Wunsch
f0c7b52223 Add a forgotten changelog entry about the ATmega168 support.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@552 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-27 21:02:53 +00:00
Joerg Wunsch
0935636c7b Update ChangeLog for my JTAG ICE mkI support.
Beautify Colin's recent entries while being here.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@551 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-25 21:32:21 +00:00
Colin O Flynn
1b38485a23 Fixed bug 15051
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@550 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-25 14:48:22 +00:00
Colin O Flynn
fa935481aa Fixed bug 15051, building for Windows breaks.
*par.c: ppi_claim and ppi_release definitions now in a Windows header file
*ppi.c: Only included if you are building for Windows
*win_ppdev.h: Initial Commit, see par.c

CV: ----------------------------------------------------------------------


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@549 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-25 14:46:43 +00:00
Colin O Flynn
5ea6e54f96 Fixed bug 14681
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@548 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-25 12:46:23 +00:00
Joerg Wunsch
92010244dc Initial import of JTAG ICE mkI support.
The very basic functionality (paged flash read/write, erase, terminal
mode reads, fuse writes) works fine.  There are still the following
issues right now:

. paged EEPROM write (i.e. through -U eeprom:w:...) only works on an
  erased EEPROM
. byte-access flash and EEPROM writes (i.e. in terminal mode) fail
. documentation needs to be updated still


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@547 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-25 06:14:06 +00:00
Colin O Flynn
85e827043d *Added Brian Dean's patch to ser_win32.c, fixing bug 14681 "-vvvv causes communication to fail"
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@546 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-24 15:00:49 +00:00
Colin O Flynn
25d844791c Added support for stk500v2 for AtMega168
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@545 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-05 13:02:55 +00:00
Colin O Flynn
3ef11e335a avrdude.conf.in:
-added support for ATMega168, patch #4532 thanks to Manfred Bartz


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@544 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-04 13:51:32 +00:00
Joerg Wunsch
58233bbed4 Update Changelog.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@543 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-03 22:41:18 +00:00
Joerg Wunsch
ad9238b29e Add ecpp(7D) (parallel port) for Solaris.
* configure.ac: add Solaris' default parallel port.
* linux_ppdev.h: change parallel port access to the new style.
* freebsd_ppi.h: New file, abstract FreeBSD's ppi(4).
* solaris_ecpp.h: New file, abstract Solaris' ecpp(7D).
* par.c: change header inclusion sequence.
* pgm.h: remove obsolete ppi_claim() and ppi_release() dummies.
* ppi.c: change header inclusion sequence, use new parport
abstraction, drop obsolete dummy implementation.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@542 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-03 22:37:37 +00:00
Joerg Wunsch
5ce121ab1c Make the lexer work with Solaris' (10) default lex(1).
While Solaris' lex understands start conditions, they cannot be grouped,
so unfold the <strng> group.

All actions need braces, even if they only consist of a comment.

As the classic lex uses semi-static resource allocation, we need to bump
the resource limits quite a bit.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@541 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-02 21:49:52 +00:00
Joerg Wunsch
5105a871be Instead of defining YYSTYPE to be a struct token_t *, make this a
two-step declaration, and first define token_p to be a token_t *,
and then define YYSTYPE to token_p.  That works around a bug in
Solaris' yacc.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@540 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-02 21:03:51 +00:00
Joerg Wunsch
496ab3fd81 Make avrdude Solaris-compatible.
* Makefile.am: distclean avrdude.conf.
* avrdude.conf.in: make the parallel-port programmers optional.
* bitbang.c: move the bitbang features out into PROGRAMMER.
* configure.ac: introduce --enable-parport, add Solaris.
* lexer.l: replace str by strng to work around problems in some
versions of flex.
* main.c: move getexitspecs into the respective programmer's
domain; replace rindex by the C-standard strrchr.
* par.c: make parallel port optional.
* par.h: everything but par_initpgm() is private now.
* pgm.h: add setping/getping/highpulsepin/getexitspecs.
* serbb_posix.c: generalize bitbang interface; replace
cfmakeraw() by explicit code.
* serbb_win32.c: generalize bitbang interface.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@539 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-11-01 23:02:06 +00:00
Joerg Wunsch
a1c528dbe2 Fix yet another sign extension bug introduced by renaming "unsigned char"
to "char".


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@538 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-10-20 11:36:19 +00:00
Joerg Wunsch
50b587155d Add the required address bits for calibration memory space...
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@537 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-10-14 20:00:01 +00:00
Joerg Wunsch
d1342a1984 Fix the size of the calibration memory in the ATmega8515.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@536 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-10-14 19:33:19 +00:00
Joerg Wunsch
f9331bc6b4 Add support for the ATmega640/1280/1281 devices.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@535 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-10-09 09:29:24 +00:00
Joerg Wunsch
08e0114447 Polish up the docs a bit. Use smallexample instead of example for
wide tty output.  Document a trick to find out about the serial
numbers of all JTAG ICEs attached to USB.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@534 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-09-27 08:25:18 +00:00
Joerg Wunsch
0f12718ab6 A number of fixes for the libusb handling:
. use the correct endpoint, depending on whether we are going to read
  or write
. when opening the USB device, set the configuration according to the
  config entry, and properly claim the interface
. when closing, release the interface again

With these changes, it works now with libusb-win32 as well.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@533 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-09-26 12:19:01 +00:00
Joerg Wunsch
1b3d1fb776 In jtagmkII_paged_write(), default the pages size to 256 early enough
so the buffer will then be allocated correctly.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@532 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-09-26 12:16:45 +00:00
79 changed files with 19150 additions and 2760 deletions

View File

@@ -4,17 +4,30 @@ y.output
y.tab.h
lexer.c
config_gram.c
config_gram.h
.cvsignore
.depend
.deps
INSTALL
Makefile.in
Makefile
ac_cfg.h.in
aclocal.m4
autom4te.cache
configure
depcomp
install-sh
compile
missing
mkinstalldirs
stamp-h.in
stamp-h1
ac_cfg.h
avrdude.conf
avrdude.conf.tmp
avrdude.spec
config.guess
config.log
config.status
config.sub
avrdude

View File

@@ -1,601 +1,319 @@
2005-09-21 Joerg Wunsch <j@uriah.heep.sax.de>
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
* main.c(do_op): use mem->desc in place of upd->memtype to
give the full name of the respective memory area, instead of
the (possibly abbreviated) name the user typed in the -U option.
* configure.ac (AC_INIT): Bump version, releasing avrdude-5.5.
2005-09-21 Joerg Wunsch <j@uriah.heep.sax.de>
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
* main.c: Add the forgotten -B option to the option string in
getopt(); sort the -s option into order.
Submitted by <bikenomad@gmail.com>:
patch #5007: Patch for line-buffering of stdout and stderr
* main.c: call setvbuf() for stdout and stderr.
2005/09/21 Brian S. Dean <bsd@bsdhome.com>
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
* avr.c:
* main.c:
* safemode.c:
* safemode.h:
* term.h:
This is Colin O'Flynn's mega patch for updating safemode support:
* add support for parts with just 'fuse' memory
* if any fuse memories are altered, reflect those changes in the
post-programming safemode check so that safemode no longer
complains about fuses which were intentionally altered; this
eliminates the need to completely disable safemode using -u in
order to program fuses.
* provide -s option which will not ask to restore fuses, it will
just do it
Submitted by <graceindustries@gmail.com>:
patch #5953: Add AT90CAN64 and AT90CAN32 to avrdude.conf
* avrdude.conf.in: Add entry for AT90CAN64 and AT90CAN32.
2005-09-19 Joerg Wunsch <j@uriah.heep.sax.de>
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
* butterfly.c (butterfly_initialize): make the device code unsigned so
it wouldn't sign-extend when >= 0x80.
Submitted by Wolfgang Moser:
patch #6121: ISP support for the C2N232I device (serial port
bitbanging)
* avrdude.conf.in: Add entry for c2n232i.
2005-09-18 Joerg Wunsch <j@uriah.heep.sax.de>
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
Add the serial bit-bang driver, contributed by Michael Holzt.
* bitbang.h: New file.
* bitbang.c: New file.
* serbb.h: New file.
* serbb_posix.c: New file.
* serbb_win32.c: New file.
* Makefile.am: Include new files.
* config_gram.y: Add serbb to configuration language.
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.)
* par.c: Centralize bit-bang code in bitbang.c.
* par.h: Declare newly published functions.
* pgm.h (struct programmer_t): Add a flag field for private use
by the programmer.
* pindefs.h: Add definitions for negated serbb pins.
* avrdude.conf.in: Add serbb programmers ponyser, dasa, and dasa3.
* avrdude.1: Document serbb code.
* avrdude.1: Document the usbtiny support.
* doc/avrdude.texi: (Ditto.)
2005/09/18 Brian S. Dean <bsd@bsdhome.com>
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
* avrdude.conf.in: Patch #4078: add VCC pin definition for DAPA
programmer.
* doc/avrdude.texi: Sort list of supported programmers into
alphabetical order, add all missing programmers.
2005/09/18 Brian S. Dean <bsd@bsdhome.com>
2007-07-24 Thomas Fischl <tfischl@gmx.de>
* avr910.c: This is patch #3277 which appears to fix a number of
issues with the avr910 programmer.
* usbasp.c: Added long addresses to support devices with more
than 64kB flash. Closes bug #20558: Long address problem with
USBasp.
Fixes the following problems with paged writes in avr910.c:
- failure to re-set address after page writes;
- no polling or delay after page writes;
- no page writes when not using auto-increment;
- an extraneous page write when data ends on page boundary.
2007-06-27 Joerg Wunsch <j@uriah.heep.sax.de>
2005-09-17 Joerg Wunsch <j@uriah.heep.sax.de>
* Makefile.am (EXTRA_DIST): Add ChangeLog-2004-2006.
* avrdude.conf.in: Fix the poll values for the ATmega103's EEPROM
so they eventually match the XML file.
This fixes bug #7492: EEPROM writing fail on atmega103 with
atavrisp
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
2005-09-17 Joerg Wunsch <j@uriah.heep.sax.de>
* configure.ac (AC_INIT): Bump version for post-release.
* avrdude.conf.in: The ATmega128 has four oscillator calibration
bytes, not only a single one.
This closes bug #11496: Memory bank calibration on atmega128
should have 4 bytes
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
2005/09/17 Brian S. Dean <bsd@bsdhome.com>
* configure.ac (AC_INIT): Bump version, releasing avrdude-5.4.
* avrdude.1:
Document -q -q. Expand a little on the description of the 'part'
command.
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
2005/09/16 Brian S. Dean <bsd@bsdhome.com>
* 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).
* fileio.c:
* main.c:
Implement -q -q to be very very quiet.
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
2005/09/16 Brian S. Dean <bsd@bsdhome.com>
* 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
* avrdude.conf.in:
Add DAPA programmer.
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
2005/09/16 Brian S. Dean <bsd@bsdhome.com>
* avr910.c: Fall back to avr_{read,write}_byte_default(). Fixes
bug #18803: Fuse reading regression in avrdude 5.3.1 with avr910
programmer
* avrdude.conf.in:
* stk500v2.c:
This fixes EEPROM access using the STK500V2 programmer, partially
undoing part of a previous general fixup commit. Choose the correct
read/write operations with the stk500v2 program function - the correct
one depends on the memory type. EEPROM is byte addressable so uses
read/write. FLASH is word addressable and so uses read_lo/write_lo.
2007-05-15 Colin O'Flynn <coflynn@newae.com>
2005-09-16 Joerg Wunsch <j@uriah.heep.sax.de>
* 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
* avrdude.1: document the memtypes for -U
* doc/avrdude.texi: (Ditto.)
Closes bug #13501: <memtype> should be listed in the man page
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
2005-09-16 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.
* doc/Makefile.am: add logic to detect the misf^H^H^H^H
gratitous API change in recent versions of texi2html where
the output directory has changed names.
Fix for:
bug #13026: The build fails with texi2html 1.76
bug #12715: make issues during install
patch #3091: commandline fix for latest version of texi2html
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
2005-09-16 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.
* usb_libusb.c (usbdev_drain): actually implement draining to aid
synchronizing against a JTAG ICE in weird state.
2007-05-01 Colin O'Flynn <coflynn@newae.com>
2005-09-16 Joerg Wunsch <j@uriah.heep.sax.de>
* 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)
* butterfly.c: improve the butterfly initialization so it is more likely
to synchonize; [bug #9787: avrdude 4.4.0 correct butterfly interface]
2007-05-01 Colin O'Flynn <coflynn@newae.com>
2005-09-14 Joerg Wunsch <j@uriah.heep.sax.de>
* safemode.c: Added verbose output from safemode routines.
* jtagmkII.c (jtagmkII_paged_load): return the number of bytes read.
This makes EEPROM block reads work again.
2007-03-25 Colin O'Flynn <coflynn@newae.com>
2005-09-14 Joerg Wunsch <j@uriah.heep.sax.de>
* stk500generic.c: Forgot to close the serial port before trying to
open it again, caused problems on Windows machines.
Closes bug #19411
* avrdude.conf.in: add a jtag2slow programmer alias, and make
"jtag2" default to 115200 Bd.
* doc/avrdude.texi: document the above changes.
2007-02-26 Joerg Wunsch <j@uriah.heep.sax.de>
2005/09/14 Brian S. Dean <bsd@bsdhome.com>
* avrdude.conf.in: Add the AT90PWM2/3B devices.
* avrdude.conf.in:
Change bit 0 of the ATmega169 efuse 'write' opcode from 'x' (ignore)
to 'i' (input). Even though this bit should be ignored, it should not
be changed. The 'x' setting sets the bit to zero which programs it
and could cause undefined behaviour. Setting to 'i' enables it to be
rewritten to its old value.
A better solution might be to read the fuse byte, apply the new value
while leaving the 'x' bit alone, then writing the value back. The
current fix is a workaround which allows the developer to change the
bit as desired.
2007-02-02 Thomas Fischl <tfischl@gmx.de>
2005-08-30 Joerg Wunsch <j@uriah.heep.sax.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
* usb_libusb.c: Consistently use unsigned char for buffers.
2007-02-01 Joerg Wunsch <j@uriah.heep.sax.de>
2005-08-29 Brian S. Dean <bsd@bsdhome.com>
* config_gram.y: Remove duplicate definition of token K_WRITEPAGE
* avr910.c: Eliminate compiler warnings. GCC 4.x elicits many
signedness warnings when passing unsigned char * when char * is in
the prototype and vice versa. Clean these up along with a few
others.
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.)
* safemode.c: (Ditto.)
* safemode.h: (Ditto.)
* ser_posix.c: (Ditto.)
* serial.h: (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.)
2005-08-28 Joerg Wunsch <j@uriah.heep.sax.de>
2007-01-29 Joerg Wunsch <j@uriah.heep.sax.de>
* avrdude.conf.in: Add support for the ATtiny25/45/85. Note that
only the ATtiny45 appears to have a complete XML description right
* 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.
* avrdude.1: Mention all the recently added device support: AT90PWM2/3,
ATmega164/324/644, ATmega329x/649x, ATtiny25/45/85.
* doc/avrdude.texi: (Ditto.)
2005/08/28 Brian S. Dean <bsd@bsdhome.com>
* avrdude.conf.in:
* stk500v2.c:
This is patch # 4338, obsoletes patch #4327, provides fixes for bugs
#13693, #13871, and #14212.
This provides bug fixes to the STK500V2 programmer type.
- incorrect token used from avrdude.conf.in
- wrong command sent to programmer, hence no write to eeprom.
- programmer was said to start writing at 0x0000 and continue
page by page and was not repositionned when a gap was found
in the hex file, or when the hex file start address was not
0x0000. Hence the verify procedure was correct, not the
write procedure.
- speed up of flash write to skip empty pages (full of 0xFF)
by re-enabling a dedicated function for that task.
- stk500v2_paged_load() was not returning the number of byte
read, so empty hex files were generated when reading memory.
2005-08-17 Joerg Wunsch <j@uriah.heep.sax.de>
* avrdude.conf.in: fix the EEPROM size for ATmega329x/649x.
2005-08-16 Joerg Wunsch <j@uriah.heep.sax.de>
* avrdude.conf.in: Add support for the AT90PWM2/3.
2005-07-27 Joerg Wunsch <j@uriah.heep.sax.de>
(This work has been done as part of a contract with Atmel, Dresden.)
* butterfly.c: Implement full support for AVR109 boot loaders.
* avrdude.conf.in: add avr109 and avr911 as alias for butterfly.
* avrdude.1: Document the AVR109 addition.
* doc/avrdude.texi: (Ditto.)
2005-07-26 Brian S. Dean <bsd@bsdhome.com>
* main.c:
Don't call exit() directly here - set the exit value and jump to the
main_exit: label to ensure the programmer is released correctly.
* stk500v2.c:
The stk500v2_getsync() function was improperly checking for success,
thus it was falsely reporting that it failed when it was actually
working correctly. Fixed.
2005-07-25 Joerg Wunsch <j@uriah.heep.sax.de>
* usb_libusb.c: Catch benign errors when reading the serial #.
2005-06-19 Joerg Wunsch <j@uriah.heep.sax.de>
* Makefile.am: Implement libusb-base USB transport for the
JTAG ICE mkII.
* configure.ac: ditto.
* jtagmkII.c: ditto.
* ser_posix.c: ditto.
* ser_win32.c: ditto.
* serial.h: ditto.
* usb_libusb.c: ditto (New file).
* avrdude.1: document the USB transport.
* doc/avrdude.texi: ditto.
2005-06-15 Joerg Wunsch <j@uriah.heep.sax.de>
* avrdude.conf.in: The AT90CAN128 has AllowFullPageBitstream = no.
2005-06-14 Joerg Wunsch <j@uriah.heep.sax.de>
* avrdude.conf.in: Add support for the ATmega164/324/644.
* jtagmkII.c: If enter_progmode fails with RSP_ILLEGAL_JTAG_ID, give
the user a hint that the JTAGEN fuse might be unset.
2005-06-11 Joerg Wunsch <j@uriah.heep.sax.de>
* avrdude.conf.in: Add support for the ATmega329x/649x.
2005-05-27 Joerg Wunsch <j@uriah.heep.sax.de>
* jtagmkII.c: fix a signedness bug when shifting bits; when
discarding a packet for being overly long, restart the state
machine instead of attempting to drop a preposterous amount
of data.
2005-05-19 Joerg Wunsch <j@uriah.heep.sax.de>
* avrdude.1:
* doc/avrdude.texi: Document that the JTAG ICE mkII code currently
cannot write to flash one byte at a time. Also mention the bug
tracker interface on savannah.
2005/05/14 Brian S. Dean <bsd@bsdhome.com>
* configure.ac:
* main.c:
Update version for beta release and copyright message.
Change the default port to 'serial' for the newly added serial
programmers stk500v2 and jtagmkii.
2005-05-10 Joerg Wunsch <j@uriah.heep.sax.de>
* Makefile.am:
* avr910.c:
* avrdude.1:
* avrdude.conf.in:
* avrpart.c:
* avrpart.h:
* butterfly.c:
* config_gram.y:
* crc16.c:
* crc16.h:
* jtagmkII.c:
* jtagmkII.h:
* jtagmkII_private.h:
* lexer.l:
* main.c:
* pgm.h:
* serial.h:
* ser_posix.c:
* ser_win32.c:
* stk500.c:
* stk500v2.c:
* stk500v2.h:
* stk500v2_private.h:
* doc/avrdude.texi:
Mega-commit to bring in both, the STK500v2 support from Erik
Walthinsen, as well as JTAG ICE mkII support (by me).
Note that for the JTAG ICE, I did change a few things in the
internal API. Notably I made the serial receive timeout
configurable by the backends via an exported variable (done in
both the Posix and the Win32 implementation), and I made the
serial_recv() function return a -1 instead of bailing out with
exit(1) upon encountering a receive timeout (currently only done
in the Posix implementation). Both measures together allow me to
receive a datastreem from the ICE at 115 kbps on a somewhat lossy
PCI multi-UART card that occasionally drops a character. The JTAG
ICE mkII protocol has enough of safety layers to allow recovering
from these events, but the previous code wasn't prepared for any
kind of recovery. The Win32 change for this still has to be done.
2005/02/11 Brian S. Dean <bsd@bsdhome.com>
* main.c:
Exit non-zero if safe-mode reverts fuse bits that were requested on
the command-line.
Variable declarations must only appear at the beginning of a block.
2005/02/10 Brian S. Dean <bsd@bsdhome.com>
* avrdude.1:
Document -u option to disable safe mode.
2005/02/10 Brian S. Dean <bsd@bsdhome.com>
* configure.ac:
doc/Makefile is now dependent on whether or not doc is enabled.
2005/02/10 Brian S. Dean <bsd@bsdhome.com>
* Makefile.am:
* configure.ac:
Disable the doc build by default; the tools needed to build
doc are either not available on all systems or are at best
inconvenient to build and install. The doc can still be built, one
just needs to specify --enable-doc at configure time.
2005-01-24 Colin O'Flynn <coflynn@newae.com>
* main.c: Add "safe mode". Fuse settings will be restored at the end
of a programming session unless the -u switch is specified.
* safemode.c: New file. Safe mode support.
* safemode.h: New file. Safe mode support.
* Makefile.am: Add new files.
* doc/avrdude.texi: Document new Safe Mode feature and switch.
2004/12/22 Brian S. Dean <bsd@bsdhome.com>
* avrdude.conf.in:
Add support for "Xilinx JTAG cable". Contributed by:
Tymm <tymm@booyaka.com>
Add support for the AT90CAN128. Not sure if all the instruction
encoding is correct, specifically the address bits don't exactly match
those of the preliminary datasheet that I have, but I don't see how
they could be right. Tested with STK500 and it works there.
Instruction encodings have not been tested due to lack of a parallel
port on my Mac development box.
2004-07-19 Theodore A. Roth <troth@openavr.org>
* avrdude.1: Remove reference to ppi programmer schematic.
* configure.ac (AC_INIT): Set version to "4.4.0cvs".
2004-07-18 Theodore A. Roth <troth@openavr.org>
* AVRDUDE 4.4.0 has been released (cvs release tag is "release_4_4_0").
2004-07-18 Theodore A. Roth <troth@openavr.org>
* Makefile.am (EXTRA_DIST): Remove avrdude.pdf since it is no longer
supplied.
* NEWS: Fix typo.
* bootstrap: Delete the autom4te.cache dir before running the
autotools.
* configure.ac (AC_INIT): Set version to 4.4.0.
2004-07-17 Jan-Hinnerk Reichert <hinni@despammed.com>
* avrdude.1: Fixed obvious copy and paste error
(Patch #3199 contributed by Galen Seitz)
2004-07-15 Theodore A. Roth <troth@openavr.org>
* main.c (main): Don't indent CPP directives.
When showing update progress in a no tty situation, use unbuffered IO
for all systems, not just win32 native.
Update copyright year when printing version.
Remove warning about native win32 being experimental.
Split a line string.
* ppiwin.c: Update copyright year.
Add cvs Id keyword.
(usleep): Cleanup debug CPP directives to improve readability.
* ser_win32.c: Include <stdio.h> to fix failing build.
2004-07-08 Theodore A. Roth <troth@openavr.org>
* AUTHORS: Add names of recent major contributors.
* ser_win32.c: Assign copyright to Martin J. Thomas since he did all
real work on this file.
2004-07-07 Jan-Hinnerk Reichert <hinni@despammed.com>
* NEWS, doc/TODO: Updated NEWS and TODO
2004-07-07 Jan-Hinnerk Reichert <hinni@despammed.com>
* stk500.c, term.c, doc/avrdude.texi, avrdude.1:
added "sck"-command to the terminal mode.
This command allows slowing down of the SCK of
STK500-programmers.
2004-07-05 Jan-Hinnerk Reichert <hinni@despammed.com>
* *.c, *.h: Removed unnecessary includes of
config.h
2004-07-04 Jan-Hinnerk Reichert <hinni@despammed.com>
* avr.h: Removed some unused prototypes
2004-07-04 Jan-Hinnerk Reichert <hinni@despammed.com>
* stk500.c: Fixed fosc behaviour for values exceeding
maximum frequency (contributed by Galen Seitz)
2004-07-04 Jan-Hinnerk Reichert <hinni@despammed.com>
* avrdude.conf.in: Added support for
ATtiny2313 (contributed by Bob Paddock)
2004-06-25 Joerg Wunsch <j@uriah.heep.sax.de>
* avrdude.conf.in: Fix efuse bits for ATmega169.
2004-06-24 Alex Shepherd <maillists@ajsystems.co.nz>
Merged in Win32 Native changes contributed by Martin Thomas
Changed all instances of __CYGWIN__ conditional compilation to
WIN32NATIVE
* ser_win32.c: fleshed out all the previous stubs
* ser_posix.c: added WIN32NATIVE conditional compilation to skip
all function to allow ser_win32.c functions to operate
* ppi.h: removed commented code
* pgh.h: added usleep macros
* main.c: stdout,stderr tweaks for Win32
* configure.ac: added CFLAGS and LDFLAGS for Win32Native
* config_gram.y: added strtok_r macro
* buterfly.c: added various stub functions and EXIT processing
* avr910.c: added return 0 to avr910_open() and included time headers
* term.c: added warning about libreadline not supported in WIN32NATIVE
2004-06-17 Jan-Hinnerk Reichert <hinni@despammed.com>
* avrdude.conf.in: Added support for
- tiny13 (contributed by Pawel Moll)
- mega48 and mega88 (contributed by Galen Seitz)
However, the STK500-code for mega8 remains unchanged.
2004-05-19 Brian S. Dean <bsd@bsdhome.com>
* main.c:
* stk500.c: Allow the baud rate to be specified on the command
line with a new -b switch. The specified baud rate will
override the default serial port baud rate for a particular
programmer.
2004-05-19 Brian S. Dean <bsd@bsdhome.com>
* ppi.c: Stub-out the ppi_* functions in ppi.c with empty
wrappers that simply return an error code in order to build
successfully on MacOS X. This allows avrdude to work on MacOS
X and was tested using a USB<->RS232 cable adapter,
specifically Keyspan model USA-19HS.
2004-04-23 Joerg Wunsch <j@uriah.heep.sax.de>
* lists.h, lists.c: Drop LISTSZ and the check for
it in lcreat().
2004-04-17 Jan-Hinnerk Reichert <hinni@despammed.com>
* avr910.c: Hopefully fixed that weird "first byte not
programmed"-error in a good way (previous fix was not
working with all firmwares)
2004-02-10 Jan-Hinnerk Reichert <hinni@despammed.com>
* avrdude.1, doc/avrdude.texi, doc/TODO:
Removed the deprecated options from documentation
2004-02-10 Jan-Hinnerk Reichert <hinni@despammed.com>
* main.c: Removed deprecated options.
2004-01-28 Jan-Hinnerk Reichert <hinni@despammed.com>
* pgm.c, main.c, avr910.c, butterfly.c, stk500.c:
Changed default for powerup, powerdown and LED-commands
to do nothing and return OK. Then removed these commands
from avr910, butterfly and stk500.
* pgm.c: Fixed wrong type for default_open introduced by
the cleanup yesterday.
2004-01-29 Jan-Hinnerk Reichert <hinni@despammed.com>
* par.c: changed order of port-read/writes in par_txrx().
This change should increase immunity to delays in the
programmer-hardware.
Also did some unrelated cleanup in par_txrx().
2004-01-28 Jan-Hinnerk Reichert <hinni@despammed.com>
* pgm.[ch], main.c, par.c, avr910.c, butterfly.c, stk500.c:
Move save/restore-functionality into open/close.
* par.c: open/close now saves/restores PPICTRL, too.
* TODO: exitspecs don't work if RESET is in PPICTRL.
2004-01-26 Theodore A. Roth <troth@openavr.org>
* configure.ac (AC_INIT): Post release version update.
2004-01-26 Theodore A. Roth <troth@openavr.org>
* AVRDUDE 4.3.0 has been released (cvs release tag is "release_4_3_0").
2004-01-26 Theodore A. Roth <troth@openavr.org>
* configure.ac: Update copyright year.
(AC_INIT): Set version to 4.3.0.
2004-01-25 Theodore A. Roth <troth@openavr.org>
* ChangeLog: Minor formatting cleanups.
Move to all 2003 entries to ChangeLog-2003.
* ChangeLog-2003: New file.
* Makefile.am: Update copyright year.
(EXTRA_DIST): Add ChangeLog-2003.
2004-01-17 Jan-Hinnerk Reichert <hinni@despammed.com>
* doc/avrdude.texi: Get rid of those black boxes marking "overfull
hbox".
2004-01-17 Jan-Hinnerk Reichert <hinni@despammed.com>
* doc/avrdude.texi: New appendix "Troubleshooting".
2004-01-12 Jan-Hinnerk Reichert <hinni@despammed.com>
* avr910.c, avrpart.c, avrpart.h, doc/TODO:
Look up devicecode and report device.
2004-01-03 Jan-Hinnerk Reichert <hinni@despammed.com>
* avr910.c, pgm.c, pgm.h, config_gram.y, lexer.l: Add new configuration
parameter baudrate to support avr910-programmers with non-standard
baudrates.
* avrdude.conf.in, doc/avrdude.texi: Added "baudrate" to documentation.
2004-01-03 Jan-Hinnerk Reichert <hinni@despammed.com>
* avr910.c: Removed debugging stuff that is no longer needed.
2004-01-03 Jan-Hinnerk Reichert <hinni@despammed.com>
* doc/TODO: Removed two items.
2004-01-03 Jan-Hinnerk Reichert <hinni@despammed.com>
* main.c, avr.c, avr.h, par.c, stk500.c: Add function
avr_chip_erase() to unify handling of cycle-count.
Makes cycle-count work for avr910-programmers.
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.

1644
avrdude/ChangeLog-2004-2006 Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -22,9 +22,11 @@
#
EXTRA_DIST = \
ChangeLog \
ChangeLog-2001 \
ChangeLog-2002 \
ChangeLog-2003 \
ChangeLog-2004-2006 \
avrdude.1 \
avrdude.spec \
bootstrap
@@ -44,17 +46,41 @@ AM_YFLAGS = -d
avrdude_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
avrdude_CFLAGS = @ENABLE_WARNINGS@
libavrdude_a_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
avrdude_CFLAGS = @ENABLE_WARNINGS@
libavrdude_a_CFLAGS = @ENABLE_WARNINGS@
avrdude_LDADD = $(top_builddir)/$(noinst_LIBRARIES) @LIBUSB@ @LIBHID@
bin_PROGRAMS = avrdude
avrdude_SOURCES = \
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.
#
# See
#
# https://savannah.nongnu.org/bugs/index.php?func=detailitem&item_id=15536
#
# for why we don't want to have them.
dist-hook:
rm -f \
$(distdir)/lexer.c \
$(distdir)/config_gram.c \
$(distdir)/config_gram.h
libavrdude_a_SOURCES = \
config_gram.y \
lexer.l \
avr.c \
avr.h \
avr910.c \
avr910.h \
avrdude.h \
avrpart.c \
avrpart.h \
bitbang.c \
@@ -69,13 +95,17 @@ avrdude_SOURCES = \
crc16.h \
fileio.c \
fileio.h \
freebsd_ppi.h \
jtagmkI.c \
jtagmkI.h \
jtagmkI_private.h \
jtagmkII.c \
jtagmkII.h \
jtagmkII_private.h \
linux_ppdev.h \
lists.c \
lists.h \
main.c \
my_ddk_hidsdi.h \
par.c \
par.h \
pgm.c \
@@ -90,17 +120,31 @@ avrdude_SOURCES = \
serbb.h \
serbb_posix.c \
serbb_win32.c \
ser_avrdoper.c \
ser_posix.c \
ser_win32.c \
solaris_ecpp.h \
stk500.c \
stk500.h \
stk500_private.h \
stk500v2.c \
stk500v2.h \
stk500v2_private.h \
stk500generic.c \
stk500generic.h \
term.c \
term.h \
usb_libusb.c
usbasp.c \
usbasp.h \
usbdevs.h \
usb_libusb.c \
usbtiny.h \
usbtiny.c \
update.h \
update.c
avrdude_SOURCES = \
main.c
man_MANS = avrdude.1
@@ -108,6 +152,9 @@ sysconf_DATA = avrdude.conf
install-exec-local: backup-avrdude-conf
distclean-local:
rm -f avrdude.conf
# This will get run before the config file is installed.
backup-avrdude-conf:
@echo "Backing up avrdude.conf in ${DESTDIR}${sysconfdir}"

View File

@@ -5,8 +5,84 @@ Approximate change log for AVRDUDE by version.
(For more detailed changes, see the ChangeLog file.)
----------------------------------------------------------------------
Current:
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,
debugWire).
* Add support for debugWire (both, JTAG ICE mkII, and AVR Dragon).
* Add support for the AVR Doper USB HID-class programmer.
* Bugfixes.
Version 5.2:
* New devices supported:
- AT90USB646/647/1286/1287
- ATmega2560/2561
- ATmega325/3250/645/6450
- ATtiny11 (HVSP only device)
- ATtiny261/461/861
* Fixed paged flash write operations for AT90PWMx devices
(error in datasheet).
* Add signature verification.
* Add high-voltage mode programming for the STK500 (both,
parallel, and high-voltage serial programming).
* Add support for using the JTAG ICE mkII as a generic ISP
programmer.
* Allow for specifying the ISP clock delay as an option for
bit-bang programming adapters.
* Add support for Thomas Fischl's USBasp low-cost USB-attached
programmer.
* The "stk500" programmer type is now implemented as a stub
that tries to probe for either "stk500v1" or "stk500v2".
* Many bugfixes.
Version 5.1:
* New devices supported:
- ATmega640/1280/1281
- ATtiny24/44/84
* JTAG mkII support now works with libusb-win32, too
* JTAG ICE mkI support has been added
* Solaris support has been added (including ecpp(7D) parallel-port
bit-bang mode)
Version 5.0:

View File

@@ -28,30 +28,34 @@
#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)
{
unsigned char cmd[4];
unsigned char res[4];
unsigned char data;
OPCODE * readop;
OPCODE * readop, * lext;
if (pgm->cmd == NULL) {
fprintf(stderr,
"%s: Error: %s programmer uses avr_read_byte_default() but does not\n"
"provide a cmd() method.\n",
progname, pgm->type);
return -1;
}
pgm->pgm_led(pgm, ON);
pgm->err_led(pgm, OFF);
@@ -79,6 +83,18 @@ int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
return -1;
}
/*
* If this device has a "load extended address" command, issue it.
*/
lext = mem->op[AVR_OP_LOAD_EXT_ADDR];
if (lext != NULL) {
memset(cmd, 0, sizeof(cmd));
avr_set_bits(lext, cmd);
avr_set_addr(lext, cmd, addr);
pgm->cmd(pgm, cmd, res);
}
memset(cmd, 0, sizeof(cmd));
avr_set_bits(readop, cmd);
@@ -95,26 +111,6 @@ int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
}
/*
* read a byte of data from the indicated memory region
*/
int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value)
{
int rc;
if (pgm->read_byte) {
rc = pgm->read_byte(pgm, p, mem, addr, value);
if (rc == 0) {
return rc;
}
/* read_byte() method failed, try again with default. */
}
return avr_read_byte_default(pgm, p, mem, addr, value);
}
/*
* Return the number of "interesting" bytes in a memory buffer,
* "interesting" being defined as up to the last non-0xff data
@@ -176,26 +172,19 @@ 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 (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
* instead
*/
if (mem->paged) {
rc = pgm->paged_load(pgm, p, mem, mem->page_size, size);
if (rc < 0)
return rc;
rc = pgm->paged_load(pgm, p, mem, mem->page_size, size);
if (rc >= 0) {
if (strcasecmp(mem->desc, "flash") == 0)
return avr_mem_hiaddr(mem);
else
return rc;
}
else {
rc = pgm->paged_load(pgm, p, mem, pgm->page_size, size);
if (rc < 0)
return rc;
}
if (strcasecmp(mem->desc, "flash") == 0)
return avr_mem_hiaddr(mem);
else
return rc;
}
}
@@ -206,7 +195,7 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
}
for (i=0; i<size; i++) {
rc = avr_read_byte(pgm, p, mem, i, &rbyte);
rc = pgm->read_byte(pgm, p, mem, i, &rbyte);
if (rc != 0) {
fprintf(stderr, "avr_read(): error reading address 0x%04lx\n", i);
if (rc == -1)
@@ -234,7 +223,15 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
{
unsigned char cmd[4];
unsigned char res[4];
OPCODE * wp;
OPCODE * wp, * lext;
if (pgm->cmd == NULL) {
fprintf(stderr,
"%s: Error: %s programmer uses avr_write_page() but does not\n"
"provide a cmd() method.\n",
progname, pgm->type);
return -1;
}
wp = mem->op[AVR_OP_WRITEPAGE];
if (wp == NULL) {
@@ -254,6 +251,18 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
pgm->pgm_led(pgm, ON);
pgm->err_led(pgm, OFF);
/*
* If this device has a "load extended address" command, issue it.
*/
lext = mem->op[AVR_OP_LOAD_EXT_ADDR];
if (lext != NULL) {
memset(cmd, 0, sizeof(cmd));
avr_set_bits(lext, cmd);
avr_set_addr(lext, cmd, addr);
pgm->cmd(pgm, cmd, res);
}
memset(cmd, 0, sizeof(cmd));
avr_set_bits(wp, cmd);
@@ -288,13 +297,21 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
int readok=0;
struct timeval tv;
if (pgm->cmd == NULL) {
fprintf(stderr,
"%s: Error: %s programmer uses avr_write_byte_default() but does not\n"
"provide a cmd() method.\n",
progname, pgm->type);
return -1;
}
if (!mem->paged) {
/*
* check to see if the write is necessary by reading the existing
* value and only write if we are changing the value; we can't
* use this optimization for paged addressing.
*/
rc = avr_read_byte(pgm, p, mem, addr, &b);
rc = pgm->read_byte(pgm, p, mem, addr, &b);
if (rc != 0) {
if (rc != -1) {
return -2;
@@ -321,7 +338,7 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
writeop = mem->op[AVR_OP_WRITE_LO];
caddr = addr / 2;
}
else if (mem->op[AVR_OP_LOADPAGE_LO]) {
else if (mem->paged && mem->op[AVR_OP_LOADPAGE_LO]) {
if (addr & 0x01)
writeop = mem->op[AVR_OP_LOADPAGE_HI];
else
@@ -386,7 +403,7 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
* specified for the chip.
*/
usleep(mem->max_write_delay);
rc = avr_read_byte(pgm, p, mem, addr, &r);
rc = pgm->read_byte(pgm, p, mem, addr, &r);
if (rc != 0) {
pgm->pgm_led(pgm, OFF);
pgm->err_led(pgm, OFF);
@@ -400,7 +417,7 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
/*
* Do polling, but timeout after max_write_delay.
*/
rc = avr_read_byte(pgm, p, mem, addr, &r);
rc = pgm->read_byte(pgm, p, mem, addr, &r);
if (rc != 0) {
pgm->pgm_led(pgm, OFF);
pgm->err_led(pgm, ON);
@@ -485,7 +502,6 @@ int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned char safemode_hfuse;
unsigned char safemode_efuse;
unsigned char safemode_fuse;
int rc;
/* If we write the fuses, then we need to tell safemode that they *should* change */
safemode_memfuses(0, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
@@ -505,15 +521,7 @@ int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
if (pgm->write_byte) {
rc = pgm->write_byte(pgm, p, mem, addr, data);
if (rc == 0) {
return rc;
}
/* write_byte() method failed, try again with default. */
}
return avr_write_byte_default(pgm, p, mem, addr, data);
return pgm->write_byte(pgm, p, mem, addr, data);
}
@@ -561,13 +569,14 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
}
if ((strcmp(m->desc, "flash")==0) || (strcmp(m->desc, "eeprom")==0)) {
if (pgm->paged_write != NULL) {
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
* instead
*/
return pgm->paged_write(pgm, p, m, m->page_size, size);
if ((i = pgm->paged_write(pgm, p, m, m->page_size, size)) >= 0)
return i;
}
}
@@ -717,7 +726,7 @@ int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles)
}
for (i=4; i>0; i--) {
rc = avr_read_byte(pgm, p, a, a->size-i, &v1);
rc = pgm->read_byte(pgm, p, a, a->size-i, &v1);
if (rc < 0) {
fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n",
progname, rc);
@@ -798,3 +807,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,13 +27,18 @@
#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;
int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value);
#ifdef __cplusplus
extern "C" {
#endif
int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value);
int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
int verbose);
@@ -44,6 +49,9 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data);
int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data);
int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
int verbose);
@@ -59,6 +67,10 @@ 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

@@ -33,20 +33,19 @@
#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;
static char has_auto_incr_addr;
static int avr910_send(PROGRAMMER * pgm, char * buf, size_t len)
{
return serial_send(pgm->fd, (unsigned char *)buf, len);
return serial_send(&pgm->fd, (unsigned char *)buf, len);
}
@@ -54,7 +53,7 @@ static int avr910_recv(PROGRAMMER * pgm, char * buf, size_t len)
{
int rv;
rv = serial_recv(pgm->fd, (unsigned char *)buf, len);
rv = serial_recv(&pgm->fd, (unsigned char *)buf, len);
if (rv < 0) {
fprintf(stderr,
"%s: avr910_recv(): programmer is not responding\n",
@@ -67,7 +66,7 @@ static int avr910_recv(PROGRAMMER * pgm, char * buf, size_t len)
static int avr910_drain(PROGRAMMER * pgm, int display)
{
return serial_drain(pgm->fd, display);
return serial_drain(&pgm->fd, display);
}
@@ -134,7 +133,7 @@ static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
char hw[2];
char buf[10];
char type;
char c;
char c, devtype_1st;
int dev_supported = 0;
AVRPART * part;
@@ -173,8 +172,11 @@ static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
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);
@@ -190,15 +192,18 @@ static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
if (!dev_supported) {
fprintf(stderr,
"%s: error: selected device is not supported by programmer: %s\n",
progname, p->id);
exit(1);
"%s: %s: selected device is not supported by programmer: %s\n",
progname, ovsigck? "warning": "error", p->id);
if (!ovsigck)
exit(1);
}
/* Tell the programmer which part we selected. */
/* Tell the programmer which part we selected.
If the user forced the selection, use the first device
type that is supported by the programmer. */
buf[0] = 'T';
buf[1] = p->avr910_devcode;
buf[1] = ovsigck? devtype_1st: p->avr910_devcode;
avr910_send(pgm, buf, 2);
avr910_vfy_cmd_sent(pgm, "select device");
@@ -264,7 +269,7 @@ static int avr910_open(PROGRAMMER * pgm, char * port)
}
strcpy(pgm->port, port);
pgm->fd = serial_open(port, pgm->baudrate);
serial_open(port, pgm->baudrate, &pgm->fd);
/*
* drain any extraneous input
@@ -278,12 +283,12 @@ static void avr910_close(PROGRAMMER * pgm)
{
avr910_leave_prog_mode(pgm);
serial_close(pgm->fd);
pgm->fd = -1;
serial_close(&pgm->fd);
pgm->fd.ifd = -1;
}
static void avr910_display(PROGRAMMER * pgm, char * p)
static void avr910_display(PROGRAMMER * pgm, const char * p)
{
return;
}
@@ -321,7 +326,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;
@@ -393,7 +398,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);
}
@@ -557,6 +562,8 @@ static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int avr910_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
{
unsigned char tmp;
if (m->size < 3) {
fprintf(stderr, "%s: memsize too small for sig byte read", progname);
return -1;
@@ -564,6 +571,10 @@ static int avr910_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
avr910_send(pgm, "s", 1);
avr910_recv(pgm, (char *)m->buf, 3);
/* Returned signature has wrong order. */
tmp = m->buf[2];
m->buf[2] = m->buf[0];
m->buf[0] = tmp;
return 3;
}

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 Joerg Wunsch
.\" Copyright (C) 2001, 2002, 2003, 2005, 2006, 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
@@ -19,7 +19,7 @@
.\"
.\" $Id$
.\"
.Dd DATE September 18, 2005
.Dd DATE October 29, 2007
.Os
.Dt AVRDUDE 1
.Sh NAME
@@ -38,7 +38,9 @@
.Op \&, Ns Ar exitspec
.Oc
.Op Fl F
.Op Fl i Ar delay
.Op Fl n
.Op Fl O
.Op Fl P Ar port
.Op Fl q
.Op Fl s
@@ -55,7 +57,8 @@ is a program for downloading code and data to Atmel AVR
microcontrollers.
.Nm Avrdude
supports Atmel's STK500 programmer,
Atmel's JTAG ICE mkII,
Atmel's AVRISP and AVRISP mkII devices,
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
programmer connected directly to a
@@ -79,7 +82,7 @@ and
need to be connected to the parallel port. Optionally, some otherwise
unused output pins of the parallel port can be used to supply power
for the MCU part, so it is also possible to construct a passive
standalone programming device. Some status LEDs indicating the
stand-alone programming device. Some status LEDs indicating the
current operating state of the programmer can be connected, and a
signal is available to control a buffer/driver IC 74LS367 (or
74HCT367). The latter can be useful to decouple the parallel port
@@ -98,14 +101,37 @@ Atmel's STK500 programmer is also supported and connects to a serial
port.
Both, firmware versions 1.x and 2.x can be handled, but require a
different programmer type specification (by now).
Using firmware version 2, high-voltage programming is also supported,
both parallel and serial
(programmer types stk500pp and stk500hvsp).
.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
supported on a serial port.
.Pp
Atmel's JTAG ICE mkII is supported as well to up- or download memory
Atmel's JTAG ICE (both mkI and mkII) is supported as well to up- or download memory
areas from/to an AVR target (no support for on-chip debugging).
For the JTAG ICE mkII, JTAG, debugWire and ISP mode are supported.
See below for the limitations of debugWire.
.Pp
The AVR Dragon is supported in all modes (ISP, JTAG, HVSP, PP, debugWire).
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.
When used in ISP mode, the AVR Dragon behaves similar to an
AVRISP mkII (or JTAG ICE mkII in ISP mode), so all device-specific
comments will apply there.
In particular, the Dragon starts out with a rather fast ISP clock
frequency, so the
.Fl B Ar bitclock
option might be required to achieve a stable ISP communication.
.Pp
The USBasp ISP and USBtinyISP adapters are also supported, provided
.Nm avrdude
has been compiled with libusb support.
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
@@ -122,7 +148,7 @@ can program the EEPROM and flash ROM memory cells of supported AVR
parts. Where supported by the serial instruction set, fuse bits and
lock bits can be programmed as well. These are implemented within
.Nm
as seperate memory types and can be programmed using data from a file
as separate memory types and can be programmed using data from a file
(see the
.Fl m
option) or from terminal mode (see the
@@ -169,18 +195,23 @@ pwm3 AT90PWM3
8535 AT90S8535
m103 ATmega103
m128 ATmega128
m1280 ATmega1280
m1281 ATmega1281
m16 ATmega16
m161 ATmega161
m162 ATmega162
m163 ATmega163
m164 ATmega164
m169 ATmega169
m2560 ATmega2560 (**)
m2561 ATmega2561 (**)
m32 ATmega32
m324 ATmega324
m329 ATmega329
m3290 ATmega3290
m48 ATmega48
m64 ATmega64
m640 ATmega640
m644 ATmega644
m649 ATmega649
m6490 ATmega6490
@@ -197,15 +228,19 @@ t26 ATtiny26
t45 ATtiny45
t85 ATtiny85
.TE
.Bl -tag -width "(*) "
.Bl -tag -width "(**) "
.It "(*)"
The AT90S2323 and ATtiny22 use the same algorithm.
.It "(**)"
Flash addressing above 128 KB is not supported by all
programming hardware. Known to work are jtag2, stk500v2,
and bit-bang programmers.
.El
.It Fl b Ar baudrate
Override the RS-232 connection baud rate specified in the respective
programmer's entry of the configuration file.
.It Fl B Ar bitclock
Specify the bit clock period for the JTAG interface (JTAG ICE only).
Specify the bit clock period for the JTAG interface or the ISP clock (JTAG ICE only).
The value is a floating-point number in microseconds.
The default value of the JTAG ICE results in about 1 microsecond bit
clock period, suitable for target MCUs running at 4 MHz clock and
@@ -317,10 +352,34 @@ 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.
.It Fl i Ar delay
For bitbang-type programmers, delay for approximately
.Ar delay
microseconds between each bit state change.
If the host system is very fast, or the target runs off a slow clock
(like a 32 kHz crystal, or the 128 kHz internal RC oscillator), this
can become necessary to satisfy the requirement that the ISP clock
frequency must not be higher than 1/4 of the CPU clock frequency.
This is implemented as a spin-loop delay to allow even for very
short delays.
On Unix-style operating systems, the spin loop is initially calibrated
against a system timer, so the number of microseconds might be rather
realistic, assuming a constant system load while
.Nm
is running.
On Win32 operating systems, a preconfigured number of cycles per
microsecond is assumed that might be off a bit for very fast or very
slow machines.
.It Fl n
No-write - disables actually writing data to the MCU (useful for debugging
.Nm avrdude
).
.It Fl O
Perform a RC oscillator run-time calibration according to Atmel
application note AVR053.
This is only supported on the STK500v2, AVRISP mkII, and JTAG ICE mkII
hardware.
Note that the result will be stored in the EEPROM cell at address 0.
.It Fl P Ar port
Use
.Ar port
@@ -338,7 +397,7 @@ For the JTAG ICE mkII, if
has been configured with libusb support,
.Ar port
can alternatively be specified as
.Ar usb Ns Op \&: Ns Ar serialno .
.Pa usb Ns Op \&: Ns Ar serialno .
This will cause
.Nm
to search a JTAG ICE mkII on USB.
@@ -349,6 +408,34 @@ from any JTAG ICE mkII found on USB.
The match is done after stripping any existing colons from the given
serial number, and right-to-left, so only the least significant bytes
from the serial number need to be given.
.Pp
As the AVRISP mkII device can only be talked to over USB, the very
same method of specifying the port is required there.
.Pp
For the USB programmer "AVR-Doper" running in HID mode, the port must
be specified as
.Ar avrdoper.
Libusb support is required on Unix but not on Windows. For more
information about AVR-Doper see http://www.obdev.at/avrusb/avrdoper.html.
.Pp
For programmers that attach to a serial port using some kind of
higher level protocol (as opposed to bit-bang style programmers),
.Ar port
can be specified as
.Pa net Ns \&: Ns Ar host Ns \&: Ns Ar port .
In this case, instead of trying to open a local device, a TCP
network connection to (TCP)
.Ar port
on
.Ar host
is established.
The remote endpoint is assumed to be a terminal or console server
that connects the network stream to a local serial port where the
actual programmer has been attached to.
The port is assumed to be properly configured, for example using a
transparent 8-bit data connection without parity at 115200 Baud
for a STK500.
.Em This feature is currently not implemented for Win32 systems.
.It Fl q
Disable (or quell) output of the progress bar while reading or writing
to the device. Specify it a second time for even quieter operation.
@@ -383,7 +470,7 @@ option to disable safemode prompting.
Perform a memory operation as indicated. The
.Ar memtype
field specifies the memory type to operate on.
The available memory types are device-dependant, the actual
The available memory types are device-dependent, the actual
configuration can be viewed with the
.Cm part
command in terminal mode.
@@ -443,13 +530,31 @@ Motorola S-record
.It Ar r
raw binary; little-endian byte order, in the case of the flash ROM data
.It Ar m
immediate; actual byte values specified on the command line, seperated
immediate; actual byte values specified on the command line, separated
by commas or spaces. This is good for programming fuse bytes without
having to create a single-byte file or enter terminal mode.
.It Ar a
auto detect; valid for input only, and only if the input is not
provided at
.Em stdin .
.It Ar d
decimal; this and the following formats are only valid on output.
They generate one line of output for the respective memory section,
forming a comma-separated list of the values.
This can be particularly useful for subsequent processing, like for
fuse bit settings.
.It Ar h
hexadecimal; each value will get the string
.Em 0x
prepended.
.It Ar o
octal; each value will get a
.Em 0
prepended unless it is less than 8 in which case it gets no prefix.
.It Ar b
binary; each value will get the string
.Em 0b
prepended.
.El
.Pp
The default is to use auto detection for input files, and raw binary
@@ -461,6 +566,14 @@ contains a colon, the
field is no longer optional since the filename part following the colon
would otherwise be misinterpreted as
.Ar format .
.Pp
As an abbreviation, the form
.Fl U Ar filename
is equivalent to specifying
.Fl U Em flash:w: Ns Ar filename Ns :a .
This will only work if
.Ar filename
does not have a colon in it.
.It Fl v
Enable verbose output.
.It Fl V
@@ -575,6 +688,8 @@ microseconds.
Note that unlike STK500 settings, this setting will be reverted to
its default value (approximately 1 microsecond) when the programming
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:
Display the current voltage and master oscillator parameters.
@@ -602,6 +717,33 @@ ll.
10 MISO (from MCU)
18-25 GND
.TE
.Ss debugWire limitations
The debugWire protocol is Atmel's proprietary one-wire (plus ground)
protocol to allow an in-circuit emulation of the smaller AVR devices,
using the
.Ql /RESET
line.
DebugWire mode is initiated by activating the
.Ql DWEN
fuse, and then power-cycling the target.
While this mode is mainly intented for debugging/emulation, it
also offers limited programming capabilities.
Effectively, the only memory areas that can be read or programmed
in this mode are flash ROM and EEPROM.
It is also possible to read out the signature.
All other memory areas cannot be accessed.
There is no
.Em chip erase
functionality in debugWire mode; instead, while reprogramming the
flash ROM, each flash ROM page is erased right before updating it.
This is done transparently by the JTAG ICE mkII (or AVR Dragon).
The only way back from debugWire mode is to initiate a special
sequence of commands to the JTAG ICE mkII (or AVR Dragon), so the
debugWire mode will be temporarily disabled, and the target can
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.
.Sh FILES
.Bl -tag -offset indent -width /dev/ppi0XXX
.It Pa /dev/ppi0
@@ -619,7 +761,31 @@ library
Schematic of programming hardware
.El
.\" .Sh EXAMPLES
.\" .Sh DIAGNOSTICS
.Sh DIAGNOSTICS
.Bd -literal
avrdude: jtagmkII_setparm(): bad response to set parameter command: RSP_FAILED
avrdude: jtagmkII_getsync(): ISP activation failed, trying debugWire
avrdude: Target prepared for ISP, signed off.
avrdude: Please restart avrdude without power-cycling the target.
.Ed
.Pp
If the target AVR has been set up for debugWire mode (i. e. the
.Em DWEN
fuse is programmed), normal ISP connection attempts will fail as
the
.Em /RESET
pin is not available.
When using the JTAG ICE mkII in ISP mode, the message shown indicates
that
.Nm
has guessed this condition, and tried to initiate a debugWire reset
to the target.
When successful, this will leave the target AVR in a state where it
can respond to normal ISP communication again (until the next power
cycle).
Typically, the same command is going to be retried again immediately
afterwards, and will then succeed connecting to the target using
normal ISP communication.
.Sh SEE ALSO
.Xr avr-objcopy 1 ,
.Xr ppi 4 ,
@@ -640,14 +806,17 @@ This man page by
Please report bugs via
.Dl "http://savannah.nongnu.org/bugs/?group=avrdude" .
.Pp
The JTAGICE mkII programmer currently cannot write to the flash ROM
The JTAG ICE programmers currently cannot write to the flash ROM
one byte at a time.
For that reason, updating the flash ROM from terminal mode does not
work.
.Pp
The device IDs used by AVR910 and AVR109 do not match, so the
avr109 (aka. butterfly) programmer might report
.Dl "selected device is not supported by programmer" .
Use the -F option to force
.Nm
to contiue anway.
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.
.Pp
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)
*/
void usleep(unsigned long 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

@@ -7,6 +7,9 @@
%define debug_package %{nil}
%define _with_docs 1
%{?_without_docs: %define _with_docs 0}
Summary: AVRDUDE is software for programming Atmel AVR Microcontrollers.
Name: avrdude
Version: @VERSION@
@@ -20,12 +23,14 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-root
%description
AVRDUDE is software for programming Atmel AVR Microcontrollers.
%if %{_with_docs}
## The avrdude-docs subpackage
%package docs
Summary: Documentation for AVRDUDE.
Group: Documentation
%description docs
Documentation for avrdude in html, postscript and pdf formats.
Documentation for avrdude in info, html, postscript and pdf formats.
%endif
%prep
%setup -q
@@ -33,7 +38,12 @@ Documentation for avrdude in html, postscript and pdf formats.
%build
./configure --prefix=%{_prefix} --sysconfdir=/etc --mandir=%{_mandir} \
--infodir=%{_infodir}
--infodir=%{_infodir} \
%if %{_with_docs}
--enable-doc=yes
%else
--enable-doc=no
%endif
make
@@ -51,34 +61,43 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir
%clean
rm -rf $RPM_BUILD_ROOT
%post
%if %{_with_docs}
%post docs
[ -f %{_infodir}/avrdude.info ] && \
/sbin/install-info %{_infodir}/avrdude.info %{_infodir}/dir || :
[ -f %{_infodir}/avrdude.info.gz ] && \
/sbin/install-info %{_infodir}/avrdude.info.gz %{_infodir}/dir || :
%preun
%preun docs
if [ $1 = 0 ]; then
[ -f %{_infodir}/avrdude.info ] && \
/sbin/install-info --delete %{_infodir}/avrdude.info %{_infodir}/dir || :
[ -f %{_infodir}/avrdude.info.gz ] && \
/sbin/install-info --delete %{_infodir}/avrdude.info.gz %{_infodir}/dir || :
fi
%endif
%files
%defattr(-,root,root)
%{_prefix}/bin/avrdude
%{_mandir}/man1/avrdude.1.gz
%{_infodir}/*info*
%attr(0644,root,root) %config /etc/avrdude.conf
%if %{_with_docs}
%files docs
%doc %{_infodir}/*info*
%doc doc/avrdude-html/*.html
%doc doc/TODO
%doc doc/avrdude.ps
%doc doc/avrdude.pdf
%endif
%changelog
* Fri Sep 23 2005 Galen Seitz <galens@seitzassoc.com>
- Default to enable-doc=yes during configure.
- Move info file to docs package.
- Make building of docs package conditional. Basic idea copied from avr-gcc.
* Wed Aug 27 2003 Theodore A. Roth <troth@openavr.org>
[Thanks to Artur Lipowski <LAL@pro.onet.pl>]
- Do not build debug package.

View File

@@ -2,6 +2,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2006 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
@@ -23,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
***/
@@ -163,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;
@@ -174,6 +173,7 @@ char * avr_op_str(int op)
case AVR_OP_WRITE_HI : return "WRITE_HI"; break;
case AVR_OP_LOADPAGE_LO : return "LOADPAGE_LO"; break;
case AVR_OP_LOADPAGE_HI : return "LOADPAGE_HI"; break;
case AVR_OP_LOAD_EXT_ADDR : return "LOAD_EXT_ADDR"; break;
case AVR_OP_WRITEPAGE : return "WRITEPAGE"; break;
case AVR_OP_CHIP_ERASE : return "CHIP_ERASE"; break;
case AVR_OP_PGM_ENABLE : return "PGM_ENABLE"; break;
@@ -182,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;
@@ -285,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;
@@ -317,7 +317,7 @@ void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
m->max_write_delay,
m->readback[0],
m->readback[1]);
if (verbose > 2) {
if (verbose > 4) {
fprintf(stderr,
"%s Memory Ops:\n"
"%s Oeration Inst Bit Bit Type Bitno Value\n"
@@ -369,6 +369,8 @@ AVRPART * avr_new_part(void)
p->flags = AVRPART_SERIALOK | AVRPART_PARALLELOK | AVRPART_ENABLEPAGEPROGRAMMING;
p->config_file[0] = 0;
p->lineno = 0;
memset(p->signature, 0xFF, 3);
p->ctl_stack_type = CTL_STACK_NONE;
p->mem = lcreat(NULL, 0);
@@ -432,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";
@@ -457,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";
@@ -469,11 +479,11 @@ 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;

View File

@@ -1,6 +1,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2006 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,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
*/
@@ -41,6 +40,7 @@ enum {
AVR_OP_WRITE_HI,
AVR_OP_LOADPAGE_LO,
AVR_OP_LOADPAGE_HI,
AVR_OP_LOAD_EXT_ADDR,
AVR_OP_WRITEPAGE,
AVR_OP_CHIP_ERASE,
AVR_OP_PGM_ENABLE,
@@ -61,6 +61,12 @@ enum { /* these are assigned to reset_disposition of AVRPART */
RESET_IO /* reset pin might be configured as an I/O pin */
};
enum ctl_stack_t {
CTL_STACK_NONE, /* no control stack defined */
CTL_STACK_PP, /* parallel programming control stack */
CTL_STACK_HVSP /* high voltage serial programming control stack */
};
/*
* serial programming instruction bit specifications
*/
@@ -81,9 +87,13 @@ typedef struct opcode {
#define AVRPART_HAS_JTAG 0x0008 /* part has a JTAG i/f */
#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 AVR_DESCLEN 64
#define AVR_IDLEN 32
#define CTL_STACK_SIZE 32
#define FLASH_INSTR_SIZE 3
#define EEPROM_INSTR_SIZE 20
typedef struct avrpart {
char desc[AVR_DESCLEN]; /* long part name */
char id[AVR_IDLEN]; /* short part name */
@@ -92,6 +102,7 @@ typedef struct avrpart {
int chip_erase_delay; /* microseconds */
unsigned char pagel; /* for parallel programming */
unsigned char bs2; /* for parallel programming */
unsigned char signature[3]; /* expected value of signature bytes */
int reset_disposition; /* see RESET_ enums */
int retry_pulse; /* retry program enable by pulsing
this pin (PIN_AVR_*) */
@@ -108,6 +119,30 @@ typedef struct avrpart {
int postdelay; /* stk500 v2 xml file parameter */
int pollmethod; /* stk500 v2 xml file parameter */
enum ctl_stack_t ctl_stack_type; /* what to use the ctl stack for */
unsigned char controlstack[CTL_STACK_SIZE]; /* stk500v2 PP/HVSP ctl stack */
unsigned char flash_instr[FLASH_INSTR_SIZE]; /* flash instructions (debugWire, JTAG) */
unsigned char eeprom_instr[EEPROM_INSTR_SIZE]; /* EEPROM instructions (debugWire, JTAG) */
int hventerstabdelay; /* stk500 v2 hv mode parameter */
int progmodedelay; /* stk500 v2 hv mode parameter */
int latchcycles; /* stk500 v2 hv mode parameter */
int togglevtg; /* stk500 v2 hv mode parameter */
int poweroffdelay; /* stk500 v2 hv mode parameter */
int resetdelayms; /* stk500 v2 hv mode parameter */
int resetdelayus; /* stk500 v2 hv mode parameter */
int hvleavestabdelay; /* stk500 v2 hv mode parameter */
int resetdelay; /* stk500 v2 hv mode parameter */
int chiperasepulsewidth; /* stk500 v2 hv mode parameter */
int chiperasepolltimeout; /* stk500 v2 hv mode parameter */
int chiperasetime; /* stk500 v2 hv mode parameter */
int programfusepulsewidth; /* stk500 v2 hv mode parameter */
int programfusepolltimeout; /* stk500 v2 hv mode parameter */
int programlockpulsewidth; /* stk500 v2 hv mode parameter */
int programlockpolltimeout; /* stk500 v2 hv mode parameter */
int synchcycles; /* stk500 v2 hv mode parameter */
int hvspcmdexedelay; /* stk500 v2 xml file parameter */
unsigned char idr; /* JTAG ICE mkII XML file parameter */
unsigned char rampz; /* JTAG ICE mkII XML file parameter */
unsigned char spmcr; /* JTAG ICE mkII XML file parameter */
@@ -145,6 +180,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);
@@ -157,7 +196,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 */
@@ -165,7 +204,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

@@ -28,47 +28,100 @@
#include <unistd.h>
#include <errno.h>
#if !defined(WIN32NATIVE)
# include <signal.h>
# include <sys/time.h>
#endif
#include "avrdude.h"
#include "avr.h"
#include "pindefs.h"
#include "pgm.h"
#include "par.h"
#include "serbb.h"
#define SLOW_TOGGLE 0
static int delay_decrement;
extern char * progname;
extern int do_cycles;
extern int verbose;
#if !defined(WIN32NATIVE)
static volatile int done;
static int bitbang_setpin(PROGRAMMER * pgm, int pin, int value)
typedef void (*mysighandler_t)(int);
static mysighandler_t saved_alarmhandler;
static void alarmhandler(int signo)
{
if ( pgm->flag )
serbb_setpin(pgm->fd,pin,value);
else
par_setpin(pgm->fd,pin,value);
done = 1;
signal(SIGALRM, saved_alarmhandler);
}
#endif /* !WIN32NATIVE */
return 0;
/*
* Calibrate the microsecond delay loop below.
*/
static void bitbang_calibrate_delay(void)
{
/*
* Right now, we don't have any Win32 implementation for this, so we
* can only run on a preconfigured delay stepping there. The figure
* below should at least be correct within an order of magnitude,
* judging from the auto-calibration figures seen on various Unix
* systems on comparable hardware.
*/
#if defined(WIN32NATIVE)
delay_decrement = 100;
#else /* !WIN32NATIVE */
struct itimerval itv;
volatile int i;
if (verbose >= 2)
fprintf(stderr,
"%s: Calibrating delay loop...",
progname);
i = 0;
done = 0;
saved_alarmhandler = signal(SIGALRM, alarmhandler);
/*
* Set ITIMER_REAL to 100 ms. All known systems have a timer
* granularity of 10 ms or better, so counting the delay cycles
* accumulating over 100 ms should give us a rather realistic
* picture, without annoying the user by a lengthy startup time (as
* an alarm(1) would do). Of course, if heavy system activity
* happens just during calibration but stops before the remaining
* part of AVRDUDE runs, this will yield wrong values. There's not
* much we can do about this.
*/
itv.it_value.tv_sec = 0;
itv.it_value.tv_usec = 100000;
itv.it_interval.tv_sec = itv.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, 0);
while (!done)
i--;
itv.it_value.tv_sec = itv.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, 0);
/*
* Calculate back from 100 ms to 1 us.
*/
delay_decrement = -i / 100000;
if (verbose >= 2)
fprintf(stderr,
" calibrated to %d cycles per us\n",
delay_decrement);
#endif /* WIN32NATIVE */
}
static int bitbang_getpin(PROGRAMMER * pgm, int pin)
/*
* Delay for approximately the number of microseconds specified.
* usleep()'s granularity is usually like 1 ms or 10 ms, so it's not
* really suitable for short delays in bit-bang algorithms.
*/
void bitbang_delay(int us)
{
if ( pgm->flag )
return serbb_getpin(pgm->fd,pin);
else
return par_getpin(pgm->fd,pin);
volatile int del = us * delay_decrement;
while (del > 0)
del--;
}
static int bitbang_highpulsepin(PROGRAMMER * pgm, int pin)
{
if ( pgm->flag )
return serbb_highpulsepin(pgm->fd,pin);
else
return par_highpulsepin(pgm->fd,pin);
}
/*
* transmit and receive a byte of data to/from the AVR device
*/
@@ -82,7 +135,7 @@ static unsigned char bitbang_txrx(PROGRAMMER * pgm, unsigned char byte)
/*
* Write and read one bit on SPI.
* Some notes on timing: Let T be the time it takes to do
* one bitbang_setpin()-call resp. par clrpin()-call, then
* one pgm->setpin()-call resp. par clrpin()-call, then
* - SCK is high for 2T
* - SCK is low for 2T
* - MOSI setuptime is 1T
@@ -99,17 +152,17 @@ static unsigned char bitbang_txrx(PROGRAMMER * pgm, unsigned char byte)
b = (byte >> i) & 0x01;
/* set the data input line as desired */
bitbang_setpin(pgm, pgm->pinno[PIN_AVR_MOSI], b);
pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], b);
bitbang_setpin(pgm, pgm->pinno[PIN_AVR_SCK], 1);
pgm->setpin(pgm, pgm->pinno[PIN_AVR_SCK], 1);
/*
* read the result bit (it is either valid from a previous falling
* edge or it is ignored in the current context)
*/
r = bitbang_getpin(pgm, pgm->pinno[PIN_AVR_MISO]);
r = pgm->getpin(pgm, pgm->pinno[PIN_AVR_MISO]);
bitbang_setpin(pgm, pgm->pinno[PIN_AVR_SCK], 0);
pgm->setpin(pgm, pgm->pinno[PIN_AVR_SCK], 0);
rbyte |= r << i;
}
@@ -120,25 +173,25 @@ static unsigned char bitbang_txrx(PROGRAMMER * pgm, unsigned char byte)
int bitbang_rdy_led(PROGRAMMER * pgm, int value)
{
bitbang_setpin(pgm, pgm->pinno[PIN_LED_RDY], !value);
pgm->setpin(pgm, pgm->pinno[PIN_LED_RDY], !value);
return 0;
}
int bitbang_err_led(PROGRAMMER * pgm, int value)
{
bitbang_setpin(pgm, pgm->pinno[PIN_LED_ERR], !value);
pgm->setpin(pgm, pgm->pinno[PIN_LED_ERR], !value);
return 0;
}
int bitbang_pgm_led(PROGRAMMER * pgm, int value)
{
bitbang_setpin(pgm, pgm->pinno[PIN_LED_PGM], !value);
pgm->setpin(pgm, pgm->pinno[PIN_LED_PGM], !value);
return 0;
}
int bitbang_vfy_led(PROGRAMMER * pgm, int value)
{
bitbang_setpin(pgm, pgm->pinno[PIN_LED_VFY], !value);
pgm->setpin(pgm, pgm->pinno[PIN_LED_VFY], !value);
return 0;
}
@@ -233,14 +286,16 @@ int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
int rc;
int tries;
bitbang_calibrate_delay();
pgm->powerup(pgm);
usleep(20000);
bitbang_setpin(pgm, pgm->pinno[PIN_AVR_SCK], 0);
bitbang_setpin(pgm, pgm->pinno[PIN_AVR_RESET], 0);
pgm->setpin(pgm, pgm->pinno[PIN_AVR_SCK], 0);
pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 0);
usleep(20000);
bitbang_highpulsepin(pgm, pgm->pinno[PIN_AVR_RESET]);
pgm->highpulsepin(pgm, pgm->pinno[PIN_AVR_RESET]);
usleep(20000); /* 20 ms XXX should be a per-chip parameter */
@@ -261,7 +316,7 @@ int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
rc = pgm->program_enable(pgm, p);
if ((rc == 0)||(rc == -1))
break;
bitbang_highpulsepin(pgm, pgm->pinno[p->retry_pulse/*PIN_AVR_SCK*/]);
pgm->highpulsepin(pgm, pgm->pinno[p->retry_pulse/*PIN_AVR_SCK*/]);
tries++;
} while (tries < 65);
@@ -277,4 +332,30 @@ int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
return 0;
}
static void verify_pin_assigned(PROGRAMMER * pgm, int pin, char * desc)
{
if (pgm->pinno[pin] == 0) {
fprintf(stderr, "%s: error: no pin has been assigned for %s\n",
progname, desc);
exit(1);
}
}
/*
* Verify all prerequisites for a bit-bang programmer are present.
*/
void bitbang_check_prerequisites(PROGRAMMER *pgm)
{
verify_pin_assigned(pgm, PIN_AVR_RESET, "AVR RESET");
verify_pin_assigned(pgm, PIN_AVR_SCK, "AVR SCK");
verify_pin_assigned(pgm, PIN_AVR_MISO, "AVR MISO");
verify_pin_assigned(pgm, PIN_AVR_MOSI, "AVR MOSI");
if (pgm->cmd == NULL) {
fprintf(stderr, "%s: error: no cmd() method defined for bitbang programmer\n",
progname);
exit(1);
}
}

View File

@@ -22,9 +22,16 @@
#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);
void bitbang_delay(unsigned int us);
void bitbang_check_prerequisites(PROGRAMMER *pgm);
int bitbang_rdy_led (PROGRAMMER * pgm, int value);
int bitbang_err_led (PROGRAMMER * pgm, int value);
@@ -40,4 +47,8 @@ int bitbang_initialize (PROGRAMMER * pgm, AVRPART * p);
void bitbang_disable (PROGRAMMER * pgm);
void bitbang_enable (PROGRAMMER * pgm);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -44,14 +44,12 @@
#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;
static char has_auto_incr_addr;
static unsigned buffersize = 0;
@@ -69,7 +67,7 @@ static int butterfly_send(PROGRAMMER * pgm, char * buf, size_t len)
{
no_show_func_info();
return serial_send(pgm->fd, (unsigned char *)buf, len);
return serial_send(&pgm->fd, (unsigned char *)buf, len);
}
@@ -79,7 +77,7 @@ static int butterfly_recv(PROGRAMMER * pgm, char * buf, size_t len)
no_show_func_info();
rv = serial_recv(pgm->fd, (unsigned char *)buf, len);
rv = serial_recv(&pgm->fd, (unsigned char *)buf, len);
if (rv < 0) {
fprintf(stderr,
"%s: butterfly_recv(): programmer is not responding\n",
@@ -94,7 +92,7 @@ static int butterfly_drain(PROGRAMMER * pgm, int display)
{
no_show_func_info();
return serial_drain(pgm->fd, display);
return serial_drain(&pgm->fd, display);
}
@@ -226,8 +224,7 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
char hw[2];
char buf[10];
char type;
char c;
int dev_supported = 0;
char c, devtype_1st;
no_show_func_info();
@@ -297,9 +294,9 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
exit(1);
};
butterfly_recv(pgm, &c, 1);
buffersize = c<<8;
buffersize = (unsigned int)(unsigned char)c<<8;
butterfly_recv(pgm, &c, 1);
buffersize += c;
buffersize += (unsigned int)(unsigned char)c;
fprintf(stderr,
"Programmer supports buffered memory access with buffersize=%i bytes.\n",
buffersize);
@@ -308,39 +305,35 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
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);
/* FIXME: Need to lookup devcode and report the device. */
if (p->avr910_devcode == (int)(unsigned char)c)
dev_supported = 1;
};
fprintf(stderr,"\n");
if (!dev_supported) {
/* FIXME: if nothing matched, we should rather compare the device
signatures. */
fprintf(stderr,
"%s: error: selected device is not supported by programmer: %s\n",
progname, p->id);
}
/* 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 (dev_supported)
butterfly_enter_prog_mode(pgm);
butterfly_enter_prog_mode(pgm);
return dev_supported? 0: -1;
return 0;
}
@@ -374,7 +367,7 @@ static int butterfly_open(PROGRAMMER * pgm, char * port)
if(pgm->baudrate == 0) {
pgm->baudrate = 19200;
}
pgm->fd = serial_open(port, pgm->baudrate);
serial_open(port, pgm->baudrate, &pgm->fd);
/*
* drain any extraneous input
@@ -389,15 +382,16 @@ static void butterfly_close(PROGRAMMER * pgm)
{
no_show_func_info();
/* "exit programmer" added by Martin Thomas 2/2004 */
/* "exit programmer" */
butterfly_send(pgm, "E", 1);
butterfly_vfy_cmd_sent(pgm, "exit bootloader");
serial_close(pgm->fd);
pgm->fd = -1;
serial_close(&pgm->fd);
pgm->fd.ifd = -1;
}
static void butterfly_display(PROGRAMMER * pgm, char * p)
static void butterfly_display(PROGRAMMER * pgm, const char * p)
{
no_show_func_info();
@@ -418,12 +412,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;
int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
no_show_func_info();
@@ -441,7 +450,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)
{
@@ -465,6 +478,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;
@@ -473,7 +487,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);
@@ -550,6 +568,7 @@ static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int max_addr = n_bytes;
char *cmd;
unsigned int blocksize = buffersize;
int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
return -2;
@@ -557,7 +576,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);
@@ -598,6 +621,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"))
@@ -610,7 +634,11 @@ static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
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;
@@ -675,17 +703,15 @@ void butterfly_initpgm(PROGRAMMER * pgm)
pgm->powerdown = butterfly_powerdown;
pgm->program_enable = butterfly_program_enable;
pgm->chip_erase = butterfly_chip_erase;
/* pgm->cmd not supported, use default error message */
pgm->open = butterfly_open;
pgm->close = butterfly_close;
pgm->read_byte = butterfly_read_byte;
pgm->write_byte = butterfly_write_byte;
/*
* optional functions
*/
pgm->write_byte = butterfly_write_byte;
pgm->read_byte = butterfly_read_byte;
pgm->paged_write = butterfly_paged_write;
pgm->paged_load = butterfly_paged_load;

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"
@@ -41,6 +41,7 @@ typedef struct token_t {
int primary;
VALUE value;
} TOKEN;
typedef struct token_t *token_p;
extern FILE * yyin;
@@ -48,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[];
@@ -58,13 +61,17 @@ extern char default_serial[];
#if !defined(HAS_YYSTYPE)
#define YYSTYPE struct token_t *
#define YYSTYPE token_p
#endif
extern YYSTYPE yylval;
extern char string_buf[MAX_STR_CONST];
extern char *string_buf_ptr;
#ifdef __cplusplus
extern "C" {
#endif
int yyparse(void);
@@ -88,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

@@ -1,6 +1,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2006 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
@@ -26,6 +27,8 @@
#include <string.h>
#include <math.h>
#include "avrdude.h"
#include "config.h"
#include "lists.h"
#include "par.h"
@@ -35,9 +38,13 @@
#include "pgm.h"
#include "stk500.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"
#if defined(WIN32NATIVE)
@@ -45,8 +52,6 @@
( *(_lasts) = strtok( (_s), (_sep) ) )
#endif
extern char * progname;
int yylex(void);
int yyerror(char * errmsg);
@@ -64,6 +69,7 @@ static int parse_cmdbits(OPCODE * op);
%token K_WRITE_HI
%token K_LOADPAGE_LO
%token K_LOADPAGE_HI
%token K_LOAD_EXT_ADDR
%token K_WRITEPAGE
%token K_CHIP_ERASE
%token K_PGM_ENABLE
@@ -83,6 +89,11 @@ static int parse_cmdbits(OPCODE * op);
%token K_DEFAULT_SERIAL
%token K_DESC
%token K_DEVICECODE
%token K_DRAGON_DW
%token K_DRAGON_HVSP
%token K_DRAGON_ISP
%token K_DRAGON_JTAG
%token K_DRAGON_PP
%token K_STK500_DEVCODE
%token K_AVR910_DEVCODE
%token K_EEPROM
@@ -90,7 +101,10 @@ static int parse_cmdbits(OPCODE * op);
%token K_FLASH
%token K_ID
%token K_IO
%token K_JTAG_MKI
%token K_JTAG_MKII
%token K_JTAG_MKII_DW
%token K_JTAG_MKII_ISP
%token K_LOADPAGE
%token K_MAX_WRITE_DELAY
%token K_MIN_WRITE_DELAY
@@ -114,23 +128,30 @@ static int parse_cmdbits(OPCODE * op);
%token K_SERBB
%token K_SERIAL
%token K_SCK
%token K_SIGNATURE
%token K_SIZE
%token K_STK500
%token K_STK500HVSP
%token K_STK500PP
%token K_STK500V2
%token K_STK500GENERIC
%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
/* stk500 v2 xml file parameters */
/* ISP */
%token K_TIMEOUT
%token K_STABDELAY
%token K_CMDEXEDELAY
%token K_HVSPCMDEXEDELAY
%token K_SYNCHLOOPS
%token K_BYTEDELAY
%token K_POLLVALUE
@@ -142,6 +163,29 @@ static int parse_cmdbits(OPCODE * op);
%token K_DELAY
%token K_BLOCKSIZE
%token K_READSIZE
/* HV mode */
%token K_HVENTERSTABDELAY
%token K_PROGMODEDELAY
%token K_LATCHCYCLES
%token K_TOGGLEVTG
%token K_POWEROFFDELAY
%token K_RESETDELAYMS
%token K_RESETDELAYUS
%token K_HVLEAVESTABDELAY
%token K_RESETDELAY
%token K_SYNCHCYCLES
%token K_HVCMDEXEDELAY
%token K_CHIPERASEPULSEWIDTH
%token K_CHIPERASEPOLLTIMEOUT
%token K_CHIPERASETIME
%token K_PROGRAMFUSEPULSEWIDTH
%token K_PROGRAMFUSEPOLLTIMEOUT
%token K_PROGRAMLOCKPULSEWIDTH
%token K_PROGRAMLOCKPOLLTIMEOUT
%token K_PP_CONTROLSTACK
%token K_HVSP_CONTROLSTACK
/* JTAG ICE mkII specific parameters */
%token K_ALLOWFULLPAGEBITSTREAM /*
@@ -153,10 +197,13 @@ 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_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 */
%token K_EECR /* address of EECR in memory space */
%token K_FLASH_INSTR /* flash instructions */
%token K_EEPROM_INSTR /* EEPROM instructions */
%token TKN_COMMA
%token TKN_EQUAL
@@ -346,24 +393,102 @@ prog_parm :
}
} |
K_TYPE TKN_EQUAL K_STK500HVSP {
{
stk500hvsp_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_STK500PP {
{
stk500pp_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_STK500GENERIC {
{
stk500generic_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_AVR910 {
{
avr910_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_USBASP {
{
usbasp_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_USBTINY {
{
usbtiny_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_BUTTERFLY {
{
butterfly_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_JTAG_MKI {
{
jtagmkI_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_JTAG_MKII {
{
jtagmkII_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_JTAG_MKII_DW {
{
jtagmkII_dw_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_JTAG_MKII_ISP {
{
stk500v2_jtagmkII_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_DRAGON_DW {
{
jtagmkII_dragon_dw_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_DRAGON_HVSP {
{
stk500v2_dragon_hvsp_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_DRAGON_ISP {
{
stk500v2_dragon_isp_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_DRAGON_JTAG {
{
jtagmkII_dragon_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_DRAGON_PP {
{
stk500v2_dragon_pp_initpgm(current_prog);
}
} |
K_DESC TKN_EQUAL TKN_STRING {
strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN);
current_prog->desc[PGM_DESCLEN-1] = 0;
@@ -380,15 +505,7 @@ prog_parm :
while (lsize(number_list)) {
t = lrmv_n(number_list, 1);
pin = t->value.number;
if ((pin < 2) || (pin > 9)) {
fprintf(stderr,
"%s: error at line %d of %s: VCC must be one or more "
"pins from the range 2-9\n",
progname, lineno, infile);
exit(1);
}
current_prog->pinno[PPI_AVR_VCC] |= (1 << (pin-2));
current_prog->pinno[PPI_AVR_VCC] |= (1 << pin);
free_token(t);
}
@@ -405,15 +522,7 @@ prog_parm :
while (lsize(number_list)) {
t = lrmv_n(number_list, 1);
pin = t->value.number;
if ((pin < 2) || (pin > 9)) {
fprintf(stderr,
"%s: error at line %d of %s: BUFF must be one or more "
"pins from the range 2-9\n",
progname, lineno, infile);
exit(1);
}
current_prog->pinno[PPI_AVR_BUFF] |= (1 << (pin-2));
current_prog->pinno[PPI_AVR_BUFF] |= (1 << pin);
free_token(t);
}
@@ -459,6 +568,7 @@ opcode :
K_WRITE_HI |
K_LOADPAGE_LO |
K_LOADPAGE_HI |
K_LOAD_EXT_ADDR |
K_WRITEPAGE |
K_CHIP_ERASE |
K_PGM_ENABLE
@@ -522,6 +632,165 @@ part_parm :
}
} |
K_SIGNATURE TKN_EQUAL TKN_NUMBER TKN_NUMBER TKN_NUMBER {
{
current_part->signature[0] = $3->value.number;
current_part->signature[1] = $4->value.number;
current_part->signature[2] = $5->value.number;
free_token($3);
free_token($4);
free_token($5);
}
} |
K_PP_CONTROLSTACK TKN_EQUAL num_list {
{
TOKEN * t;
unsigned nbytes;
int ok;
if (current_part->ctl_stack_type != CTL_STACK_NONE)
{
fprintf(stderr,
"%s: error at line %d of %s: "
"control stack already defined\n",
progname, lineno, infile);
exit(1);
}
current_part->ctl_stack_type = CTL_STACK_PP;
nbytes = 0;
ok = 1;
while (lsize(number_list)) {
t = lrmv_n(number_list, 1);
if (nbytes < CTL_STACK_SIZE)
{
current_part->controlstack[nbytes] = t->value.number;
nbytes++;
}
else
{
ok = 0;
}
free_token(t);
}
if (!ok)
{
fprintf(stderr,
"%s: Warning: line %d of %s: "
"too many bytes in control stack\n",
progname, lineno, infile);
}
}
} |
K_HVSP_CONTROLSTACK TKN_EQUAL num_list {
{
TOKEN * t;
unsigned nbytes;
int ok;
if (current_part->ctl_stack_type != CTL_STACK_NONE)
{
fprintf(stderr,
"%s: error at line %d of %s: "
"control stack already defined\n",
progname, lineno, infile);
exit(1);
}
current_part->ctl_stack_type = CTL_STACK_HVSP;
nbytes = 0;
ok = 1;
while (lsize(number_list)) {
t = lrmv_n(number_list, 1);
if (nbytes < CTL_STACK_SIZE)
{
current_part->controlstack[nbytes] = t->value.number;
nbytes++;
}
else
{
ok = 0;
}
free_token(t);
}
if (!ok)
{
fprintf(stderr,
"%s: Warning: line %d of %s: "
"too many bytes in control stack\n",
progname, lineno, infile);
}
}
} |
K_FLASH_INSTR TKN_EQUAL num_list {
{
TOKEN * t;
unsigned nbytes;
int ok;
nbytes = 0;
ok = 1;
while (lsize(number_list)) {
t = lrmv_n(number_list, 1);
if (nbytes < FLASH_INSTR_SIZE)
{
current_part->flash_instr[nbytes] = t->value.number;
nbytes++;
}
else
{
ok = 0;
}
free_token(t);
}
if (!ok)
{
fprintf(stderr,
"%s: Warning: line %d of %s: "
"too many bytes in flash instructions\n",
progname, lineno, infile);
}
}
} |
K_EEPROM_INSTR TKN_EQUAL num_list {
{
TOKEN * t;
unsigned nbytes;
int ok;
nbytes = 0;
ok = 1;
while (lsize(number_list)) {
t = lrmv_n(number_list, 1);
if (nbytes < EEPROM_INSTR_SIZE)
{
current_part->eeprom_instr[nbytes] = t->value.number;
nbytes++;
}
else
{
ok = 0;
}
free_token(t);
}
if (!ok)
{
fprintf(stderr,
"%s: Warning: line %d of %s: "
"too many bytes in EEPROM instructions\n",
progname, lineno, infile);
}
}
} |
K_CHIP_ERASE_DELAY TKN_EQUAL TKN_NUMBER
{
current_part->chip_erase_delay = $3->value.number;
@@ -568,6 +837,12 @@ part_parm :
free_token($3);
} |
K_HVSPCMDEXEDELAY TKN_EQUAL TKN_NUMBER
{
current_part->hvspcmdexedelay = $3->value.number;
free_token($3);
} |
K_SYNCHLOOPS TKN_EQUAL TKN_NUMBER
{
current_part->synchloops = $3->value.number;
@@ -610,6 +885,108 @@ part_parm :
free_token($3);
} |
K_HVENTERSTABDELAY TKN_EQUAL TKN_NUMBER
{
current_part->hventerstabdelay = $3->value.number;
free_token($3);
} |
K_PROGMODEDELAY TKN_EQUAL TKN_NUMBER
{
current_part->progmodedelay = $3->value.number;
free_token($3);
} |
K_LATCHCYCLES TKN_EQUAL TKN_NUMBER
{
current_part->latchcycles = $3->value.number;
free_token($3);
} |
K_TOGGLEVTG TKN_EQUAL TKN_NUMBER
{
current_part->togglevtg = $3->value.number;
free_token($3);
} |
K_POWEROFFDELAY TKN_EQUAL TKN_NUMBER
{
current_part->poweroffdelay = $3->value.number;
free_token($3);
} |
K_RESETDELAYMS TKN_EQUAL TKN_NUMBER
{
current_part->resetdelayms = $3->value.number;
free_token($3);
} |
K_RESETDELAYUS TKN_EQUAL TKN_NUMBER
{
current_part->resetdelayus = $3->value.number;
free_token($3);
} |
K_HVLEAVESTABDELAY TKN_EQUAL TKN_NUMBER
{
current_part->hvleavestabdelay = $3->value.number;
free_token($3);
} |
K_RESETDELAY TKN_EQUAL TKN_NUMBER
{
current_part->resetdelay = $3->value.number;
free_token($3);
} |
K_CHIPERASEPULSEWIDTH TKN_EQUAL TKN_NUMBER
{
current_part->chiperasepulsewidth = $3->value.number;
free_token($3);
} |
K_CHIPERASEPOLLTIMEOUT TKN_EQUAL TKN_NUMBER
{
current_part->chiperasepolltimeout = $3->value.number;
free_token($3);
} |
K_CHIPERASETIME TKN_EQUAL TKN_NUMBER
{
current_part->chiperasetime = $3->value.number;
free_token($3);
} |
K_PROGRAMFUSEPULSEWIDTH TKN_EQUAL TKN_NUMBER
{
current_part->programfusepulsewidth = $3->value.number;
free_token($3);
} |
K_PROGRAMFUSEPOLLTIMEOUT TKN_EQUAL TKN_NUMBER
{
current_part->programfusepolltimeout = $3->value.number;
free_token($3);
} |
K_PROGRAMLOCKPULSEWIDTH TKN_EQUAL TKN_NUMBER
{
current_part->programlockpulsewidth = $3->value.number;
free_token($3);
} |
K_PROGRAMLOCKPOLLTIMEOUT TKN_EQUAL TKN_NUMBER
{
current_part->programlockpolltimeout = $3->value.number;
free_token($3);
} |
K_SYNCHCYCLES TKN_EQUAL TKN_NUMBER
{
current_part->synchcycles = $3->value.number;
free_token($3);
} |
K_HAS_JTAG TKN_EQUAL yesno
{
if ($3->primary == K_YES)
@@ -620,6 +997,16 @@ part_parm :
free_token($3);
} |
K_HAS_DW TKN_EQUAL yesno
{
if ($3->primary == K_YES)
current_part->flags |= AVRPART_HAS_DW;
else if ($3->primary == K_NO)
current_part->flags &= ~AVRPART_HAS_DW;
free_token($3);
} |
K_ALLOWFULLPAGEBITSTREAM TKN_EQUAL yesno
{
if ($3->primary == K_YES)
@@ -907,6 +1294,7 @@ static int which_opcode(TOKEN * opcode)
case K_WRITE_HI : return AVR_OP_WRITE_HI; break;
case K_LOADPAGE_LO : return AVR_OP_LOADPAGE_LO; break;
case K_LOADPAGE_HI : return AVR_OP_LOADPAGE_HI; break;
case K_LOAD_EXT_ADDR : return AVR_OP_LOAD_EXT_ADDR; break;
case K_WRITEPAGE : return AVR_OP_WRITEPAGE; break;
case K_CHIP_ERASE : return AVR_OP_CHIP_ERASE; break;
case K_PGM_ENABLE : return AVR_OP_PGM_ENABLE; break;

View File

@@ -24,7 +24,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57)
AC_INIT(avrdude, 5.0cvs, avrdude-dev@nongnu.org)
AC_INIT(avrdude, 5.5, avrdude-dev@nongnu.org)
AC_CANONICAL_BUILD
AC_CANONICAL_HOST
@@ -32,25 +32,41 @@ AC_CANONICAL_TARGET
AC_CONFIG_SRCDIR([main.c])
AM_INIT_AUTOMAKE
AM_CONFIG_HEADER([ac_cfg.h])
AM_CONFIG_HEADER(ac_cfg.h)
# Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_YACC
AM_PROG_LEX
AC_PROG_RANLIB
# Checks for libraries.
AC_CHECK_LIB([termcap], [tputs])
AC_CHECK_LIB([ncurses], [tputs])
AC_CHECK_LIB([readline], [readline])
# usb_get_string_simple is only available in recent enough
# versions of libusb, so use that as a decision base.
AC_CHECK_LIB([usb], [usb_get_string_simple])
AH_TEMPLATE([HAVE_LIBUSB],
[Define if USB support is enabled via libusb])
AC_CHECK_LIB([usb], [usb_get_string_simple], [have_libusb=yes])
if test x$have_libusb = xyes; then
case $target in
*-*-darwin*)
LIBUSB="-lusb -framework CoreFoundation -framework IOKit"
;;
*)
LIBUSB="-lusb"
;;
esac
AC_DEFINE([HAVE_LIBUSB])
fi
AC_SUBST(LIBUSB, $LIBUSB)
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([fcntl.h limits.h stdlib.h string.h sys/ioctl.h sys/time.h termios.h unistd.h])
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
@@ -59,7 +75,49 @@ 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])
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* | *-*-cygwin* | *-*-windows*)
LIBHID="-lhid -lsetupapi"
if test $ac_cv_header_ddk_hidsdi_h = yes
then
HIDINCLUDE="#include <ddk/hidsdi.h>"
else
HIDINCLUDE="#include \"my_ddk_hidsdi.h\""
fi
;;
*)
LIBHID=""
;;
esac
LIBS="${LIBS} ${LIBHID}"
AH_TEMPLATE([HAVE_LIBHID],
[Define if HID support is enabled via the Win32 DDK])
AC_TRY_RUN([#include <windows.h>
#include <setupapi.h>
$HIDINCLUDE
int
main(void)
{
GUID hidGuid;
HidD_GetHidGuid(&hidGuid);
return 0;
}
], [have_libhid=yes], [have_libhid=no], [have_libhid=no])
AC_MSG_RESULT([$have_libhid])
if test x$have_libhid = xyes; then
AC_DEFINE([HAVE_LIBHID])
else
LIBHID=""
fi
LIBS="${SAVED_LIBS}"
AC_SUBST(LIBHID, $LIBHID)
# Checks for misc stuff.
@@ -85,7 +143,7 @@ AC_ARG_ENABLE(
[doc],
AC_HELP_STRING(
[--enable-doc],
[Enable building documents(default)]),
[Enable building documents]),
[case "${enableval}" in
yes) enabled_doc=yes ;;
no) enabled_doc=no ;;
@@ -93,25 +151,35 @@ AC_ARG_ENABLE(
esac],
[enabled_doc=no])
if test "$enabled_doc" = "yes"; then
AC_ARG_ENABLE(
[parport],
AC_HELP_STRING(
[--enable-parport],
[Enable accessing parallel ports(default)]),
[case "${enableval}" in
yes) enabled_parport=yes ;;
no) enabled_parport=no ;;
*) AC_MSG_ERROR(bad value ${enableval} for enable-parport option) ;;
esac],
[enabled_parport=yes])
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 @WINDOWS_DIRS@'
else
SUBDIRS_AC='@WINDOWS_DIRS@'
fi
AC_SUBST(DOC_INST_DIR, $DOC_INST_DIR)
AC_SUBST(SUBDIRS_AC, $SUBDIRS_AC)
AC_SUBST(SUBDIRS_AC, $SUBDIRS_AC)
AC_SUBST(DIST_SUBDIRS_AC, $DIST_SUBDIRS_AC)
# Find the parallel serial device files based on target system
# If a system doesn't have a PC style parallel, mark it as unknown.
case $target in
i[[3456]]86-*-linux*)
i[[3456]]86-*-linux*|x86_64-*-linux*)
DEFAULT_PAR_PORT="/dev/parport0"
DEFAULT_SER_PORT="/dev/ttyS0"
;;
@@ -119,7 +187,7 @@ case $target in
DEFAULT_PAR_PORT="unknown"
DEFAULT_SER_PORT="/dev/ttyS0"
;;
i[[3456]]86-*-freebsd*)
i[[3456]]86-*-freebsd*|amd64-*-freebsd*)
DEFAULT_PAR_PORT="/dev/ppi0"
DEFAULT_SER_PORT="/dev/cuaa0"
;;
@@ -127,6 +195,10 @@ case $target in
DEFAULT_PAR_PORT="unknown"
DEFAULT_SER_PORT="/dev/cuaa0"
;;
*-*-solaris*)
DEFAULT_PAR_PORT="/dev/printers/0"
DEFAULT_SER_PORT="/dev/term/a"
;;
*-*-msdos* | *-*-mingw32* | *-*-cygwin* | *-*-windows*)
DEFAULT_PAR_PORT="lpt1"
DEFAULT_SER_PORT="com1"
@@ -137,20 +209,35 @@ case $target in
;;
esac
AC_MSG_CHECKING([for parallel device])
AC_MSG_RESULT([$DEFAULT_PAR_PORT])
AC_SUBST(DEFAULT_PAR_PORT, $DEFAULT_PAR_PORT)
if test "$enabled_parport" = "yes"; then
AC_MSG_CHECKING([for parallel device])
if test "$DEFAULT_PAR_PORT" = "unknown"; then
AC_MSG_NOTICE([parallel port access disabled for this system])
enabled_parport=no
else
AC_MSG_RESULT([$DEFAULT_PAR_PORT])
fi
AC_SUBST(DEFAULT_PAR_PORT, $DEFAULT_PAR_PORT)
fi
AC_MSG_CHECKING([for serial device])
AC_MSG_RESULT([$DEFAULT_SER_PORT])
AC_SUBST(DEFAULT_SER_PORT, $DEFAULT_SER_PORT)
if test "$enabled_parport" = "yes"; then
AC_DEFINE(HAVE_PARPORT, 1, [parallel port access enabled])
confsubst="-e /^@HAVE_PARPORT_/d"
else
confsubst="-e /^@HAVE_PARPORT_BEGIN@/,/^@HAVE_PARPORT_END@/d"
fi
export confsubst
# See if we need to drop into the windows subdir.
case $target in
*-*-mingw32* | *-*-cygwin* | *-*-windows*)
WINDOWS_DIRS="windows"
CFLAGS="-mno-cygwin -DWIN32NATIVE"
LDFLAGS="-static"
CFLAGS="${CFLAGS} -mno-cygwin -DWIN32NATIVE"
LDFLAGS="${LDFLAGS} -static"
;;
esac
AC_SUBST(WINDOWS_DIRS,$WINDOWS_DIRS)
@@ -161,16 +248,21 @@ 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
avrdude.conf
Makefile
])
AC_OUTPUT
# The procedure to create avrdude.conf involves two steps. First,
# normal autoconf substitution will be applied, resulting in
# avrdude.conf.tmp. Finally, a sed command will be applied to filter
# out unwanted parts (currently the parallel port programmer types)
# based on previous configuration results, thereby producing the final
# avrdude.conf file.
AC_CONFIG_FILES([avrdude.conf.tmp:avrdude.conf.in],
[sed $confsubst avrdude.conf.tmp > avrdude.conf])
AC_OUTPUT

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

22
avrdude/doc/.cvsignore Normal file
View File

@@ -0,0 +1,22 @@
.cvsignore
Makefile
Makefile.in
avrdude-html
avrdude.aux
avrdude.cp
avrdude.cps
avrdude.dvi
avrdude.fn
avrdude.info
avrdude.ky
avrdude.log
avrdude.pdf
avrdude.pg
avrdude.ps
avrdude.toc
avrdude.tp
avrdude.vr
mdate-sh
stamp-vti
texinfo.tex
version.texi

View File

@@ -28,7 +28,9 @@ This file documents the avrdude program.
For avrdude version @value{VERSION}, @value{UPDATED}.
Copyright @copyright{} 2003,2005 Brian Dean
Copyright @copyright{} 2003, 2005 Brian Dean
Copyright @copyright{} 2006, 2007 J@"org Wunsch
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -59,11 +61,13 @@ by the Free Software Foundation.
@author by Brian S. Dean
@page
@hfill (Send bugs and comments on AVRDUDE to @w{@email{avrdude-dev@@nongnu.org}}.)
Send comments on AVRDUDE to @w{@email{avrdude-dev@@nongnu.org}}.
@vfill
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
@sp 2
Permission is granted to make and distribute verbatim copies of
@@ -94,6 +98,14 @@ This file documents the avrdude program for downloading/uploading
programs to Atmel AVR microcontrollers.
For avrdude version @value{VERSION}, @value{UPDATED}.
Send comments on AVRDUDE to @w{@email{avrdude-dev@@nongnu.org}}.
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
@end ifinfo
@menu
@@ -129,8 +141,9 @@ from the contents of a file, while interactive mode is useful for
exploring memory contents, modifing individual bytes of eeprom,
programming fuse/lock bits, etc.
AVRDUDE supports six basic programmer types: Atmel's STK500,
Atmel's JTAG ICE mkII, appnote
AVRDUDE supports the following basic programmer types: Atmel's STK500,
Atmel's AVRISP and AVRISP mkII devices,
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,
and the PPI (parallel port interface). PPI represents a class
@@ -166,9 +179,29 @@ The JTAG ICE also uses a serial communication protocol which is similar
to the STK500 firmware version 2 one. However, as the JTAG ICE is
intented to allow on-chip debugging as well as memory programming, the
protocol is more sophisticated.
(This protocol can also be run on top of USB.)
(The JTAG ICE mkII protocol can also be run on top of USB.)
Only the memory programming functionality of the JTAG ICE is supported
by AVRDUDE.
For the JTAG ICE mkII, JTAG, debugWire and ISP mode are supported.
See below for the limitations of debugWire.
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.
When used in ISP mode, the AVR Dragon behaves similar to an
AVRISP mkII (or JTAG ICE mkII in ISP mode), so all device-specific
comments will apply there.
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 and USBtinyISP adapters are also supported, provided AVRDUDE
has been compiled with libusb support.
They both feature simple firwmare-only USB implementations, running on
an ATmega8 (or ATmega88), or ATtiny2313, respectively.
@menu
* History::
@@ -223,9 +256,9 @@ Roth.
@noindent
AVRDUDE is a command line tool, used as follows:
@example
@smallexample
avrdude -p partno @var{options} @dots{}
@end example
@end smallexample
@noindent
Command line options are used to control AVRDUDE's behaviour. The
@@ -242,140 +275,67 @@ but it can be added to the configuration file if you have the Atmel
datasheet so that you can enter the programming specifications.
Currently, the following MCU types are understood:
@table @code
@itemx c128
AT90CAN128
@itemx pwm2
AT90PWM2
@itemx pwm3
AT90PWM3
@itemx 1200
AT90S1200
@itemx 2313
AT90S2313
@itemx 2333
AT90S2333
@itemx 2343
AT90S2343 (*)
@itemx 4414
AT90S4414
@itemx 4433
AT90S4433
@itemx 4434
AT90S4434
@itemx 8515
AT90S8515
@itemx 8535
AT90S8535
@itemx m103
ATmega103
@itemx m128
ATmega128
@itemx m16
ATmega16
@itemx m161
ATmega161
@itemx m162
ATmega162
@itemx m163
ATmega163
@itemx m164
ATmega164
@itemx m169
ATmega169
@itemx m32
ATmega32
@itemx m324
ATmega324
@itemx m329
ATmega329
@itemx m3290
ATmega3290
@itemx m48
ATmega48
@itemx m64
ATmega64
@itemx m644
ATmega644
@itemx m649
ATmega649
@itemx m6490
ATmega6490
@itemx m8
ATmega8
@itemx m8515
ATmega8515
@itemx m8535
ATmega8535
@itemx m88
ATmega88
@itemx t12
ATtiny12
@itemx t13
ATtiny13
@itemx t15
ATtiny15
@itemx t2313
ATtiny2313
@itemx t25
ATtiny25
@itemx t26
ATtiny26
@itemx t45
ATtiny45
@itemx t85
ATtiny85
@end table
@multitable @columnfractions .15 .3
@item @code{c128} @tab AT90CAN128
@item @code{pwm2} @tab AT90PWM2
@item @code{pwm3} @tab AT90PWM3
@item @code{1200} @tab AT90S1200
@item @code{2313} @tab AT90S2313
@item @code{2333} @tab AT90S2333
@item @code{2343} @tab AT90S2343 (*)
@item @code{4414} @tab AT90S4414
@item @code{4433} @tab AT90S4433
@item @code{4434} @tab AT90S4434
@item @code{8515} @tab AT90S8515
@item @code{8535} @tab AT90S8535
@item @code{m103} @tab ATmega103
@item @code{m128} @tab ATmega128
@item @code{m1280} @tab ATmega1280
@item @code{m1281} @tab ATmega1281
@item @code{m16} @tab ATmega16
@item @code{m161} @tab ATmega161
@item @code{m162} @tab ATmega162
@item @code{m163} @tab ATmega163
@item @code{m164} @tab ATmega164
@item @code{m169} @tab ATmega169
@item @code{m2560} @tab ATmega2560 (**)
@item @code{m2561} @tab ATmega2561 (**)
@item @code{m32} @tab ATmega32
@item @code{m324} @tab ATmega324
@item @code{m329} @tab ATmega329
@item @code{m3290} @tab ATmega3290
@item @code{m48} @tab ATmega48
@item @code{m64} @tab ATmega64
@item @code{m640} @tab ATmega640
@item @code{m644} @tab ATmega644
@item @code{m649} @tab ATmega649
@item @code{m6490} @tab ATmega6490
@item @code{m8} @tab ATmega8
@item @code{m8515} @tab ATmega8515
@item @code{m8535} @tab ATmega8535
@item @code{m88} @tab ATmega88
@item @code{t12} @tab ATtiny12
@item @code{t13} @tab ATtiny13
@item @code{t15} @tab ATtiny15
@item @code{t2313} @tab ATtiny2313
@item @code{t25} @tab ATtiny25
@item @code{t26} @tab ATtiny26
@item @code{t45} @tab ATtiny45
@item @code{t85} @tab ATtiny85
@end multitable
(*) The AT90S2323 and ATtiny22 use the same algorithm.
(**) Flash addressing above 128 KB is not supported by all
programming hardware. Known to work are jtag2, stk500v2,
and bit-bang programmers.
@item -b @var{baudrate}
Override the RS-232 connection baud rate specified in the respective
programmer's entry of the configuration file.
@item -B @var{bitclock}
Specify the bit clock period for the JTAG interface (JTAG ICE only).
Specify the bit clock period for the JTAG interface or the ISP clock (JTAG ICE only).
The value is a floating-point number in microseconds.
The default value of the JTAG ICE results in about 1 microsecond bit
clock period, suitable for target MCUs running at 4 MHz clock and
@@ -397,70 +357,120 @@ file without any code changes to AVRDUDE. Simply copy an existing entry
and change the pin definitions to match that of the unknown programmer.
Currently, the following programmer ids are understood and supported:
@table @code
@itemx abcmini
@multitable @columnfractions .2 .6
@item @code{abcmini} @tab
ABCmini Board, aka Dick Smith HOTCHIP
@itemx alf
Nightshade ALF-PgmAVR, http://nightshade.homeip.net/
@itemx avr109
@item @code{alf} @tab
Nightshade ALF-PgmAVR,@*
@url{http://nightshade.homeip.net/}
@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
@itemx avr910
@item @code{avr910} @tab
Atmel Low Cost Serial Programmer
@itemx avr911
@item @code{avr911} @tab
Atmel AppNote AVR911 AVROSP (an alias for avr109)
@itemx avrisp
Atmel AVR ISP
@itemx bascom
@item @code{avrisp} @tab
Atmel AVR ISP (an alias for stk500)
@item @code{avrisp2} @tab
Atmel AVR ISP mkII (alias for stk500v2)
@item @code{avrispmkII} @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
@itemx bsd
Brian Dean's Programmer, http://www.bsdhome.com/avrdude/
@itemx butterfly
@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
@itemx 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
AVR Dragon in high-voltage serial programming mode
@item @code{dragon_isp} @tab
AVR Dragon in ISP mode
@item @code{dragon_jtag} @tab
AVR Dragon in JTAG mode
@item @code{dragon_pp} @tab
AVR Dragon in (high-voltage) parallel programming mode
@item @code{dt006} @tab
Dontronics DT006
@item jtagmkII
@itemx jtag2slow
@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
Atmel JTAG ICE mkI, running at 115200 Bd
@item @code{jtag1slow} @tab
Atmel JTAG ICE mkI, running at 19200 Bd
@item @code{jtag2slow} @tab
Atmel JTAG ICE mkII (default speed 19200 Bd)
@itemx jtag2fast
@item @code{jtag2} @tab
Atmel JTAG ICE mkII, running at 115200 Bd
@itemx jtag2
Same as before.
@itemx pavr
@item @code{jtag2fast} @tab
Atmel JTAG ICE mkII, running at 115200 Bd
@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{pavr} @tab
Jason Kyle's pAVR Serial Programmer
@itemx picoweb
Picoweb Programming Cable, http://www.picoweb.net/
@itemx pony-stk200
@item @code{picoweb} @tab
Picoweb Programming Cable,@*
@url{http://www.picoweb.net/}
@item @code{pony-stk200} @tab
Pony Prog STK200
@itemx sp12
@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
@itemx stk200
@item @code{stk200} @tab
STK200
@itemx stk500
Atmel STK500
@itemx stk500v2
Atmel STK500, running a verrsion 2.x firmware
@end table
@item @code{stk500} @tab
Atmel STK500, probing for either version 1.x or 2.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{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
@@ -534,10 +544,34 @@ 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.
@item -i @var{delay}
For bitbang-type programmers, delay for approximately
@var{delay}
microseconds between each bit state change.
If the host system is very fast, or the target runs off a slow clock
(like a 32 kHz crystal, or the 128 kHz internal RC oscillator), this
can become necessary to satisfy the requirement that the ISP clock
frequency must not be higher than 1/4 of the CPU clock frequency.
This is implemented as a spin-loop delay to allow even for very
short delays.
On Unix-style operating systems, the spin loop is initially calibrated
against a system timer, so the number of microseconds might be rather
realistic, assuming a constant system load while AVRDUDE is running.
On Win32 operating systems, a preconfigured number of cycles per
microsecond is assumed that might be off a bit for very fast or very
slow machines.
@item -n
No-write - disables actually writing data to the MCU (useful for
debugging AVRDUDE).
@item -O
Perform a RC oscillator run-time calibration according to Atmel
application note AVR053.
This is only supported on the STK500v2, AVRISP mkII, and JTAG ICE mkII
hardware.
Note that the result will be stored in the EEPROM cell at address 0.
@item -P @var{port}
Use port to identify the device to which the programmer is attached.
Normally, the default parallel port is used, but if the programmer type
@@ -548,12 +582,38 @@ parallel or serial port, use this option to specify the alternate port name.
For the JTAG ICE mkII, if AVRDUDE has been built with libusb support,
@var{port} may alternatively be specified as
@var{usb}[:@var{serialno}]. In that case, the JTAG ICE mkII will be
@code{usb}[:@var{serialno}]. In that case, the JTAG ICE mkII will be
looked up on USB. If @var{serialno} is also specified, it will be
matched against the serial number read from any JTAG ICE mkII found on
USB. The match is done after stripping any existing colons from the
given serial number, and right-to-left, so only the least significant
bytes from the serial number need to be given.
For a trick how to find out the serial numbers of all JTAG ICEs
attached to USB, see @ref{Example Command Line Invocations}.
As the AVRISP mkII device can only be talked to over USB, the very
same method of specifying the port is required there.
For the USB programmer "AVR-Doper" running in HID mode, the port must
be specified as @var{avrdoper}. Libusb support is required on Unix
but not on Windows. For more information about AVR-Doper see
@url{http://www.obdev.at/avrusb/avrdoper.html}.
For programmers that attach to a serial port using some kind of
higher level protocol (as opposed to bit-bang style programmers),
@var{port} can be specified as @code{net}:@var{host}:@var{port}.
In this case, instead of trying to open a local device, a TCP
network connection to (TCP) @var{port} on @var{host}
is established.
The remote endpoint is assumed to be a terminal or console server
that connects the network stream to a local serial port where the
actual programmer has been attached to.
The port is assumed to be properly configured, for example using a
transparent 8-bit data connection without parity at 115200 Baud
for a STK500.
@emph{This feature is currently not implemented for Win32 systems.}
@item -q
Disable (or quell) output of the progress bar while reading or writing
@@ -650,6 +710,23 @@ treated as decimal.
auto detect; valid for input only, and only if the input is not provided
at stdin.
@itemx d
decimal; this and the following formats are only valid on output.
They generate one line of output for the respective memory section,
forming a comma-separated list of the values.
This can be particularly useful for subsequent processing, like for
fuse bit settings.
@itemx h
hexadecimal; each value will get the string @emph{0x} prepended.
@itemx o
octal; each value will get a @emph{0}
prepended unless it is less than 8 in which case it gets no prefix.
@itemx b
binary; each value will get the string @emph{0b} prepended.
@end table
The default is to use auto detection for input files, and raw binary
@@ -659,6 +736,11 @@ Note that if @var{filename} contains a colon, the @var{format} field is
no longer optional since the filename part following the colon would
otherwise be misinterpreted as @var{format}.
As an abbreviation, the form @code{-U} @var{filename}
is equivalent to specifying
@code{-U} @emph{flash:w:}@var{filename}@emph{:a}.
This will only work if @var{filename} does not have a colon in it.
@item -v
Enable verbose output.
@@ -699,7 +781,7 @@ should not be used.
Download the file @code{diag.hex} to the ATmega128 chip using the
STK500 programmer connected to the default serial port:
@example
@smallexample
@cartouche
% avrdude -p m128 -c stk500 -e -U flash:w:diag.hex
@@ -735,7 +817,7 @@ avrdude done. Thank you.
%
@end cartouche
@end example
@end smallexample
@page
@noindent
@@ -743,7 +825,7 @@ Upload the flash memory from the ATmega128 connected to the STK500
programmer and save it in raw binary format in the file named
@code{c:/diag flash.bin}:
@example
@smallexample
@cartouche
% avrdude -p m128 -c stk500 -U flash:r:"c:/diag flash.bin":r
@@ -764,7 +846,7 @@ avrdude done. Thank you.
%
@end cartouche
@end example
@end smallexample
@page
@noindent
@@ -772,7 +854,7 @@ Using the default programmer, download the file @code{diag.hex} to
flash, @code{eeprom.hex} to EEPROM, and set the Extended, High, and Low
fuse bytes to 0xff, 0x89, and 0x2e respectively:
@example
@smallexample
@cartouche
% avrdude -p m128 -u -U flash:w:diag.hex \
@@ -813,14 +895,14 @@ avrdude done. Thank you.
%
@end cartouche
@end example
@end smallexample
@page
@noindent
Connect to the JTAG ICE mkII which serial number ends up in 1C37 via
USB, and enter terminal mode:
@example
@smallexample
@cartouche
% avrdude -c jtag2 -p m649 -P usb:1c:37 -t
@@ -836,8 +918,27 @@ avrdude: Device signature = 0x1e9603
avrdude done. Thank you.
@end cartouche
@end example
@end smallexample
@noindent
List the serial numbers of all JTAG ICEs attached to USB. This is
done by specifying an invalid serial number, and increasing the
verbosity level.
@smallexample
@cartouche
% avrdude -c jtag2 -p m128 -P usb:xx -v
[...]
Using Port : usb:xxx
Using Programmer : jtag2
avrdude: usbdev_open(): Found JTAG ICE, serno: 00A000001C6B
avrdude: usbdev_open(): Found JTAG ICE, serno: 00A000001C3A
avrdude: usbdev_open(): Found JTAG ICE, serno: 00A000001C30
avrdude: usbdev_open(): did not find any (matching) USB device "usb:xxx"
@end cartouche
@end smallexample
@c
@@ -939,6 +1040,8 @@ Set the JTAG ICE bit clock period to @var{period} microseconds.
Note that unlike STK500 settings, this setting will be reverted to
its default value (approximately 1 microsecond) when the programming
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.
@item parms
@emph{STK500 only:}
@@ -958,7 +1061,7 @@ Display the current target supply voltage and JTAG bit clock rate/period.
@noindent
Display part parameters, modify eeprom cells, perform a chip erase:
@example
@smallexample
@cartouche
% avrdude -p m128 -c stk500 -t
@@ -1010,7 +1113,7 @@ avrdude> dump eeprom 0 16
avrdude>
@end cartouche
@end example
@end smallexample
@noindent
@@ -1020,7 +1123,7 @@ rising power). Note since we are working with fuse bits the -u (unsafe)
option is specified, which allows you to modify the fuse bits. First
display the factory defaults, then reprogram:
@example
@smallexample
@cartouche
% avrdude -p m128 -u -c stk500 -t
@@ -1050,7 +1153,7 @@ avrdude> w lfuse 0 0x2f
avrdude>
@end cartouche
@end example
@end smallexample
@c
@@ -1119,7 +1222,7 @@ option.
@noindent
The format of the programmer definition is as follows:
@example
@smallexample
programmer
id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
desc = <description> ; # quoted string
@@ -1135,7 +1238,7 @@ programmer
pgmled = <num> ; # pin number
vfyled = <num> ; # pin number
;
@end example
@end smallexample
@c
@@ -1144,7 +1247,7 @@ programmer
@node Part Definitions, Other Notes, Programmer Definitions, Configuration File
@section Part Definitions
@example
@smallexample
part
id = <id> ; # quoted string
desc = <description> ; # quoted string
@@ -1177,7 +1280,7 @@ part
writepage = <instruction format> ;
;
;
@end example
@end smallexample
@menu
* Instruction Format::
@@ -1226,7 +1329,7 @@ specification closely follows the instruction data provided in Atmel's
data sheets for their parts. For example, the EEPROM read and write
instruction for an AT90S2313 AVR part could be encoded as:
@example
@smallexample
read = "1 0 1 0 0 0 0 0 x x x x x x x x",
"x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
@@ -1234,7 +1337,7 @@ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
write = "1 1 0 0 0 0 0 0 x x x x x x x x",
"x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
@end example
@end smallexample
@@ -1464,6 +1567,9 @@ The following table lists the default names for a given system.
@item Linux
@tab @code{/dev/parport0}
@tab @code{/dev/ttyS0}
@item Solaris
@tab @code{/dev/printers/0}
@tab @code{/dev/term/a}
@end multitable
On FreeBSD systems, AVRDUDE uses the ppi(4) interface for
@@ -1474,6 +1580,10 @@ On Linux systems, AVRDUDE uses the ppdev interface for
accessing the parallel port and the tty driver for serial port
access.
On Solaris systems, AVRDUDE uses the ecpp(7D) driver for
accessing the parallel port and the asy(7D) driver for serial port
access.
@c
@c Node
@c
@@ -1750,6 +1860,7 @@ line driven and for writing the batch files.
@noindent
In general, please report any bugs encountered via
@*
@url{http://savannah.nongnu.org/bugs/?group=avrdude}.
@@ -1791,35 +1902,104 @@ Problem: I'm not using linux and my AVR910 programmer is really slow.
Solutions: The reasons for this are the same as above.
If you know how to work around this on your OS, please let us know.
@item
Problem: I cannot modify the fuse bits on my AVR!
Solution: You probably forgot to specify the -u option, which allows you to modify fuse bits.
This is done to prevent corrupt data from changing the fuse bits without you knowing about it, and
currently also prevents the user from changing the fuse bits by accident. This patch was added in
response to a number of occasions when an AVR had stopped responding because the fuse bits got changed
by an error caused by the programmer. Programmer of course meaning both the physical device, and the
person sitting at the keyboard.
@item
Problem: AVRDUDE says my device is not supported when using the AVR109 boot loader
Solution: Currently, AVRDUDE uses the AVR910 device codes given in the
@code{avrdude.conf} file, and matches them against the list of supported
devices reported by the programmer. Unfortunately, there are no device
codes at all for some of the newer AVR devices, and even worse, the
device codes listed in @code{preprocessor.xls} of appnote AVR109 do not
match those once specified in AVR910.
Use the -F option to force AVRDUDE to continue anyway.
@item
Problem: Updating the flash ROM from terminal mode does not work with the
JTAG ICE mkII.
JTAG ICEs.
Solution: None at this time. Currently, the JTAG ICE mkII code cannot
Solution: None at this time. Currently, the JTAG ICE code cannot
write to the flash ROM one byte at a time.
@item
Problem: Page-mode programming the EEPROM (using the -U option) does
not erase EEPROM cells before writing, and thus cannot overwrite any
previous value != 0xff.
Solution: None. This is an inherent feature of the way JTAG EEPROM
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.
@item
Problem: How do I turn off the @var{DWEN} fuse?
Solution: If the @var{DWEN} (debugWire enable) fuse is activated,
the @var{/RESET} pin is not functional anymore, so normal ISP
communication cannot be established.
There are two options to deactivate that fuse again: high-voltage
programming, or getting the JTAG ICE mkII talk debugWire, and
prepare the target AVR to accept normal ISP communication again.
The first option requires a programmer that is capable of high-voltage
programming (either serial or parallel, depending on the AVR device),
for example the STK500. In high-voltage programming mode, the
@var{/RESET} pin is activated initially using a 12 V pulse (thus the
name @emph{high voltage}), so the target AVR can subsequently be
reprogrammed, and the @var{DWEN} fuse can be cleared. Typically, this
operation cannot be performed while the AVR is located in the target
circuit though.
The second option requires a JTAG ICE mkII that can talk the debugWire
protocol. The ICE needs to be connected to the target using the
JTAG-to-ISP adapter, so the JTAG ICE mkII can be used as a debugWire
initiator as well as an ISP programmer. AVRDUDE will then be activated
using the @var{jtag2isp} programmer type. The initial ISP
communication attempt will fail, but AVRDUDE then tries to iniate a
debugWire reset. When successful, this will leave the target AVR in a
state where it can accept standard ISP communication. The ICE is then
signed off (which will make it signing off from the USB as well), so
AVRDUDE has to be called again afterwards. This time, standard ISP
communication can work, so the @var{DWEN} fuse can be cleared.
The pin mapping for the JTAG-to-ISP adapter is:
@multitable @columnfractions .2 .2
@item @strong{JTAG pin} @tab @strong{ISP pin}
@item 1 @tab 3
@item 2 @tab 6
@item 3 @tab 1
@item 4 @tab 2
@item 6 @tab 5
@item 9 @tab 4
@end multitable
@item
Problem: Multiple USBasp or USBtinyISP programmers connected simultaneously are not
found.
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 of them is supported.
@item
Problem: I cannot do @dots{} when the target is in debugWire mode.
Solution: debugWire mode imposes several limitations.
The debugWire protocol is Atmel's proprietary one-wire (plus ground)
protocol to allow an in-circuit emulation of the smaller AVR devices,
using the @var{/RESET} line.
DebugWire mode is initiated by activating the @var{DWEN}
fuse, and then power-cycling the target.
While this mode is mainly intented for debugging/emulation, it
also offers limited programming capabilities.
Effectively, the only memory areas that can be read or programmed
in this mode are flash ROM and EEPROM.
It is also possible to read out the signature.
All other memory areas cannot be accessed.
There is no
@emph{chip erase}
functionality in debugWire mode; instead, while reprogramming the
flash ROM, each flash ROM page is erased right before updating it.
This is done transparently by the JTAG ICE mkII (or AVR Dragon).
The only way back from debugWire mode is to initiate a special
sequence of commands to the JTAG ICE mkII (or AVR Dragon), so the
debugWire mode will be temporarily disabled, and the target can
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.
@end itemize

View File

@@ -28,6 +28,7 @@
#include <errno.h>
#include <ctype.h>
#include "avrdude.h"
#include "avr.h"
#include "fileio.h"
@@ -46,38 +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 fmt_autodetect(char * fname);
static int fileio_num(struct fioparms * fio,
char * filename, FILE * f, unsigned char * buf, int size,
FILEFMT fmt);
static int fmt_autodetect(char * fname);
@@ -94,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)
{
@@ -172,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];
@@ -261,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 ];
@@ -356,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)
{
@@ -462,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];
@@ -538,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 ];
@@ -658,8 +659,47 @@ int srec2b(char * infile, FILE * inf,
return maxaddr;
}
/*
* Simple itoa() implementation. Caller needs to allocate enough
* space in buf. Only positive integers are handled.
*/
static char *itoa_simple(int n, char *buf, int base)
{
div_t q;
char c, *cp, *cp2;
int fileio_rbin(struct fioparms * fio,
cp = buf;
/*
* Divide by base until the number disappeared, but ensure at least
* one digit will be emitted.
*/
do {
q = div(n, base);
n = q.quot;
if (q.rem >= 10)
c = q.rem - 10 + 'a';
else
c = q.rem + '0';
*cp++ = c;
} while (q.quot != 0);
/* Terminate the string. */
*cp-- = '\0';
/* Now revert the result string. */
cp2 = buf;
while (cp > cp2) {
c = *cp;
*cp-- = *cp2;
*cp2++ = c;
}
return buf;
}
static int fileio_rbin(struct fioparms * fio,
char * filename, FILE * f, unsigned char * buf, int size)
{
int rc;
@@ -689,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;
@@ -703,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",
@@ -732,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;
@@ -762,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;
@@ -793,6 +837,78 @@ int fileio_srec(struct fioparms * fio,
}
static int fileio_num(struct fioparms * fio,
char * filename, FILE * f, unsigned char * buf, int size,
FILEFMT fmt)
{
const char *prefix;
char cbuf[20];
int base, i, num;
switch (fmt) {
case FMT_HEX:
prefix = "0x";
base = 16;
break;
default:
case FMT_DEC:
prefix = "";
base = 10;
break;
case FMT_OCT:
prefix = "0";
base = 8;
break;
case FMT_BIN:
prefix = "0b";
base = 2;
break;
}
switch (fio->op) {
case FIO_WRITE:
break;
default:
fprintf(stderr, "%s: fileio: invalid operation=%d\n",
progname, fio->op);
return -1;
}
for (i = 0; i < size; i++) {
if (i > 0) {
if (putc(',', f) == EOF)
goto writeerr;
}
num = (unsigned int)buf[i];
/*
* For a base of 8 and a value < 8 to convert, don't write the
* prefix. The conversion will be indistinguishable from a
* decimal one then.
*/
if (prefix[0] != '\0' && !(base == 8 && num < 8)) {
if (fputs(prefix, f) == EOF)
goto writeerr;
}
itoa_simple(num, cbuf, base);
if (fputs(cbuf, f) == EOF)
goto writeerr;
}
if (putc('\n', f) == EOF)
goto writeerr;
return 0;
writeerr:
fprintf(stderr, "%s: error writing to %s: %s\n",
progname, filename, strerror(errno));
return -1;
}
int fileio_setparms(int op, struct fioparms * fp)
{
fp->op = op;
@@ -824,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];
@@ -911,7 +1027,7 @@ int fileio(int op, char * filename, FILEFMT format,
if (rc < 0)
return -1;
#if defined(WIN32NATIVE)
#if defined(WIN32NATIVE)
/* Open Raw Binary format in binary mode on Windows.*/
if(format == FMT_RBIN)
{
@@ -924,7 +1040,7 @@ int fileio(int op, char * filename, FILEFMT format,
fio.mode = "wb";
}
}
#endif
#endif
/* point at the requested memory buffer */
buf = mem->buf;
@@ -1005,6 +1121,13 @@ int fileio(int op, char * filename, FILEFMT format,
rc = fileio_imm(&fio, fname, f, buf, size);
break;
case FMT_HEX:
case FMT_DEC:
case FMT_OCT:
case FMT_BIN:
rc = fileio_num(&fio, fname, f, buf, size, format);
break;
default:
fprintf(stderr, "%s: invalid %s file format: %d\n",
progname, fio.iodesc, format);

View File

@@ -19,15 +19,19 @@
/* $Id$ */
#ifndef __fileio_h__
#define __fileio_h__
#ifndef fileio_h
#define fileio_h
typedef enum {
FMT_AUTO,
FMT_SREC,
FMT_IHEX,
FMT_RBIN,
FMT_IMM
FMT_IMM,
FMT_HEX,
FMT_DEC,
FMT_OCT,
FMT_BIN
} FILEFMT;
struct fioparms {
@@ -43,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

40
avrdude/freebsd_ppi.h Normal file
View File

@@ -0,0 +1,40 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2005 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 freebsd_ppi_h
#define freebsd_ppi_h
#include <dev/ppbus/ppi.h>
#define ppi_claim(fd) {}
#define ppi_release(fd) {}
#define DO_PPI_READ(fd, reg, valp) \
(void)ioctl(fd, \
(reg) == PPIDATA? PPIGDATA: ((reg) == PPICTRL? PPIGCTRL: PPIGSTATUS), \
valp)
#define DO_PPI_WRITE(fd, reg, valp) \
(void)ioctl(fd, \
(reg) == PPIDATA? PPISDATA: ((reg) == PPICTRL? PPISCTRL: PPISSTATUS), \
valp)
#endif /* freebsd_ppi_h */

1378
avrdude/jtagmkI.c Normal file

File diff suppressed because it is too large Load Diff

36
avrdude/jtagmkI.h Normal file
View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2002-2004, 2006 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,7 +22,25 @@
#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);
int jtagmkII_getsync(PROGRAMMER * pgm, int mode);
int jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm,
unsigned char * value);
void jtagmkII_initpgm (PROGRAMMER * pgm);
void jtagmkII_dw_initpgm (PROGRAMMER * pgm);
void jtagmkII_dragon_initpgm (PROGRAMMER * pgm);
void jtagmkII_dragon_dw_initpgm (PROGRAMMER * pgm);
#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, 2006 Joerg Wunsch <j@uriah.heep.sax.de>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -26,6 +26,7 @@
* Taken from Appnote AVR067
*/
#if !defined(JTAGMKII_PRIVATE_EXPORTED)
/*
* Communication with the JTAG ICE works in frames. The protocol
* somewhat resembles the STK500v2 protocol, yet it is sufficiently
@@ -71,6 +72,8 @@
*/
#define MAX_MESSAGE 100000
#endif /* JTAGMKII_PRIVATE_EXPORTED */
/* ICE command codes */
#define CMND_CHIP_ERASE 0x13
#define CMND_CLEAR_EVENTS 0x22
@@ -83,6 +86,7 @@
#define CMND_GET_SIGN_ON 0x01
#define CMND_GET_SYNC 0x0f
#define CMND_GO 0x08
#define CMND_ISP_PACKET 0x2F
#define CMND_LEAVE_PROGMODE 0x15
#define CMND_READ_MEMORY 0x05
#define CMND_READ_PC 0x07
@@ -173,7 +177,7 @@
#define PAR_EMULATOR_MODE 0x03
# define EMULATOR_MODE_DEBUGWIRE 0x00
# define EMULATOR_MODE_JTAG 0x01
# define EMULATOR_MODE_UNKNOWN 0x02
# define EMULATOR_MODE_HV 0x02 /* HVSP or PP mode of AVR Dragon */
# define EMULATOR_MODE_SPI 0x03
#define PAR_IREG 0x04
#define PAR_BAUD_RATE 0x05
@@ -232,6 +236,7 @@
# define PAGEPROG_NOT_ALLOWED 0x00
# define PAGEPROG_ALLOWED 0x01
#if !defined(JTAGMKII_PRIVATE_EXPORTED)
/*
* In appnote AVR067, struct device_descriptor is written with
* int/long field types. We cannot use them directly, as they were
@@ -288,3 +293,4 @@ struct device_descriptor
/* new as of early 2005, firmware 4.x */
unsigned char EECRAddress[2]; /* EECR memory-mapped IO address */
};
#endif /* JTAGMKII_PRIVATE_EXPORTED */

169
avrdude/jtagmkI_private.h Normal file
View File

@@ -0,0 +1,169 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2005 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
* 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$ */
/*
* JTAG ICE mkI definitions
*/
/* ICE command codes */
/* 0x20 Get Synch [Resp_OK] */
#define CMD_GET_SYNC ' '
/* 0x31 Single Step [Sync_CRC/EOP] [Resp_OK] */
/* 0x32 Read PC [Sync_CRC/EOP] [Resp_OK] [program counter]
* [Resp_OK] */
/* 0x33 Write PC [program counter] [Sync_CRC/EOP] [Resp_OK]
* [Resp_OK] */
/* 0xA2 Firmware Upgrade [upgrade string] [Sync_CRC/EOP] [Resp_OK]
* [Resp_OK] */
/* 0xA0 Set Device Descriptor [device info] [Sync_CRC/EOP] [Resp_OK]
* [Resp_OK] */
#define CMD_SET_DEVICE_DESCRIPTOR 0xA0
/* 0x42 Set Parameter [parameter] [setting] [Sync_CRC/EOP] [Resp_OK]
* [Resp_OK] */
#define CMD_SET_PARAM 'B'
/* 0x46 Forced Stop [Sync_CRC/EOP] [Resp_OK] [checksum][program
* counter] [Resp_OK] */
#define CMD_STOP 'F'
/* 0x47 Go [Sync_CRC/EOP] [Resp_OK] */
#define CMD_GO 'G'
/* 0x52 Read Memory [memory type] [word count] [start address]
* [Sync_CRC/EOP] [Resp_OK] [word 0] ... [word n] [checksum]
* [Resp_OK] */
#define CMD_READ_MEM 'R'
/* 0x53 Get Sign On [Sync_CRC/EOP] [Resp_OK] ["AVRNOCD"] [Resp_OK] */
#define CMD_GET_SIGNON 'S'
/* 0XA1 Erase Page spm [address] [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */
/* 0x57 Write Memory [memory type] [word count] [start address]
* [Sync_CRC/EOP] [Resp_OK] [Cmd_DATA] [word 0] ... [word n] */
#define CMD_WRITE_MEM 'W'
/* Second half of write memory: the data command. Undocumented. */
#define CMD_DATA 'h'
/* 0x64 Get Debug Info [Sync_CRC/EOP] [Resp_OK] [0x00] [Resp_OK] */
/* 0x71 Get Parameter [parameter] [Sync_CRC/EOP] [Resp_OK] [setting]
* [Resp_OK] */
#define CMD_GET_PARAM 'q'
/* 0x78 Reset [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */
#define CMD_RESET 'x'
/* 0xA3 Enter Progmode [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */
#define CMD_ENTER_PROGMODE 0xa3
/* 0xA4 Leave Progmode [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */
#define CMD_LEAVE_PROGMODE 0xa4
/* 0xA5 Chip Erase [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */
#define CMD_CHIP_ERASE 0xa5
/* ICE responses */
#define RESP_OK 'A'
#define RESP_BREAK 'B'
#define RESP_INFO 'G'
#define RESP_FAILED 'F'
#define RESP_SYNC_ERROR 'E'
#define RESP_SLEEP 'H'
#define RESP_POWER 'I'
#define PARM_BITRATE 'b'
#define PARM_SW_VERSION 0x7b
#define PARM_HW_VERSION 0x7a
#define PARM_IREG_HIGH 0x81
#define PARM_IREG_LOW 0x82
#define PARM_OCD_VTARGET 0x84
#define PARM_OCD_BREAK_CAUSE 0x85
#define PARM_CLOCK 0x86
#define PARM_EXTERNAL_RESET 0x8b
#define PARM_FLASH_PAGESIZE_LOW 0x88
#define PARM_FLASH_PAGESIZE_HIGH 0x89
#define PARM_EEPROM_PAGESIZE 0x8a
#define PARM_TIMERS_RUNNING 0xa0
#define PARM_BP_FLOW 0xa1
#define PARM_BP_X_HIGH 0xa2
#define PARM_BP_X_LOW 0xa3
#define PARM_BP_Y_HIGH 0xa4
#define PARM_BP_Y_LOW 0xa5
#define PARM_BP_MODE 0xa6
#define PARM_JTAGID_BYTE0 0xa7
#define PARM_JTAGID_BYTE1 0xa8
#define PARM_JTAGID_BYTE2 0xa9
#define PARM_JTAGID_BYTE3 0xaa
#define PARM_UNITS_BEFORE 0xab
#define PARM_UNITS_AFTER 0xac
#define PARM_BIT_BEFORE 0xad
#define PARM_BIT_AFTER 0xae
#define PARM_PSB0_LOW 0xaf
#define PARM_PSBO_HIGH 0xb0
#define PARM_PSB1_LOW 0xb1
#define PARM_PSB1_HIGH 0xb2
#define PARM_MCU_MODE 0xb3
#define JTAG_BITRATE_1_MHz 0xff
#define JTAG_BITRATE_500_kHz 0xfe
#define JTAG_BITRATE_250_kHz 0xfd
#define JTAG_BITRATE_125_kHz 0xfb
/* memory types for CMND_{READ,WRITE}_MEMORY */
#define MTYPE_IO_SHADOW 0x30 /* cached IO registers? */
#define MTYPE_SRAM 0x20 /* target's SRAM or [ext.] IO registers */
#define MTYPE_EEPROM 0x22 /* EEPROM, what way? */
#define MTYPE_EVENT 0x60 /* ICE event memory */
#define MTYPE_SPM 0xA0 /* flash through LPM/SPM */
#define MTYPE_FLASH_PAGE 0xB0 /* flash in programming mode */
#define MTYPE_EEPROM_PAGE 0xB1 /* EEPROM in programming mode */
#define MTYPE_FUSE_BITS 0xB2 /* fuse bits in programming mode */
#define MTYPE_LOCK_BITS 0xB3 /* lock bits in programming mode */
#define MTYPE_SIGN_JTAG 0xB4 /* signature in programming mode */
#define MTYPE_OSCCAL_BYTE 0xB5 /* osccal cells in programming mode */
struct device_descriptor
{
unsigned char ucReadIO[8]; /*LSB = IOloc 0, MSB = IOloc63 */
unsigned char ucWriteIO[8]; /*LSB = IOloc 0, MSB = IOloc63 */
unsigned char ucReadIOShadow[8]; /*LSB = IOloc 0, MSB = IOloc63 */
unsigned char ucWriteIOShadow[8]; /*LSB = IOloc 0, MSB = IOloc63 */
unsigned char ucReadExtIO[20]; /*LSB = IOloc 96, MSB = IOloc255 */
unsigned char ucWriteExtIO[20]; /*LSB = IOloc 96, MSB = IOloc255 */
unsigned char ucReadIOExtShadow[20]; /*LSB = IOloc 96, MSB = IOloc255 */
unsigned char ucWriteIOExtShadow[20];/*LSB = IOloc 96, MSB = IOloc255 */
unsigned char ucIDRAddress; /*IDR address */
unsigned char ucSPMCRAddress; /*SPMCR Register address and dW BasePC */
unsigned char ucRAMPZAddress; /*RAMPZ Register address in SRAM I/O */
/*space */
unsigned char uiFlashPageSize[2]; /*Device Flash Page Size, Size = */
/*2 exp ucFlashPageSize */
unsigned char ucEepromPageSize; /*Device Eeprom Page Size in bytes */
unsigned char ulBootAddress[4]; /*Device Boot Loader Start Address */
unsigned char uiUpperExtIOLoc; /*Topmost (last) extended I/O */
/*location, 0 if no external I/O */
};

View File

@@ -1,6 +1,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2006 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
@@ -28,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
%}
@@ -46,17 +44,22 @@ HEXDIGIT [0-9a-fA-F]
ID [_a-zA-Z][_a-zA-Z0-9]*
SIGN [+-]
%x str
%x strng
%x incl
%x comment
/* Bump resources for classic lex. */
%e2000
%p5000
%n1000
%%
{SIGN}*{DIGIT}+ { yylval = number(yytext); return TKN_NUMBER; }
{SIGN}*{DIGIT}+"."{DIGIT}* { yylval = number(yytext); return TKN_NUMBER; }
{SIGN}*"."{DIGIT}* { yylval = number(yytext); return TKN_NUMBER; }
"\"" { string_buf_ptr = string_buf; BEGIN(str); }
"\"" { string_buf_ptr = string_buf; BEGIN(strng); }
0x{HEXDIGIT}+ { yylval = hexnumber(yytext); return TKN_NUMBER; }
@@ -64,7 +67,7 @@ SIGN [+-]
# { /* The following eats '#' style comments to end of line */
BEGIN(comment); }
<comment>[^\n] /* eat comments */
<comment>[^\n] { /* eat comments */ }
<comment>\n { lineno++; BEGIN(INITIAL); }
@@ -99,25 +102,25 @@ SIGN [+-]
}
<str>{
\" { *string_buf_ptr = 0; string_buf_ptr = string_buf;
yylval = string(string_buf_ptr); BEGIN(INITIAL); return TKN_STRING; }
\\n *string_buf_ptr++ = '\n';
\\t *string_buf_ptr++ = '\t';
\\r *string_buf_ptr++ = '\r';
\\b *string_buf_ptr++ = '\b';
\\f *string_buf_ptr++ = '\f';
\\(.|\n) *(string_buf_ptr++) = yytext[1];
[^\\\n\"]+ { char *yptr = yytext; while (*yptr)
<strng>\" { *string_buf_ptr = 0; string_buf_ptr = string_buf;
yylval = string(string_buf_ptr); BEGIN(INITIAL); return TKN_STRING; }
<strng>\\n *string_buf_ptr++ = '\n';
<strng>\\t *string_buf_ptr++ = '\t';
<strng>\\r *string_buf_ptr++ = '\r';
<strng>\\b *string_buf_ptr++ = '\b';
<strng>\\f *string_buf_ptr++ = '\f';
<strng>\\(.|\n) *(string_buf_ptr++) = yytext[1];
<strng>[^\\\n\"]+ { char *yptr = yytext; while (*yptr)
*(string_buf_ptr++) = *(yptr++); }
\n { fprintf(stderr, "error at line %d: unterminated character constant\n",
lineno);
exit(1); }
}
<strng>\n { fprintf(stderr, "error at line %d: unterminated character constant\n",
lineno);
exit(1); }
allowfullpagebitstream { yylval=NULL; return K_ALLOWFULLPAGEBITSTREAM; }
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; }
@@ -130,15 +133,24 @@ default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
devicecode { yylval=NULL; return K_DEVICECODE; }
dragon_dw { yylval=NULL; return K_DRAGON_DW; }
dragon_hvsp { yylval=NULL; return K_DRAGON_HVSP; }
dragon_isp { yylval=NULL; return K_DRAGON_ISP; }
dragon_jtag { yylval=NULL; return K_DRAGON_JTAG; }
dragon_pp { yylval=NULL; return K_DRAGON_PP; }
eecr { yylval=NULL; return K_EECR; }
eeprom { yylval=NULL; return K_EEPROM; }
enablepageprogramming { yylval=NULL; return K_ENABLEPAGEPROGRAMMING; }
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; }
id { yylval=NULL; return K_ID; }
idr { yylval=NULL; return K_IDR; }
jtagmki { yylval=NULL; return K_JTAG_MKI; }
jtagmkii { yylval=NULL; return K_JTAG_MKII; }
jtagmkii_dw { yylval=NULL; return K_JTAG_MKII_DW; }
jtagmkii_isp { yylval=NULL; return K_JTAG_MKII_ISP; }
max_write_delay { yylval=NULL; return K_MAX_WRITE_DELAY; }
memory { yylval=NULL; return K_MEMORY; }
min_write_delay { yylval=NULL; return K_MIN_WRITE_DELAY; }
@@ -162,10 +174,14 @@ readback_p2 { yylval=NULL; return K_READBACK_P2; }
retry_pulse { yylval=NULL; return K_RETRY_PULSE; }
serbb { yylval=NULL; return K_SERBB; }
serial { yylval=NULL; return K_SERIAL; }
signature { yylval=NULL; return K_SIGNATURE; }
size { yylval=NULL; return K_SIZE; }
spmcr { yylval=NULL; return K_SPMCR; }
stk500 { yylval=NULL; return K_STK500; }
stk500hvsp { yylval=NULL; return K_STK500HVSP; }
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; }
type { yylval=NULL; return K_TYPE; }
vcc { yylval=NULL; return K_VCC; }
@@ -174,6 +190,7 @@ vfyled { yylval=NULL; return K_VFYLED; }
timeout { yylval=NULL; return K_TIMEOUT; }
stabdelay { yylval=NULL; return K_STABDELAY; }
cmdexedelay { yylval=NULL; return K_CMDEXEDELAY; }
hvspcmdexedelay { yylval=NULL; return K_HVSPCMDEXEDELAY; }
synchloops { yylval=NULL; return K_SYNCHLOOPS; }
bytedelay { yylval=NULL; return K_BYTEDELAY; }
pollvalue { yylval=NULL; return K_POLLVALUE; }
@@ -185,8 +202,27 @@ mode { yylval=NULL; return K_MODE; }
delay { yylval=NULL; return K_DELAY; }
blocksize { yylval=NULL; return K_BLOCKSIZE; }
readsize { yylval=NULL; return K_READSIZE; }
pp_controlstack { yylval=NULL; return K_PP_CONTROLSTACK; }
hvsp_controlstack { yylval=NULL; return K_HVSP_CONTROLSTACK; }
hventerstabdelay { yylval=NULL; return K_HVENTERSTABDELAY; }
progmodedelay { yylval=NULL; return K_PROGMODEDELAY; }
latchcycles { yylval=NULL; return K_LATCHCYCLES; }
togglevtg { yylval=NULL; return K_TOGGLEVTG; }
poweroffdelay { yylval=NULL; return K_POWEROFFDELAY; }
resetdelayms { yylval=NULL; return K_RESETDELAYMS; }
resetdelayus { yylval=NULL; return K_RESETDELAYUS; }
hvleavestabdelay { yylval=NULL; return K_HVLEAVESTABDELAY; }
resetdelay { yylval=NULL; return K_RESETDELAY; }
synchcycles { yylval=NULL; return K_SYNCHCYCLES; }
chiperasepulsewidth { yylval=NULL; return K_CHIPERASEPULSEWIDTH; }
chiperasepolltimeout { yylval=NULL; return K_CHIPERASEPOLLTIMEOUT; }
chiperasetime { yylval=NULL; return K_CHIPERASETIME; }
programfusepulsewidth { yylval=NULL; return K_PROGRAMFUSEPULSEWIDTH; }
programfusepolltimeout { yylval=NULL; return K_PROGRAMFUSEPOLLTIMEOUT; }
programlockpulsewidth { yylval=NULL; return K_PROGRAMLOCKPULSEWIDTH; }
programlockpolltimeout { yylval=NULL; return K_PROGRAMLOCKPOLLTIMEOUT; }
flash_instr { yylval=NULL; return K_FLASH_INSTR; }
eeprom_instr { yylval=NULL; return K_EEPROM_INSTR; }
dedicated { yylval=new_token(K_DEDICATED); return K_DEDICATED; }
io { yylval=new_token(K_IO); return K_IO; }
@@ -203,6 +239,7 @@ write_lo { yylval=new_token(K_WRITE_LO); return K_WRITE_LO; }
write_hi { yylval=new_token(K_WRITE_HI); return K_WRITE_HI; }
loadpage_lo { yylval=new_token(K_LOADPAGE_LO); return K_LOADPAGE_LO; }
loadpage_hi { yylval=new_token(K_LOADPAGE_HI); return K_LOADPAGE_HI; }
load_ext_addr { yylval=new_token(K_LOAD_EXT_ADDR); return K_LOAD_EXT_ADDR; }
writepage { yylval=new_token(K_WRITEPAGE); return K_WRITEPAGE; }
chip_erase { yylval=new_token(K_CHIP_ERASE); return K_CHIP_ERASE; }
pgm_enable { yylval=new_token(K_PGM_ENABLE); return K_PGM_ENABLE; }
@@ -216,7 +253,7 @@ yes { yylval=new_token(K_YES); return K_YES; }
"~" { yylval = NULL; pyytext(); return TKN_TILDE; }
"\n" { lineno++; }
[ \r\t]+ /* ignore whitespace */
[ \r\t]+ { /* ignore whitespace */ }
c: { fprintf(stderr, "error at %s:%d: possible old-style config file entry\n",
infile, lineno);

View File

@@ -1,5 +1,26 @@
#ifndef __linux_ppdev_h__
#define __linux_ppdev_h__
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003, 2005 Theodore A. Roth
*
* 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 linux_ppdev_h
#define linux_ppdev_h
#define OBSOLETE__IOW _IOW
@@ -9,29 +30,28 @@
#include <stdlib.h>
#define PPISDATA PPWDATA
#define PPIGDATA PPRDATA
#define PPISCTRL PPWCONTROL
#define PPIGCTRL PPRCONTROL
#define PPISSTATUS PPWSTATUS
#define PPIGSTATUS PPRSTATUS
#define ppi_claim(pgm) \
if (ioctl(pgm->fd, PPCLAIM)) { \
#define ppi_claim(fd) \
if (ioctl(fd, PPCLAIM)) { \
fprintf(stderr, "%s: can't claim device \"%s\": %s\n\n", \
progname, port, strerror(errno)); \
close(pgm->fd); \
close(fd); \
exit(1); \
}
}
#define ppi_release(pgm) \
if (ioctl(pgm->fd, PPRELEASE)) { \
#define ppi_release(fd) \
if (ioctl(fd, PPRELEASE)) { \
fprintf(stderr, "%s: can't release device: %s\n\n", \
progname, strerror(errno)); \
exit(1); \
}
#define DO_PPI_READ(fd, reg, valp) \
(void)ioctl(fd, \
(reg) == PPIDATA? PPRDATA: ((reg) == PPICTRL? PPRCONTROL: PPRSTATUS), \
valp)
#define DO_PPI_WRITE(fd, reg, valp) \
(void)ioctl(fd, \
(reg) == PPIDATA? PPWDATA: ((reg) == PPICTRL? PPWCONTROL: PPWSTATUS), \
valp)
#endif /* __linux_ppdev_h__ */
#endif /* linux_ppdev_h */

View File

@@ -1290,8 +1290,8 @@ int lprint ( FILE * f, LISTID lid )
l = (LIST *)lid;
fprintf ( f, "list id 0x%08x internal data structures:\n",
(unsigned int)lid );
fprintf ( f, "list id %p internal data structures:\n",
lid );
#if CHECK_MAGIC
if ((l->magic1 != MAGIC) || (l->magic2 != MAGIC)) {
fprintf ( f, " *** WARNING: LIST MAGIC IS CORRUPT ***\n" );

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

@@ -53,61 +53,53 @@
#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 */
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;
/*
* 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"
"Options:\n"
" -p <partno> Required. Specify AVR device.\n"
" -b <baudrate> Override RS-232 baud rate.\n"
" -B <bitclock> Specify JTAG bit clock period (us).\n"
" -B <bitclock> Specify JTAG/STK500v2 bit clock period (us).\n"
" -C <config-file> Specify location of configuration file.\n"
" -c <programmer> Specify programmer type.\n"
" -D Disable auto erase for flash memory\n"
" -i <delay> ISP Clock Delay [in microseconds]\n"
" -P <port> Specify connection port.\n"
" -F Override invalid signature check.\n"
" -e Perform a chip erase.\n"
" -O Perform RC oscillator calibration (see AVR053). \n"
" -U <memtype>:r|w|v:<filename>[:format]\n"
" Memory operation specification.\n"
" Multiple -U options are allowed, each request\n"
@@ -129,179 +121,6 @@ void usage(void)
}
/*
* parse the -E string
*/
int getexitspecs(char *s, int *set, int *clr)
{
char *cp;
while ((cp = strtok(s, ","))) {
if (strcmp(cp, "reset") == 0) {
*clr |= par_getpinmask(pgm->pinno[PIN_AVR_RESET]);
}
else if (strcmp(cp, "noreset") == 0) {
*set |= par_getpinmask(pgm->pinno[PIN_AVR_RESET]);
}
else if (strcmp(cp, "vcc") == 0) {
if (pgm->pinno[PPI_AVR_VCC])
*set |= pgm->pinno[PPI_AVR_VCC];
}
else if (strcmp(cp, "novcc") == 0) {
if (pgm->pinno[PPI_AVR_VCC])
*clr |= pgm->pinno[PPI_AVR_VCC];
}
else {
return -1;
}
s = 0; /* strtok() should be called with the actual string only once */
}
return 0;
}
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);
}
void verify_pin_assigned(int pin, char * desc)
{
if (pgm->pinno[pin] == 0) {
fprintf(stderr, "%s: error: no pin has been assigned for %s\n",
progname, desc);
exit(1);
}
}
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];
@@ -360,336 +179,46 @@ static void update_progress_no_tty (int percent, double etime, char *hdr)
last = (percent>>1)*2; /* Make last a multiple of 2. */
}
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 != ':') {
fprintf(stderr, "%s: invalid update specification\n", progname);
free(upd);
return NULL;
}
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;
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, upd->memtype, 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, upd->memtype);
}
}
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, upd->memtype);
}
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);
}
/*
* main routine
*/
@@ -706,18 +235,18 @@ int main(int argc, char * argv [])
struct stat sb;
UPDATE * upd;
LNODEID * ln;
PROGRAMMER * pgm;
/* options / operating mode variables */
int erase; /* 1=erase chip, 0=don't */
int calibrate; /* 1=calibrate RC oscillator, 0=don't */
int auto_erase; /* 0=never erase unless explicity told to do
so, 1=erase if we are going to program flash */
int ovsigck; /* 1=override sig check, 0=don't */
char * port; /* device port (/dev/xxx) */
int terminal; /* 1=enter terminal mode, 0=don't */
int nowrite; /* don't actually write anything to the chip */
int verify; /* perform a verify operation */
int ppisetbits; /* bits to set in ppi data register at exit */
int ppiclrbits; /* bits to clear in ppi data register at exit */
char * exitspecs; /* exit specs string from command line */
char * programmer; /* programmer id */
char * partdesc; /* part id */
@@ -728,6 +257,7 @@ int main(int argc, char * argv [])
char * e; /* for strtol() error checking */
int baudrate; /* override default programmer baud rate */
double bitclock; /* Specify programmer bit clock (JTAG ICE) */
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 */
unsigned char safemode_lfuse = 0xff;
@@ -742,11 +272,18 @@ int main(int argc, char * argv [])
char * homedir;
#endif
progname = rindex(argv[0],'/');
/*
* 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)
/* take care of backslash as dir sep in W32 */
if (!progname) progname = rindex(argv[0],'\\');
if (!progname) progname = strrchr(argv[0],'\\');
#endif /* WIN32NATIVE */
if (progname)
@@ -768,6 +305,7 @@ int main(int argc, char * argv [])
partdesc = NULL;
port = default_parallel;
erase = 0;
calibrate = 0;
auto_erase = 1;
p = NULL;
ovsigck = 0;
@@ -775,8 +313,6 @@ int main(int argc, char * argv [])
nowrite = 0;
verify = 1; /* on by default */
quell_progress = 0;
ppisetbits = 0;
ppiclrbits = 0;
exitspecs = NULL;
pgm = NULL;
programmer = default_programmer;
@@ -785,6 +321,7 @@ int main(int argc, char * argv [])
set_cycles = -1;
baudrate = 0;
bitclock = 0.0;
ispdelay = 0;
safemode = 1; /* Safemode on by default */
silentsafe = 0; /* Ask by default */
@@ -835,7 +372,7 @@ int main(int argc, char * argv [])
/*
* process command line arguments
*/
while ((ch = getopt(argc,argv,"?b:B:c:C:DeE:Fnp:P:qstU:uvVyY:")) != -1) {
while ((ch = getopt(argc,argv,"?b:B:c:C:DeE:Fi:np:OP:qstU:uvVyY:")) != -1) {
switch (ch) {
case 'b': /* override default programmer baud rate */
@@ -856,6 +393,15 @@ int main(int argc, char * argv [])
}
break;
case 'i': /* specify isp clock delay */
ispdelay = strtol(optarg, &e,10);
if ((e == optarg) || (*e != 0) || ispdelay == 0) {
fprintf(stderr, "%s: invalid isp clock delay specified '%s'\n",
progname, optarg);
exit(1);
}
break;
case 'c': /* programmer id */
programmer = optarg;
break;
@@ -885,6 +431,10 @@ int main(int argc, char * argv [])
nowrite = 1;
break;
case 'O': /* perform RC oscillator calibration */
calibrate = 1;
break;
case 'p' : /* specify AVR part */
partdesc = optarg;
break;
@@ -982,9 +532,9 @@ int main(int argc, char * argv [])
* they are running
*/
fprintf(stderr,
"\n%s: Version %s\n"
"\n%s: Version %s, compiled on %s at %s\n"
"%sCopyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/\n\n",
progname, version, progbuf);
progname, version, __DATE__, __TIME__, progbuf);
}
if (verbose) {
@@ -1106,20 +656,18 @@ int main(int argc, char * argv [])
if (exitspecs != NULL) {
if (strcmp(pgm->type, "PPI") != 0) {
if (pgm->parseexitspecs == NULL) {
fprintf(stderr,
"%s: WARNING: -E option is only valid with \"PPI\" "
"programmer types\n",
"%s: WARNING: -E option not supported by this programmer type\n",
progname);
exitspecs = NULL;
}
else if (getexitspecs(exitspecs, &ppisetbits, &ppiclrbits) < 0) {
else if (pgm->parseexitspecs(pgm, exitspecs) < 0) {
usage();
exit(1);
}
}
/*
* set up seperate instances of the avr part, one for use in
* programming, one for use in verifying. These are separate
@@ -1128,13 +676,6 @@ int main(int argc, char * argv [])
p = avr_dup_part(p);
v = avr_dup_part(p);
if (strcmp(pgm->type, "PPI") == 0) {
verify_pin_assigned(PIN_AVR_RESET, "AVR RESET");
verify_pin_assigned(PIN_AVR_SCK, "AVR SCK");
verify_pin_assigned(PIN_AVR_MISO, "AVR MISO");
verify_pin_assigned(PIN_AVR_MOSI, "AVR MOSI");
}
/*
* open the programmer
*/
@@ -1163,9 +704,17 @@ int main(int argc, char * argv [])
if (verbose) {
fprintf(stderr, "%sSetting bit clk period: %.1f\n", progbuf, bitclock);
}
pgm->bitclock = bitclock * 1e-6;
}
if (ispdelay != 0) {
if (verbose) {
fprintf(stderr, "%sSetting isp clock delay: %3i\n", progbuf, ispdelay);
}
pgm->ispdelay = ispdelay;
}
rc = pgm->open(pgm, port);
if (rc < 0) {
exitrc = 1;
@@ -1173,10 +722,25 @@ int main(int argc, char * argv [])
goto main_exit;
}
if (calibrate) {
/*
* perform an RC oscillator calibration
* as outlined in appnote AVR053
*/
fprintf(stderr, "%s: performing RC oscillator calibration\n", progname);
exitrc = pgm->perform_osccal(pgm);
if (exitrc == 0 && quell_progress < 2) {
fprintf(stderr,
"%s: calibration value is now stored in EEPROM at address 0\n",
progname);
}
goto main_exit;
}
if (verbose) {
avr_display(stderr, p, progbuf, verbose);
fprintf(stderr, "\n");
programmer_display(progbuf);
programmer_display(pgm, progbuf);
}
if (quell_progress < 2) {
@@ -1185,14 +749,6 @@ int main(int argc, char * argv [])
exitrc = 0;
/*
* handle exit specs. FIXME: this should be moved to "par.c"
*/
if (strcmp(pgm->type, "PPI") == 0) {
pgm->ppidata &= ~ppiclrbits;
pgm->ppidata |= ppisetbits;
}
/*
* enable the programmer
*/
@@ -1234,8 +790,8 @@ int main(int argc, char * argv [])
/*
* Let's read the signature bytes to make sure there is at least a
* chip on the other end that is responding correctly. A check
* against 0xffffffff should ensure that the signature bytes are
* valid.
* against 0xffffff / 0x000000 should ensure that the signature bytes
* are valid.
*/
rc = avr_signature(pgm, p);
if (rc != 0) {
@@ -1253,24 +809,26 @@ int main(int argc, char * argv [])
}
if (sig != NULL) {
int ff;
int ff, zz;
if (quell_progress < 2) {
fprintf(stderr, "%s: Device signature = 0x", progname);
}
ff = 1;
ff = zz = 1;
for (i=0; i<sig->size; i++) {
if (quell_progress < 2) {
fprintf(stderr, "%02x", sig->buf[i]);
}
if (sig->buf[i] != 0xff)
ff = 0;
if (sig->buf[i] != 0x00)
zz = 0;
}
if (quell_progress < 2) {
fprintf(stderr, "\n");
}
if (ff) {
if (ff || zz) {
fprintf(stderr,
"%s: Yikes! Invalid device signature.\n", progname);
if (!ovsigck) {
@@ -1282,23 +840,58 @@ int main(int argc, char * argv [])
goto main_exit;
}
}
if (sig->size != 3 ||
sig->buf[0] != p->signature[0] ||
sig->buf[1] != p->signature[1] ||
sig->buf[2] != p->signature[2]) {
fprintf(stderr,
"%s: Expected signature for %s is %02X %02X %02X\n",
progname, p->desc,
p->signature[0], p->signature[1], p->signature[2]);
if (!ovsigck) {
fprintf(stderr, "%sDouble check chip, "
"or use -F to override this check.\n",
progbuf);
exitrc = 1;
goto main_exit;
}
}
}
if (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);
}
}
@@ -1420,7 +1013,7 @@ int main(int argc, char * argv [])
/* Try reading back fuses, make sure they are reliable to read back */
if (safemode_readfuses(&safemodeafter_lfuse, &safemodeafter_hfuse,
&safemodeafter_efuse, &safemode_fuse, pgm, p, verbose) != 0) {
&safemodeafter_efuse, &safemodeafter_fuse, pgm, p, verbose) != 0) {
/* Uh-oh.. try once more to read back fuses */
if (safemode_readfuses(&safemodeafter_lfuse, &safemodeafter_hfuse,
&safemodeafter_efuse, &safemodeafter_fuse, pgm, p, verbose) != 0) {

49
avrdude/my_ddk_hidsdi.h Normal file
View File

@@ -0,0 +1,49 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2006 Christian Starkjohann
*
* 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$ */
/*
The following is a replacement for hidsdi.h from the Windows DDK. It defines some
of the types and function prototypes of this header for our project. If you
have the Windows DDK version of this file or a version shipped with MinGW, use
that instead.
*/
#ifndef MY_DDK_HIDSDI_H
#define MY_DDK_HIDSDI_H
#include <pshpack4.h>
#include <ddk/hidusage.h>
#include <ddk/hidpi.h>
typedef struct{
ULONG Size;
USHORT VendorID;
USHORT ProductID;
USHORT VersionNumber;
}HIDD_ATTRIBUTES;
void __stdcall HidD_GetHidGuid(OUT LPGUID hidGuid);
BOOLEAN __stdcall HidD_GetAttributes(IN HANDLE device, OUT HIDD_ATTRIBUTES *attributes);
BOOLEAN __stdcall HidD_GetManufacturerString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen);
BOOLEAN __stdcall HidD_GetProductString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen);
BOOLEAN __stdcall HidD_GetSerialNumberString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen);
BOOLEAN __stdcall HidD_GetFeature(IN HANDLE device, OUT void *reportBuffer, IN ULONG bufferLen);
BOOLEAN __stdcall HidD_SetFeature(IN HANDLE device, IN void *reportBuffer, IN ULONG bufferLen);
BOOLEAN __stdcall HidD_GetNumInputBuffers(IN HANDLE device, OUT ULONG *numBuffers);
BOOLEAN __stdcall HidD_SetNumInputBuffers(IN HANDLE device, OUT ULONG numBuffers);
#include <poppack.h>
#endif /* MY_DDK_HIDSDI_H */

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2000-2006 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,18 +29,21 @@
#include <errno.h>
#if defined(__FreeBSD__)
#include <dev/ppbus/ppi.h>
# include "freebsd_ppi.h"
#elif defined(__linux__)
#include "linux_ppdev.h"
# include "linux_ppdev.h"
#elif defined(__sun__) && defined(__svr4__) /* Solaris */
# include "solaris_ecpp.h"
#endif
#include "avrdude.h"
#include "avr.h"
#include "pindefs.h"
#include "pgm.h"
#include "ppi.h"
#include "bitbang.h"
#define SLOW_TOGGLE 0
#if HAVE_PARPORT
struct ppipins_t {
int pin;
@@ -49,7 +52,7 @@ struct ppipins_t {
int inverted;
};
struct ppipins_t ppipins[] = {
static struct ppipins_t ppipins[] = {
{ 1, PPICTRL, 0x01, 1 },
{ 2, PPIDATA, 0x01, 0 },
{ 3, PPIDATA, 0x02, 0 },
@@ -71,14 +74,11 @@ struct ppipins_t ppipins[] = {
#define NPINS (sizeof(ppipins)/sizeof(struct ppipins_t))
extern char * progname;
extern int do_cycles;
extern int verbose;
int par_setpin(int fd, int pin, int value)
static int par_setpin(PROGRAMMER * pgm, int pin, int value)
{
int inverted;
inverted = pin & PIN_INVERSE;
pin &= PIN_MASK;
if (pin < 1 || pin > 17)
@@ -87,25 +87,38 @@ int par_setpin(int fd, int pin, int value)
pin--;
if (ppipins[pin].inverted)
inverted = !inverted;
if (inverted)
value = !value;
if (value)
ppi_set(fd, ppipins[pin].reg, ppipins[pin].bit);
ppi_set(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
else
ppi_clr(fd, ppipins[pin].reg, ppipins[pin].bit);
ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
#if SLOW_TOGGLE
usleep(1000);
#endif
if (pgm->ispdelay > 1)
bitbang_delay(pgm->ispdelay);
return 0;
}
static void par_setmany(PROGRAMMER * pgm, unsigned int pinset, int value)
{
int pin;
int par_getpin(int fd, int pin)
for (pin = 1; pin <= 17; pin++) {
if (pinset & (1 << pin))
par_setpin(pgm, pin, value);
}
}
static int par_getpin(PROGRAMMER * pgm, int pin)
{
int value;
int inverted;
inverted = pin & PIN_INVERSE;
pin &= PIN_MASK;
if (pin < 1 || pin > 17)
@@ -113,79 +126,82 @@ int par_getpin(int fd, int pin)
pin--;
value = ppi_get(fd, ppipins[pin].reg, ppipins[pin].bit);
value = ppi_get(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
if (value)
value = 1;
if (ppipins[pin].inverted)
inverted = !inverted;
if (inverted)
value = !value;
return value;
}
int par_highpulsepin(int fd, int pin)
static int par_highpulsepin(PROGRAMMER * pgm, int pin)
{
int inverted;
inverted = pin & PIN_INVERSE;
pin &= PIN_MASK;
if (pin < 1 || pin > 17)
return -1;
pin--;
ppi_set(fd, ppipins[pin].reg, ppipins[pin].bit);
#if SLOW_TOGGLE
usleep(1000);
#endif
ppi_clr(fd, ppipins[pin].reg, ppipins[pin].bit);
if (ppipins[pin].inverted)
inverted = !inverted;
#if SLOW_TOGGLE
usleep(1000);
#endif
if (inverted) {
ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
if (pgm->ispdelay > 1)
bitbang_delay(pgm->ispdelay);
ppi_set(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
if (pgm->ispdelay > 1)
bitbang_delay(pgm->ispdelay);
} else {
ppi_set(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
if (pgm->ispdelay > 1)
bitbang_delay(pgm->ispdelay);
ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
if (pgm->ispdelay > 1)
bitbang_delay(pgm->ispdelay);
}
return 0;
}
int par_getpinmask(int pin)
static char * pins_to_str(unsigned int pmask)
{
pin &= PIN_MASK;
if (pin < 1 || pin > 17)
return -1;
return ppipins[pin-1].bit;
}
char vccpins_buf[64];
char * vccpins_str(unsigned int pmask)
{
unsigned int mask;
static char buf[64];
int pin;
char b2[8];
char * b;
b = vccpins_buf;
b[0] = 0;
for (pin = 2, mask = 1; mask < 0x80; mask = mask << 1, pin++) {
if (pmask & mask) {
buf[0] = 0;
for (pin = 1; pin <= 17; pin++) {
if (pmask & (1 << pin)) {
sprintf(b2, "%d", pin);
if (b[0] != 0)
strcat(b, ",");
strcat(b, b2);
if (buf[0] != 0)
strcat(buf, ",");
strcat(buf, b2);
}
}
return b;
return buf;
}
/*
* apply power to the AVR processor
*/
void par_powerup(PROGRAMMER * pgm)
static void par_powerup(PROGRAMMER * pgm)
{
ppi_set(pgm->fd, PPIDATA, pgm->pinno[PPI_AVR_VCC]); /* power up */
par_setmany(pgm, pgm->pinno[PPI_AVR_VCC], 1); /* power up */
usleep(100000);
}
@@ -193,17 +209,17 @@ void par_powerup(PROGRAMMER * pgm)
/*
* remove power from the AVR processor
*/
void par_powerdown(PROGRAMMER * pgm)
static void par_powerdown(PROGRAMMER * pgm)
{
ppi_clr(pgm->fd, PPIDATA, pgm->pinno[PPI_AVR_VCC]); /* power down */
par_setmany(pgm, pgm->pinno[PPI_AVR_VCC], 0); /* power down */
}
void par_disable(PROGRAMMER * pgm)
static void par_disable(PROGRAMMER * pgm)
{
ppi_set(pgm->fd, PPIDATA, pgm->pinno[PPI_AVR_BUFF]);
par_setmany(pgm, pgm->pinno[PPI_AVR_BUFF], 1); /* turn off */
}
void par_enable(PROGRAMMER * pgm)
static void par_enable(PROGRAMMER * pgm)
{
/*
* Prepare to start talking to the connected device - pull reset low
@@ -216,39 +232,39 @@ void par_enable(PROGRAMMER * pgm)
* and not via the buffer chip.
*/
par_setpin(pgm->fd, pgm->pinno[PIN_AVR_RESET], 0);
par_setpin(pgm, pgm->pinno[PIN_AVR_RESET], 0);
usleep(1);
/*
* enable the 74367 buffer, if connected; this signal is active low
*/
ppi_clr(pgm->fd, PPIDATA, pgm->pinno[PPI_AVR_BUFF]);
par_setmany(pgm, pgm->pinno[PPI_AVR_BUFF], 0);
}
int par_open(PROGRAMMER * pgm, char * port)
static int par_open(PROGRAMMER * pgm, char * port)
{
int rc;
pgm->fd = ppi_open(port);
if (pgm->fd < 0) {
bitbang_check_prerequisites(pgm);
ppi_open(port, &pgm->fd);
if (pgm->fd.ifd < 0) {
fprintf(stderr, "%s: failed to open parallel port \"%s\"\n\n",
progname, port);
exit(1);
}
ppi_claim(pgm);
/*
* save pin values, so they can be restored when device is closed
*/
rc = ppi_getall(pgm->fd, PPIDATA);
rc = ppi_getall(&pgm->fd, PPIDATA);
if (rc < 0) {
fprintf(stderr, "%s: error reading status of ppi data port\n", progname);
return -1;
}
pgm->ppidata = rc;
rc = ppi_getall(pgm->fd, PPICTRL);
rc = ppi_getall(&pgm->fd, PPICTRL);
if (rc < 0) {
fprintf(stderr, "%s: error reading status of ppi ctrl port\n", progname);
return -1;
@@ -259,46 +275,76 @@ int par_open(PROGRAMMER * pgm, char * port)
}
void par_close(PROGRAMMER * pgm)
static void par_close(PROGRAMMER * pgm)
{
/*
* Restore pin values before closing,
* but ensure that buffers are turned off.
*/
pgm->ppidata |= pgm->pinno[PPI_AVR_BUFF];
ppi_setall(pgm->fd, PPIDATA, pgm->ppidata);
ppi_setall(pgm->fd, PPICTRL, pgm->ppictrl);
ppi_setall(&pgm->fd, PPIDATA, pgm->ppidata);
ppi_setall(&pgm->fd, PPICTRL, pgm->ppictrl);
ppi_release(pgm);
par_setpin(pgm, pgm->pinno[PPI_AVR_BUFF], 1);
ppi_close(pgm->fd);
pgm->fd = -1;
/*
* Handle exit specs.
*/
switch (pgm->exit_reset) {
case EXIT_RESET_ENABLED:
par_setpin(pgm, pgm->pinno[PIN_AVR_RESET], 0);
break;
case EXIT_RESET_DISABLED:
par_setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1);
break;
case EXIT_RESET_UNSPEC:
/* Leave it alone. */
break;
}
switch (pgm->exit_vcc) {
case EXIT_VCC_ENABLED:
par_setmany(pgm, pgm->pinno[PPI_AVR_VCC], 1);
break;
case EXIT_VCC_DISABLED:
par_setmany(pgm, pgm->pinno[PPI_AVR_VCC], 0);
break;
case EXIT_VCC_UNSPEC:
/* Leave it alone. */
break;
}
ppi_close(&pgm->fd);
pgm->fd.ifd = -1;
}
void par_display(PROGRAMMER * pgm, char * p)
static void par_display(PROGRAMMER * pgm, const char * p)
{
char vccpins[64];
char buffpins[64];
if (pgm->pinno[PPI_AVR_VCC]) {
snprintf(vccpins, sizeof(vccpins), " = pins %s",
vccpins_str(pgm->pinno[PPI_AVR_VCC]));
snprintf(vccpins, sizeof(vccpins), "%s",
pins_to_str(pgm->pinno[PPI_AVR_VCC]));
}
else {
strcpy(vccpins, " (not used)");
}
if (pgm->pinno[PPI_AVR_BUFF]) {
snprintf(buffpins, sizeof(buffpins), " = pins %s",
vccpins_str(pgm->pinno[PPI_AVR_BUFF]));
snprintf(buffpins, sizeof(buffpins), "%s",
pins_to_str(pgm->pinno[PPI_AVR_BUFF]));
}
else {
strcpy(buffpins, " (not used)");
}
fprintf(stderr,
"%s VCC = 0x%02x%s\n"
"%s BUFF = 0x%02x%s\n"
"%s VCC = %s\n"
"%s BUFF = %s\n"
"%s RESET = %d\n"
"%s SCK = %d\n"
"%s MOSI = %d\n"
@@ -308,8 +354,8 @@ void par_display(PROGRAMMER * pgm, char * p)
"%s PGM LED = %d\n"
"%s VFY LED = %d\n",
p, pgm->pinno[PPI_AVR_VCC], vccpins,
p, pgm->pinno[PPI_AVR_BUFF], buffpins,
p, vccpins,
p, buffpins,
p, pgm->pinno[PIN_AVR_RESET],
p, pgm->pinno[PIN_AVR_SCK],
p, pgm->pinno[PIN_AVR_MOSI],
@@ -321,10 +367,42 @@ void par_display(PROGRAMMER * pgm, char * p)
}
/*
* parse the -E string
*/
static int par_parseexitspecs(PROGRAMMER * pgm, char *s)
{
char *cp;
while ((cp = strtok(s, ","))) {
if (strcmp(cp, "reset") == 0) {
pgm->exit_reset = EXIT_RESET_ENABLED;
}
else if (strcmp(cp, "noreset") == 0) {
pgm->exit_reset = EXIT_RESET_DISABLED;
}
else if (strcmp(cp, "vcc") == 0) {
pgm->exit_vcc = EXIT_VCC_ENABLED;
}
else if (strcmp(cp, "novcc") == 0) {
pgm->exit_vcc = EXIT_VCC_DISABLED;
}
else {
return -1;
}
s = 0; /* strtok() should be called with the actual string only once */
}
return 0;
}
void par_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "PPI");
pgm->exit_vcc = EXIT_VCC_UNSPEC;
pgm->exit_reset = EXIT_RESET_UNSPEC;
pgm->rdy_led = bitbang_rdy_led;
pgm->err_led = bitbang_err_led;
pgm->pgm_led = bitbang_pgm_led;
@@ -340,7 +418,21 @@ void par_initpgm(PROGRAMMER * pgm)
pgm->cmd = bitbang_cmd;
pgm->open = par_open;
pgm->close = par_close;
/* this is a parallel port bitbang device */
pgm->flag = 0;
pgm->setpin = par_setpin;
pgm->getpin = par_getpin;
pgm->highpulsepin = par_highpulsepin;
pgm->parseexitspecs = par_parseexitspecs;
pgm->read_byte = avr_read_byte_default;
pgm->write_byte = avr_write_byte_default;
}
#else /* !HAVE_PARPORT */
void par_initpgm(PROGRAMMER * pgm)
{
fprintf(stderr,
"%s: parallel port access not available in this configuration\n",
progname);
}
#endif /* HAVE_PARPORT */

View File

@@ -19,16 +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);
int par_getpinmask(int pin);
int par_setpin(int fd, int pin, int value);
int par_getpin(int fd, int pin);
int par_highpulsepin(int fd, int pin);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -25,15 +25,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 *, unsigned char cmd[4],
unsigned char res[4]);
static void pgm_default_6 (struct programmer_t *, char *);
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 *, const char *);
static int pgm_default_open (struct programmer_t *pgm, char * name)
@@ -96,9 +97,10 @@ PROGRAMMER * pgm_new(void)
pgm->powerdown = pgm_default_powerup_powerdown;
pgm->program_enable = pgm_default_2;
pgm->chip_erase = pgm_default_2;
pgm->cmd = pgm_default_5;
pgm->open = pgm_default_open;
pgm->close = pgm_default_4;
pgm->read_byte = pgm_default_3;
pgm->write_byte = pgm_default_5;
/*
* predefined functions - these functions have a valid default
@@ -114,15 +116,15 @@ PROGRAMMER * pgm_new(void)
* optional functions - these are checked to make sure they are
* assigned before they are called
*/
pgm->cmd = NULL;
pgm->paged_write = NULL;
pgm->paged_load = NULL;
pgm->write_setup = NULL;
pgm->write_byte = NULL;
pgm->read_byte = NULL;
pgm->read_sig_bytes = NULL;
pgm->set_vtarget = NULL;
pgm->set_varef = NULL;
pgm->set_fosc = NULL;
pgm->perform_osccal = NULL;
return pgm;
}
@@ -140,21 +142,81 @@ static int pgm_default_2 (struct programmer_t * pgm, AVRPART * p)
return -1;
}
static void pgm_default_4 (struct programmer_t * pgm)
{
pgm_default();
}
static int pgm_default_5 (struct programmer_t * pgm, unsigned char cmd[4],
unsigned char res[4])
static int pgm_default_3 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value)
{
pgm_default();
return -1;
}
static void pgm_default_6 (struct programmer_t * pgm, char * p)
static void pgm_default_4 (struct programmer_t * pgm)
{
pgm_default();
}
static int pgm_default_5 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data)
{
pgm_default();
return -1;
}
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

@@ -19,15 +19,15 @@
/* $Id$ */
#ifndef __pgm_h__
#define __pgm_h__
#ifndef pgm_h
#define pgm_h
#include <limits.h>
#include "avrpart.h"
#include "lists.h"
#include "pindefs.h"
#include "serial.h"
#define ON 1
#define OFF 0
@@ -36,7 +36,17 @@
#define PGM_PORTLEN PATH_MAX
#define PGM_TYPELEN 32
extern LISTID programmers;
typedef enum {
EXIT_VCC_UNSPEC,
EXIT_VCC_ENABLED,
EXIT_VCC_DISABLED
} exit_vcc_t;
typedef enum {
EXIT_RESET_UNSPEC,
EXIT_RESET_ENABLED,
EXIT_RESET_DISABLED
} exit_reset_t;
typedef struct programmer_t {
LISTID id;
@@ -44,18 +54,21 @@ typedef struct programmer_t {
char type[PGM_TYPELEN];
char port[PGM_PORTLEN];
unsigned int pinno[N_PINS];
exit_vcc_t exit_vcc;
exit_reset_t exit_reset;
int ppidata;
int ppictrl;
int baudrate;
double bitclock; /* JTAG ICE clock period in microseconds */
int fd;
int ispdelay; /* ISP clock delay */
union filedescriptor fd;
int page_size; /* page size if the programmer supports paged write/load */
int (*rdy_led) (struct programmer_t * pgm, int value);
int (*err_led) (struct programmer_t * pgm, int value);
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);
@@ -81,40 +94,32 @@ typedef struct programmer_t {
int (*set_varef) (struct programmer_t * pgm, 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);
int (*getpin) (struct programmer_t * pgm, int pin);
int (*highpulsepin) (struct programmer_t * pgm, int pin);
int (*parseexitspecs) (struct programmer_t * pgm, char *s);
int (*perform_osccal) (struct programmer_t * pgm);
char config_file[PATH_MAX]; /* config file where defined */
int lineno; /* config file line number */
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 <windows.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);
/* 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);
void gettimeofday(struct timeval*, void*z);
#define rindex strrchr
#endif /* __win32native_h */
#if !defined(ppi_claim)
# define ppi_claim(pgm)
#endif
#if !defined(ppi_release)
# define ppi_release(pgm)
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -19,10 +19,13 @@
/* $Id$ */
#if defined(__FreeBSD__) || defined(__linux__)
#if !defined(WIN32NATIVE)
#include "ac_cfg.h"
#if HAVE_PARPORT
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -31,44 +34,39 @@
#include <errno.h>
#if defined(__FreeBSD__)
#include <dev/ppbus/ppi.h>
# include "freebsd_ppi.h"
#elif defined(__linux__)
#include "linux_ppdev.h"
# include "linux_ppdev.h"
#elif defined(__sun__) && defined(__svr4__) /* 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(int fd, 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;
unsigned long set, get;
switch (reg) {
case PPIDATA:
set = PPISDATA;
get = PPIGDATA;
shadow_num = 0;
break;
case PPICTRL:
set = PPISCTRL;
get = PPIGCTRL;
shadow_num = 1;
break;
case PPISTATUS:
set = PPISSTATUS;
get = PPIGSTATUS;
shadow_num = 2;
break;
default:
@@ -83,12 +81,12 @@ int ppi_shadow_access(int fd, int reg, unsigned char *v, unsigned char action)
*v = shadow[shadow_num];
break;
case PPI_READ:
ioctl(fd, get, v);
DO_PPI_READ(fdp->ifd, reg, v);
shadow[shadow_num]=*v;
break;
case PPI_WRITE:
shadow[shadow_num]=*v;
ioctl(fd, set, v);
DO_PPI_WRITE(fdp->ifd, reg, v);
break;
}
return 0;
@@ -97,14 +95,14 @@ int ppi_shadow_access(int fd, int reg, unsigned char *v, unsigned char action)
/*
* set the indicated bit of the specified register.
*/
int ppi_set(int fd, int reg, int bit)
int ppi_set(union filedescriptor *fdp, int reg, int bit)
{
unsigned char v;
int rc;
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
v |= bit;
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
if (rc)
return -1;
@@ -116,14 +114,14 @@ int ppi_set(int fd, int reg, int bit)
/*
* clear the indicated bit of the specified register.
*/
int ppi_clr(int fd, int reg, int bit)
int ppi_clr(union filedescriptor *fdp, int reg, int bit)
{
unsigned char v;
int rc;
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
v &= ~bit;
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
if (rc)
return -1;
@@ -135,12 +133,12 @@ int ppi_clr(int fd, int reg, int bit)
/*
* get the indicated bit of the specified register.
*/
int ppi_get(int fd, int reg, int bit)
int ppi_get(union filedescriptor *fdp, int reg, int bit)
{
unsigned char v;
int rc;
rc = ppi_shadow_access(fd, reg, &v, PPI_READ);
rc = ppi_shadow_access(fdp, reg, &v, PPI_READ);
v &= bit;
if (rc)
@@ -152,14 +150,14 @@ int ppi_get(int fd, int reg, int bit)
/*
* toggle the indicated bit of the specified register.
*/
int ppi_toggle(int fd, int reg, int bit)
int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
{
unsigned char v;
int rc;
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
v ^= bit;
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
if (rc)
return -1;
@@ -171,12 +169,12 @@ int ppi_toggle(int fd, int reg, int bit)
/*
* get all bits of the specified register.
*/
int ppi_getall(int fd, int reg)
int ppi_getall(union filedescriptor *fdp, int reg)
{
unsigned char v;
int rc;
rc = ppi_shadow_access(fd, reg, &v, PPI_READ);
rc = ppi_shadow_access(fdp, reg, &v, PPI_READ);
if (rc)
return -1;
@@ -187,13 +185,13 @@ int ppi_getall(int fd, int reg)
/*
* set all bits of the specified register to val.
*/
int ppi_setall(int fd, int reg, int val)
int ppi_setall(union filedescriptor *fdp, int reg, int val)
{
unsigned char v;
int rc;
v = val;
rc = ppi_shadow_access(fd, reg, &v, PPI_WRITE);
rc = ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
if (rc)
return -1;
@@ -202,7 +200,7 @@ int ppi_setall(int fd, int reg, int val)
}
int ppi_open(char * port)
void ppi_open(char * port, union filedescriptor *fdp)
{
int fd;
unsigned char v;
@@ -211,96 +209,30 @@ int ppi_open(char * port)
if (fd < 0) {
fprintf(stderr, "%s: can't open device \"%s\": %s\n",
progname, port, strerror(errno));
return -1;
fdp->ifd = -1;
return;
}
ppi_claim (fd);
/*
* Initialize shadow registers
*/
ppi_shadow_access (fd, PPIDATA, &v, PPI_READ);
ppi_shadow_access (fd, PPICTRL, &v, PPI_READ);
ppi_shadow_access (fd, PPISTATUS, &v, PPI_READ);
ppi_shadow_access (fdp, PPIDATA, &v, PPI_READ);
ppi_shadow_access (fdp, PPICTRL, &v, PPI_READ);
ppi_shadow_access (fdp, PPISTATUS, &v, PPI_READ);
return fd;
fdp->ifd = fd;
}
void ppi_close(int fd)
void ppi_close(union filedescriptor *fdp)
{
close(fd);
ppi_release (fdp->ifd);
close(fdp->ifd);
}
#endif /* HAVE_PARPORT */
#elif defined(__POWERPC__) && defined(__APPLE__)
int ppi_shadow_access(int fd, int reg, unsigned char *v, unsigned char action)
{
return -1;
}
/*
* set the indicated bit of the specified register.
*/
int ppi_set(int fd, int reg, int bit)
{
return -1;
}
/*
* clear the indicated bit of the specified register.
*/
int ppi_clr(int fd, int reg, int bit)
{
return -1;
}
/*
* get the indicated bit of the specified register.
*/
int ppi_get(int fd, int reg, int bit)
{
return -1;
}
/*
* toggle the indicated bit of the specified register.
*/
int ppi_toggle(int fd, int reg, int bit)
{
return -1;
}
/*
* get all bits of the specified register.
*/
int ppi_getall(int fd, int reg)
{
return -1;
}
/*
* set all bits of the specified register to val.
*/
int ppi_setall(int fd, int reg, int val)
{
return -1;
}
int ppi_open(char * port)
{
return -1;
}
void ppi_close(int fd)
{
}
#endif
#endif /* !WIN32NATIVE */

View File

@@ -19,8 +19,8 @@
/* $Id$ */
#ifndef __ppi_h__
#define __ppi_h__
#ifndef ppi_h
#define ppi_h
/*
* PPI registers
@@ -31,23 +31,29 @@ enum {
PPISTATUS
};
#ifdef __cplusplus
extern "C" {
#endif
int ppi_get (union filedescriptor *fdp, int reg, int bit);
int ppi_get (int fd, int reg, int bit);
int ppi_set (union filedescriptor *fdp, int reg, int bit);
int ppi_set (int fd, int reg, int bit);
int ppi_clr (union filedescriptor *fdp, int reg, int bit);
int ppi_clr (int fd, int reg, int bit);
int ppi_getall (union filedescriptor *fdp, int reg);
int ppi_getall (int fd, int reg);
int ppi_setall (union filedescriptor *fdp, int reg, int val);
int ppi_setall (int fd, int reg, int val);
int ppi_toggle (union filedescriptor *fdp, int reg, int bit);
int ppi_toggle (int fd, int reg, int bit);
void ppi_open (char * port, union filedescriptor *fdp);
int ppi_open (char * port);
void ppi_close (union filedescriptor *fdp);
void ppi_close (int fd);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,6 +1,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003, 2004 Eric B. Weddington <ericw@evcohs.com>
* Copyright (C) 2003, 2004, 2006
* Eric B. Weddington <eweddington@cso.atmel.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
@@ -29,7 +30,7 @@ reg = register as defined in an enum in ppi.h. This must be converted
*/
#include "ac_cfg.h"
#if defined (WIN32NATIVE)
@@ -42,12 +43,11 @@ 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 "avrdude.h"
#include "serial.h"
#include "ppi.h"
extern char *progname;
#define DEVICE_LPT1 "lpt1"
#define DEVICE_LPT2 "lpt2"
#define DEVICE_LPT3 "lpt3"
@@ -73,7 +73,7 @@ static const winpp winports[DEVICE_MAX] =
/* FUNCTION PROTOTYPES */
static int winnt_pp_open(void);
static unsigned short port_get(int fd, int reg);
static unsigned short port_get(union filedescriptor *fdp, int reg);
static unsigned char reg2offset(int reg);
static unsigned char inb(unsigned short port);
static void outb(unsigned char value, unsigned short port);
@@ -82,7 +82,7 @@ static void outb(unsigned char value, unsigned short port);
/* FUNCTION DEFINITIONS */
int ppi_open(char *port)
void ppi_open(char *port, union filedescriptor *fdp)
{
unsigned char i;
int fd;
@@ -92,7 +92,8 @@ int ppi_open(char *port)
if(fd < 0)
{
fprintf(stderr, "%s: can't open device \"giveio\"\n\n", progname);
return(-1);
fdp->ifd = -1;
return;
}
/* Search the windows port names for a match */
@@ -109,10 +110,11 @@ int ppi_open(char *port)
if(fd < 0)
{
fprintf(stderr, "%s: can't open device \"%s\"\n\n", progname, port);
return(-1);
fdp->ifd = -1;
return;
}
return(fd);
fdp->ifd = fd;
}
@@ -157,7 +159,7 @@ static int winnt_pp_open(void)
void ppi_close(int fd)
void ppi_close(union filedescriptor *fdp)
{
return;
}
@@ -167,12 +169,12 @@ void ppi_close(int fd)
/*
* set the indicated bit of the specified register.
*/
int ppi_set(int fd, int reg, int bit)
int ppi_set(union filedescriptor *fdp, int reg, int bit)
{
unsigned char v;
unsigned short port;
port = port_get(fd, reg);
port = port_get(fdp, reg);
v = inb(port);
v |= bit;
outb(v, port);
@@ -183,12 +185,12 @@ int ppi_set(int fd, int reg, int bit)
/*
* clear the indicated bit of the specified register.
*/
int ppi_clr(int fd, int reg, int bit)
int ppi_clr(union filedescriptor *fdp, int reg, int bit)
{
unsigned char v;
unsigned short port;
port = port_get(fd, reg);
port = port_get(fdp, reg);
v = inb(port);
v &= ~bit;
outb(v, port);
@@ -200,11 +202,11 @@ int ppi_clr(int fd, int reg, int bit)
/*
* get the indicated bit of the specified register.
*/
int ppi_get(int fd, int reg, int bit)
int ppi_get(union filedescriptor *fdp, int reg, int bit)
{
unsigned char v;
v = inb(port_get(fd, reg));
v = inb(port_get(fdp, reg));
v &= bit;
return(v);
@@ -216,12 +218,12 @@ int ppi_get(int fd, int reg, int bit)
/*
* toggle the indicated bit of the specified register.
*/
int ppi_toggle(int fd, int reg, int bit)
int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
{
unsigned char v;
unsigned short port;
port = port_get(fd, reg);
port = port_get(fdp, reg);
v = inb(port);
v ^= bit;
@@ -234,11 +236,11 @@ int ppi_toggle(int fd, int reg, int bit)
/*
* get all bits of the specified register.
*/
int ppi_getall(int fd, int reg)
int ppi_getall(union filedescriptor *fdp, int reg)
{
unsigned char v;
v = inb(port_get(fd, reg));
v = inb(port_get(fdp, reg));
return((int)v);
}
@@ -249,9 +251,9 @@ int ppi_getall(int fd, int reg)
/*
* set all bits of the specified register to val.
*/
int ppi_setall(int fd, int reg, int val)
int ppi_setall(union filedescriptor *fdp, int reg, int val)
{
outb((unsigned char)val, port_get(fd, reg));
outb((unsigned char)val, port_get(fdp, reg));
return 0;
}
@@ -259,9 +261,9 @@ int ppi_setall(int fd, int reg, int val)
/* Calculate port address to access. */
static unsigned short port_get(int fd, int reg)
static unsigned short port_get(union filedescriptor *fdp, int reg)
{
return((unsigned short)(fd + reg2offset(reg)));
return((unsigned short)(fdp->ifd + reg2offset(reg)));
}
@@ -316,7 +318,9 @@ static void outb(unsigned char value, unsigned short port)
return;
}
void gettimeofday(struct timeval*tv, void*z){
#if !defined(HAVE_GETTIMEOFDAY)
struct timezone;
int gettimeofday(struct timeval *tv, struct timezone *unused){
// i've found only ms resolution, avrdude expects us
SYSTEMTIME st;
@@ -324,7 +328,10 @@ void gettimeofday(struct timeval*tv, void*z){
tv->tv_sec=(long)(st.wSecond+st.wMinute*60+st.wHour*3600);
tv->tv_usec=(long)(st.wMilliseconds*1000);
return 0;
}
#endif /* HAVE_GETTIMEOFDAY */
// #define W32USLEEPDBG

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
@@ -49,8 +48,14 @@ int safemode_writefuse (unsigned char fuse, char * fusename, PROGRAMMER * pgm,
/* Keep trying to write then read back the fuse values */
while (tries > 0) {
avr_write_byte(pgm, p, m, 0, fuse);
avr_read_byte(pgm, p, m, 0, &fuseread);
if (avr_write_byte(pgm, p, m, 0, fuse) != 0)
{
continue;
}
if (pgm->read_byte(pgm, p, m, 0, &fuseread) != 0)
{
continue;
}
/* Report information to user if needed */
if (verbose > 0) {
@@ -81,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;
@@ -99,15 +105,43 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
m = avr_locate_mem(p, "fuse");
if (m != NULL) {
fusegood = 0; /* By default fuse is a failure */
avr_read_byte(pgm, p, m, 0, &safemode_fuse);
avr_read_byte(pgm, p, m, 0, &value);
if (value == safemode_fuse) {
avr_read_byte(pgm, p, m, 0, &value);
if (value == safemode_fuse){
fusegood = 1; /* Fuse read OK three times */
if(pgm->read_byte(pgm, p, m, 0, &safemode_fuse) != 0)
{
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)
{
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)
{
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 */
}
}
}
}
//Programmer does not allow fuse reading.... no point trying anymore
if (allowfuseread == 0)
{
return -5;
}
if (fusegood == 0) {
fprintf(stderr,
@@ -126,16 +160,44 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
m = avr_locate_mem(p, "lfuse");
if (m != NULL) {
fusegood = 0; /* By default fuse is a failure */
avr_read_byte(pgm, p, m, 0, &safemode_lfuse);
avr_read_byte(pgm, p, m, 0, &value);
if (pgm->read_byte(pgm, p, m, 0, &safemode_lfuse) != 0)
{
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)
{
allowfuseread = 0;
}
if (verbose > 2)
{
fprintf(stderr, "%s: safemode read 2, lfuse value: %x\n",progname, value);
}
if (value == safemode_lfuse) {
avr_read_byte(pgm, p, m, 0, &value);
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
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. "
@@ -152,16 +214,43 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
m = avr_locate_mem(p, "hfuse");
if (m != NULL) {
fusegood = 0; /* By default fuse is a failure */
avr_read_byte(pgm, p, m, 0, &safemode_hfuse);
avr_read_byte(pgm, p, m, 0, &value);
if (pgm->read_byte(pgm, p, m, 0, &safemode_hfuse) != 0)
{
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)
{
allowfuseread = 0;
}
if (verbose > 2)
{
fprintf(stderr, "%s: safemode read 2, hfuse value: %x\n",progname, value);
}
if (value == safemode_hfuse) {
avr_read_byte(pgm, p, m, 0, &value);
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
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. "
@@ -178,16 +267,43 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
m = avr_locate_mem(p, "efuse");
if (m != NULL) {
fusegood = 0; /* By default fuse is a failure */
avr_read_byte(pgm, p, m, 0, &safemode_efuse);
avr_read_byte(pgm, p, m, 0, &value);
if (pgm->read_byte(pgm, p, m, 0, &safemode_efuse) != 0)
{
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)
{
allowfuseread = 0;
}
if (verbose > 2)
{
fprintf(stderr, "%s: safemode read 2, efuse value: %x\n",progname, value);
}
if (value == safemode_efuse) {
avr_read_byte(pgm, p, m, 0, &value);
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
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 */

646
avrdude/ser_avrdoper.c Normal file
View File

@@ -0,0 +1,646 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
* Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
* Copyright (C) 2006 Christian Starkjohann
*
* 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$ */
/*
* Serial Interface emulation for USB programmer "AVR-Doper" in HID mode.
*/
#include "ac_cfg.h"
#if defined(HAVE_LIBUSB) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
#include <stdio.h>
#include <string.h>
#include "avrdude.h"
#include "serial.h"
/* ------------------------------------------------------------------------ */
/* Numeric constants for 'reportType' parameters */
#define USB_HID_REPORT_TYPE_INPUT 1
#define USB_HID_REPORT_TYPE_OUTPUT 2
#define USB_HID_REPORT_TYPE_FEATURE 3
/* These are the error codes which can be returned by functions of this
* module.
*/
#define USB_ERROR_NONE 0
#define USB_ERROR_ACCESS 1
#define USB_ERROR_NOTFOUND 2
#define USB_ERROR_BUSY 16
#define USB_ERROR_IO 5
#define USB_VENDOR_ID 0x16c0
#define USB_PRODUCT_ID 0x05df
static int reportDataSizes[4] = {13, 29, 61, 125};
static unsigned char avrdoperRxBuffer[280]; /* buffer for receive data */
static int avrdoperRxLength = 0; /* amount of valid bytes in rx buffer */
static int avrdoperRxPosition = 0; /* amount of bytes already consumed in rx buffer */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
#if defined(WIN32NATIVE) && defined(HAVE_LIBHID)
#include <windows.h>
#include <setupapi.h>
#if defined(HAVE_DDK_HIDSDI_H)
# include <ddk/hidsdi.h>
#else
# include "my_ddk_hidsdi.h"
#endif
#include <ddk/hidpi.h>
#ifdef USB_DEBUG
#define DEBUG_PRINT(arg) printf arg
#else
#define DEBUG_PRINT(arg)
#endif
/* ------------------------------------------------------------------------ */
static void convertUniToAscii(char *buffer)
{
unsigned short *uni = (void *)buffer;
char *ascii = buffer;
while(*uni != 0){
if(*uni >= 256){
*ascii++ = '?';
}else{
*ascii++ = *uni++;
}
}
*ascii++ = 0;
}
static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
int product, char *productName, int usesReportIDs)
{
GUID hidGuid; /* GUID for HID driver */
HDEVINFO deviceInfoList;
SP_DEVICE_INTERFACE_DATA deviceInfo;
SP_DEVICE_INTERFACE_DETAIL_DATA *deviceDetails = NULL;
DWORD size;
int i, openFlag = 0; /* may be FILE_FLAG_OVERLAPPED */
int errorCode = USB_ERROR_NOTFOUND;
HANDLE handle = INVALID_HANDLE_VALUE;
HIDD_ATTRIBUTES deviceAttributes;
HidD_GetHidGuid(&hidGuid);
deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL,
DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
deviceInfo.cbSize = sizeof(deviceInfo);
for(i=0;;i++){
if(handle != INVALID_HANDLE_VALUE){
CloseHandle(handle);
handle = INVALID_HANDLE_VALUE;
}
if(!SetupDiEnumDeviceInterfaces(deviceInfoList, 0, &hidGuid, i, &deviceInfo))
break; /* no more entries */
/* first do a dummy call just to determine the actual size required */
SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL);
if(deviceDetails != NULL)
free(deviceDetails);
deviceDetails = malloc(size);
deviceDetails->cbSize = sizeof(*deviceDetails);
/* this call is for real: */
SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails,
size, &size, NULL);
DEBUG_PRINT(("checking HID path \"%s\"\n", deviceDetails->DevicePath));
/* attempt opening for R/W -- we don't care about devices which can't be accessed */
handle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
openFlag, NULL);
if(handle == INVALID_HANDLE_VALUE){
DEBUG_PRINT(("opening failed: %d\n", (int)GetLastError()));
/* errorCode = USB_ERROR_ACCESS; opening will always fail for mouse -- ignore */
continue;
}
deviceAttributes.Size = sizeof(deviceAttributes);
HidD_GetAttributes(handle, &deviceAttributes);
DEBUG_PRINT(("device attributes: vid=%d pid=%d\n",
deviceAttributes.VendorID, deviceAttributes.ProductID));
if(deviceAttributes.VendorID != vendor || deviceAttributes.ProductID != product)
continue; /* ignore this device */
errorCode = USB_ERROR_NOTFOUND;
if(vendorName != NULL && productName != NULL){
char buffer[512];
if(!HidD_GetManufacturerString(handle, buffer, sizeof(buffer))){
DEBUG_PRINT(("error obtaining vendor name\n"));
errorCode = USB_ERROR_IO;
continue;
}
convertUniToAscii(buffer);
DEBUG_PRINT(("vendorName = \"%s\"\n", buffer));
if(strcmp(vendorName, buffer) != 0)
continue;
if(!HidD_GetProductString(handle, buffer, sizeof(buffer))){
DEBUG_PRINT(("error obtaining product name\n"));
errorCode = USB_ERROR_IO;
continue;
}
convertUniToAscii(buffer);
DEBUG_PRINT(("productName = \"%s\"\n", buffer));
if(strcmp(productName, buffer) != 0)
continue;
}
break; /* we have found the device we are looking for! */
}
SetupDiDestroyDeviceInfoList(deviceInfoList);
if(deviceDetails != NULL)
free(deviceDetails);
if(handle != INVALID_HANDLE_VALUE){
fdp->pfd = (void *)handle;
errorCode = 0;
}
return errorCode;
}
/* ------------------------------------------------------------------------ */
static void usbCloseDevice(union filedescriptor *fdp)
{
CloseHandle((HANDLE)fdp->pfd);
}
/* ------------------------------------------------------------------------ */
static int usbSetReport(union filedescriptor *fdp, int reportType, char *buffer, int len)
{
HANDLE handle = (HANDLE)fdp->pfd;
BOOLEAN rval = 0;
DWORD bytesWritten;
switch(reportType){
case USB_HID_REPORT_TYPE_INPUT:
break;
case USB_HID_REPORT_TYPE_OUTPUT:
rval = WriteFile(handle, buffer, len, &bytesWritten, NULL);
break;
case USB_HID_REPORT_TYPE_FEATURE:
rval = HidD_SetFeature(handle, buffer, len);
break;
}
return rval == 0 ? USB_ERROR_IO : 0;
}
/* ------------------------------------------------------------------------ */
static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNumber,
char *buffer, int *len)
{
HANDLE handle = (HANDLE)fdp->pfd;
BOOLEAN rval = 0;
DWORD bytesRead;
switch(reportType){
case USB_HID_REPORT_TYPE_INPUT:
buffer[0] = reportNumber;
rval = ReadFile(handle, buffer, *len, &bytesRead, NULL);
if(rval)
*len = bytesRead;
break;
case USB_HID_REPORT_TYPE_OUTPUT:
break;
case USB_HID_REPORT_TYPE_FEATURE:
buffer[0] = reportNumber;
rval = HidD_GetFeature(handle, buffer, *len);
break;
}
return rval == 0 ? USB_ERROR_IO : 0;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
#else /* !(WIN32NATIVE && HAVE_LIBHID) */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
#include <usb.h>
/* ------------------------------------------------------------------------- */
#define USBRQ_HID_GET_REPORT 0x01
#define USBRQ_HID_SET_REPORT 0x09
static int usesReportIDs;
/* ------------------------------------------------------------------------- */
static int usbGetStringAscii(usb_dev_handle *dev, int index, int langid, char *buf, int buflen)
{
char buffer[256];
int rval, i;
if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR,
(USB_DT_STRING << 8) + index, langid, buffer,
sizeof(buffer), 1000)) < 0)
return rval;
if(buffer[1] != USB_DT_STRING)
return 0;
if((unsigned char)buffer[0] < rval)
rval = (unsigned char)buffer[0];
rval /= 2;
/* lossy conversion to ISO Latin1 */
for(i=1;i<rval;i++){
if(i > buflen) /* destination buffer overflow */
break;
buf[i-1] = buffer[2 * i];
if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */
buf[i-1] = '?';
}
buf[i-1] = 0;
return i-1;
}
static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
int product, char *productName, int doReportIDs)
{
struct usb_bus *bus;
struct usb_device *dev;
usb_dev_handle *handle = NULL;
int errorCode = USB_ERROR_NOTFOUND;
static int didUsbInit = 0;
if(!didUsbInit){
usb_init();
didUsbInit = 1;
}
usb_find_busses();
usb_find_devices();
for(bus=usb_get_busses(); bus; bus=bus->next){
for(dev=bus->devices; dev; dev=dev->next){
if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product){
char string[256];
int len;
handle = usb_open(dev); /* we need to open the device in order to query strings */
if(!handle){
errorCode = USB_ERROR_ACCESS;
fprintf(stderr, "Warning: cannot open USB device: %s\n",
usb_strerror());
continue;
}
if(vendorName == NULL && productName == NULL){ /* name does not matter */
break;
}
/* now check whether the names match: */
len = usbGetStringAscii(handle, dev->descriptor.iManufacturer,
0x0409, string, sizeof(string));
if(len < 0){
errorCode = USB_ERROR_IO;
fprintf(stderr,
"Warning: cannot query manufacturer for device: %s\n",
usb_strerror());
}else{
errorCode = USB_ERROR_NOTFOUND;
/* fprintf(stderr, "seen device from vendor ->%s<-\n", string); */
if(strcmp(string, vendorName) == 0){
len = usbGetStringAscii(handle, dev->descriptor.iProduct,
0x0409, string, sizeof(string));
if(len < 0){
errorCode = USB_ERROR_IO;
fprintf(stderr,
"Warning: cannot query product for device: %s\n",
usb_strerror());
}else{
errorCode = USB_ERROR_NOTFOUND;
/* fprintf(stderr, "seen product ->%s<-\n", string); */
if(strcmp(string, productName) == 0)
break;
}
}
}
usb_close(handle);
handle = NULL;
}
}
if(handle)
break;
}
if(handle != NULL){
int rval, retries = 3;
if(usb_set_configuration(handle, 1)){
fprintf(stderr, "Warning: could not set configuration: %s\n",
usb_strerror());
}
/* now try to claim the interface and detach the kernel HID driver on
* linux and other operating systems which support the call.
*/
while((rval = usb_claim_interface(handle, 0)) != 0 && retries-- > 0){
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
if(usb_detach_kernel_driver_np(handle, 0) < 0){
fprintf(stderr, "Warning: could not detach kernel HID driver: %s\n",
usb_strerror());
}
#endif
}
if(rval != 0)
fprintf(stderr, "Warning: could not claim interface\n");
/* Continue anyway, even if we could not claim the interface. Control transfers
* should still work.
*/
errorCode = 0;
fdp->pfd = (void *)handle;
usesReportIDs = doReportIDs;
}
return errorCode;
}
/* ------------------------------------------------------------------------- */
static void usbCloseDevice(union filedescriptor *fdp)
{
usb_close((usb_dev_handle *)fdp->pfd);
}
/* ------------------------------------------------------------------------- */
static int usbSetReport(union filedescriptor *fdp, int reportType, char *buffer, int len)
{
int bytesSent;
if(!usesReportIDs){
buffer++; /* skip dummy report ID */
len--;
}
bytesSent = usb_control_msg((usb_dev_handle *)fdp->pfd, USB_TYPE_CLASS |
USB_RECIP_INTERFACE | USB_ENDPOINT_OUT, USBRQ_HID_SET_REPORT,
reportType << 8 | buffer[0], 0, buffer, len, 5000);
if(bytesSent != len){
if(bytesSent < 0)
fprintf(stderr, "Error sending message: %s\n", usb_strerror());
return USB_ERROR_IO;
}
return 0;
}
/* ------------------------------------------------------------------------- */
static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNumber,
char *buffer, int *len)
{
int bytesReceived, maxLen = *len;
if(!usesReportIDs){
buffer++; /* make room for dummy report ID */
maxLen--;
}
bytesReceived = usb_control_msg((usb_dev_handle *)fdp->pfd, USB_TYPE_CLASS |
USB_RECIP_INTERFACE | USB_ENDPOINT_IN, USBRQ_HID_GET_REPORT,
reportType << 8 | reportNumber, 0, buffer, maxLen, 5000);
if(bytesReceived < 0){
fprintf(stderr, "Error sending message: %s\n", usb_strerror());
return USB_ERROR_IO;
}
*len = bytesReceived;
if(!usesReportIDs){
buffer[-1] = reportNumber; /* add dummy report ID */
*len++;
}
return 0;
}
#endif /* WIN32NATIVE */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------- */
static void dumpBlock(char *prefix, unsigned char *buf, int len)
{
int i;
if(len <= 8){ /* more compact format for short blocks */
fprintf(stderr, "%s: %d bytes: ", prefix, len);
for(i = 0; i < len; i++){
fprintf(stderr, "%02x ", buf[i]);
}
fprintf(stderr, " \"");
for(i = 0; i < len; i++){
if(buf[i] >= 0x20 && buf[i] < 0x7f){
fputc(buf[i], stderr);
}else{
fputc('.', stderr);
}
}
fprintf(stderr, "\"\n");
}else{
fprintf(stderr, "%s: %d bytes:\n", prefix, len);
while(len > 0){
for(i = 0; i < 16; i++){
if(i < len){
fprintf(stderr, "%02x ", buf[i]);
}else{
fprintf(stderr, " ");
}
if(i == 7)
fputc(' ', stderr);
}
fprintf(stderr, " \"");
for(i = 0; i < 16; i++){
if(i < len){
if(buf[i] >= 0x20 && buf[i] < 0x7f){
fputc(buf[i], stderr);
}else{
fputc('.', stderr);
}
}
}
fprintf(stderr, "\"\n");
buf += 16;
len -= 16;
}
}
}
static char *usbErrorText(int usbErrno)
{
static char buffer[32];
switch(usbErrno){
case USB_ERROR_NONE: return "Success.";
case USB_ERROR_ACCESS: return "Access denied.";
case USB_ERROR_NOTFOUND:return "Device not found.";
case USB_ERROR_BUSY: return "Device is busy.";
case USB_ERROR_IO: return "I/O Error.";
default:
sprintf(buffer, "Unknown error %d.", usbErrno);
return buffer;
}
}
/* ------------------------------------------------------------------------- */
static void avrdoper_open(char *port, long baud, union filedescriptor *fdp)
{
int rval;
char *vname = "obdev.at";
char *devname = "AVR-Doper";
rval = usbOpenDevice(fdp, USB_VENDOR_ID, vname, USB_PRODUCT_ID, devname, 1);
if(rval != 0){
fprintf(stderr, "%s: avrdoper_open(): %s\n", progname, usbErrorText(rval));
exit(1);
}
}
/* ------------------------------------------------------------------------- */
static void avrdoper_close(union filedescriptor *fdp)
{
usbCloseDevice(fdp);
}
/* ------------------------------------------------------------------------- */
static int chooseDataSize(int len)
{
int i;
for(i = 0; i < sizeof(reportDataSizes)/sizeof(reportDataSizes[0]); i++){
if(reportDataSizes[i] >= len)
return i;
}
return i - 1;
}
static int avrdoper_send(union filedescriptor *fdp, unsigned char *buf, size_t buflen)
{
if(verbose > 3)
dumpBlock("Send", buf, buflen);
while(buflen > 0){
unsigned char buffer[256];
int rval, lenIndex = chooseDataSize(buflen);
int thisLen = buflen > reportDataSizes[lenIndex] ?
reportDataSizes[lenIndex] : buflen;
buffer[0] = lenIndex + 1; /* report ID */
buffer[1] = thisLen;
memcpy(buffer + 2, buf, thisLen);
if(verbose > 3)
fprintf(stderr, "Sending %d bytes data chunk\n", thisLen);
rval = usbSetReport(fdp, USB_HID_REPORT_TYPE_FEATURE, (char *)buffer,
reportDataSizes[lenIndex] + 2);
if(rval != 0){
fprintf(stderr, "%s: avrdoper_send(): %s\n", progname, usbErrorText(rval));
exit(1);
}
buflen -= thisLen;
buf += thisLen;
}
return 0;
}
/* ------------------------------------------------------------------------- */
static void avrdoperFillBuffer(union filedescriptor *fdp)
{
int bytesPending = reportDataSizes[1]; /* guess how much data is buffered in device */
avrdoperRxPosition = avrdoperRxLength = 0;
while(bytesPending > 0){
int len, usbErr, lenIndex = chooseDataSize(bytesPending);
unsigned char buffer[128];
len = sizeof(avrdoperRxBuffer) - avrdoperRxLength; /* bytes remaining */
if(reportDataSizes[lenIndex] + 2 > len) /* requested data would not fit into buffer */
break;
len = reportDataSizes[lenIndex] + 2;
usbErr = usbGetReport(fdp, USB_HID_REPORT_TYPE_FEATURE, lenIndex + 1,
(char *)buffer, &len);
if(usbErr != 0){
fprintf(stderr, "%s: avrdoperFillBuffer(): %s\n", progname, usbErrorText(usbErr));
exit(1);
}
if(verbose > 3)
fprintf(stderr, "Received %d bytes data chunk of total %d\n", len - 2, buffer[1]);
len -= 2; /* compensate for report ID and length byte */
bytesPending = buffer[1] - len; /* amount still buffered */
if(len > buffer[1]) /* cut away padding */
len = buffer[1];
if(avrdoperRxLength + len > sizeof(avrdoperRxBuffer)){
fprintf(stderr,
"%s: avrdoperFillBuffer(): internal error: buffer overflow\n",
progname);
exit(1);
}
memcpy(avrdoperRxBuffer + avrdoperRxLength, buffer + 2, len);
avrdoperRxLength += len;
}
}
static int avrdoper_recv(union filedescriptor *fdp, unsigned char *buf, size_t buflen)
{
unsigned char *p = buf;
int remaining = buflen;
while(remaining > 0){
int len, available = avrdoperRxLength - avrdoperRxPosition;
if(available <= 0){ /* buffer is empty */
avrdoperFillBuffer(fdp);
continue;
}
len = remaining < available ? remaining : available;
memcpy(p, avrdoperRxBuffer + avrdoperRxPosition, len);
p += len;
remaining -= len;
avrdoperRxPosition += len;
}
if(verbose > 3)
dumpBlock("Receive", buf, buflen);
return 0;
}
/* ------------------------------------------------------------------------- */
static int avrdoper_drain(union filedescriptor *fdp, int display)
{
do{
avrdoperFillBuffer(fdp);
}while(avrdoperRxLength > 0);
return 0;
}
/* ------------------------------------------------------------------------- */
struct serial_device avrdoper_serdev =
{
.open = avrdoper_open,
.close = avrdoper_close,
.send = avrdoper_send,
.recv = avrdoper_recv,
.drain = avrdoper_drain,
.flags = SERDEV_FL_NONE,
};
#endif /* defined(HAVE_LIBUSB) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID)) */

View File

@@ -1,6 +1,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
* Copyright (C) 2006 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,16 +34,17 @@
#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <fcntl.h>
#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 {
@@ -65,6 +67,9 @@ static struct baud_mapping baud_lookup_table [] = {
{ 0, 0 } /* Terminator. */
};
static struct termios original_termios;
static int saved_original_termios;
static speed_t serial_baud_lookup(long baud)
{
struct baud_mapping *map = baud_lookup_table;
@@ -75,103 +80,197 @@ static speed_t serial_baud_lookup(long baud)
map++;
}
fprintf(stderr, "%s: serial_baud_lookup(): unknown baud rate: %ld",
fprintf(stderr, "%s: serial_baud_lookup(): unknown baud rate: %ld\n",
progname, baud);
exit(1);
}
static int ser_setspeed(int fd, long baud)
static int ser_setspeed(union filedescriptor *fd, long baud)
{
int rc;
struct termios termios;
speed_t speed = serial_baud_lookup (baud);
if (!isatty(fd))
return -1;
if (!isatty(fd->ifd))
return -ENOTTY;
/*
* initialize terminal modes
*/
rc = tcgetattr(fd, &termios);
rc = tcgetattr(fd->ifd, &termios);
if (rc < 0) {
fprintf(stderr, "%s: ser_setspeed(): tcgetattr() failed, %s",
progname, strerror(errno));
fprintf(stderr, "%s: ser_setspeed(): tcgetattr() failed",
progname);
return -errno;
}
termios.c_iflag = 0;
/*
* copy termios for ser_close if we haven't already
*/
if (! saved_original_termios++) {
original_termios = termios;
}
termios.c_iflag = IGNBRK;
termios.c_oflag = 0;
termios.c_cflag = 0;
termios.c_cflag |= (CS8 | CREAD | CLOCAL);
termios.c_lflag = 0;
termios.c_cflag = (CS8 | CREAD | CLOCAL);
termios.c_cc[VMIN] = 1;
termios.c_cc[VTIME] = 0;
cfsetospeed(&termios, speed);
cfsetispeed(&termios, speed);
rc = tcsetattr(fd, TCSANOW, &termios);
rc = tcsetattr(fd->ifd, TCSANOW | TCSAFLUSH, &termios);
if (rc < 0) {
fprintf(stderr, "%s: ser_setspeed(): tcsetattr() failed, %s",
progname, strerror(errno));
fprintf(stderr, "%s: ser_setspeed(): tcsetattr() failed",
progname);
return -errno;
}
#if 0
/*
* set non blocking mode
* Everything is now set up for a local line without modem control
* or flow control, so clear O_NONBLOCK again.
*/
rc = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, rc | O_NONBLOCK);
#endif
rc = fcntl(fd->ifd, F_GETFL, 0);
if (rc != -1)
fcntl(fd->ifd, F_SETFL, rc & ~O_NONBLOCK);
return 0;
}
/*
* Given a port description of the form <host>:<port>, open a TCP
* connection to the specified destination, which is assumed to be a
* terminal/console server with serial parameters configured
* appropriately (e. g. 115200-8-N-1 for a STK500.)
*/
static void
net_open(const char *port, union filedescriptor *fdp)
{
char *hstr, *pstr, *end;
unsigned int pnum;
int fd;
struct sockaddr_in sockaddr;
struct hostent *hp;
static int ser_open(char * port, long baud)
if ((hstr = strdup(port)) == NULL) {
fprintf(stderr, "%s: net_open(): Out of memory!\n",
progname);
exit(1);
}
if (((pstr = strchr(hstr, ':')) == NULL) || (pstr == hstr)) {
fprintf(stderr, "%s: net_open(): Mangled host:port string \"%s\"\n",
progname, hstr);
free(hstr);
exit(1);
}
/*
* Terminate the host section of the description.
*/
*pstr++ = '\0';
pnum = strtoul(pstr, &end, 10);
if ((*pstr == '\0') || (*end != '\0') || (pnum == 0) || (pnum > 65535)) {
fprintf(stderr, "%s: net_open(): Bad port number \"%s\"\n",
progname, pstr);
free(hstr);
exit(1);
}
if ((hp = gethostbyname(hstr)) == NULL) {
fprintf(stderr, "%s: net_open(): unknown host \"%s\"\n",
progname, hstr);
free(hstr);
exit(1);
}
free(hstr);
if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
fprintf(stderr, "%s: net_open(): Cannot open socket: %s\n",
progname, strerror(errno));
exit(1);
}
memset(&sockaddr, 0, sizeof(struct sockaddr_in));
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(pnum);
memcpy(&(sockaddr.sin_addr.s_addr), hp->h_addr, sizeof(struct in_addr));
if (connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) {
fprintf(stderr, "%s: net_open(): Connect failed: %s\n",
progname, strerror(errno));
exit(1);
}
fdp->ifd = fd;
}
static void ser_open(char * port, long baud, union filedescriptor *fdp)
{
int rc;
int fd;
/*
* If the port is of the form "net:<host>:<port>", then
* handle it as a TCP connection to a terminal server.
*/
if (strncmp(port, "net:", strlen("net:")) == 0) {
net_open(port + strlen("net:"), fdp);
return;
}
/*
* open the serial port
*/
fd = open(port, O_RDWR | O_NOCTTY /*| O_NONBLOCK*/);
fd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd < 0) {
fprintf(stderr, "%s: ser_open(): can't open device \"%s\": %s\n",
progname, port, strerror(errno));
exit(1);
}
fdp->ifd = fd;
/*
* set serial line attributes
*/
rc = ser_setspeed(fd, baud);
rc = ser_setspeed(fdp, baud);
if (rc) {
fprintf(stderr,
"%s: ser_open(): can't set attributes for device \"%s\"\n",
progname, port);
"%s: ser_open(): can't set attributes for device \"%s\": %s\n",
progname, port, strerror(-rc));
exit(1);
}
return fd;
}
static void ser_close(int fd)
static void ser_close(union filedescriptor *fd)
{
/* FIXME: Should really restore the terminal to original state here. */
/*
* restore original termios settings from ser_open
*/
if (saved_original_termios) {
int rc = tcsetattr(fd->ifd, TCSANOW | TCSADRAIN, &original_termios);
if (rc) {
fprintf(stderr,
"%s: ser_close(): can't reset attributes for device: %s\n",
progname, strerror(errno));
}
saved_original_termios = 0;
}
close(fd);
close(fd->ifd);
}
static int ser_send(int fd, unsigned char * buf, size_t buflen)
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;
@@ -205,30 +304,7 @@ static int ser_send(int fd, unsigned char * buf, size_t buflen)
to2 = timeout;
while (len) {
reselect:
FD_ZERO(&wfds);
FD_SET(fd, &wfds);
nfds = select(fd+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, p, (len > 1024) ? 1024 : len);
rc = write(fd->ifd, p, (len > 1024) ? 1024 : len);
if (rc < 0) {
fprintf(stderr, "%s: ser_send(): write error: %s\n",
progname, strerror(errno));
@@ -242,7 +318,7 @@ static int ser_send(int fd, unsigned char * buf, size_t buflen)
}
static int ser_recv(int fd, unsigned char * buf, size_t buflen)
static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
{
struct timeval timeout, to2;
fd_set rfds;
@@ -258,9 +334,9 @@ static int ser_recv(int fd, unsigned char * buf, size_t buflen)
while (len < buflen) {
reselect:
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
FD_SET(fd->ifd, &rfds);
nfds = select(fd+1, &rfds, NULL, NULL, &to2);
nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &to2);
if (nfds == 0) {
if (verbose > 1)
fprintf(stderr,
@@ -282,7 +358,7 @@ static int ser_recv(int fd, unsigned char * buf, size_t buflen)
}
}
rc = read(fd, p, (buflen - len > 1024) ? 1024 : buflen - len);
rc = read(fd->ifd, p, (buflen - len > 1024) ? 1024 : buflen - len);
if (rc < 0) {
fprintf(stderr, "%s: ser_recv(): read error: %s\n",
progname, strerror(errno));
@@ -318,7 +394,7 @@ static int ser_recv(int fd, unsigned char * buf, size_t buflen)
}
static int ser_drain(int fd, int display)
static int ser_drain(union filedescriptor *fd, int display)
{
struct timeval timeout;
fd_set rfds;
@@ -335,10 +411,10 @@ static int ser_drain(int fd, int display)
while (1) {
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
FD_SET(fd->ifd, &rfds);
reselect:
nfds = select(fd+1, &rfds, NULL, NULL, &timeout);
nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &timeout);
if (nfds == 0) {
if (display) {
fprintf(stderr, "<drain\n");
@@ -357,7 +433,7 @@ static int ser_drain(int fd, int display)
}
}
rc = read(fd, &buf, 1);
rc = read(fd->ifd, &buf, 1);
if (rc < 0) {
fprintf(stderr, "%s: ser_drain(): read error: %s\n",
progname, strerror(errno));
@@ -379,6 +455,7 @@ struct serial_device serial_serdev =
.send = ser_send,
.recv = ser_recv,
.drain = ser_drain,
.flags = SERDEV_FL_CANSETSPEED,
};
struct serial_device *serdev = &serial_serdev;

View File

@@ -1,6 +1,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003, 2004 Martin J. Thomas <mthomas@rhrk.uni-kl.de>
* Copyright (C) 2006 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
@@ -28,10 +29,9 @@
#include <windows.h>
#include <stdio.h>
#include <ctype.h> /* for isprint */
#include "serial.h"
extern char *progname;
extern int verbose;
#include "avrdude.h"
#include "serial.h"
long serial_recv_timeout = 5000; /* ms */
@@ -83,10 +83,10 @@ static BOOL serial_w32SetTimeOut(HANDLE hComPort, DWORD timeout) // in ms
return SetCommTimeouts(hComPort, &ctmo);
}
static int ser_setspeed(int fd, long baud)
static int ser_setspeed(union filedescriptor *fd, long baud)
{
DCB dcb;
HANDLE hComPort = (HANDLE)fd;
HANDLE hComPort = (HANDLE)fd->pfd;
ZeroMemory (&dcb, sizeof(DCB));
dcb.DCBlength = sizeof(DCB);
@@ -105,11 +105,25 @@ static int ser_setspeed(int fd, long baud)
}
static int ser_open(char * port, long baud)
static void ser_open(char * port, long baud, union filedescriptor *fdp)
{
LPVOID lpMsgBuf;
HANDLE hComPort=INVALID_HANDLE_VALUE;
/*
* If the port is of the form "net:<host>:<port>", then
* handle it as a TCP connection to a terminal server.
*
* This is curently not implemented for Win32.
*/
if (strncmp(port, "net:", strlen("net:")) == 0) {
fprintf(stderr,
"%s: ser_open(): network connects are currently not"
"implemented for Win32 environments\n",
progname);
exit(1);
}
/* if (hComPort!=INVALID_HANDLE_VALUE)
fprintf(stderr, "%s: ser_open(): \"%s\" is already open\n",
progname, port);
@@ -143,8 +157,8 @@ static int ser_open(char * port, long baud)
exit(1);
}
if (ser_setspeed((int)hComPort, baud) != 0)
fdp->pfd = (void *)hComPort;
if (ser_setspeed(fdp, baud) != 0)
{
CloseHandle(hComPort);
fprintf(stderr, "%s: ser_open(): can't set com-state for \"%s\"\n",
@@ -159,14 +173,12 @@ static int ser_open(char * port, long baud)
progname, port);
exit(1);
}
return (int)hComPort;
}
static void ser_close(int fd)
static void ser_close(union filedescriptor *fd)
{
HANDLE hComPort=(HANDLE)fd;
HANDLE hComPort=(HANDLE)fd->pfd;
if (hComPort != INVALID_HANDLE_VALUE)
CloseHandle (hComPort);
@@ -174,13 +186,14 @@ static void ser_close(int fd)
}
static int ser_send(int fd, char * buf, size_t buflen)
static int ser_send(union filedescriptor *fd, unsigned char * buf, size_t buflen)
{
size_t len = buflen;
unsigned char c='\0';
DWORD written;
unsigned char * b = buf;
HANDLE hComPort=(HANDLE)fd;
HANDLE hComPort=(HANDLE)fd->pfd;
if (hComPort == INVALID_HANDLE_VALUE) {
fprintf(stderr, "%s: ser_send(): port not open\n",
@@ -195,8 +208,8 @@ static int ser_send(int fd, char * buf, size_t buflen)
{
fprintf(stderr, "%s: Send: ", progname);
while (buflen) {
c = *buf;
while (len) {
c = *b;
if (isprint(c)) {
fprintf(stderr, "%c ", c);
}
@@ -204,8 +217,8 @@ static int ser_send(int fd, char * buf, size_t buflen)
fprintf(stderr, ". ");
}
fprintf(stderr, "[%02x] ", c);
buf++;
buflen--;
b++;
len--;
}
fprintf(stderr, "\n");
}
@@ -228,14 +241,13 @@ static int ser_send(int fd, char * buf, size_t buflen)
}
static int ser_recv(int fd, char * buf, size_t buflen)
static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
{
unsigned char c;
char * p = buf;
size_t len = 0;
unsigned char * p = buf;
DWORD read;
HANDLE hComPort=(HANDLE)fd;
HANDLE hComPort=(HANDLE)fd->pfd;
if (hComPort == INVALID_HANDLE_VALUE) {
fprintf(stderr, "%s: ser_read(): port not open\n",
@@ -269,7 +281,7 @@ static int ser_recv(int fd, char * buf, size_t buflen)
{
fprintf(stderr, "%s: Recv: ", progname);
while (len) {
while (read) {
c = *p;
if (isprint(c)) {
fprintf(stderr, "%c ", c);
@@ -280,7 +292,7 @@ static int ser_recv(int fd, char * buf, size_t buflen)
fprintf(stderr, "[%02x] ", c);
p++;
len--;
read--;
}
fprintf(stderr, "\n");
}
@@ -288,14 +300,14 @@ static int ser_recv(int fd, char * buf, size_t buflen)
}
static int ser_drain(int fd, int display)
static int ser_drain(union filedescriptor *fd, int display)
{
// int rc;
unsigned char buf[10];
BOOL readres;
DWORD read;
HANDLE hComPort=(HANDLE)fd;
HANDLE hComPort=(HANDLE)fd->pfd;
if (hComPort == INVALID_HANDLE_VALUE) {
fprintf(stderr, "%s: ser_drain(): port not open\n",
@@ -348,6 +360,7 @@ struct serial_device serial_serdev =
.send = ser_send,
.recv = ser_recv,
.drain = ser_drain,
.flags = SERDEV_FL_CANSETSPEED,
};
struct serial_device *serdev = &serial_serdev;

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

@@ -2,6 +2,7 @@
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
* Copyright (C) 2006 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
@@ -36,6 +37,7 @@
#include <sys/ioctl.h>
#include <termios.h>
#include "avrdude.h"
#include "avr.h"
#include "pindefs.h"
#include "pgm.h"
@@ -43,32 +45,36 @@
#undef DEBUG
extern char *progname;
struct termios oldmode;
static struct termios oldmode;
/*
serial port/pin mapping
1 cd <-
2 rxd <-
2 (rxd) <-
3 txd ->
4 dtr ->
5 dsr <-
6 rts ->
7 cts <-
5 GND
6 dsr <-
7 rts ->
8 cts <-
9 ri <-
*/
int serregbits[] =
{ TIOCM_CD, 0, 0, TIOCM_DTR, TIOCM_DSR, TIOCM_RTS, TIOCM_CTS };
#define DB9PINS 9
static int serregbits[DB9PINS + 1] =
{ 0, TIOCM_CD, 0, 0, TIOCM_DTR, 0, TIOCM_DSR, TIOCM_RTS, TIOCM_CTS, TIOCM_RI };
#ifdef DEBUG
char *serpins[7] =
{ "CD", "RXD", "TXD ~RESET", "DTR MOSI", "DSR", "RTS SCK", "CTS MISO" };
static char *serpins[DB9PINS + 1] =
{ "NONE", "CD", "RXD", "TXD", "DTR", "GND", "DSR", "RTS", "CTS", "RI" };
#endif
void serbb_setpin(int fd, int pin, int value)
static int serbb_setpin(PROGRAMMER * pgm, int pin, int value)
{
unsigned int ctl;
int r;
if (pin & PIN_INVERSE)
{
@@ -76,10 +82,8 @@ void serbb_setpin(int fd, int pin, int value)
pin &= PIN_MASK;
}
if ( pin < 1 || pin > 7 )
return;
pin--;
if ( pin < 1 || pin > DB9PINS )
return -1;
#ifdef DEBUG
printf("%s to %d\n",serpins[pin],value);
@@ -87,28 +91,42 @@ void serbb_setpin(int fd, int pin, int value)
switch ( pin )
{
case 2: /* txd */
ioctl(fd, value ? TIOCSBRK : TIOCCBRK, 0);
return;
case 3: /* txd */
r = ioctl(pgm->fd.ifd, value ? TIOCSBRK : TIOCCBRK, 0);
if (r < 0) {
perror("ioctl(\"TIOCxBRK\")");
return -1;
}
return 0;
case 3: /* dtr, rts */
case 5: ioctl(fd, TIOCMGET, &ctl);
case 4: /* dtr */
case 7: /* rts */
r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl);
if (r < 0) {
perror("ioctl(\"TIOCMGET\")");
return -1;
}
if ( value )
ctl |= serregbits[pin];
else
ctl &= ~(serregbits[pin]);
ioctl(fd, TIOCMSET, &ctl);
return;
r = ioctl(pgm->fd.ifd, TIOCMSET, &ctl);
if (r < 0) {
perror("ioctl(\"TIOCMSET\")");
return -1;
}
return 0;
default: /* impossible */
return;
return -1;
}
}
int serbb_getpin(int fd, int pin)
static int serbb_getpin(PROGRAMMER * pgm, int pin)
{
unsigned int ctl;
unsigned char invert;
int r;
if (pin & PIN_INVERSE)
{
@@ -117,21 +135,23 @@ int serbb_getpin(int fd, int pin)
} else
invert = 0;
if ( pin < 1 || pin > 7 )
if ( pin < 1 || pin > DB9PINS )
return(-1);
pin --;
switch ( pin )
{
case 1: /* rxd, currently not implemented, FIXME */
case 2: /* rxd, currently not implemented, FIXME */
return(-1);
case 0: /* cd, dsr, dtr, rts, cts */
case 3:
case 4:
case 5:
case 6: ioctl(fd, TIOCMGET, &ctl);
case 1: /* cd */
case 6: /* dsr */
case 8: /* cts */
case 9: /* ri */
r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl);
if (r < 0) {
perror("ioctl(\"TIOCMGET\")");
return -1;
}
if ( !invert )
{
#ifdef DEBUG
@@ -152,95 +172,114 @@ int serbb_getpin(int fd, int pin)
}
}
int serbb_highpulsepin(int fd, int pin)
static int serbb_highpulsepin(PROGRAMMER * pgm, int pin)
{
if (pin < 1 || pin > 7)
if ( pin < 1 || pin > DB9PINS )
return -1;
serbb_setpin(fd, pin, 1);
#if SLOW_TOGGLE
usleep(1000);
#endif
serbb_setpin(fd, pin, 0);
serbb_setpin(pgm, pin, 1);
if (pgm->ispdelay > 1)
bitbang_delay(pgm->ispdelay);
#if SLOW_TOGGLE
usleep(1000);
#endif
serbb_setpin(pgm, pin, 0);
if (pgm->ispdelay > 1)
bitbang_delay(pgm->ispdelay);
return 0;
}
void serbb_display(PROGRAMMER *pgm, char *p)
static void serbb_display(PROGRAMMER *pgm, const char *p)
{
/* MAYBE */
}
void serbb_enable(PROGRAMMER *pgm)
static void serbb_enable(PROGRAMMER *pgm)
{
/* nothing */
}
void serbb_disable(PROGRAMMER *pgm)
static void serbb_disable(PROGRAMMER *pgm)
{
/* nothing */
}
void serbb_powerup(PROGRAMMER *pgm)
static void serbb_powerup(PROGRAMMER *pgm)
{
/* nothing */
}
void serbb_powerdown(PROGRAMMER *pgm)
static void serbb_powerdown(PROGRAMMER *pgm)
{
/* nothing */
}
int serbb_open(PROGRAMMER *pgm, char *port)
static int serbb_open(PROGRAMMER *pgm, char *port)
{
struct termios mode;
int flags;
int r;
bitbang_check_prerequisites(pgm);
/* adapted from uisp code */
pgm->fd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
pgm->fd.ifd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
if ( pgm->fd > 0 )
{
tcgetattr(pgm->fd, &mode);
oldmode = mode;
cfmakeraw(&mode);
mode.c_iflag &= ~(INPCK | IXOFF | IXON);
mode.c_cflag &= ~(HUPCL | CSTOPB | CRTSCTS);
mode.c_cflag |= (CLOCAL | CREAD);
mode.c_cc [VMIN] = 1;
mode.c_cc [VTIME] = 0;
tcsetattr(pgm->fd, TCSANOW, &mode);
/* Clear O_NONBLOCK flag. */
flags = fcntl(pgm->fd, F_GETFL, 0);
if (flags == -1)
{
fprintf(stderr, "%s: Can not get flags\n", progname);
return(-1);
}
flags &= ~O_NONBLOCK;
if (fcntl(pgm->fd, F_SETFL, flags) == -1)
{
fprintf(stderr, "%s: Can not clear nonblock flag\n", progname);
return(-1);
}
if (pgm->fd.ifd < 0) {
perror(port);
return(-1);
}
r = tcgetattr(pgm->fd.ifd, &mode);
if (r < 0) {
fprintf(stderr, "%s: ", port);
perror("tcgetattr");
return(-1);
}
oldmode = mode;
mode.c_iflag = IGNBRK | IGNPAR;
mode.c_oflag = 0;
mode.c_cflag = CLOCAL | CREAD | CS8 | B9600;
mode.c_cc [VMIN] = 1;
mode.c_cc [VTIME] = 0;
r = tcsetattr(pgm->fd.ifd, TCSANOW, &mode);
if (r < 0) {
fprintf(stderr, "%s: ", port);
perror("tcsetattr");
return(-1);
}
/* Clear O_NONBLOCK flag. */
flags = fcntl(pgm->fd.ifd, F_GETFL, 0);
if (flags == -1)
{
fprintf(stderr, "%s: Can not get flags: %s\n",
progname, strerror(errno));
return(-1);
}
flags &= ~O_NONBLOCK;
if (fcntl(pgm->fd.ifd, F_SETFL, flags) == -1)
{
fprintf(stderr, "%s: Can not clear nonblock flag: %s\n",
progname, strerror(errno));
return(-1);
}
return(0);
}
void serbb_close(PROGRAMMER *pgm)
static void serbb_close(PROGRAMMER *pgm)
{
tcsetattr(pgm->fd, TCSADRAIN, &oldmode);
if (pgm->fd.ifd != -1)
{
(void)tcsetattr(pgm->fd.ifd, TCSANOW, &oldmode);
pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1);
close(pgm->fd.ifd);
}
return;
}
@@ -263,9 +302,11 @@ void serbb_initpgm(PROGRAMMER *pgm)
pgm->cmd = bitbang_cmd;
pgm->open = serbb_open;
pgm->close = serbb_close;
/* this is a serial port bitbang device */
pgm->flag = 1;
pgm->setpin = serbb_setpin;
pgm->getpin = serbb_getpin;
pgm->highpulsepin = serbb_highpulsepin;
pgm->read_byte = avr_read_byte_default;
pgm->write_byte = avr_write_byte_default;
}
#endif /* WIN32NATIVE */

View File

@@ -2,7 +2,7 @@
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003, 2004 Martin J. Thomas <mthomas@rhrk.uni-kl.de>
* Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
* Copyright (C) 2005 Joerg Wunsch <j@uriah.heep.sax.de>
* Copyright (C) 2005, 2006 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
@@ -32,14 +32,12 @@
#include <windows.h>
#include <stdio.h>
#include "avrdude.h"
#include "avr.h"
#include "pindefs.h"
#include "pgm.h"
#include "bitbang.h"
extern char *progname;
extern int verbose;
/* cached status lines */
static int dtr, rts, txd;
@@ -49,19 +47,21 @@ static int dtr, rts, txd;
serial port/pin mapping
1 cd <-
2 rxd <-
2 (rxd) <-
3 txd ->
4 dtr ->
5 dsr <-
6 rts ->
7 cts <-
Negative pin # means negated value.
5 GND
6 dsr <-
7 rts ->
8 cts <-
9 ri <-
*/
void serbb_setpin(int fd, int pin, int value)
#define DB9PINS 9
static int serbb_setpin(PROGRAMMER * pgm, int pin, int value)
{
HANDLE hComPort = (HANDLE)fd;
HANDLE hComPort = (HANDLE)pgm->fd.pfd;
LPVOID lpMsgBuf;
DWORD dwFunc;
const char *name;
@@ -72,26 +72,24 @@ void serbb_setpin(int fd, int pin, int value)
pin &= PIN_MASK;
}
if (pin < 1 || pin > 7)
return;
pin--;
if (pin < 1 || pin > DB9PINS)
return -1;
switch (pin)
{
case 2: /* txd */
case 3: /* txd */
dwFunc = value? SETBREAK: CLRBREAK;
name = value? "SETBREAK": "CLRBREAK";
txd = value;
break;
case 3: /* dtr */
case 4: /* dtr */
dwFunc = value? SETDTR: CLRDTR;
name = value? "SETDTR": "CLRDTR";
dtr = value;
break;
case 5: /* rts */
case 7: /* rts */
dwFunc = value? SETRTS: CLRRTS;
name = value? "SETRTS": "CLRRTS";
break;
@@ -101,7 +99,7 @@ void serbb_setpin(int fd, int pin, int value)
fprintf(stderr,
"%s: serbb_setpin(): unknown pin %d\n",
progname, pin + 1);
return;
return -1;
}
if (verbose > 4)
fprintf(stderr,
@@ -126,12 +124,12 @@ void serbb_setpin(int fd, int pin, int value)
LocalFree(lpMsgBuf);
exit(1);
}
return;
return 0;
}
int serbb_getpin(int fd, int pin)
static int serbb_getpin(PROGRAMMER * pgm, int pin)
{
HANDLE hComPort = (HANDLE)fd;
HANDLE hComPort = (HANDLE)pgm->fd.pfd;
LPVOID lpMsgBuf;
int invert, rv;
const char *name;
@@ -144,12 +142,10 @@ int serbb_getpin(int fd, int pin)
} else
invert = 0;
if (pin < 1 || pin > 7)
if (pin < 1 || pin > DB9PINS)
return -1;
pin --;
if (pin == 0 /* cd */ || pin == 4 /* dsr */ || pin == 6 /* cts */)
if (pin == 1 /* cd */ || pin == 6 /* dsr */ || pin == 8 /* cts */)
{
if (!GetCommModemStatus(hComPort, &modemstate))
{
@@ -176,13 +172,13 @@ int serbb_getpin(int fd, int pin)
progname, modemstate);
switch (pin)
{
case 0:
case 1:
modemstate &= MS_RLSD_ON;
break;
case 4:
case 6:
modemstate &= MS_DSR_ON;
break;
case 6:
case 8:
modemstate &= MS_CTS_ON;
break;
}
@@ -195,15 +191,15 @@ int serbb_getpin(int fd, int pin)
switch (pin)
{
case 2: /* txd */
case 3: /* txd */
rv = txd;
name = "TXD";
break;
case 3: /* dtr */
case 4: /* dtr */
rv = dtr;
name = "DTR";
break;
case 5: /* rts */
case 7: /* rts */
rv = rts;
name = "RTS";
break;
@@ -224,56 +220,56 @@ int serbb_getpin(int fd, int pin)
return rv;
}
int serbb_highpulsepin(int fd, int pin)
static int serbb_highpulsepin(PROGRAMMER * pgm, int pin)
{
if (pin < 1 || pin > 7)
return -1;
serbb_setpin(fd, pin, 1);
#if SLOW_TOGGLE
usleep(1000);
#endif
serbb_setpin(fd, pin, 0);
serbb_setpin(pgm, pin, 1);
if (pgm->ispdelay > 1)
bitbang_delay(pgm->ispdelay);
#if SLOW_TOGGLE
usleep(1000);
#endif
serbb_setpin(pgm, pin, 0);
if (pgm->ispdelay > 1)
bitbang_delay(pgm->ispdelay);
return 0;
}
void serbb_display(PROGRAMMER *pgm, char *p)
static void serbb_display(PROGRAMMER *pgm, const char *p)
{
/* MAYBE */
}
void serbb_enable(PROGRAMMER *pgm)
static void serbb_enable(PROGRAMMER *pgm)
{
/* nothing */
}
void serbb_disable(PROGRAMMER *pgm)
static void serbb_disable(PROGRAMMER *pgm)
{
/* nothing */
}
void serbb_powerup(PROGRAMMER *pgm)
static void serbb_powerup(PROGRAMMER *pgm)
{
/* nothing */
}
void serbb_powerdown(PROGRAMMER *pgm)
static void serbb_powerdown(PROGRAMMER *pgm)
{
/* nothing */
}
int serbb_open(PROGRAMMER *pgm, char *port)
static int serbb_open(PROGRAMMER *pgm, char *port)
{
DCB dcb;
LPVOID lpMsgBuf;
HANDLE hComPort = INVALID_HANDLE_VALUE;
bitbang_check_prerequisites(pgm);
hComPort = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
@@ -325,18 +321,21 @@ int serbb_open(PROGRAMMER *pgm, char *port)
"%s: ser_open(): opened comm port \"%s\", handle 0x%x\n",
progname, port, (int)hComPort);
pgm->fd = (int)hComPort;
pgm->fd.pfd = (void *)hComPort;
dtr = rts = txd = 0;
return 0;
}
void serbb_close(PROGRAMMER *pgm)
static void serbb_close(PROGRAMMER *pgm)
{
HANDLE hComPort=(HANDLE)pgm->fd;
HANDLE hComPort=(HANDLE)pgm->fd.pfd;
if (hComPort != INVALID_HANDLE_VALUE)
{
pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1);
CloseHandle (hComPort);
}
if (verbose > 2)
fprintf(stderr,
"%s: ser_close(): closed comm port handle 0x%x\n",
@@ -364,9 +363,11 @@ void serbb_initpgm(PROGRAMMER *pgm)
pgm->cmd = bitbang_cmd;
pgm->open = serbb_open;
pgm->close = serbb_close;
/* this is a serial port bitbang device */
pgm->flag = 1;
pgm->setpin = serbb_setpin;
pgm->getpin = serbb_getpin;
pgm->highpulsepin = serbb_highpulsepin;
pgm->read_byte = avr_read_byte_default;
pgm->write_byte = avr_write_byte_default;
}
#endif /* WIN32NATIVE */

View File

@@ -27,24 +27,36 @@
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 serial_device
{
int (*open)(char * port, long baud);
int (*setspeed)(int fd, long baud);
void (*close)(int fd);
void (*open)(char * port, long baud, union filedescriptor *fd);
int (*setspeed)(union filedescriptor *fd, long baud);
void (*close)(union filedescriptor *fd);
int (*send)(int fd, unsigned char * buf, size_t buflen);
int (*recv)(int fd, unsigned char * buf, size_t buflen);
int (*drain)(int fd, int display);
int (*send)(union filedescriptor *fd, unsigned char * buf, size_t buflen);
int (*recv)(union filedescriptor *fd, unsigned char * buf, size_t buflen);
int (*drain)(union filedescriptor *fd, int display);
int flags;
#define SERDEV_FL_NONE 0x0000 /* no flags */
#define SERDEV_FL_CANSETSPEED 0x0001 /* device can change speed */
};
extern struct serial_device *serdev;
extern struct serial_device serial_serdev, usb_serdev;
extern struct serial_device serial_serdev;
extern struct serial_device usb_serdev;
extern struct serial_device usb_serdev_frame;
extern struct serial_device avrdoper_serdev;
#define serial_open (serdev->open)
#define serial_setspeed (serdev->setspeed)
@@ -53,4 +65,4 @@ extern struct serial_device serial_serdev, usb_serdev;
#define serial_recv (serdev->recv)
#define serial_drain (serdev->drain)
#endif /* __serial_h__ */
#endif /* serial_h */

51
avrdude/solaris_ecpp.h Normal file
View File

@@ -0,0 +1,51 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2005 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 solaris_ecpp_h
#define solaris_ecpp_h
#include <sys/ecppio.h>
#define ppi_claim(fd) \
do { \
struct ecpp_transfer_parms p; \
(void)ioctl(fd, ECPPIOC_GETPARMS, &p); \
p.mode = ECPP_DIAG_MODE; \
(void)ioctl(fd, ECPPIOC_SETPARMS, &p); \
} while(0);
#define ppi_release(fd)
#define DO_PPI_READ(fd, reg, valp) \
do { struct ecpp_regs r; \
if ((reg) == PPIDATA) { (void)ioctl(fd, ECPPIOC_GETDATA, valp); } \
else { (void)ioctl(fd, ECPPIOC_GETREGS, &r); \
*(valp) = ((reg) == PPICTRL)? r.dcr: r.dsr; } \
} while(0)
#define DO_PPI_WRITE(fd, reg, valp) \
do { struct ecpp_regs r; \
if ((reg) == PPIDATA) { (void)ioctl(fd, ECPPIOC_SETDATA, valp); } \
else { if ((reg) == PPICTRL) r.dcr = *(valp); else r.dsr = *(valp); \
(void)ioctl(fd, ECPPIOC_SETREGS, &r); } \
} while(0)
#endif /* solaris_ecpp_h */

View File

@@ -36,6 +36,7 @@
#include <errno.h>
#include <unistd.h>
#include "avrdude.h"
#include "avr.h"
#include "pgm.h"
#include "stk500_private.h"
@@ -43,21 +44,16 @@
#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);
static int stk500_send(PROGRAMMER * pgm, unsigned char * buf, size_t len)
{
return serial_send(pgm->fd, buf, len);
return serial_send(&pgm->fd, buf, len);
}
@@ -65,12 +61,12 @@ static int stk500_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
{
int rv;
rv = serial_recv(pgm->fd, buf, len);
rv = serial_recv(&pgm->fd, buf, len);
if (rv < 0) {
fprintf(stderr,
"%s: stk500_recv(): programmer is not responding\n",
progname);
exit(1);
return -1;
}
return 0;
}
@@ -78,7 +74,7 @@ static int stk500_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
static int stk500_drain(PROGRAMMER * pgm, int display)
{
return serial_drain(pgm->fd, display);
return serial_drain(&pgm->fd, display);
}
@@ -90,23 +86,35 @@ static int stk500_getsync(PROGRAMMER * pgm)
* get in sync */
buf[0] = Cmnd_STK_GET_SYNC;
buf[1] = Sync_CRC_EOP;
/*
* First send and drain a few times to get rid of line noise
*/
stk500_send(pgm, buf, 2);
stk500_recv(pgm, resp, 1);
stk500_drain(pgm, 0);
stk500_send(pgm, buf, 2);
stk500_drain(pgm, 0);
stk500_send(pgm, buf, 2);
if (stk500_recv(pgm, resp, 1) < 0)
return -1;
if (resp[0] != Resp_STK_INSYNC) {
fprintf(stderr,
"%s: stk500_getsync(): not in sync: resp=0x%02x\n",
progname, resp[0]);
stk500_drain(pgm, 0);
exit(1);
return -1;
}
stk500_recv(pgm, resp, 1);
if (stk500_recv(pgm, resp, 1) < 0)
return -1;
if (resp[0] != Resp_STK_OK) {
fprintf(stderr,
"%s: stk500_getsync(): can't communicate with device: "
"resp=0x%02x\n",
progname, resp[0]);
exit(1);
return -1;
}
return 0;
@@ -131,7 +139,8 @@ static int stk500_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
stk500_send(pgm, buf, 6);
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] != Resp_STK_INSYNC) {
fprintf(stderr, "%s: stk500_cmd(): programmer is out of sync\n", progname);
exit(1);
@@ -140,9 +149,11 @@ static int stk500_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
res[0] = cmd[1];
res[1] = cmd[2];
res[2] = cmd[3];
stk500_recv(pgm, &res[3], 1);
if (stk500_recv(pgm, &res[3], 1) < 0)
exit(1);
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] != Resp_STK_OK) {
fprintf(stderr, "%s: stk500_cmd(): protocol error\n", progname);
exit(1);
@@ -161,6 +172,14 @@ static int stk500_chip_erase(PROGRAMMER * pgm, AVRPART * p)
unsigned char cmd[4];
unsigned char res[4];
if (pgm->cmd == NULL) {
fprintf(stderr,
"%s: Error: %s programmer uses stk500_chip_erase() but does not\n"
"provide a cmd() method.\n",
progname, pgm->type);
return -1;
}
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
fprintf(stderr, "chip erase instruction not defined for part \"%s\"\n",
p->desc);
@@ -197,14 +216,16 @@ static int stk500_program_enable(PROGRAMMER * pgm, AVRPART * p)
buf[1] = Sync_CRC_EOP;
stk500_send(pgm, buf, 2);
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
fprintf(stderr, "%s: stk500_program_enable(): can't get into sync\n",
progname);
return -1;
}
stk500_getsync(pgm);
if (stk500_getsync(pgm) < 0)
return -1;
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
@@ -215,7 +236,8 @@ static int stk500_program_enable(PROGRAMMER * pgm, AVRPART * p)
return -1;
}
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_OK) {
return 0;
}
@@ -261,14 +283,16 @@ static int stk500_set_extended_parms(PROGRAMMER * pgm, int n,
buf[i] = Sync_CRC_EOP;
stk500_send(pgm, buf, i+1);
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
fprintf(stderr, "%s: stk500_set_extended_parms(): can't get into sync\n",
progname);
return -1;
}
stk500_getsync(pgm);
if (stk500_getsync(pgm) < 0)
return -1;
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
@@ -279,7 +303,8 @@ static int stk500_set_extended_parms(PROGRAMMER * pgm, int n,
return -1;
}
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_OK) {
return 0;
}
@@ -426,14 +451,16 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
buf[21] = Sync_CRC_EOP;
stk500_send(pgm, buf, 22);
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_NOSYNC) {
fprintf(stderr,
"%s: stk500_initialize(): programmer not in sync, resp=0x%02x\n",
progname, buf[0]);
if (tries > 33)
return -1;
stk500_getsync(pgm);
if (stk500_getsync(pgm) < 0)
return -1;
goto retry;
return -1;
}
@@ -445,7 +472,8 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
return -1;
}
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] != Resp_STK_OK) {
fprintf(stderr,
"%s: stk500_initialize(): (b) protocol error, "
@@ -507,14 +535,16 @@ static void stk500_disable(PROGRAMMER * pgm)
buf[1] = Sync_CRC_EOP;
stk500_send(pgm, buf, 2);
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
fprintf(stderr, "%s: stk500_disable(): can't get into sync\n",
progname);
return;
}
stk500_getsync(pgm);
if (stk500_getsync(pgm) < 0)
return;
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
@@ -525,7 +555,8 @@ static void stk500_disable(PROGRAMMER * pgm)
return;
}
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_OK) {
return;
}
@@ -550,19 +581,15 @@ static void stk500_enable(PROGRAMMER * pgm)
static int stk500_open(PROGRAMMER * pgm, char * port)
{
strcpy(pgm->port, port);
if (pgm->baudrate)
pgm->fd = serial_open(port, pgm->baudrate);
else
pgm->fd = serial_open(port, 115200);
serial_open(port, pgm->baudrate? pgm->baudrate: 115200, &pgm->fd);
/*
* drain any extraneous input
*/
stk500_drain(pgm, 0);
stk500_getsync(pgm);
stk500_drain(pgm, 0);
if (stk500_getsync(pgm) < 0)
return -1;
return 0;
}
@@ -570,8 +597,8 @@ static int stk500_open(PROGRAMMER * pgm, char * port)
static void stk500_close(PROGRAMMER * pgm)
{
serial_close(pgm->fd);
pgm->fd = -1;
serial_close(&pgm->fd);
pgm->fd.ifd = -1;
}
@@ -590,14 +617,16 @@ static int stk500_loadaddr(PROGRAMMER * pgm, unsigned int addr)
stk500_send(pgm, buf, 4);
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
fprintf(stderr, "%s: stk500_loadaddr(): can't get into sync\n",
progname);
return -1;
}
stk500_getsync(pgm);
if (stk500_getsync(pgm) < 0)
return -1;
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
@@ -608,7 +637,8 @@ static int stk500_loadaddr(PROGRAMMER * pgm, unsigned int addr)
return -1;
}
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_OK) {
return 0;
}
@@ -625,13 +655,14 @@ static int stk500_loadaddr(PROGRAMMER * pgm, unsigned int addr)
static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes)
{
unsigned char buf[16];
unsigned char buf[page_size + 16];
int memtype;
unsigned int addr;
int a_div;
int block_size;
int tries;
unsigned int n;
unsigned int i;
int flash;
if (page_size == 0) {
@@ -697,25 +728,29 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
retry:
tries++;
stk500_loadaddr(pgm, addr/a_div);
buf[0] = Cmnd_STK_PROG_PAGE;
buf[1] = (block_size >> 8) & 0xff;
buf[2] = block_size & 0xff;
buf[3] = memtype;
stk500_send(pgm, buf, 4);
stk500_send(pgm, &m->buf[addr], block_size);
/* build command block and avoid multiple send commands as it leads to a crash
of the silabs usb serial driver on mac os x */
i = 0;
buf[i++] = Cmnd_STK_PROG_PAGE;
buf[i++] = (block_size >> 8) & 0xff;
buf[i++] = block_size & 0xff;
buf[i++] = memtype;
memcpy(&buf[i], &m->buf[addr], block_size);
i += block_size;
buf[i++] = Sync_CRC_EOP;
stk500_send( pgm, buf, i);
buf[0] = Sync_CRC_EOP;
stk500_send(pgm, buf, 1);
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
fprintf(stderr, "\n%s: stk500_paged_write(): can't get into sync\n",
progname);
return -3;
}
stk500_getsync(pgm);
if (stk500_getsync(pgm) < 0)
return -1;
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
@@ -726,7 +761,8 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
return -4;
}
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] != Resp_STK_OK) {
fprintf(stderr,
"\n%s: stk500_paged_write(): (a) protocol error, "
@@ -814,14 +850,16 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
buf[4] = Sync_CRC_EOP;
stk500_send(pgm, buf, 5);
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
fprintf(stderr, "\n%s: stk500_paged_load(): can't get into sync\n",
progname);
return -3;
}
stk500_getsync(pgm);
if (stk500_getsync(pgm) < 0)
return -1;
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
@@ -832,9 +870,11 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
return -4;
}
stk500_recv(pgm, &m->buf[addr], block_size);
if (stk500_recv(pgm, &m->buf[addr], block_size) < 0)
exit(1);
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] != Resp_STK_OK) {
fprintf(stderr,
"\n%s: stk500_paged_load(): (a) protocol error, "
@@ -993,14 +1033,16 @@ static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
stk500_send(pgm, buf, 3);
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
fprintf(stderr, "\n%s: stk500_getparm(): can't get into sync\n",
progname);
return -1;
}
stk500_getsync(pgm);
if (stk500_getsync(pgm) < 0)
return -1;
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
@@ -1011,10 +1053,12 @@ static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
return -2;
}
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
v = buf[0];
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_FAILED) {
fprintf(stderr,
"\n%s: stk500_getparm(): parameter 0x%02x failed\n",
@@ -1049,14 +1093,16 @@ static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value)
stk500_send(pgm, buf, 4);
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
fprintf(stderr, "\n%s: stk500_setparm(): can't get into sync\n",
progname);
return -1;
}
stk500_getsync(pgm);
if (stk500_getsync(pgm) < 0)
return -1;
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
@@ -1067,12 +1113,14 @@ static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value)
return -2;
}
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_OK)
return 0;
parm = buf[0]; /* if not STK_OK, we've been echoed parm here */
stk500_recv(pgm, buf, 1);
if (stk500_recv(pgm, buf, 1) < 0)
exit(1);
if (buf[0] == Resp_STK_FAILED) {
fprintf(stderr,
"\n%s: stk500_setparm(): parameter 0x%02x failed\n",
@@ -1089,7 +1137,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;
@@ -1120,7 +1168,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;
@@ -1189,6 +1237,8 @@ void stk500_initpgm(PROGRAMMER * pgm)
pgm->cmd = stk500_cmd;
pgm->open = stk500_open;
pgm->close = stk500_close;
pgm->read_byte = avr_read_byte_default;
pgm->write_byte = avr_write_byte_default;
/*
* optional functions

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

73
avrdude/stk500generic.c Normal file
View File

@@ -0,0 +1,73 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2006 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* $Id$ */
/*
* avrdude interface for Atmel STK500 programmer
*
* This is a wrapper around the STK500[v1] and STK500v2 programmers.
* Try to select the programmer type that actually responds, and
* divert to the actual programmer implementation if successful.
*/
#include "ac_cfg.h"
#include <stdio.h>
#include <string.h>
#include "avrdude.h"
#include "pgm.h"
#include "stk500.h"
#include "stk500v2.h"
static int stk500generic_open(PROGRAMMER * pgm, char * port)
{
stk500_initpgm(pgm);
if (pgm->open(pgm, port) >= 0)
{
fprintf(stderr,
"%s: successfully opened stk500v1 device -- please use -c stk500v1\n",
progname);
return 0;
}
pgm->close(pgm);
stk500v2_initpgm(pgm);
if (pgm->open(pgm, port) >= 0)
{
fprintf(stderr,
"%s: successfully opened stk500v2 device -- please use -c stk500v2\n",
progname);
return 0;
}
fprintf(stderr,
"%s: cannot open either stk500v1 or stk500v2 programmer\n",
progname);
return -1;
}
void stk500generic_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "STK500GENERIC");
pgm->open = stk500generic_open;
}

29
avrdude/stk500generic.h Normal file
View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2002-2005 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2006 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,10 +20,24 @@
/* $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);
void stk500pp_initpgm (PROGRAMMER * pgm);
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);
#ifdef __cplusplus
}
#endif
#endif

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,31 +49,44 @@ 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[]);
struct command cmd[] = {
@@ -105,7 +113,7 @@ struct command cmd[] = {
int nexttok(char * buf, char ** tok, char ** next)
static int nexttok(char * buf, char ** tok, char ** next)
{
char * q, * n;
@@ -134,7 +142,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 +174,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 +197,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 +224,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;
@@ -292,7 +301,7 @@ int cmd_dump(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
}
for (i=0; i<len; i++) {
rc = avr_read_byte(pgm, p, mem, addr+i, &buf[i]);
rc = pgm->read_byte(pgm, p, mem, addr+i, &buf[i]);
if (rc != 0) {
fprintf(stderr, "error reading %s address 0x%05lx of part %s\n",
mem->desc, addr+i, p->desc);
@@ -315,7 +324,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;
@@ -399,7 +409,7 @@ int cmd_write(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
werror = 1;
}
rc = avr_read_byte(pgm, p, mem, addr+i, &b);
rc = pgm->read_byte(pgm, p, mem, addr+i, &b);
if (b != buf[i]) {
fprintf(stderr,
"%s (write): error writing 0x%02x at 0x%05lx cell=0x%02x\n",
@@ -420,13 +430,21 @@ 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;
int i;
int len;
if (pgm->cmd == NULL) {
fprintf(stderr,
"The %s programmer does not support direct ISP commands.\n",
pgm->type);
return -1;
}
if (argc != 5) {
fprintf(stderr, "Usage: send <byte1> <byte2> <byte3> <byte4>\n");
return -1;
@@ -463,7 +481,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);
@@ -471,7 +490,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);
@@ -481,7 +501,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;
@@ -510,13 +531,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,
@@ -531,7 +554,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;
@@ -561,7 +585,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;
@@ -600,7 +625,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;
@@ -632,7 +658,8 @@ 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;
double v;
@@ -662,7 +689,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;
@@ -680,7 +708,7 @@ int cmd_help(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
}
int tokenize(char * s, char *** argv)
static int tokenize(char * s, char *** argv)
{
int i, n, l, nargs, offset;
int len, slen;
@@ -757,7 +785,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,155 @@
<?xml version="1.0" encoding='ISO-8859-1' ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--
* Copyright (c) 2006 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 the debugWire parameters
* from the XML, and format it the way src/devdescr.cc needs it.
*
* Run this file together with the respective AVR's XML file through
* an XSLT processor (xsltproc, saxon), and capture the output for
* inclusion into avrdude.conf.in.
-->
<xsl:output method="text"/>
<xsl:template match="/">
<!-- Extract everything we need out of the XML. -->
<xsl:variable name="devname_orig"
select="/AVRPART/ADMIN/PART_NAME" />
<xsl:variable name="devname"
select="translate(/AVRPART/ADMIN/PART_NAME,
'abcdefghijklmnopqrstuvwxyz',
'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" />
<xsl:variable name="devname_lower"
select="translate(/AVRPART/ADMIN/PART_NAME,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')" />
<xsl:variable name="ucEepromInst"
select="//AVRPART/ICE_SETTINGS/JTAGICEmkII/ucEepromInst" />
<xsl:variable name="ucFlashInst"
select="//AVRPART/ICE_SETTINGS/JTAGICEmkII/ucFlashInst" />
<!-- If there's a JTAGICEmkII node indicating debugWire, emit the entry. -->
<xsl:if test='//AVRPART/ICE_SETTINGS/JTAGICEmkII/Interface="DebugWire"'>
<!-- start of new entry -->
<xsl:text>#------------------------------------------------------------&#010;</xsl:text>
<xsl:text># </xsl:text>
<xsl:value-of select="$devname_orig" />
<xsl:text>&#010;</xsl:text>
<xsl:text>#------------------------------------------------------------&#010;</xsl:text>
<xsl:text>part&#010; desc = &quot;</xsl:text>
<xsl:value-of select="$devname_orig" />
<xsl:text>&quot;;&#010; has_debugwire = yes;&#010;</xsl:text>
<xsl:text> flash_instr = </xsl:text>
<xsl:call-template name="format-hex">
<xsl:with-param name="arg" select="$ucFlashInst" />
<xsl:with-param name="count" select="0" />
</xsl:call-template>
<xsl:text>;&#010;</xsl:text>
<xsl:text> eeprom_instr = </xsl:text>
<xsl:call-template name="format-hex">
<xsl:with-param name="arg" select="$ucEepromInst" />
<xsl:with-param name="count" select="0" />
</xsl:call-template>
<xsl:text>;&#010;</xsl:text>
</xsl:if> <!-- JTAGICEmkII uses debugWire -->
</xsl:template>
<xsl:template name="toupper">
</xsl:template>
<!-- return argument $arg if non-empty, 0 otherwise -->
<xsl:template name="maybezero">
<xsl:param name="arg" />
<xsl:choose>
<xsl:when test="string-length($arg) = 0"><xsl:text>0</xsl:text></xsl:when>
<xsl:otherwise><xsl:value-of select="$arg" /></xsl:otherwise>
</xsl:choose>
</xsl:template> <!-- maybezero -->
<!-- convert $XX hex number in $arg (if any) into 0xXX; -->
<!-- return 0 if $arg is empty -->
<xsl:template name="dollar-to-0x">
<xsl:param name="arg" />
<xsl:choose>
<xsl:when test="string-length($arg) = 0">
<xsl:text>0</xsl:text>
</xsl:when>
<xsl:when test="substring($arg, 1, 1) = '&#036;'">
<xsl:text>0x</xsl:text>
<xsl:value-of select="substring($arg, 2)" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$arg" />
</xsl:otherwise>
</xsl:choose>
</xsl:template> <!-- dollar-to-0x -->
<!-- Format a string of 0xXX numbers: start a new line -->
<!-- after each 8 hex numbers -->
<!-- call with parameter $count = 0, calls itself -->
<!-- recursively then until everything has been done -->
<xsl:template name="format-hex">
<xsl:param name="arg" />
<xsl:choose>
<xsl:when test="string-length($arg) &lt;= 4">
<!-- Last element, print it, and leave template. -->
<xsl:value-of select="$arg" />
</xsl:when>
<xsl:otherwise>
<!--
* More arguments follow, print first value,
* followed by a comma, decide whether a space
* or a newline needs to be emitted, and recurse
* with the remaining part of $arg.
-->
<xsl:value-of select="substring($arg, 1, 4)" />
<xsl:choose>
<xsl:when test="$count mod 8 = 7">
<xsl:text>,&#010;&#009; </xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>, </xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:variable name="newarg">
<!-- see whether there is a space after comma -->
<xsl:choose>
<xsl:when test="substring($arg, 6, 1) = ' '">
<xsl:value-of select="substring($arg, 7)" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring($arg, 6)" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="format-hex">
<xsl:with-param name="arg" select="$newarg" />
<xsl:with-param name="count" select="$count + 1" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,254 @@
<?xml version="1.0" encoding='ISO-8859-1' ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--
* Copyright (c) 2006 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 high-voltage (parallel and serial) programming parameters
* out of the Atmel XML files, and convert them into avrdude.conf
* snippets.
*
* Run this file together with the respective AVR's XML file through
* an XSLT processor (xsltproc, saxon), and capture the output for
* inclusion into avrdude.conf.in.
-->
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each select="//*">
<xsl:if test='name() = "STK500_2"'>
<!--
* High-voltage parallel programming parameters.
-->
<xsl:for-each
select="*[starts-with(translate(name(),
'abcdefghijklmnopqrstuvwxyz',
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
'PP')]">
<xsl:if test="self::node()[name() = 'PPControlStack']"
> pp_controlstack =
<xsl:call-template name="format_cstack">
<xsl:with-param name="stack" select="." />
<xsl:with-param name="count" select="0" />
</xsl:call-template>;
</xsl:if> <!-- PPControlStack -->
<xsl:if test="self::node()[name() = 'PpEnterProgMode']">
<xsl:for-each select="*">
<xsl:if test="self::node()[name() = 'stabDelay']"
> hventerstabdelay = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'progModeDelay']"
> progmodedelay = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'latchCycles']"
> latchcycles = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'toggleVtg']"
> togglevtg = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'powerOffDelay']"
> poweroffdelay = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'resetDelayMs']"
> resetdelayms = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'resetDelayUs']"
> resetdelayus = <xsl:value-of select="." />;
</xsl:if>
</xsl:for-each>
</xsl:if> <!-- PpEnterProgMode -->
<xsl:if test="self::node()[name() = 'PpLeaveProgMode']">
<xsl:for-each select="*">
<xsl:if test="self::node()[name() = 'stabDelay']"
> hvleavestabdelay = <xsl:value-of select="." />;
</xsl:if>
</xsl:for-each>
</xsl:if> <!-- PpLeaveProgMode -->
<xsl:if test="self::node()[name() = 'PpChipErase']">
<xsl:for-each select="*">
<xsl:if test="self::node()[name() = 'pulseWidth']"
> chiperasepulsewidth = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'pollTimeout']"
> chiperasepolltimeout = <xsl:value-of select="." />;
</xsl:if>
</xsl:for-each>
</xsl:if> <!-- PpChipErase -->
<xsl:if test="self::node()[name() = 'PpProgramFuse']">
<xsl:for-each select="*">
<xsl:if test="self::node()[name() = 'pulseWidth']"
> programfusepulsewidth = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'pollTimeout']"
> programfusepolltimeout = <xsl:value-of select="." />;
</xsl:if>
</xsl:for-each>
</xsl:if> <!-- PpProgramFuse -->
<xsl:if test="self::node()[name() = 'PpProgramLock']">
<xsl:for-each select="*">
<xsl:if test="self::node()[name() = 'pulseWidth']"
> programlockpulsewidth = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'pollTimeout']"
> programlockpolltimeout = <xsl:value-of select="." />;
</xsl:if>
</xsl:for-each>
</xsl:if> <!-- PpProgramLock -->
</xsl:for-each> <!-- PP parameters -->
<!--
* High-voltage serial programming parameters.
-->
<xsl:for-each
select="*[starts-with(translate(name(),
'abcdefghijklmnopqrstuvwxyz',
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
'HVSP')]">
<xsl:if test="self::node()[name() = 'HvspControlStack']"
> hvsp_controlstack =
<xsl:call-template name="format_cstack">
<xsl:with-param name="stack" select="." />
<xsl:with-param name="count" select="0" />
</xsl:call-template>;
</xsl:if> <!-- HvspControlStack -->
<xsl:if test="self::node()[name() = 'HvspEnterProgMode']">
<xsl:for-each select="*">
<xsl:if test="self::node()[name() = 'stabDelay']"
> hventerstabdelay = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'cmdexeDelay']"
> hvspcmdexedelay = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'synchCycles']"
> synchcycles = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'latchCycles']"
> latchcycles = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'toggleVtg']"
> togglevtg = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'powoffDelay']"
> poweroffdelay = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'resetDelay1']"
> resetdelayms = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'resetDelay2']"
> resetdelayus = <xsl:value-of select="." />;
</xsl:if>
</xsl:for-each>
</xsl:if> <!-- HvspEnterProgMode -->
<xsl:if test="self::node()[name() = 'HvspLeaveProgMode']">
<xsl:for-each select="*">
<xsl:if test="self::node()[name() = 'stabDelay']"
> hvleavestabdelay = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'resetDelay']"
> resetdelay = <xsl:value-of select="." />;
</xsl:if>
</xsl:for-each>
</xsl:if> <!-- HvspLeaveProgMode -->
<xsl:if test="self::node()[name() = 'HvspChipErase']">
<xsl:for-each select="*">
<xsl:if test="self::node()[name() = 'pollTimeout']"
> chiperasepolltimeout = <xsl:value-of select="." />;
</xsl:if>
<xsl:if test="self::node()[name() = 'eraseTime']"
> chiperasetime = <xsl:value-of select="." />;
</xsl:if>
</xsl:for-each>
</xsl:if> <!-- HvspChipErase -->
<xsl:if test="self::node()[name() = 'HvspProgramFuse']">
<xsl:for-each select="*">
<xsl:if test="self::node()[name() = 'pollTimeout']"
> programfusepolltimeout = <xsl:value-of select="." />;
</xsl:if>
</xsl:for-each>
</xsl:if> <!-- HvspProgramFuse -->
<xsl:if test="self::node()[name() = 'HvspProgramLock']">
<xsl:for-each select="*">
<xsl:if test="self::node()[name() = 'pollTimeout']"
> programlockpolltimeout = <xsl:value-of select="." />;
</xsl:if>
</xsl:for-each>
</xsl:if> <!-- HvspProgramLock -->
</xsl:for-each> <!-- HVSP parameters -->
</xsl:if> <!-- STK500_2 parameters -->
</xsl:for-each> <!-- All nodes -->
</xsl:template>
<!--
* Format the control stack argument: replace space-separated
* list by a list separated with commas, followed by either
* a space or a newline, dependend on the current argument
* count.
* This template calls itself recursively, until the entire
* argument $stack has been processed.
-->
<xsl:template name="format_cstack">
<xsl:param name="stack" />
<xsl:choose>
<xsl:when test="string-length($stack) &lt;= 4">
<!-- Last element, print it, and leave template. -->
<xsl:value-of select="$stack" />
</xsl:when>
<xsl:otherwise>
<!--
* More arguments follow, print first value,
* followed by a comma, decide whether a space
* or a newline needs to be emitted, and recurse
* with the remaining part of $stack.
-->
<xsl:value-of select="substring($stack, 1, 4)" />
<xsl:choose>
<xsl:when test="$count mod 8 = 7">
<!-- comma, newline, 8 spaces indentation -->
<xsl:text>,
</xsl:text>
</xsl:when>
<xsl:otherwise>
<!-- comma, space -->
<xsl:text>, </xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="format_cstack">
<xsl:with-param name="stack" select="substring($stack, 6)"
/>
<xsl:with-param name="count" select="$count + 1" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</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

@@ -1,6 +1,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2005 Joerg Wunsch
* Copyright (C) 2005,2006 Joerg Wunsch
* Copyright (C) 2006 David Moore
*
* 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
@@ -37,26 +38,23 @@
#include <usb.h>
#include "avrdude.h"
#include "serial.h"
#include "usbdevs.h"
extern char *progname;
extern int verbose;
#define USB_VENDOR_ATMEL 1003
#define USB_DEVICE_JTAGICEMKII 0x2103
/*
* Should we query the endpoint number and max transfer size from USB?
* After all, the JTAG ICE mkII docs document these values.
*/
#define JTAGICE_BULK_EP 2
#define JTAGICE_MAX_XFER 64
static char usbbuf[JTAGICE_MAX_XFER];
static char usbbuf[USBDEV_MAX_XFER];
static int buflen = -1, bufptr;
static int usbdev_open(char * port, long baud)
static int usb_interface;
/*
* The "baud" parameter is meaningless for USB devices, so we reuse it
* to pass the desired USB device ID.
*/
static void usbdev_open(char * port, long baud, union filedescriptor *fd)
{
char string[256];
char product[256];
struct usb_bus *bus;
struct usb_device *dev;
usb_dev_handle *udev;
@@ -99,7 +97,7 @@ static int usbdev_open(char * port, long baud)
usb_find_busses();
usb_find_devices();
for (bus = usb_busses; bus; bus = bus->next)
for (bus = usb_get_busses(); bus; bus = bus->next)
{
for (dev = bus->devices; dev; dev = dev->next)
{
@@ -107,7 +105,7 @@ static int usbdev_open(char * port, long baud)
if (udev)
{
if (dev->descriptor.idVendor == USB_VENDOR_ATMEL &&
dev->descriptor.idProduct == USB_DEVICE_JTAGICEMKII)
dev->descriptor.idProduct == (unsigned short)baud)
{
/* yeah, we found something */
if (usb_get_string_simple(udev,
@@ -130,10 +128,20 @@ static int usbdev_open(char * port, long baud)
strcpy(string, "[unknown]");
}
if (usb_get_string_simple(udev,
dev->descriptor.iProduct,
product, sizeof(product)) < 0)
{
fprintf(stderr,
"%s: usb_open(): cannot read product name \"%s\"\n",
progname, usb_strerror());
strcpy(product, "[unnamed product]");
}
if (verbose)
fprintf(stderr,
"%s: usb_open(): Found JTAG ICE, serno: %s\n",
progname, string);
"%s: usbdev_open(): Found %s, serno: %s\n",
progname, product, string);
if (serno != NULL)
{
/*
@@ -153,8 +161,36 @@ static int usbdev_open(char * port, long baud)
}
}
return (int)udev;
if (dev->config == NULL)
{
fprintf(stderr,
"%s: usbdev_open(): USB device has no configuration\n",
progname);
goto trynext;
}
if (usb_set_configuration(udev, dev->config[0].bConfigurationValue))
{
fprintf(stderr,
"%s: usbdev_open(): error setting configuration %d: %s\n",
progname, dev->config[0].bConfigurationValue,
usb_strerror());
goto trynext;
}
usb_interface = dev->config[0].interface[0].altsetting[0].bInterfaceNumber;
if (usb_claim_interface(udev, usb_interface))
{
fprintf(stderr,
"%s: usbdev_open(): error claiming interface %d: %s\n",
progname, usb_interface, usb_strerror());
goto trynext;
}
fd->pfd = udev;
return;
}
trynext:
usb_close(udev);
}
}
@@ -165,24 +201,70 @@ static int usbdev_open(char * port, long baud)
exit(1);
}
static int usbdev_setspeed(int fd, long baud)
static void usbdev_close(union filedescriptor *fd)
{
return 0;
}
usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
static void usbdev_close(int fd)
{
usb_dev_handle *udev = (usb_dev_handle *)fd;
(void)usb_release_interface(udev, usb_interface);
/*
* Without this reset, the AVRISP mkII seems to stall the second
* time we try to connect to it.
*/
usb_reset(udev);
usb_close(udev);
}
static int usbdev_send(int fd, unsigned char *bp, size_t mlen)
static int usbdev_send(union filedescriptor *fd, unsigned char *bp, size_t mlen)
{
usb_dev_handle *udev = (usb_dev_handle *)fd;
usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
int rv;
int i = mlen;
unsigned char * p = bp;
int tx_size;
return usb_bulk_write(udev, JTAGICE_BULK_EP, (char *)bp, mlen, 5000) != mlen;
/*
* Split the frame into multiple packets. It's important to make
* sure we finish with a short packet, or else the device won't know
* the frame is finished. For example, if we need to send 64 bytes,
* we must send a packet of length 64 followed by a packet of length
* 0.
*/
do {
tx_size = (mlen < USBDEV_MAX_XFER)? mlen: USBDEV_MAX_XFER;
rv = usb_bulk_write(udev, USBDEV_BULK_EP_WRITE, (char *)bp, tx_size, 5000);
if (rv != tx_size)
{
fprintf(stderr, "%s: usbdev_send(): wrote %d out of %d bytes, err = %s\n",
progname, rv, tx_size, usb_strerror());
return -1;
}
bp += tx_size;
mlen -= tx_size;
} while (tx_size == USBDEV_MAX_XFER);
if (verbose > 3)
{
fprintf(stderr, "%s: Sent: ", progname);
while (i) {
unsigned char c = *p;
if (isprint(c)) {
fprintf(stderr, "%c ", c);
}
else {
fprintf(stderr, ". ");
}
fprintf(stderr, "[%02x] ", c);
p++;
i--;
}
fprintf(stderr, "\n");
}
return 0;
}
/*
@@ -198,7 +280,7 @@ usb_fill_buf(usb_dev_handle *udev)
{
int rv;
rv = usb_bulk_read(udev, JTAGICE_BULK_EP, usbbuf, JTAGICE_MAX_XFER, 5000);
rv = usb_bulk_read(udev, USBDEV_BULK_EP_READ, usbbuf, USBDEV_MAX_XFER, 5000);
if (rv < 0)
{
if (verbose > 1)
@@ -213,9 +295,9 @@ usb_fill_buf(usb_dev_handle *udev)
return 0;
}
static int usbdev_recv(int fd, unsigned char *buf, size_t nbytes)
static int usbdev_recv(union filedescriptor *fd, unsigned char *buf, size_t nbytes)
{
usb_dev_handle *udev = (usb_dev_handle *)fd;
usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
int i, amnt;
unsigned char * p = buf;
@@ -256,14 +338,79 @@ static int usbdev_recv(int fd, unsigned char *buf, size_t nbytes)
return 0;
}
static int usbdev_drain(int fd, int display)
/*
* This version of recv keeps reading packets until we receive a short
* packet. Then, the entire frame is assembled and returned to the
* user. The length will be unknown in advance, so we return the
* length as the return value of this function, or -1 in case of an
* error.
*
* This is used for the AVRISP mkII device.
*/
static int usbdev_recv_frame(union filedescriptor *fd, unsigned char *buf, size_t nbytes)
{
usb_dev_handle *udev = (usb_dev_handle *)fd;
usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
int rv, n;
int i;
unsigned char * p = buf;
n = 0;
do
{
rv = usb_bulk_read(udev, USBDEV_BULK_EP_READ, usbbuf,
USBDEV_MAX_XFER, 10000);
if (rv < 0)
{
if (verbose > 1)
fprintf(stderr, "%s: usbdev_recv_frame(): usb_bulk_read(): %s\n",
progname, usb_strerror());
return -1;
}
if (rv <= nbytes)
{
memcpy (buf, usbbuf, rv);
buf += rv;
}
n += rv;
nbytes -= rv;
}
while (rv == USBDEV_MAX_XFER);
if (nbytes < 0)
return -1;
if (verbose > 3)
{
i = n;
fprintf(stderr, "%s: Recv: ", progname);
while (i) {
unsigned char c = *p;
if (isprint(c)) {
fprintf(stderr, "%c ", c);
}
else {
fprintf(stderr, ". ");
}
fprintf(stderr, "[%02x] ", c);
p++;
i--;
}
fprintf(stderr, "\n");
}
return n;
}
static int usbdev_drain(union filedescriptor *fd, int display)
{
usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
int rv;
do {
rv = usb_bulk_read(udev, JTAGICE_BULK_EP, usbbuf, JTAGICE_MAX_XFER, 100);
rv = usb_bulk_read(udev, USBDEV_BULK_EP_READ, usbbuf, USBDEV_MAX_XFER, 100);
if (rv > 0 && verbose >= 4)
fprintf(stderr, "%s: usbdev_drain(): flushed %d characters\n",
progname, rv);
@@ -272,14 +419,30 @@ static int usbdev_drain(int fd, int display)
return 0;
}
/*
* Device descriptor for the JTAG ICE mkII.
*/
struct serial_device usb_serdev =
{
.open = usbdev_open,
.setspeed = usbdev_setspeed,
.close = usbdev_close,
.send = usbdev_send,
.recv = usbdev_recv,
.drain = usbdev_drain,
.flags = SERDEV_FL_NONE,
};
/*
* Device descriptor for the AVRISP mkII.
*/
struct serial_device usb_serdev_frame =
{
.open = usbdev_open,
.close = usbdev_close,
.send = usbdev_send,
.recv = usbdev_recv_frame,
.drain = usbdev_drain,
.flags = SERDEV_FL_NONE,
};
#endif /* HAVE_LIBUSB */

467
avrdude/usbasp.c Normal file
View File

@@ -0,0 +1,467 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2006 Thomas Fischl
*
* 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$ */
/*
* Interface to the USBasp programmer.
*
* See http://www.fischl.de/usbasp/
*/
#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 "usbasp.h"
#ifdef HAVE_LIBUSB
#include <usb.h>
static usb_dev_handle *usbhandle;
/*
* wrapper for usb_control_msg call
*/
static int usbasp_transmit(unsigned char receive, unsigned char functionid,
unsigned char send[4], unsigned char * buffer, int buffersize)
{
int nbytes;
nbytes = usb_control_msg(usbhandle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | (receive << 7),
functionid,
(send[1] << 8) | send[0],
(send[3] << 8) | send[2],
buffer, buffersize,
5000);
if(nbytes < 0){
fprintf(stderr, "%s: error: usbasp_transmit: %s\n", progname, usb_strerror());
exit(1);
}
return nbytes;
}
/*
* Try to open USB device with given VID, PID, vendor and product name
* Parts of this function were taken from an example code by OBJECTIVE
* DEVELOPMENT Software GmbH (www.obdev.at) to meet conditions for
* shared VID/PID
*/
static int usbOpenDevice(usb_dev_handle **device, int vendor,
char *vendorName, int product, char *productName)
{
struct usb_bus *bus;
struct usb_device *dev;
usb_dev_handle *handle = NULL;
int errorCode = USB_ERROR_NOTFOUND;
static int didUsbInit = 0;
if(!didUsbInit){
didUsbInit = 1;
usb_init();
}
usb_find_busses();
usb_find_devices();
for(bus=usb_get_busses(); bus; bus=bus->next){
for(dev=bus->devices; dev; dev=dev->next){
if(dev->descriptor.idVendor == vendor &&
dev->descriptor.idProduct == product){
char string[256];
int len;
/* we need to open the device in order to query strings */
handle = usb_open(dev);
if(!handle){
errorCode = USB_ERROR_ACCESS;
fprintf(stderr,
"%s: Warning: cannot open USB device: %s\n",
progname, usb_strerror());
continue;
}
if(vendorName == NULL && productName == NULL){
/* name does not matter */
break;
}
/* now check whether the names match: */
len = usb_get_string_simple(handle, dev->descriptor.iManufacturer,
string, sizeof(string));
if(len < 0){
errorCode = USB_ERROR_IO;
fprintf(stderr,
"%s: Warning: cannot query manufacturer for device: %s\n",
progname, usb_strerror());
}else{
errorCode = USB_ERROR_NOTFOUND;
if (verbose > 1)
fprintf(stderr,
"%s: seen device from vendor ->%s<-\n",
progname, string);
if(strcmp(string, vendorName) == 0){
len = usb_get_string_simple(handle, dev->descriptor.iProduct,
string, sizeof(string));
if(len < 0){
errorCode = USB_ERROR_IO;
fprintf(stderr,
"%s: Warning: cannot query product for device: %s\n",
progname, usb_strerror());
}else{
errorCode = USB_ERROR_NOTFOUND;
if (verbose > 1)
fprintf(stderr,
"%s: seen product ->%s<-\n",
progname, string);
if(strcmp(string, productName) == 0)
break;
}
}
}
usb_close(handle);
handle = NULL;
}
}
if(handle)
break;
}
if(handle != NULL){
errorCode = 0;
*device = handle;
}
return errorCode;
}
static int usbasp_open(PROGRAMMER * pgm, char * port)
{
usb_init();
if (usbOpenDevice(&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",
USBASP_OLD_PID, "USBasp") != 0) {
/* no USBasp found */
fprintf(stderr,
"%s: error: could not find USB device "
"\"USBasp\" with vid=0x%x pid=0x%x\n",
progname, USBASP_SHARED_VID, USBASP_SHARED_PID);
exit(1);
} else {
/* found USBasp with old IDs */
fprintf(stderr,
"%s: Warning: Found USB device \"USBasp\" with "
"old VID/PID! Please update firmware of USBasp!\n",
progname);
}
}
return 0;
}
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));
usb_close(usbhandle);
}
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));
usleep(100000);
return pgm->program_enable(pgm, p);
}
static void usbasp_disable(PROGRAMMER * pgm)
{
/* Do nothing. */
return;
}
static void usbasp_enable(PROGRAMMER * pgm)
{
/* Do nothing. */
return;
}
static void usbasp_display(PROGRAMMER * pgm, const char * p)
{
return;
}
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));
if(nbytes != 4){
fprintf(stderr, "%s: error: wrong responds size\n",
progname);
return -1;
}
return 0;
}
static int usbasp_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
unsigned char res[4];
unsigned char cmd[4];
memset(cmd, 0, sizeof(cmd));
memset(res, 0, sizeof(res));
cmd[0] = 0;
int nbytes =
usbasp_transmit(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",
progname, res[0]);
return -1;
}
return 0;
}
static int usbasp_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
unsigned char cmd[4];
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;
}
memset(cmd, 0, sizeof(cmd));
avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
pgm->cmd(pgm, cmd, res);
usleep(p->chip_erase_delay);
pgm->initialize(pgm, p);
return 0;
}
static int usbasp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes)
{
int n;
unsigned char cmd[4];
int address = 0;
int wbytes = n_bytes;
int blocksize;
unsigned char * buffer = m->buf;
int function;
if (strcmp(m->desc, "flash") == 0) {
function = USBASP_FUNC_READFLASH;
} else if (strcmp(m->desc, "eeprom") == 0) {
function = USBASP_FUNC_READEEPROM;
} else {
return -2;
}
while (wbytes) {
if (wbytes > USBASP_READBLOCKSIZE) {
blocksize = USBASP_READBLOCKSIZE;
wbytes -= USBASP_READBLOCKSIZE;
} else {
blocksize = wbytes;
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(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);
if (n != blocksize) {
fprintf(stderr, "%s: error: wrong reading bytes %x\n",
progname, n);
exit(1);
}
buffer += blocksize;
address += blocksize;
report_progress (address, n_bytes, NULL);
}
return n_bytes;
}
static int usbasp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes)
{
int n;
unsigned char cmd[4];
int address = 0;
int wbytes = n_bytes;
int blocksize;
unsigned char * buffer = m->buf;
unsigned char blockflags = USBASP_BLOCKFLAG_FIRST;
int function;
if (strcmp(m->desc, "flash") == 0) {
function = USBASP_FUNC_WRITEFLASH;
} else if (strcmp(m->desc, "eeprom") == 0) {
function = USBASP_FUNC_WRITEEEPROM;
} else {
return -2;
}
while (wbytes) {
if (wbytes > USBASP_WRITEBLOCKSIZE) {
blocksize = USBASP_WRITEBLOCKSIZE;
wbytes -= USBASP_WRITEBLOCKSIZE;
} else {
blocksize = wbytes;
wbytes = 0;
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(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);
if (n != blocksize) {
fprintf(stderr, "%s: error: wrong count at writing %x\n",
progname, n);
exit(1);
}
buffer += blocksize;
address += blocksize;
report_progress (address, n_bytes, NULL);
}
return n_bytes;
}
void usbasp_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "usbasp");
/*
* mandatory functions
*/
pgm->initialize = usbasp_initialize;
pgm->display = usbasp_display;
pgm->enable = usbasp_enable;
pgm->disable = usbasp_disable;
pgm->program_enable = usbasp_program_enable;
pgm->chip_erase = usbasp_chip_erase;
pgm->cmd = usbasp_cmd;
pgm->open = usbasp_open;
pgm->close = usbasp_close;
pgm->read_byte = avr_read_byte_default;
pgm->write_byte = avr_write_byte_default;
/*
* optional functions
*/
pgm->paged_write = usbasp_paged_write;
pgm->paged_load = usbasp_paged_load;
}
#else /* HAVE_LIBUSB */
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",
progname);
exit(1);
}
void usbasp_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "usbasp");
pgm->open = usbasp_nousb_open;
}
#endif /* HAVE_LIBUSB */

64
avrdude/usbasp.h Normal file
View File

@@ -0,0 +1,64 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2006 Thomas Fischl
*
* 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 usbasp_h
#define usbasp_h
#include "avrpart.h"
#define USBASP_SHARED_VID 0x16C0 /* VOTI */
#define USBASP_SHARED_PID 0x05DC /* Obdev's free shared PID */
#define USBASP_OLD_VID 0x03EB /* ATMEL */
#define USBASP_OLD_PID 0xC7B4 /* (unoffical) USBasp */
#define USBASP_FUNC_CONNECT 1
#define USBASP_FUNC_DISCONNECT 2
#define USBASP_FUNC_TRANSMIT 3
#define USBASP_FUNC_READFLASH 4
#define USBASP_FUNC_ENABLEPROG 5
#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
#define USBASP_READBLOCKSIZE 200
#define USBASP_WRITEBLOCKSIZE 200
#define USB_ERROR_NOTFOUND 1
#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 */

42
avrdude/usbdevs.h Normal file
View File

@@ -0,0 +1,42 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2006 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$ */
/*
* defines for the USB interface
*/
#ifndef usbdevs_h
#define usbdevs_h
#define USB_VENDOR_ATMEL 1003
#define USB_DEVICE_JTAGICEMKII 0x2103
#define USB_DEVICE_AVRISPMKII 0x2104
#define USB_DEVICE_AVRDRAGON 0x2107
/*
* Should we query the endpoint number and max transfer size from USB?
* After all, the JTAG ICE mkII docs document these values.
*/
#define USBDEV_BULK_EP_WRITE 0x02
#define USBDEV_BULK_EP_READ 0x82
#define USBDEV_MAX_XFER 64
#endif /* usbdevs_h */

484
avrdude/usbtiny.c Normal file
View File

@@ -0,0 +1,484 @@
/*
* 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>
typedef unsigned int uint_t;
typedef unsigned long ulong_t;
extern int avr_write_byte_default ( PROGRAMMER* pgm, AVRPART* p,
AVRMEM* mem, ulong_t addr,
unsigned char data );
static usb_dev_handle* usb_handle;
static int sck_period;
static int chunk_size;
// ----------------------------------------------------------------------
// Wrapper for simple usb_control_msg messages
static int usb_control (unsigned int requestid, unsigned int val, unsigned int index )
{
int nbytes;
nbytes = usb_control_msg( 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, "%s: error: usbtiny_transmit: %s\n", progname, usb_strerror());
exit(1);
}
return nbytes;
}
// Wrapper for simple usb_control_msg messages to receive data from programmer
static int usb_in (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( usb_handle,
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
requestid,
val, index,
(char *)buffer, buflen,
timeout);
if (nbytes != buflen) {
fprintf(stderr, "%s: error: usbtiny_receive: %s (expected %d, got %d)\n",
progname, usb_strerror(), buflen, nbytes);
exit(1);
}
return nbytes;
}
// Wrapper for simple usb_control_msg messages to send data to programmer
static int usb_out (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( usb_handle,
USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
requestid,
val, index,
(char *)buffer, buflen,
timeout);
if (nbytes != buflen) {
fprintf(stderr, "%s: error: usbtiny_send: %s (expected %d, got %d)\n",
progname, usb_strerror(), buflen, nbytes);
exit(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
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?
usb_handle = usb_open(dev); // attempt to connect to device
// wrong permissions or something?
if (!usb_handle) {
fprintf(stderr, "%s: Warning: cannot open USB device: %s\n",
progname, usb_strerror());
continue;
}
}
}
}
if (!usb_handle) {
fprintf( stderr, "%s: Error: Could not find USBtiny device (0x%x/0x%x)\n",
progname, USBTINY_VENDOR, USBTINY_PRODUCT );
exit(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 (! usb_handle) {
return; // not a valid handle, bail!
}
usb_close(usb_handle); // ask libusb to clean up
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 (int period)
{
chunk_size = CHUNK_SIZE; // start with the maximum (default)
while (chunk_size > 8 && period > 16) {
// Reduce the chunk size for a slow SCK to reduce
// the maximum time of a single USB transfer.
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)
{
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 (sck_period < SCK_MIN)
sck_period = SCK_MIN;
// We can't go slower, due to the byte-size of the clock variable
if (sck_period > SCK_MAX)
sck_period = SCK_MAX;
printf( "%s: Setting SCK period to %d usec\n", progname, sck_period );
// send the command to the usbtiny device.
usb_control(USBTINY_POWERUP, sck_period, RESET_LOW); // MEME: for at90's fix resetstate?
// with the new speed, we'll have to update how much data we send per usb transfer
usbtiny_set_chunk_size(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
sck_period = SCK_DEFAULT;
if (verbose) {
printf( "%s: Using SCK period of %d usec\n",
progname, sck_period );
}
usb_control( USBTINY_POWERUP, sck_period, RESET_LOW );
usbtiny_set_chunk_size(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
usb_control(USBTINY_POWERUP, sck_period, RESET_HIGH);
usb_control(USBTINY_POWERUP, sck_period, RESET_LOW);
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 (!usb_handle) {
return; // wasn't connected in the first place
}
usb_control(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', sizeof(res) );
nbytes = usb_in( USBTINY_SPI,
(cmd[1] << 8) | cmd[0], // convert to 16-bit words
(cmd[3] << 8) | cmd[2], // "
res, sizeof(res), 8 * sck_period );
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 == sizeof(res)) && // 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 = 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
usb_in(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 * sck_period); // each byte gets turned into a 4-byte SPI cmd
// usb_in() multiplies this per byte.
// Tell avrdude how we're doing to provide user feedback
report_progress(i + chunk, n_bytes, NULL );
}
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];
usb_control( USBTINY_POLL_BYTES, i, 0 );
delay = m->max_write_delay;
}
for (i=0; i < n_bytes; i=next) {
// start with the max chunk size
chunk = 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;
usb_out(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 * sck_period + delay // each byte gets turned into a
// 4-byte SPI cmd usb_in() multiplies
// this per byte. Then add the cmd-delay
);
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;
}
#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);
exit(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 */

View File

@@ -0,0 +1,4 @@
.cvsignore
.deps
Makefile
Makefile.in