177 Commits

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

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/tags/RELEASE_5_3_0@710 81a1dc3b-b13d-400b-aceb-764788c761c2
2006-12-21 22:40:07 +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
62 changed files with 15096 additions and 1460 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

File diff suppressed because it is too large Load Diff

View File

@@ -22,6 +22,7 @@
#
EXTRA_DIST = \
ChangeLog \
ChangeLog-2001 \
ChangeLog-2002 \
ChangeLog-2003 \
@@ -46,8 +47,25 @@ avrdude_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
avrdude_CFLAGS = @ENABLE_WARNINGS@
avrdude_LDADD = @LIBUSB@
bin_PROGRAMS = avrdude
# 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
avrdude_SOURCES = \
config_gram.y \
lexer.l \
@@ -69,6 +87,10 @@ 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 \
@@ -76,6 +98,7 @@ avrdude_SOURCES = \
lists.c \
lists.h \
main.c \
my_ddk_hidsdi.h \
par.c \
par.h \
pgm.c \
@@ -90,16 +113,23 @@ 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 \
usbasp.c \
usbasp.h \
usbdevs.h \
usb_libusb.c
man_MANS = avrdude.1
@@ -108,6 +138,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,62 @@ Approximate change log for AVRDUDE by version.
(For more detailed changes, see the ChangeLog file.)
----------------------------------------------------------------------
Current:
Version 5.3:
* 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

@@ -51,7 +51,15 @@ int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
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 +87,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 +115,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
@@ -182,20 +182,13 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
* 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 +199,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 +227,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 +255,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 +301,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 +342,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 +407,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 +421,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 +506,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 +525,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);
}
@@ -567,7 +579,8 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
* 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 +730,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);

View File

@@ -32,8 +32,8 @@
extern struct avrpart parts[];
int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value);
int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value);
int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
int verbose);
@@ -44,6 +44,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);

View File

@@ -40,13 +40,14 @@
extern char * progname;
extern int do_cycles;
extern int ovsigck;
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 +55,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 +68,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 +135,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 +174,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 +194,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 +271,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,8 +285,8 @@ 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;
}
@@ -557,6 +564,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 +573,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

@@ -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 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 26, 2006
.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 adapter is also supported, provided
.Nm avrdude
has been compiled with libusb support.
It features a simple firwmare-only USB implementation, running on
an ATmega8 (or ATmega88).
.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 driver does 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

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
@@ -174,6 +175,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;
@@ -317,7 +319,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 +371,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);

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
@@ -41,6 +42,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 +63,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 +89,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 +104,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 +121,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 */

View File

@@ -28,47 +28,103 @@
#include <unistd.h>
#include <errno.h>
#if !defined(WIN32NATIVE)
# include <signal.h>
# include <sys/time.h>
#endif
#include "avr.h"
#include "pindefs.h"
#include "pgm.h"
#include "par.h"
#include "serbb.h"
#define SLOW_TOGGLE 0
extern char * progname;
extern int do_cycles;
extern int verbose;
static int bitbang_setpin(PROGRAMMER * pgm, int pin, int value)
{
if ( pgm->flag )
serbb_setpin(pgm->fd,pin,value);
else
par_setpin(pgm->fd,pin,value);
static int delay_decrement;
return 0;
#if !defined(WIN32NATIVE)
static volatile int done;
typedef void (*mysighandler_t)(int);
static mysighandler_t saved_alarmhandler;
static void alarmhandler(int signo)
{
done = 1;
signal(SIGALRM, saved_alarmhandler);
}
#endif /* !WIN32NATIVE */
/*
* 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 +138,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 +155,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 +176,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 +289,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 +319,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 +335,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

@@ -25,6 +25,9 @@
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);

View File

@@ -69,7 +69,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 +79,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 +94,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);
}
@@ -227,7 +227,6 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
char buf[10];
char type;
char c;
int dev_supported = 0;
no_show_func_info();
@@ -297,9 +296,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);
@@ -313,22 +312,9 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
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. */
buf[0] = 'T';
@@ -337,10 +323,9 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
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 +359,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,11 +374,12 @@ 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;
}
@@ -675,17 +661,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

@@ -41,6 +41,7 @@ typedef struct token_t {
int primary;
VALUE value;
} TOKEN;
typedef struct token_t *token_p;
extern FILE * yyin;
@@ -58,7 +59,7 @@ extern char default_serial[];
#if !defined(HAS_YYSTYPE)
#define YYSTYPE struct token_t *
#define YYSTYPE token_p
#endif
extern YYSTYPE yylval;

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
@@ -35,9 +36,12 @@
#include "pgm.h"
#include "stk500.h"
#include "stk500v2.h"
#include "stk500generic.h"
#include "avr910.h"
#include "butterfly.h"
#include "usbasp.h"
#include "avr.h"
#include "jtagmkI.h"
#include "jtagmkII.h"
#if defined(WIN32NATIVE)
@@ -64,6 +68,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 +88,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 +100,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,10 +127,15 @@ 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_BUTTERFLY
%token K_TYPE
%token K_VCC
@@ -128,9 +146,11 @@ static int parse_cmdbits(OPCODE * op);
%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 +162,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 +196,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 +392,96 @@ 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_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 +498,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 +515,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 +561,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 +625,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 +830,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 +878,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 +990,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 +1287,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.3, avrdude-dev@nongnu.org)
AC_CANONICAL_BUILD
AC_CANONICAL_HOST
@@ -32,7 +32,7 @@ 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
@@ -44,13 +44,65 @@ AM_PROG_LEX
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)
AC_MSG_CHECKING([for a Win32 HID libray])
SAVED_LIBS="${LIBS}"
case $target in
*-*-mingw32*)
LIBHID="-lhid -lsetupapi"
HIDINCLUDE="#include <ddk/hidsdi.h>"
;;
*)
LIBHID="-lhid"
HIDINCLUDE='#include "my_ddk_hidsdi.h"'
;;
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}"
# 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 +111,7 @@ 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])
# Checks for misc stuff.
@@ -85,7 +137,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,6 +145,18 @@ AC_ARG_ENABLE(
esac],
[enabled_doc=no])
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])
if test "$enabled_doc" = "yes"; then
SUBDIRS_AC='doc @WINDOWS_DIRS@'
@@ -104,14 +168,14 @@ DIST_SUBDIRS_AC='windows'
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 +183,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 +191,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 +205,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"
LDFLAGS="${LDFLAGS} -static"
;;
esac
AC_SUBST(WINDOWS_DIRS,$WINDOWS_DIRS)
@@ -168,9 +251,17 @@ fi
AC_CONFIG_FILES([
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

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 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 adapter is also supported, provided AVRDUDE
has been compiled with libusb support.
It features a simple firwmare-only USB implementation, running on
an ATmega8 (or ATmega88).
@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,87 @@ 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{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{avrispv2} @tab
Atmel AVR ISP, running a version 2.x firmware (an alias for stk500v2)
@item @code{avrispmkII} @tab
Atmel AVR ISP mkII (alias for stk500v2)
@item @code{avrispmk2} @tab
Atmel AVR ISP mkII (alias for stk500v2)
@item @code{bascom} @tab
Bascom SAMPLE programming cable
@itemx bsd
Brian Dean's Programmer, http://www.bsdhome.com/avrdude/
@itemx butterfly
@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{dt006} @tab
Dontronics DT006
@item jtagmkII
@itemx jtag2slow
@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{frank-stk200} @tab
Frank's STK200 clone, @url{http://electropol.free.fr/spip/spip.php?article15}
@item @code{jtagmkI} @tab
Atmel JTAG ICE mkI, running at 115200 Bd
@item @code{jtag1} @tab
@emph{Same as before.}
@item @code{jtag1slow} @tab
Atmel JTAG ICE mkI, running at 19200 Bd
@item @code{jtagmkII} @tab
Atmel JTAG ICE mkII (default speed 19200 Bd)
@itemx jtag2fast
@item @code{jtag2slow} @tab
@emph{Same as before.}
@item @code{jtag2fast} @tab
Atmel JTAG ICE mkII, running at 115200 Bd
@itemx jtag2
Same as before.
@itemx pavr
@item @code{jtag2} @tab
@emph{Same as before.}
@item @code{jtag2isp} @tab
Atmel JTAG ICE mkII in ISP mode.
@item @code{jtag2dw} @tab
Atmel JTAG ICE mkII in debugWire mode.
@item @code{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{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{stk500v1} @tab
Atmel STK500, running a version 1.x firmware
@item @code{stk500hvsp} @tab
Atmel STK500 in high-voltage serial programming mode(version 2.x firmware only)
@item @code{stk500pp} @tab
Atmel STK500 in parallel programming mode (version 2.xfirmware only)
@item @code{stk500v2} @tab
Atmel STK500, running a version 2.x firmware
@end multitable
@@ -534,10 +511,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 +549,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 +677,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 +703,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 +748,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 +784,7 @@ avrdude done. Thank you.
%
@end cartouche
@end example
@end smallexample
@page
@noindent
@@ -743,7 +792,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 +813,7 @@ avrdude done. Thank you.
%
@end cartouche
@end example
@end smallexample
@page
@noindent
@@ -772,7 +821,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 +862,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 +885,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 +1007,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 +1028,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 +1080,7 @@ avrdude> dump eeprom 0 16
avrdude>
@end cartouche
@end example
@end smallexample
@noindent
@@ -1020,7 +1090,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 +1120,7 @@ avrdude> w lfuse 0 0x2f
avrdude>
@end cartouche
@end example
@end smallexample
@c
@@ -1119,7 +1189,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 +1205,7 @@ programmer
pgmled = <num> ; # pin number
vfyled = <num> ; # pin number
;
@end example
@end smallexample
@c
@@ -1144,7 +1214,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 +1247,7 @@ part
writepage = <instruction format> ;
;
;
@end example
@end smallexample
@menu
* Instruction Format::
@@ -1226,7 +1296,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 +1304,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 +1534,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 +1547,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 +1827,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 +1869,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 programmers connected simultaneously are not
found.
Solution: none at this time. The simplicity of the USBasp programmer
doesn't offer a method to distinguish multiple programmers that are
connected simultaneously, so effectively only one USBasp 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

@@ -77,6 +77,10 @@ int fileio_ihex(struct fioparms * fio,
int fileio_srec(struct fioparms * fio,
char * filename, FILE * f, unsigned char * buf, int size);
int fileio_num(struct fioparms * fio,
char * filename, FILE * f, unsigned char * buf, int size,
FILEFMT fmt);
int fmt_autodetect(char * fname);
@@ -658,6 +662,45 @@ 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;
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;
}
int fileio_rbin(struct fioparms * fio,
char * filename, FILE * f, unsigned char * buf, int size)
@@ -793,6 +836,78 @@ int fileio_srec(struct fioparms * fio,
}
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;
@@ -911,7 +1026,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 +1039,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 +1120,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

@@ -27,7 +27,11 @@ typedef enum {
FMT_SREC,
FMT_IHEX,
FMT_RBIN,
FMT_IMM
FMT_IMM,
FMT_HEX,
FMT_DEC,
FMT_OCT,
FMT_BIN
} FILEFMT;
struct fioparms {

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

1380
avrdude/jtagmkI.c Normal file

File diff suppressed because it is too large Load Diff

28
avrdude/jtagmkI.h Normal file
View File

@@ -0,0 +1,28 @@
/*
* 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
void jtagmkI_initpgm (PROGRAMMER * pgm);
#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,17 @@
#ifndef jtagmkII_h
#define jtagmkII_h
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);
#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
@@ -46,17 +47,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 +70,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 +105,24 @@ 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; }
bank_size { yylval=NULL; return K_PAGE_SIZE; }
banked { yylval=NULL; return K_PAGED; }
baudrate { yylval=NULL; return K_BAUDRATE; }
@@ -130,15 +135,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 +176,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 +192,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 +204,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 +241,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 +255,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

@@ -76,6 +76,7 @@ char * version = VERSION;
int verbose; /* verbose output */
int quell_progress; /* un-verebose output */
int ovsigck; /* 1=override sig check, 0=don't */
char * progname;
char progbuf[PATH_MAX]; /* temporary buffer of spaces the same
length as progname; used for lining up
@@ -101,13 +102,15 @@ void usage(void)
"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,39 +132,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;
@@ -197,17 +167,6 @@ void programmer_display(char * 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;
@@ -381,9 +340,20 @@ UPDATE * parse_op(char * s)
buf[i++] = *p++;
if (*p != ':') {
fprintf(stderr, "%s: invalid update specification\n", progname);
free(upd);
return NULL;
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;
@@ -457,6 +427,10 @@ UPDATE * parse_op(char * s)
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);
@@ -589,7 +563,7 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite,
*/
if (quell_progress < 2) {
fprintf(stderr, "%s: writing %s (%d bytes):\n",
progname, upd->memtype, size);
progname, mem->desc, size);
}
if (!nowrite) {
@@ -615,7 +589,7 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite,
if (quell_progress < 2) {
fprintf(stderr, "%s: %d bytes of %s written\n", progname,
vsize, upd->memtype);
vsize, mem->desc);
}
}
@@ -647,7 +621,7 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, int nowrite,
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);
progname, mem->desc);
}
report_progress (0,1,"Reading");
@@ -709,15 +683,13 @@ int main(int argc, char * argv [])
/* 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 +700,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 +715,11 @@ int main(int argc, char * argv [])
char * homedir;
#endif
progname = rindex(argv[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 +741,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 +749,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 +757,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 +808,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 +829,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 +867,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 +968,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 +1092,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 +1112,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 +1140,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,6 +1158,21 @@ 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");
@@ -1185,14 +1185,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 +1226,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 +1245,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,6 +1276,23 @@ 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) {
@@ -1420,7 +1431,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,9 +29,11 @@
#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 "avr.h"
@@ -40,7 +42,11 @@
#include "ppi.h"
#include "bitbang.h"
#define SLOW_TOGGLE 0
extern char * progname;
extern int do_cycles;
extern int verbose;
#if HAVE_PARPORT
struct ppipins_t {
int pin;
@@ -49,7 +55,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 +77,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 +90,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 +129,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 +212,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 +235,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 +278,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, 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 +357,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 +370,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 +421,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

@@ -24,11 +24,6 @@
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);
#endif

View File

@@ -30,9 +30,11 @@
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 int pgm_default_5 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data);
static void pgm_default_6 (struct programmer_t *, char *);
@@ -96,9 +98,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 +117,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,13 +143,20 @@ static int pgm_default_2 (struct programmer_t * pgm, AVRPART * p)
return -1;
}
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_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_5 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data)
{
pgm_default();
return -1;

View File

@@ -27,7 +27,7 @@
#include "avrpart.h"
#include "lists.h"
#include "pindefs.h"
#include "serial.h"
#define ON 1
#define OFF 0
@@ -38,17 +38,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;
char desc[PGM_DESCLEN];
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);
@@ -81,6 +96,11 @@ 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 */
@@ -91,6 +111,7 @@ PROGRAMMER * pgm_new(void);
#if defined(WIN32NATIVE)
#include "ac_cfg.h"
#include <windows.h>
/* usleep replacements */
@@ -102,19 +123,12 @@ PROGRAMMER * pgm_new(void);
*/
void usleep(unsigned long us);
void gettimeofday(struct timeval*, void*z);
#define rindex strrchr
#if !defined(HAVE_GETTIMEOFDAY)
struct timezone;
int gettimeofday(struct timeval *tv, struct timezone *tz);
#endif /* HAVE_GETTIMEOFDAY */
#endif /* __win32native_h */
#if !defined(ppi_claim)
# define ppi_claim(pgm)
#endif
#if !defined(ppi_release)
# define ppi_release(pgm)
#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,9 +34,11 @@
#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 "avr.h"
@@ -49,26 +54,19 @@ enum {
PPI_SHADOWREAD
};
int ppi_shadow_access(int fd, int reg, unsigned char *v, unsigned char action)
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

@@ -33,21 +33,21 @@ enum {
int ppi_get (int fd, int reg, int bit);
int ppi_get (union filedescriptor *fdp, int reg, int bit);
int ppi_set (int fd, int reg, int bit);
int ppi_set (union filedescriptor *fdp, int reg, int bit);
int ppi_clr (int fd, int reg, int bit);
int ppi_clr (union filedescriptor *fdp, int reg, int bit);
int ppi_getall (int fd, int reg);
int ppi_getall (union filedescriptor *fdp, int reg);
int ppi_setall (int fd, int reg, int val);
int ppi_setall (union filedescriptor *fdp, int reg, int val);
int ppi_toggle (int fd, int reg, int bit);
int ppi_toggle (union filedescriptor *fdp, int reg, int bit);
int ppi_open (char * port);
void ppi_open (char * port, union filedescriptor *fdp);
void ppi_close (int fd);
void ppi_close (union filedescriptor *fdp);
#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,6 +43,7 @@ reg = register as defined in an enum in ppi.h. This must be converted
#include <windows.h>
#include <sys/time.h>
#include <windows.h>
#include "serial.h"
#include "ppi.h"
extern char *progname;
@@ -73,7 +75,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 +84,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 +94,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 +112,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 +161,7 @@ static int winnt_pp_open(void)
void ppi_close(int fd)
void ppi_close(union filedescriptor *fdp)
{
return;
}
@@ -167,12 +171,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 +187,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 +204,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 +220,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 +238,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 +253,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 +263,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 +320,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 +330,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

@@ -49,8 +49,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) {
@@ -99,15 +105,25 @@ 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)
{
safemode_fuse = 1 + value; //failed - ensure they differ
}
if(pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
value = 1 + safemode_fuse; //failed - ensure they differ
}
if (value == safemode_fuse) {
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
value = 1 + safemode_fuse;
}
if (value == safemode_fuse)
{
fusegood = 1; /* Fuse read OK three times */
}
}
}
}
if (fusegood == 0) {
fprintf(stderr,
@@ -126,10 +142,19 @@ 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)
{
safemode_lfuse = 1 + value;
}
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
value = safemode_lfuse + 1;
}
if (value == safemode_lfuse) {
avr_read_byte(pgm, p, m, 0, &value);
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
value = safemode_lfuse + 1;
}
if (value == safemode_lfuse){
fusegood = 1; /* Fuse read OK three times */
}
@@ -152,10 +177,19 @@ 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)
{
safemode_hfuse = value + 1;
}
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
value = safemode_hfuse + 1;
}
if (value == safemode_hfuse) {
avr_read_byte(pgm, p, m, 0, &value);
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
value = safemode_hfuse + 1;
}
if (value == safemode_hfuse){
fusegood = 1; /* Fuse read OK three times */
}
@@ -178,10 +212,19 @@ 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)
{
safemode_efuse = value + 1;
}
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
value = safemode_efuse + 1;
}
if (value == safemode_efuse) {
avr_read_byte(pgm, p, m, 0, &value);
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
{
value = safemode_efuse + 1;
}
if (value == safemode_efuse){
fusegood = 1; /* Fuse read OK three times */
}

648
avrdude/ser_avrdoper.c Normal file
View File

@@ -0,0 +1,648 @@
/*
* 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 "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
extern char *progname;
extern int verbose;
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 */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
#ifdef WIN32NATIVE
#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 */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
#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,6 +34,9 @@
#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>
@@ -65,6 +69,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,99 +82,195 @@ 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;
@@ -207,9 +310,9 @@ static int ser_send(int fd, unsigned char * buf, size_t buflen)
while (len) {
reselect:
FD_ZERO(&wfds);
FD_SET(fd, &wfds);
FD_SET(fd->ifd, &wfds);
nfds = select(fd+1, NULL, &wfds, NULL, &to2);
nfds = select(fd->ifd + 1, NULL, &wfds, NULL, &to2);
if (nfds == 0) {
if (verbose >= 1)
fprintf(stderr,
@@ -228,7 +331,7 @@ static int ser_send(int fd, unsigned char * buf, size_t buflen)
}
}
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 +345,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 +361,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 +385,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 +421,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 +438,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 +460,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 +482,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
@@ -83,10 +84,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 +106,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 +158,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 +174,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 +187,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 +209,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 +218,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 +242,14 @@ 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;
unsigned char * p = buf;
size_t len = 0;
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",
@@ -288,14 +302,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 +362,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

@@ -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
@@ -50,25 +51,30 @@ 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, 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
@@ -49,19 +49,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 +74,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 +101,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 +126,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 +144,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 +174,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 +193,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 +222,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, 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 +323,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 +365,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

@@ -31,20 +31,32 @@
#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)

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

@@ -57,7 +57,7 @@ static int stk500_is_page_empty(unsigned int address, int page_size,
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 +65,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 +78,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 +90,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 +143,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 +153,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 +176,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 +220,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 +240,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 +287,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 +307,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 +455,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 +476,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 +539,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 +559,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 +585,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 +601,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 +621,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 +641,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 +659,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 +732,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 +765,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 +854,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 +874,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 +1037,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 +1057,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 +1097,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 +1117,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",
@@ -1189,6 +1241,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

72
avrdude/stk500generic.c Normal file
View File

@@ -0,0 +1,72 @@
/*
* 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 "pgm.h"
#include "stk500.h"
#include "stk500v2.h"
extern char *progname;
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;
}
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
@@ -23,6 +24,12 @@
#define stk500v2_h__
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);
#endif

View File

@@ -292,7 +292,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);
@@ -399,7 +399,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",
@@ -427,6 +427,13 @@ int cmd_send(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
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;

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>

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
@@ -38,25 +39,24 @@
#include <usb.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 +99,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 +107,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 +130,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 +163,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 +203,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 +282,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 +297,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 +340,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 +421,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 */

446
avrdude/usbasp.c Normal file
View File

@@ -0,0 +1,446 @@
/*
* 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 "avr.h"
#include "pgm.h"
#include "usbasp.h"
#ifdef HAVE_LIBUSB
#include <usb.h>
extern int verbose;
extern char * progname;
extern int do_cycles;
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);
pgm->program_enable(pgm, p);
return 0;
}
static void usbasp_disable(PROGRAMMER * pgm)
{
/* Do nothing. */
return;
}
static void usbasp_enable(PROGRAMMER * pgm)
{
/* Do nothing. */
return;
}
static void usbasp_display(PROGRAMMER * pgm, 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;
}
cmd[0] = address & 0xFF;
cmd[1] = address >> 8;
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;
}
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 */
extern char * progname;
static int usbasp_nousb_open (struct programmer_t *pgm, char * name)
{
fprintf(stderr, "%s: error: no usb support. please compile again with libusb installed.\n",
progname);
exit(1);
}
void usbasp_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "usbasp");
pgm->open = usbasp_nousb_open;
}
#endif /* HAVE_LIBUSB */

55
avrdude/usbasp.h Normal file
View File

@@ -0,0 +1,55 @@
/*
* 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_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
void usbasp_initpgm (PROGRAMMER * pgm);
#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 */

View File

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