mirror of
https://github.com/mariusgreuel/avrdude.git
synced 2025-12-15 02:01:07 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70246d5b09 |
@@ -4,30 +4,17 @@ 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
|
||||
|
||||
|
||||
@@ -12,17 +12,6 @@ Contributors:
|
||||
Theodore A. Roth <troth@openavr.org>
|
||||
Michael Holzt <kju-avr@fqdn.org>
|
||||
Colin O'Flynn <coflynn@newae.com>
|
||||
Thomas Fischl <tfischl@gmx.de>
|
||||
David Hoerl <dhoerl@mac.com>
|
||||
Michal Ludvig <mludvig@logix.net.nz>
|
||||
Darell Tan <darell.tan@gmail.com>
|
||||
Wolfgang Moser
|
||||
Ville Voipio
|
||||
Hannes Weisbach
|
||||
Doug Springer
|
||||
Brett Hagman <bhagman@roguerobotics.com>
|
||||
Rene Liebscher <r.liebscher@gmx.de>
|
||||
Jim Paris <jim@jtan.com>
|
||||
|
||||
For minor contributions, please see the ChangeLog files.
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
$Id$
|
||||
|
||||
How to build avrdude from SVN:
|
||||
|
||||
1. svn co svn://svn.savannah.nongnu.org/avrdude/trunk
|
||||
|
||||
2. cd trunk/avrdude
|
||||
|
||||
3. ./bootstrap
|
||||
|
||||
4. ./configure
|
||||
|
||||
5. make
|
||||
@@ -304,7 +304,8 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
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, see <http://www.gnu.org/licenses/>.
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
1128
avrdude/ChangeLog
1128
avrdude/ChangeLog
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,364 +0,0 @@
|
||||
2007-11-08 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Partially revert the line buffered output change,
|
||||
and turn stderr into unbuffered output while producing the
|
||||
progress report.
|
||||
|
||||
2007-11-07 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Add setup and teardown hooks to the programmer
|
||||
definition. If present, call the setup hook immediately after
|
||||
finding the respective programmer object, and schedule the
|
||||
teardown hook to be called upon exit. This allows the
|
||||
programmer implementation to dynamically allocate private
|
||||
programmer data.
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* avr910.c: Convert static programmer data into dynamically
|
||||
allocated data.
|
||||
* butterfly.c: (Ditto.)
|
||||
* jtagmkI.c: (Ditto.)
|
||||
* jtagmkII.c: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* usbasp.c: (Ditto.)
|
||||
* usbtiny.c: (Ditto.)
|
||||
|
||||
2007-11-06 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* butterfly.c: Remove the no_show_func_info() calls, as Brian
|
||||
promised some 4 years ago.
|
||||
|
||||
2007-11-06 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Add the -x option to pass extended parameters to
|
||||
the programmer backend.
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* jtagmkII.c: Implement the extended parameter jtagchain=
|
||||
to support JTAG daisy-chains.
|
||||
* avrdude.1: Document all of the above.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2007-10-30 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version for post-release.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version, releasing avrdude-5.5.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by <bikenomad@gmail.com>:
|
||||
patch #5007: Patch for line-buffering of stdout and stderr
|
||||
* main.c: call setvbuf() for stdout and stderr.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by <graceindustries@gmail.com>:
|
||||
patch #5953: Add AT90CAN64 and AT90CAN32 to avrdude.conf
|
||||
* avrdude.conf.in: Add entry for AT90CAN64 and AT90CAN32.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Wolfgang Moser:
|
||||
patch #6121: ISP support for the C2N232I device (serial port
|
||||
bitbanging)
|
||||
* avrdude.conf.in: Add entry for c2n232i.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by <karl.yerkes@gmail.com>:
|
||||
patch #6141: accept binary format immediate values
|
||||
* fileio.c: Detect a 0b prefix, and call strtoul() differently
|
||||
in that case.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
bug #21076: -vvvv serial receive prints are empty in Win32 build
|
||||
* ser_win32.c (ser_recv): Drop the essentially unused variable
|
||||
"len", and use the variable "read" in order to track how many
|
||||
bytes have just been read in.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
bug #21145: atmega329p not recognized
|
||||
* avrdude.conf.in: Add definitions for the ATmega329P/3290P.
|
||||
Same as ATmega329/3290 except of the different signature.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
bug #21152: Unable to program atmega324p with avrdude 5.4 and AVRISP
|
||||
using default configuration file.
|
||||
* avrdude.conf.in: Uncomment the (bogus) stk500_devcode lines for
|
||||
the ATmega164P, ATmega324P, ATmega644, and ATmega644P definitions.
|
||||
This only affects users of STK500v1 firmware.
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Submitted by <ladyada@gmail.com>:
|
||||
Patch #6233: Add support for USBtinyISP programmer
|
||||
* usbtiny.c: New file.
|
||||
* usbtiny.h: (Ditto.)
|
||||
* Makefile.am: Include usbtiny into the build.
|
||||
* avrdude.conf.in: (Ditto.)
|
||||
* config_gram.y: (Ditto.)
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.1: Document the usbtiny support.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2007-10-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* doc/avrdude.texi: Sort list of supported programmers into
|
||||
alphabetical order, add all missing programmers.
|
||||
|
||||
2007-07-24 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
* usbasp.c: Added long addresses to support devices with more
|
||||
than 64kB flash. Closes bug #20558: Long address problem with
|
||||
USBasp.
|
||||
|
||||
2007-06-27 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am (EXTRA_DIST): Add ChangeLog-2004-2006.
|
||||
|
||||
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version for post-release.
|
||||
|
||||
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac (AC_INIT): Bump version, releasing avrdude-5.4.
|
||||
|
||||
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Fix AVR910 devcodes. It seems that the AVR109
|
||||
listing refers to "BOOT"-type code, while the standard codes are
|
||||
different (usually one below).
|
||||
|
||||
2007-05-16 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avr.c (avr_read, avr_write): only use the paged_load and
|
||||
paged_write backend functions iff the memory area in question has
|
||||
a page_size != 0.
|
||||
This is supposed to fix bug #19234: avrdude-5.3.1 segfaults when
|
||||
stk500v1 tries to program an ATtiny15
|
||||
|
||||
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avr910.c: Fall back to avr_{read,write}_byte_default(). Fixes
|
||||
bug #18803: Fuse reading regression in avrdude 5.3.1 with avr910
|
||||
programmer
|
||||
|
||||
2007-05-15 Colin O'Flynn <coflynn@newae.com>
|
||||
|
||||
* avrdude.conf.in: Rename the ATmega164 and ATmega324 into
|
||||
ATmega164P and ATmega324P, resp. Add an entry for the ATmega644P.
|
||||
Fixes bug #19769: ATmega164p not recognized
|
||||
|
||||
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* ser_posix.c (ser_send): Don't select() on the output fd before
|
||||
trying to write something to the serial line. That kind of
|
||||
polling isn't very useful anyway, and it seems it breaks for the
|
||||
Linux CP210x USB<->RS-232 bridge driver which is certainly a bug
|
||||
in the driver, but we can just avoid that bug alltogether.
|
||||
|
||||
2007-05-15 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Fix the STK500v2 ISP delay parameter for
|
||||
ATmega640/1280/1281/2560/2561. Atmel has changed the XML
|
||||
files after the initial release.
|
||||
|
||||
2007-05-01 Colin O'Flynn <coflynn@newae.com>
|
||||
|
||||
* safemode.c: -Oops - bug in verbose output. Fixed.
|
||||
-Fixed handling of cases where programmer cannot read fuses (AVR910)
|
||||
* main.c: -Also fixing handling of cases where programmer cannot
|
||||
read fuses
|
||||
This should close one or more bugs (18803, 19570)
|
||||
|
||||
2007-05-01 Colin O'Flynn <coflynn@newae.com>
|
||||
|
||||
* safemode.c: Added verbose output from safemode routines.
|
||||
|
||||
2007-03-25 Colin O'Flynn <coflynn@newae.com>
|
||||
|
||||
* stk500generic.c: Forgot to close the serial port before trying to
|
||||
open it again, caused problems on Windows machines.
|
||||
Closes bug #19411
|
||||
|
||||
2007-02-26 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Add the AT90PWM2/3B devices.
|
||||
|
||||
2007-02-02 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
* usbasp.c: Changed return value of function usbasp_initialize to stop
|
||||
avrdude on communication errors between programmer and target.
|
||||
Closes bug #18581: safemode destroys fuse bits
|
||||
|
||||
2007-02-01 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* config_gram.y: Remove duplicate definition of token K_WRITEPAGE
|
||||
|
||||
2007-01-30 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* butterfly.c: Implement ATmega256x support for butterfly/avr109.
|
||||
|
||||
2007-01-30 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Fix subdir handling. Now finally, "make
|
||||
distcheck" will include the documentation into the tarball even if
|
||||
the configure had been run without the --enable-doc.
|
||||
|
||||
2007-01-30 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* safemode.c: Obtain progname from avrdude.h rather than trying to
|
||||
roll our own (duplicate) copy of it.
|
||||
* avr910.c: Constify char pointers.
|
||||
* avrpart.c: (Ditto.)
|
||||
* avrpart.h: (Ditto.)
|
||||
* butterfly.c: (Ditto.)
|
||||
* config.c: (Ditto.)
|
||||
* config.h: (Ditto.)
|
||||
* jtagmkI.c: (Ditto.)
|
||||
* jtagmkII.c: (Ditto.)
|
||||
* par.c: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* serbb_posix.c: (Ditto.)
|
||||
* serbb_win32.c: (Ditto.)
|
||||
* stk500.c: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* usbasp.c: (Ditto.)
|
||||
|
||||
2007-01-29 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrpart.c: More backend/library abstraction and generalization:
|
||||
turn the list_parts() and list_programmers() functions into
|
||||
general list iteration functions that call a caller-supplied
|
||||
callback for each element. Implement list_parts() and
|
||||
list_programmers() as private functions in main.c based on that
|
||||
approach.
|
||||
* avrpart.h: (Ditto.)
|
||||
* main.c: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
|
||||
2007-01-25 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am: Rearrange everything so it is now built into a
|
||||
libavrdude.a library, and link main.c against that library.
|
||||
* configure.ac: Add AC_PROG_RANLIB as we are building a library
|
||||
now.
|
||||
|
||||
2007-01-24 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Major code cleanup.
|
||||
- Make all internal functions "static".
|
||||
- Make sure each module's header and implementation file match.
|
||||
- Remove all library-like functionality from main.c, so only
|
||||
the actual frontend remains in main.c.
|
||||
- Add C++ brackets to all header files.
|
||||
* avr.c: (Ditto.)
|
||||
* avr.h: (Ditto.)
|
||||
* avr910.c: (Ditto.)
|
||||
* avr910.h: (Ditto.)
|
||||
* avrdude.h: (Ditto.)
|
||||
* avrpart.c: (Ditto.)
|
||||
* avrpart.h: (Ditto.)
|
||||
* bitbang.h: (Ditto.)
|
||||
* butterfly.h: (Ditto.)
|
||||
* config.c: (Ditto.)
|
||||
* config.h: (Ditto.)
|
||||
* confwin.h: (Ditto.)
|
||||
* crc16.c: (Ditto.)
|
||||
* crc16.h: (Ditto.)
|
||||
* fileio.c: (Ditto.)
|
||||
* fileio.h: (Ditto.)
|
||||
* jtagmkI.h: (Ditto.)
|
||||
* jtagmkII.h: (Ditto.)
|
||||
* lexer.l: (Ditto.)
|
||||
* lists.h: (Ditto.)
|
||||
* main.c: (Ditto.)
|
||||
* par.h: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* ppi.c: (Ditto.)
|
||||
* ppi.h: (Ditto.)
|
||||
* safemode.h: (Ditto.)
|
||||
* serbb.h: (Ditto.)
|
||||
* serial.h: (Ditto.)
|
||||
* stk500.h: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* stk500v2.h: (Ditto.)
|
||||
* term.c: (Ditto.)
|
||||
* term.h: (Ditto.)
|
||||
* usbasp.h: (Ditto.)
|
||||
* update.c: New file.
|
||||
* update.h: New file.
|
||||
* Makefile.am: Include update.c and update.h.
|
||||
|
||||
2007-01-24 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Move all "extern" declarations into a centreal header file.
|
||||
* Makefile.am: Add new avrdude.h.
|
||||
* avrdude.h: New file.
|
||||
* avr.c: Replace private extern decl's by #include "avrdude.h".
|
||||
* avr910.c: (Ditto.)
|
||||
* avrpart.c: (Ditto.)
|
||||
* bitbang.c: (Ditto.)
|
||||
* butterfly.c: (Ditto.)
|
||||
* config.c: (Ditto.)
|
||||
* config_gram.y: (Ditto.)
|
||||
* fileio.c: (Ditto.)
|
||||
* jtagmkI.c: (Ditto.)
|
||||
* jtagmkII.c: (Ditto.)
|
||||
* lexer.l: (Ditto.)
|
||||
* main.c: (Ditto.)
|
||||
* par.c: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* ppi.c: (Ditto.)
|
||||
* ppiwin.c: (Ditto.)
|
||||
* ser_avrdoper.c: (Ditto.)
|
||||
* ser_posix.c: (Ditto.)
|
||||
* ser_win32.c: (Ditto.)
|
||||
* serbb_posix.c: (Ditto.)
|
||||
* serbb_win32.c: (Ditto.)
|
||||
* stk500.c: (Ditto.)
|
||||
* stk500generic.c: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* term.c: (Ditto.)
|
||||
* usb_libusb.c: (Ditto.)
|
||||
* usbasp.c: (Ditto.)
|
||||
|
||||
2007-01-13 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega8): Bump the delay values for flash
|
||||
and EEPROM, based on the current Atmel XML file.
|
||||
|
||||
2007-01-12 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Improve the detection of the Win32 HID library,
|
||||
and the presence of the header ddk/hidsdi.h. It now works
|
||||
correctly under Cygwin and several flavours of MinGW.
|
||||
* Makefile.am: Add new LIBHID pattern.
|
||||
|
||||
2007-01-11 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
* butterfly.c (butterfly_initialize): when sending the 'T'
|
||||
command (which is ignored by current AVR109 bootloaders),
|
||||
send the first reply from the list of supported device
|
||||
codes back rather than using avrdude.conf's idea about
|
||||
an AVR910 device code. Apparently, this solves disagreements
|
||||
between different versions of at least the ATmega8 AVR910
|
||||
device code.
|
||||
Closes bug #18727: Writing flash failed
|
||||
|
||||
2007-01-07 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
|
||||
Reported by Till Harbaum:
|
||||
* avrdude.conf.in (ATtiny25/45/85): Change HVSP reset from
|
||||
500 microseconds to 1 ms, matching the most recent Atmel XML
|
||||
specs.
|
||||
@@ -1,185 +0,0 @@
|
||||
2008-11-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.h: Change the prototype for usleep() to be more Cygwin-
|
||||
friendly.
|
||||
* ppiwin.c: (Ditto.)
|
||||
|
||||
2008-11-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by limor <limor@ladyada.net>
|
||||
* usbtiny.c (usbtiny_cmd): Replace sizeof() by a fixed constant
|
||||
4 for the result array, because otherwise it would take the size
|
||||
of a pointer which miserably fails on 64-bit machines.
|
||||
|
||||
2008-11-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #6609: Using PCI parallel port cards on Windows
|
||||
* ppiwin.c (ppi_open): If the port parameter passed from the
|
||||
-p option is neither lpt1/2/3, try interpreting it directly as
|
||||
a base address.
|
||||
* avrdude.1: Document the change.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-11-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22882: Erase Cycle Counter does not work for stk500v2
|
||||
* stk500v2.c (stk500v2_chip_erase,stk500hv_chip_erase): Return
|
||||
the expected 0 for success rather than a protocol-dependant
|
||||
number.
|
||||
|
||||
2008-11-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22883: Chip Erase performed even with no-write flag (-n)
|
||||
* main.c: Do not erase the chip if both, -e and -n options have
|
||||
been specified.
|
||||
|
||||
2008-11-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #24589: AT90USB64* have wrong signature
|
||||
* avrdude.conf.in: Uncomment the correct, and delete the wrong
|
||||
signature for AT90USB646/647. Alas, the datasheet has never been
|
||||
corrected for years.
|
||||
|
||||
2008-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: Fix a serious memory corruption that happened when
|
||||
using the JTAG ICE mkII (or AVR Dragon) in ISP mode. The wrong
|
||||
set of per-programmer private data had been allocated (stk500v2
|
||||
vs. jtagmkII) which was too small to hold the actual data.
|
||||
* jtagmkII.h: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
|
||||
2008-07-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: Implement Xmega JTAG support.
|
||||
* jtagmkII_private.h: Add EMULATOR_MODE_JTAG_XMEGA.
|
||||
|
||||
2008-07-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Remember whether the device initialization worked, and
|
||||
allow to continue with -F if it failed yet do not attempt to
|
||||
perform anything on the device itself. That way, -tF could be
|
||||
specified for programmers like the STK500/STK600 even without a
|
||||
device connected, just in order to allow changing parameters on
|
||||
the programmer itself.
|
||||
* avrdude.1: Document that possible use of the -F option.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-07-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk600_xprog_paged_write): Fix a fatal miscalculation
|
||||
of the number of bytes to be written which caused a malloc chunk
|
||||
corruption.
|
||||
|
||||
2008-07-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
First implementation of ATxmega support. By now, only the
|
||||
PDI mode of the STK600 is supported. Single-byte EEPROM
|
||||
(and flash) updates do not work yet.
|
||||
* avr.c: "boot" memory is a candidate memory region for paged
|
||||
operations, besides "flash" and "eeprom".
|
||||
* avrdude.conf.in: add ATxmega128A1 and ATxmega128A1revD
|
||||
* avrpart.h: add the AVRPART_HAS_PDI flag (used to distinguish
|
||||
ATxmega parts from classic AVRs), the nvm_base part field, and
|
||||
the offset field for a memory region.
|
||||
* config_gram.y: add "has_pdi", "nvm_base", and "offset"
|
||||
* lexer.l: (Ditto.)
|
||||
* main.c: disable auto_erase for ATxmega parts
|
||||
* stk500v2.c: implement the XPROG functionality, and divert to
|
||||
this for ATxmega parts
|
||||
* avrdude.1: Document the changes.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-07-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Fix a bunch of warnings.
|
||||
* avr910.c (avr910_paged_load): possible unitialized use of
|
||||
rd_size
|
||||
* jtagmkI.c (jtagmkI_initialize): pointer signedness mixup
|
||||
* jtagmkII.c (jtagmkII_print_parms1): propagate const'ness
|
||||
of parameter
|
||||
* usbasp.c (usbasp_transmit): pointer signedness mixup
|
||||
* ser_avrdoper.c (usbGetReport): remove useless pointer deref
|
||||
|
||||
2008-07-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Ville Voipio:
|
||||
patch #6501: New autotools support for avrdude
|
||||
* Makefile.am: add @WINDOWS_DIRS@ to SUBDIR
|
||||
* bootstrap: allow for autconf-2.61 and automake-1.10, too
|
||||
* configure.ac: fix @WINDOWS_DIRS@ recursion, replace
|
||||
AC_PROG_CC by AM_PROG_CC_C_O, for esoteric reasons
|
||||
|
||||
2008-06-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Janos Sallai <janos.sallai@vanderbilt.edu>:
|
||||
patch #6074: added support for crossbow's MIB510 programmer
|
||||
* avrdude.conf.in: Add entry for mib510.
|
||||
* stk500.c: Add special hooks to handle the MIB510 programmer.
|
||||
It mostly talks STK500v1 protocol but has a special hello and
|
||||
goodbye sequence, and uses a fixed block size of 256 bytes.
|
||||
* doc/avrdude.texi: Document support for mib510.
|
||||
|
||||
2008-06-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Klaus Leidinger <klaus@mikrocontroller-projekte.de>:
|
||||
* main.c: Realign verbose messages.
|
||||
* avrpart.c: (Ditto.)
|
||||
* avr910.c: Print the device code selected in verbose mode.
|
||||
* butterfly.c: (Ditto.)
|
||||
|
||||
2008-06-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Klaus Leidinger <klaus@mikrocontroller-projekte.de>:
|
||||
Add check for buffermode feature, and use it if present. Can be
|
||||
turned off using -x no_blockmode.
|
||||
* avr910.c: Implement buffermode test and usage.
|
||||
* avrdude.1: Document -x no_blockmode.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-03-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_libusb.c: #undef interface for Win32
|
||||
|
||||
2008-03-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avr910.c: Add support for the -x devcode option.
|
||||
* avrdude.1: Document -x devcode for avr910.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2008-03-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Add initial support for the Atmel STK600, for
|
||||
"classic" AVRs (AT90, ATtiny, ATmega) in both,
|
||||
ISP and high-voltage programming modes.
|
||||
* Makefile.am: Add -lm.
|
||||
* avrdude.conf.in: Add stk600, stk600pp, and stk600hvsp.
|
||||
* config_gram.y: Add support for the stk600* keywords.
|
||||
* lexer.l: (Ditto.)
|
||||
* pgm.h: Add the "chan" parameter to set_varef().
|
||||
* stk500.c: (Ditto.)
|
||||
* serial.h: Add USB endpoint support to struct filedescriptor.
|
||||
* stk500v2.c: Implement the meat of the STK600 support.
|
||||
* stk500v2.h: Add new prototypes for stk600*() programmers.
|
||||
* stk500v2_private.h: Add new constants used in the STK600.
|
||||
* term.c: Add AREF channel support.
|
||||
* usb_libusb.c: Automatically determine the correct write
|
||||
endpoint ID, the STK600 uses 0x83 while all other tools use
|
||||
0x82. Propagate the EP to use through struct filedescriptor.
|
||||
* usbdevs.h: Add the STK600 USB product ID.
|
||||
* tools/get-stk600-cards.xsl: XSL transformation for
|
||||
targetboards.xml to obtain the list of socket and routing
|
||||
card IDs, to be used in stk500v2.c (for displaying the
|
||||
names).
|
||||
* tools/get-stk600-devices.xsl: XSL transformation for
|
||||
targetboards.xml to obtain the table of socket/routing cards
|
||||
and their respective AVR device support for doc/avrdude.texi.
|
||||
* avrdude.1: Document all the STK600 stuff.
|
||||
* doc/avrdude.texi: Ditto. Added a new chapter for
|
||||
Programmer Specific Information.
|
||||
|
||||
2008-01-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk500v2_recv): Make length computation unsigned so
|
||||
it cannot accidentally become negative.
|
||||
|
||||
@@ -1,411 +0,0 @@
|
||||
2009-11-09 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
* fileio.c: ihex2bin did not properly handle files > 64K bytes
|
||||
* usb_libusb.c: re-enabled usb_reset for Macs (no reset causes lots of failures)
|
||||
* avrdude.1: spacing issue for avr32 fixed.
|
||||
|
||||
2009-11-09 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Implemented reset= and speed= extended parameters.
|
||||
* avrdude.1: Document the change.
|
||||
|
||||
2009-11-04 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* configure.ac, Makefile.am: Test if GCC accepts -Wno-pointer-sign
|
||||
|
||||
2009-11-04 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Implemented 'BinMode' support for
|
||||
firmware 2.7 and higher.
|
||||
* avrdude.1: Added info about BusPirate.
|
||||
|
||||
2009-11-03 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* arduino.c: Add on to bug #26703 / patch #6866 - clear DTR/RTS
|
||||
when closing the port.
|
||||
* Makefile.am: Silent warnings about signedness - they're useless
|
||||
and annoying, especially for 'char' vars.
|
||||
|
||||
2009-10-22 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
* usb_libusb.c: disabled usb_reset for Macs (same as FreeBSD)
|
||||
|
||||
2009-10-12 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* main.c: Re-added default to serial port for BusPirate.
|
||||
|
||||
2009-10-12 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
* main.c: removed some avr32 code that was pushed into jtagmkII.c
|
||||
* jtagmkII.c: consolodated the avr32 reset code and avr32_chipreset
|
||||
* avrpart.h: modified AVRPART flags for avr32
|
||||
* lexer.l: added is_avr32 flag - only way to get yacc code to set flag
|
||||
* avrdude.conf.in: updated avr32 section to include "is_avr32" flag
|
||||
|
||||
2009-10-12 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
* config_gram.y: Restored inadvertantly removed buspirate entry
|
||||
* lexer.l: Restored inadvertantly removed buspirate entry
|
||||
|
||||
2009-10-12 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Replace GNU-only %as with %s in sscanf call.
|
||||
* ser_win32.c(ser_set_dtr_rts): Fixed typo in parameter name.
|
||||
* NEWS: Announce BusPirate.
|
||||
|
||||
2009-10-11 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
Support for AVR32
|
||||
|
||||
* AUTHORS: added myself
|
||||
* NEWS: announced AVR32 support
|
||||
* main.c: AVR32 flag tests to avoid several code blocks
|
||||
* fileio.c: mods to ihex read function to handle address offsets and
|
||||
size of avr32
|
||||
* jtagmkI.c: added cast to printf call to remove warning
|
||||
* arduino.c: added header file to bring in prototype for usleep()
|
||||
* config_gram.y: added defines for avr32, new jtag_mkii variant for avr32
|
||||
* jtagmkII_private.h: new jtag_mkii message types defined (used by
|
||||
avr32program)
|
||||
* jtagmkII.h: extern jtagmkII_avr32_initpgm() addition
|
||||
* jtagmkII.c: huge amount of code in support of avr32
|
||||
* avrpart.h: additional flags to AVRPART for avr32
|
||||
* usb_libusb.c: modified verbose test for USB read per-byte messages by
|
||||
by one, so with verbose=3 you get just full messages, 4 gives you bytes
|
||||
too
|
||||
* lexer.l: additions for avr32
|
||||
|
||||
2009-10-10 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
Support for Arduino auto-reset:
|
||||
* serial.h, ser_avrdoper.c, ser_posix.c, ser_win32.c: Added
|
||||
serial_device.set_dtr_rts implementations.
|
||||
* arduino.c, stk500.c, stk500.h: Call serial_set_dtr_rts()
|
||||
to reset Arduino board before program upload.
|
||||
Inspired by patch #6866, resolves bug #26703
|
||||
|
||||
2009-10-08 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Optimised buspirate_cmd() - reading 1kB EEPROM now
|
||||
takes only 14 sec instead of almost 2 mins with the original
|
||||
implementation.
|
||||
|
||||
2009-10-08 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c, buspirate.h: Support for the BusPirate programmer
|
||||
* config_gram.y, avrdude.conf.in, main.c, lexer.l, Makefile.am:
|
||||
Glue for BusPirate.
|
||||
|
||||
2009-08-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_libusb.c (usbdev_close): Repair the logic around the
|
||||
conditional compilation of usb_reset() introduced in r798.
|
||||
|
||||
2009-07-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: We are post-5.8 now.
|
||||
|
||||
2009-07-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Prepare for releasing version 5.8
|
||||
|
||||
2009-07-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Roger Wolff:
|
||||
bug #26527: bug in unicode conversion
|
||||
* ser_avrdoper.c (convertUniToAscii): when encountering a UTF-16
|
||||
character that cannot be converted to ASCII, increment the UTF-16
|
||||
pointer anyway when proceeding.
|
||||
|
||||
2009-07-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkI.c (jtagmkI_send): Replace %zd format by %u since not all
|
||||
implementations do understand the C99 formatting options (sigh).
|
||||
* jtagmkII.c (jtagmkII_send): (Ditto.)
|
||||
* stk500v2.c (stk500v2_recv): (Ditto.)
|
||||
|
||||
2009-07-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #26002: HVPP of EEPROM with AVR Dragon and ATmega8 Fails
|
||||
* avrdude.conf.in (ATmega8): add page size for EEPROM.
|
||||
|
||||
2009-07-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c: Fix a serious memory corruption problem resulting
|
||||
out of the chaining of both, the stk500v2 and the jtagmkII
|
||||
programmers for some programming hardware (JTAG ICE mkII and AVR
|
||||
Dragon running in ISP, HVSP or PP mode), where both programmers
|
||||
have to maintain their private programmer data.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Post-release (is pre-release...)
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Prepare for releasing version 5.7
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Add my name to the copyright output when being verbose.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Shaun Jackman <sjackman@gmail.com>
|
||||
bug #21798: Fix both XSLT scripts
|
||||
* tools/get-dw-params.xsl (format-hex): Add the parameter count.
|
||||
* tools/get-hv-params.xsl (format_cstack): Ditto.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #21922: ATmega163 still not working in version 5.5
|
||||
* avrdude.conf.in (atmega163): fill in stk500v2 parameters, correct
|
||||
some flash programming parameters as well.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22206: avrdude: ser_setspeed(): tcsetattr() failed
|
||||
* ser_posix.c (ser_setspeed): Don't pass TCSAFLUSH to tcsetattr() as
|
||||
it apparently fails to work on Solaris. After reading the
|
||||
documentation again, it seems TCSAFLUSH and TCSANOW are indeed
|
||||
mutually exclusive.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22234: WINDOWS version: HOWTO: Specify Serial Ports Larger than COM9
|
||||
* ser_win32.c (ser_open): prepend \\.\ to any COM port name, so it is
|
||||
safe to be used for COM ports above 9.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #26408: Crash in stk500v2_open()
|
||||
* stk500generic.c: Implement setup and teardown hooks, calling in turn
|
||||
the respective hooks of the stk500v2 implementation.
|
||||
|
||||
2009-07-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #26130: Avrdude doesn't display it's version.
|
||||
* main.c (usage): add a version number display to the default usage
|
||||
message.
|
||||
|
||||
2009-07-01 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #26412: avrdude segfaults when called with a programmer that does not
|
||||
support it
|
||||
* main.c: do not call pgm->perform_osccal() unless it is != 0.
|
||||
|
||||
2009-06-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by Zoltan Laday:
|
||||
patch #6825: xmega problems with JTAGICEmkII
|
||||
* jtagmkII.c: Many fixes for Xmega devices.
|
||||
* jtagmkII_private.h: Add various new constants required for
|
||||
Xmega devices.
|
||||
* avrdude.conf.in: New devices: ATXMEGA64A1, ATXMEGA192A1,
|
||||
ATXMEGA256A1, ATXMEGA64A3, ATXMEGA128A3, ATXMEGA192A3,
|
||||
ATXMEGA256A3, ATXMEGA256A3B, ATXMEGA16A4, ATXMEGA32A4,
|
||||
ATXMEGA64A4, ATXMEGA128A4
|
||||
* avr.c (avr_read, avr_write): Add more names for (Xmega)
|
||||
memory areas that require paged operation.
|
||||
|
||||
2009-06-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk600_xprog_write_byte): Handle writing fuse bytes.
|
||||
|
||||
2009-04-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Carl Hamilton:
|
||||
* update.c (parse_op): correctly \0-terminate buf after filling
|
||||
it, before it is potentially used as the source of a call to
|
||||
strlen or strcpy.
|
||||
|
||||
2009-04-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* doc/avrdude.texi: Merge the -P 0xXXX option description from
|
||||
avrdude.1.
|
||||
|
||||
2009-04-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: declare AM_PROG_CC_C_O to avoid the warning
|
||||
"compiling `config_gram.c' with per-target flags
|
||||
requires `AM_PROG_CC_C_O' in `configure.ac'"
|
||||
|
||||
2009-03-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #25971: "error writing to <stdout>" with multiple -U params.
|
||||
* fileio.c: Do not close the input/output stream when working on an
|
||||
stdio stream.
|
||||
|
||||
2009-02-28 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
Based on patch #6484 commited by Jurgis Brigmanis:
|
||||
* usbasp.c: added software control for ISP speed
|
||||
* usbasp.h: (Ditto.)
|
||||
|
||||
2009-02-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avr910.c (avr910_read_byte_flash): Eliminate a static variable that
|
||||
hasn't been in use for 5 years.
|
||||
|
||||
2009-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Post-release 5.6.
|
||||
|
||||
2009-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Prepare for releasing version 5.6.
|
||||
|
||||
2009-02-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Ed Okerson:
|
||||
* jtagmkII.c (jtagmkII_read_byte): Fix signature reading of
|
||||
Xmega.
|
||||
|
||||
2009-02-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Mikael Hermansson:
|
||||
* avrdude.conf.in (ATxmega256A3): new device.
|
||||
* stk500v2 (stk500v2_initialize): Enable the AVRISPmkII as a
|
||||
PDI-capable device for ATxmega parts.
|
||||
|
||||
2009-02-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Lars Immisch:
|
||||
patch #6750: Arduino support - new programmer-id
|
||||
* arduino.c: New file, inherits stk500.c.
|
||||
* arduino.h: New file.
|
||||
* Makefile.am: Add arduino.c and arduino.h.
|
||||
* config_gram.y: Add arduino keyword.
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.conf.in: (Ditto.)
|
||||
* avrdude.1: Document the new programmer type.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2009-02-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c: Turn all non-const static data into instance data.
|
||||
|
||||
2009-02-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am: Move term.[ch] from the library into the CLI
|
||||
application section, as it is not useful for anything else but
|
||||
the CLI frontend.
|
||||
|
||||
2009-02-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega1284P): new device.
|
||||
|
||||
2009-02-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
More fixes for Solaris, including fixes for the Sunpro compiler:
|
||||
* avr.h: Remove stray semicolon.
|
||||
* configure.ac: Add check for predefined types uint_t and ulong_t.
|
||||
* confwin.c: Include "avrdude.h" on top to avoid empty translation
|
||||
unit warning.
|
||||
* ppwin.c: (Ditto.)
|
||||
* ser_win32.c: (Ditto.)
|
||||
* serbb_win32.c: (Ditto.)
|
||||
* jtagmkII.c (jtagmkII_recv): remove unreachable "return".
|
||||
* stk500.c (stk500_initialize): (Ditto.)
|
||||
* par.c: Test for both, __sun__ and __sun to see whether we are
|
||||
being compiled on Solaris.
|
||||
* ppi.c: (Ditto.)
|
||||
* stk500v2.c: Implement the DEBUG and DEBUGRECV macros in a way
|
||||
that is compatible with the ISO C99 standard.
|
||||
* usbtiny.c: Only typedef uint_t and ulong_t if they have not
|
||||
been found already by the autoconf checks.
|
||||
|
||||
2009-02-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #22204: Solaris10/11 Undefiniertes Symbol gethostbyname socket
|
||||
connect
|
||||
* configure.ac: Add checks for gethostent() and socket().
|
||||
While being here, remove some old cruft left from ancient days.
|
||||
|
||||
2009-02-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* lexer.l: Bump the %p size so AT&T lex will continue to work.
|
||||
|
||||
2009-02-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
(Partially) submitted by John Voltz:
|
||||
bug #20004: AVRDUDE update (-U) operations do not close files
|
||||
* fileio.c (fmt_autodetect, fileio): fclose() files.
|
||||
|
||||
2009-02-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbtiny.c: Replace all but one (very unlikely to trigger) exit(1)
|
||||
by return -1.
|
||||
|
||||
2009-02-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Dick Streefland:
|
||||
patch #6749: make reading from the USBtinyISP programmer more robust
|
||||
* usbtiny.c: Add code to retry failed communication attempts.
|
||||
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Nick Hibma:
|
||||
bug #22271: usb_reset in usb_libusb.c not necessary in FreeBSD 6.x
|
||||
* usb_libusb.c (usbdev_close): Do not call usb_reset() on FreeBSD.
|
||||
It is not necessary there.
|
||||
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Andrew O. Shadoura:
|
||||
bug #25156: add direct SPI transfer mode
|
||||
* bitbang.c: Implement direct SPI transfers.
|
||||
* bitbang.h: (Ditto.)
|
||||
* par.c: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* term.c: Add the "spi" and "pgm" commands.
|
||||
* avrdude.1: Document the changes.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Limor ("Lady Ada"):
|
||||
bug #24749: add support for '328p
|
||||
* avrdude.conf.in (ATmega328P): new device support.
|
||||
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by "Womo":
|
||||
bug #25241: AT90USB162, AT90USB82 device support patch for avrdude-5.5
|
||||
(also: bug #21745: AT90USBxx2 support)
|
||||
* avrdude.conf.in (AT90USB162, AT90USB82): new device support.
|
||||
|
||||
2009-02-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Evangelos Arkalis:
|
||||
patch #6069: Atmel AT89ISP Cable
|
||||
* avrdude.conf.in (89isp): new programmer support.
|
||||
|
||||
2009-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Bob Paddock:
|
||||
patch #6748: ATTiny88 Config
|
||||
* avrdude.conf.in (ATtiny88): new device support.
|
||||
|
||||
2009-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Mark Litwack:
|
||||
patch #6261: avrdude won't use dragon/debugwire to write a file
|
||||
to eeprom
|
||||
* jtagmkII.c (jtagmkII_paged_write): when in debugWire mode,
|
||||
implement a paged write to EEPROM as a series of byte writes.
|
||||
|
||||
2009-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Janos Sallai:
|
||||
patch #6542: paged_load fails on the MIB510 programming board
|
||||
* stk500.c: Add a workaround for the different signon sequence on
|
||||
MIB510 programmers.
|
||||
|
||||
2009-02-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Add the ATmega128RFA1.
|
||||
* avrdude.1: document the addition of ATmega128RFA1.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
@@ -1,354 +0,0 @@
|
||||
2010-12-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega128RFA1): Bump two timing values in order to
|
||||
improve ISP programming stability, in particular with the STK600.
|
||||
|
||||
2010-12-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk500v2_command): Detect warning status codes.
|
||||
|
||||
2010-10-22 Nils Springob <nils@nicai-systems.de>
|
||||
|
||||
* serial.h: serial_open() calls will now return -1 on error (no call to exit())
|
||||
* buspirate.c: (Dito.)
|
||||
* jtagmkII.c: (Dito.)
|
||||
* butterfly.c: (Dito.)
|
||||
* jtagmkI.c: (Dito.)
|
||||
* arduino.c: (Dito.)
|
||||
* avr910.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
|
||||
2010-07-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #30566: MinGW + Ubuntu 9.04
|
||||
* stk500v2.c (stk500v2_open): use same condition to refer to the AVR
|
||||
Doper support as used in the definition in ser_avrdoper.c.
|
||||
(Thanks to Christian Starkjohann for the analysis of the problem.)
|
||||
|
||||
2010-07-19 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Added compatibility with BusPirate "NewUI" firmware 5.x
|
||||
(contributed by Kari Knuuttila)
|
||||
|
||||
2010-07-12 Nils Springob <nils@nicai-systems.de>
|
||||
|
||||
* avrdude.conf.in (atmega88p): New device.
|
||||
|
||||
2010-06-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29913: 246 Byte Bug - AVRdude crashes
|
||||
doc/avrdude.texi (Troubleshooting): Mention the libusb 0.1 API
|
||||
wrapper issue that is present in some Linux versions.
|
||||
|
||||
2010-03-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29263: Can't build avrdude on windows using latest cygwin 1.7.1
|
||||
* doc/avrdude.texi: Remove the recommendation for building
|
||||
Win32 binaries under Cygwin; mention MinGW as an alternative
|
||||
environment.
|
||||
|
||||
2010-03-08 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* ser_posix.c(ser_set_dtr_rts): Fixed DTR on/off to make
|
||||
Arduino auto-reset work. (bug #29108, patch #7100)
|
||||
|
||||
2010-03-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* buspirate.c: Replace printf() by fprintf(stderr)
|
||||
* safemode.c: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
|
||||
2010-01-22 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Cleanup Cygwin builds.
|
||||
* windows/Makefile.am (loaddrv_LDFLAGS): remove, the -mno-cygwin
|
||||
flag is supposed to be set in CFLAGS by ./configure
|
||||
* configure.ac: add a check for the presence of usleep(), add a
|
||||
check whether the linker accepts -static
|
||||
* avrdude.h: protect prototype for usleep by !defined(HAVE_USLEEP)
|
||||
* ppwin.c (usleep): protect by !defined(HAVE_USLEEP)
|
||||
* main.c: silence "array subscript of type char" compiler warnings
|
||||
by casting all arguments to tolower()/toupper() and isspace()/
|
||||
isdigit()/ispunct() to "int"
|
||||
* butterfly.c: (Dito.)
|
||||
* avr910.c: (Dito.)
|
||||
|
||||
2010-01-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump for post-5.10.
|
||||
|
||||
2010-01-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Released version 5.10.
|
||||
|
||||
2010-01-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #28677: Cygwin's GCC no longer supports -mno-cygwin option
|
||||
* configure.ac: For Win32 environments, add a check whether the
|
||||
compiler understands the -mno-cygwin option. If not, don't use
|
||||
it but suggest using a different compiler.
|
||||
|
||||
2010-01-18 David Hoerl <dhoerl@mac.com>
|
||||
|
||||
bug #28660: Problem with loading intel hex rom files that exceed
|
||||
0x10000 bytes
|
||||
* fileio.c: Fix two byte shifts.
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Michael biebl:
|
||||
* configure.ac: Fix FreeBSD default serial port name.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: If entering JTAG mode fails with a bad JTAG ID
|
||||
message, retry with external reset applied (in case the target
|
||||
is in sleep mode or has asserted the JTD bit).
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Aurelien Jarno:
|
||||
* configure.ac: Fix build for GNU/kFreeBSD.
|
||||
* ppi.c: (Dito.)
|
||||
* par.c: (Dito.)
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump version for post-5.8.
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump version for release 5.8.
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Soren Jorvang:
|
||||
bug #28611: -i delay not being applied to all serial port
|
||||
bit banging state transitions
|
||||
* serbb_win32.c: Apply ispdelay everywhere.
|
||||
* serbb_posix.c: (Dito.)
|
||||
|
||||
2010-01-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2_private.h: Implement TPI mode for AVRISPmkII/STK600
|
||||
* config_gram.y: (Dito.)
|
||||
* avrpart.h: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* main.c: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* avrdude.conf.in: Add ATtiny4/5/9/10
|
||||
* avrdude.1: Document TPI and new device support.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2010-01-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by clint fisher:
|
||||
patch #7038: Adding Atmega32U4 Device to avrdude.conf.in
|
||||
* avrdude.conf.in (atmega32u4): New device.
|
||||
* avrdude.1: Document the new device support.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2010-01-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Thomas Pircher:
|
||||
patch #6927: Documentation patches
|
||||
* doc/avrdude.texi: Fix various typos, and remove the last
|
||||
remnants of obsoleted options -i/-o/-m/-f.
|
||||
* avrdude.1: Merge typo fixes from avrdude.texi where
|
||||
applicable.
|
||||
|
||||
2010-01-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.1: Update documentation to match the reality (device
|
||||
support, memory areas).
|
||||
* doc/avrdude.texi: Update documentation to match the
|
||||
reality (device support, programmer support, memory areas).
|
||||
Merge buspirate-specific comments from avrdude.1.
|
||||
* jtagmkII.c: Add some firmware feature checks.
|
||||
|
||||
2010-01-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: Implement PDI mode support for the JTAG ICE mkII
|
||||
and the AVR Dragon.
|
||||
* jtagmkII.h: (Dito.)
|
||||
* config_gram.y: (Dito.)
|
||||
* jtagmkII_private.h: (Dito.)
|
||||
* avrdude.conf.in: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
|
||||
2010-01-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c: Update STK600 routing and socket card data from XML
|
||||
file.
|
||||
|
||||
2010-01-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c: Cleanup the open/close handling to avoid accessing
|
||||
unallocated memory (in the atexit handler) in case of bailing out.
|
||||
* main.c: (Ditto.)
|
||||
|
||||
2010-01-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: Stylistic changes: move #defines out into
|
||||
jtagmkII_private.h, drop all #if 0 blocks, fold overly long lines,
|
||||
move the *_initpgm() functions to the end of the file; while being
|
||||
here, remove all trailing whitespace.
|
||||
* jtagmkII_private.h: move AVR32 #defines here.
|
||||
|
||||
2010-01-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* bootstrap: autoconf 2.62 works well.
|
||||
|
||||
2010-01-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Various fixes for Xmega devices.
|
||||
* avrdude.conf.in: Correctly declare EEPROM page sizes for
|
||||
all Xmega devices (0x20 instead of 0x100).
|
||||
* avr.c: If a memory region has a page size declared, try
|
||||
using the paged IO routines regardless of the target memory
|
||||
name. Xmega EEPROM requires to be written in paged mode.
|
||||
Correctly use a long (rather than unsigned long) variable to
|
||||
evaluate the success status of the paged mode write attempt.
|
||||
* stk500v2.c: Don't apply TIF space offsets twice (bug #27995:
|
||||
AVRDUDE 5.8svn fails to program and read XMEGA); use
|
||||
stk500v2_loadaddr() prior to paged mode (EEPROM and flash) writes,
|
||||
otherwise programming of flash areas will fail; while being there,
|
||||
check the return value of stk500v2_loadaddr() everywhere; use the
|
||||
correct write/erase mode bits (same as AVR Studio does).
|
||||
|
||||
2010-01-12 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: Initialise firmware version to v0.0
|
||||
prior to parsing the buspirate banner.
|
||||
|
||||
2010-01-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Clean-up the Xmega erase functions.
|
||||
* jtagmkII_private.h: Add CMND_XMEGA_ERASE as well as
|
||||
the various XMEGA_ERASE_* definitions (from updated
|
||||
appnote AVR067)
|
||||
* jtagmkII.c (jtagmkII_chip_erase): Correctly implement Xmega chip
|
||||
erase based on CMND_XMEGA_ERASE. After erasing an Xmega part, do
|
||||
*not* reinitialize the world, as a subsequent programming
|
||||
operation will fail (for unknown reasons). Actually, this was
|
||||
really only required for ancient AVRs, but doesn't hurt on mega
|
||||
and tiny devices.
|
||||
* jtagmkII.c (jtagmkII_pre_write): Remove, this turned out
|
||||
to be just a chip erase.
|
||||
* jtagmkII.c (jtagmkII_program_disable): Don't try reading
|
||||
"hfuse" for Xmega parts; they don't have it.
|
||||
* main.c (main): Re-enable auto-erase. It's been done
|
||||
before (as "jtagmkII_pre_write") in jtagmkII_paged_write()
|
||||
anyway. Xmega boot and application flash areas should be
|
||||
handled separately in the future, so auto_erase can only
|
||||
affect the area just being programmed.
|
||||
|
||||
2010-01-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c (main): disable safemode for Xmega parts.
|
||||
|
||||
2010-01-12 Michal Ludvig <mludvig@logix.net.nz>
|
||||
|
||||
* buspirate.c: If the BusPirate doesn't respond
|
||||
to a standard a reset command assume it was in binmode
|
||||
and attempt to exit to text mode first.
|
||||
|
||||
2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* bitbang.c: Fix Win32 build error: move freq up to the file
|
||||
level.
|
||||
* buspirate.c: Fix Win32 build warning: include <malloc.h> to
|
||||
to get a declaration for alloca().
|
||||
|
||||
2010-01-08 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
bug #28520: Programming with USBasp with low clock speed fails
|
||||
* usbasp.c: Change blocksize depending on sck frequency to
|
||||
avoid usb transmition timeouts.
|
||||
|
||||
2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #27505: serbb_posix does not cope with inverted pins
|
||||
* serbb_posix (serbb_highpulsepin): apply PIN_MASK when
|
||||
checking pin numbers.
|
||||
* serbb_win32 (serbb_highpulsepin): (Dito.)
|
||||
|
||||
2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #28516: Linux/Dragon: Error message on exit
|
||||
* stk500v2.c: Fix the "bad response to GO command:
|
||||
RSP_ILLEGAL_EMULATOR_MODE" message. jtagmkII_close()
|
||||
has been called with the wrong pgm->cookie. Wrap it
|
||||
inside stk500v2_jtagmkII_close(), adjusting the cookie
|
||||
data appropriately.
|
||||
|
||||
2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Doug:
|
||||
patch #7010: Win32 enhanced bitbang_delay
|
||||
* bitbang.c (bitbang_calibrate_delay, bitbang_delay): On Win32,
|
||||
use the high-resolution performance counter rather than the
|
||||
uneducated delay loop guess if it is available on the target
|
||||
hardware.
|
||||
|
||||
2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Gerard:
|
||||
patch #6828: Using arbitrary BAUD rates
|
||||
* ser_posix.c (serial_baud_lookup): Allow non-standard baud
|
||||
rates.
|
||||
* ser_win32.c (serial_baud_lookup): (Dito.)
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Eric Trein:
|
||||
bug #27596: AT90s2333 is not correctly supported in avrdude.conf
|
||||
* avrdude.conf.in (at90s2333): add various STK500v2 parameters.
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Gyorgy Szekely:
|
||||
bug #28458: Buffer line is incorrectly released for PP programmers
|
||||
* par.c (par_close): use par_setmany() rather than par_setpin()
|
||||
for PPI_AVR_BUFF.
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Lukasz Goralczyk:
|
||||
bug #27507: SIGSEGV when using avrdragon (avrdude 5.8)
|
||||
* stk500v2.c (stk500v2_dragon_isp_initpgm): Use
|
||||
stk500v2_jtagmkII_setup/stk500v2_jtagmkII_rather than their
|
||||
jtagII counterparts, to get the private data properly
|
||||
initialized.
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* buspirate.c: Cosmetics: remove UTF-8 dashes, adjust for 8-column
|
||||
hard tabs.
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* buspirate.c: add $ Id $ line.
|
||||
* buspirate.h: add $ Id $ line.
|
||||
|
||||
2010-01-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Fix a few warnings that came up recently (some of them only triggered
|
||||
by recent GCC versions).
|
||||
* config_gram.y (parse_cmdbits): "brkt possibly used uninitialized"
|
||||
(GCC errs here)
|
||||
* jtagmkII.c (jtagmkII_reset32): "status possibly used uninitialized"
|
||||
(I think GCC errs, too)
|
||||
* buspirate.c: "pointers differ in signedness" (mismatch between
|
||||
string processing and the use of "unsigned char" throughought the
|
||||
AVRDUDE API)
|
||||
|
||||
2010-01-01 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c (jtagmkII_smc_init32): replace sleep() by usleep() for
|
||||
win32 compatibility.
|
||||
@@ -1,489 +0,0 @@
|
||||
2011-12-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* avrdude.conf.in: Added is_at90s1200 option to part description
|
||||
* doc/avrdude.texi: Added missing options to part definition
|
||||
* config_gram.y: Fixed resetting of is_at90s1200 and is_avr32 flags
|
||||
|
||||
2011-12-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7693: Fix config file atmel URLs
|
||||
* avrdude.conf.in: Updated URLs
|
||||
* avrpart.h: Updated URLs
|
||||
* doc/avrdude.texi: Updated URLs
|
||||
|
||||
2011-12-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* ser_posix.c (baud_lookup_table): Conditionalize the inclusion of
|
||||
non-standard baud rates (only baud rates up to B38400 are
|
||||
standardized by the Single UNIX Specification).
|
||||
|
||||
2011-12-29 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #34302: Feature request : device configuration with parent classes
|
||||
* config_gram.y: Added part parent rule and allow overwriting existing
|
||||
data at several places
|
||||
* avrdude.conf.in: Added description comment and m328/m328p as example
|
||||
* avrpart.c: avr_dup_mem-functions now copy buf and tags memory block
|
||||
only they are already allocated.
|
||||
* lexer.l: Added parent as valid token
|
||||
|
||||
(not in original patch)
|
||||
* avrpart.c: New function avr_dup_opcode. avr_dup_mem/avr_dup_part-
|
||||
functions now duplicate the opcodes in their op-array to avoid memory leaks.
|
||||
* doc/avrdude.texi: Added description of part parent feature
|
||||
|
||||
2011-12-29 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7687: Autogenerating programmers and parts lists for docs
|
||||
(generating the parts lists, programmers lists follows later)
|
||||
* doc/Makefile.am: Add rule how to create avrdude before generating parts list
|
||||
|
||||
2011-12-29 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7687: Autogenerating programmers and parts lists for docs
|
||||
(generating the parts lists, programmers lists follows later)
|
||||
* doc/avrdude.texi: Add include of generated table of parts
|
||||
* doc/Makefile.am: Add generating of table of parts in parts.texi
|
||||
* doc/parts_comments.txt: Adding file containing part commenz references
|
||||
* avrdude.1: Remove table of parts and mention "-p ?" option
|
||||
* avrpart.c: Use AVR_DESCLEN for strncasecmp at list sorting
|
||||
|
||||
2011-12-22 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* configure.ac: Add writing of definition of confsubst to config.status,
|
||||
so it can run alone, not only called by configure.
|
||||
|
||||
2011-12-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7680: Fixing timeout problem in ser_recv in ser_win32.c
|
||||
* ser_win32.c: Return -1 at timeout in ser_recv().
|
||||
|
||||
2011-12-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* config_gram.y: Fixed another memory leak, when define an operation
|
||||
more than once
|
||||
* avrdude.conf.in: Fixed double definition at ATmega6490
|
||||
|
||||
2011-12-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* config_gram.y: Restructuring and compacting programmer definition
|
||||
part of grammar (in preparation of patch #7688)
|
||||
|
||||
2011-12-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* avrdude.conf.in: Update documentation of programmer definition
|
||||
* doc/avrdude.texi: Update documentation of programmer definition
|
||||
and add list of implemented programmer types
|
||||
|
||||
2011-12-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7667: Minor memory handling fixes
|
||||
* config_gram.y: Added several free_token() calls.
|
||||
|
||||
2011-12-16 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7671: Sorting programmers and parts lists for console output
|
||||
* avrdude.conf.in: change part desc of several parts to common pattern
|
||||
AT(mega|tiny|xmega)[0-9]+[A-Z]* (Upper case AT, lower case in middle)
|
||||
* list.[ch]: added sorting function lsort()
|
||||
* pgm.[ch]: added function sort_programmers()
|
||||
* avrpart.[ch]: added function sort_avrparts()
|
||||
* main.c: use sort functions in list_programmers() and list_parts()
|
||||
* main.c: list functions show config file info only at verbose mode
|
||||
|
||||
2011-10-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Replace "cvs" in version number by "svn".
|
||||
|
||||
2011-10-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #34518: loading intel hex files > 64k using record-type 4
|
||||
(Extended Linear Address Record)
|
||||
fileio.c: Replace the change from r928 (handling of 0x8000000
|
||||
offset in AVR32 files) by a completely different logic that no
|
||||
longer breaks hex files for other devices starting with an
|
||||
offset; also apply a similar change to S-record files, as well
|
||||
as when writing files.
|
||||
fileio.c: (Ditto.)
|
||||
|
||||
2011-09-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrftdi.c: Remove stray printf()s by fprintf(stderr)
|
||||
* usbtiny.c: (Ditto.)
|
||||
|
||||
2011-09-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* main.c: Restrict the cyclecounter readout to those cases where
|
||||
it has been explicitly requested (by -y or -Y), rather than always
|
||||
attempting to read the last EEPROM bytes.
|
||||
|
||||
2011-09-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk600_xprog_paged_load, stk600_xprog_paged_write):
|
||||
Fix regression in the AVRISPmkII/STK600 TPI handling introduced
|
||||
by the USBasp's TPI implementation which added a pagesize even for
|
||||
the minor memory regions of TPI devices. Also fix wrong offset
|
||||
introduced by the memory tagging patch.
|
||||
|
||||
2011-09-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avr.c (avr_read, avr_write): Don't bail out on TPI parts if
|
||||
their programmer doesn't provide a (low-level) cmd_tpi method;
|
||||
instead, fall back to the normal programmer methods which are
|
||||
supposed to handle the situation.
|
||||
This fixes a regression where the recent bitbang-TPI implementation
|
||||
broke TPI handling of STK600/AVRISPmkII.
|
||||
|
||||
2011-09-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Mega-commit to bring in memory tagging.
|
||||
Each memory image byte is now tagged as it's being read from a file.
|
||||
Only bytes read from a file will be written or verified (modulo page
|
||||
granularity requirements).
|
||||
* avrpart.h: Add memory tags.
|
||||
* avrpart.c: Allocate and initialize tag area.
|
||||
* update.h: Drop unused parameter "verify" from do_op().
|
||||
* pgm.h: Add parameter base_addr to the paged_load and paged_write
|
||||
methods, respectively.
|
||||
* avr.h: New parameter to avr_read: second AVRPART to verify against.
|
||||
* fileio.c: Track all memory regions that have been read from an
|
||||
input file by tagging them.
|
||||
* update.c: Call avr_read() with the new parameter list.
|
||||
* main.c: Call avr_initmem() to initialize the memory regions, rather
|
||||
than trying to duplicate an unitialized part, and then let the
|
||||
original part rot away.
|
||||
* avr.c: Implement the heart of the new featureset. For paged memory
|
||||
areas, when writing or verifying, call the paged_write and paged_load
|
||||
methods, respectively, once per page instead of on the entire memory.
|
||||
When writing, only write bytes or pages that have content read from a
|
||||
file. Whe verifying, only read memory bytes or pages where the
|
||||
verification data have been read from a file. Only verify those bytes
|
||||
that have been read from a file.
|
||||
* avrftdi.c: Implement the new API for paged_load and paged_write,
|
||||
respectively.
|
||||
* jtagmkII.c: (Ditto.)
|
||||
* butterfly.c: (Ditto.)
|
||||
* jtagmkI.c: (Ditto.)
|
||||
* avr910.c: (Ditto.)
|
||||
* stk500.c: (Ditto.)
|
||||
* usbasp.c: (Ditto.)
|
||||
* stk500v2.c: (Ditto.)
|
||||
* usbtiny.c: (Ditto.)
|
||||
|
||||
2011-09-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk500v2_command): Treat warnings as errors rather than
|
||||
success.
|
||||
|
||||
2011-08-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #34027: avrdude AT90S1200 Problem (part 3 - documentation)
|
||||
* avrdude.1: Document the programmer type restrictions for AT90S1200
|
||||
devices.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2011-08-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #34027: avrdude AT90S1200 Problem (part 2 - stk500v2 and relatives)
|
||||
* stk500v2.c (stk500v2_initialize): For the AT90S1200, release
|
||||
/RESET for a moment before reinitializing, as this is required by
|
||||
its programming protocol.
|
||||
|
||||
2011-08-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: In AC_CHECK_LIB for libftdi, check for
|
||||
ftdi_usb_get_strings() rathern than ftdi_init(), as this is a more
|
||||
specific thing to search for in order to make sure getting a
|
||||
recent enough libftdi.
|
||||
|
||||
2011-08-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #34027: avrdude AT90S1200 Problem (part 1 - bitbang
|
||||
programmers)
|
||||
* config_gram.y: Introduce new keyword "is_at90s1200".
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.conf.in: Applew new keyword to the AT90S1200 device.
|
||||
* avrpart.h: Introduce new flag AVRPART_IS_AT90S1200, reflecting
|
||||
the is_at90s1200 configuration keyword.
|
||||
* bitbang.c (bitbang_initialize): Replace existing test for
|
||||
AT90S1200 by AVRPART_IS_AT90S1200
|
||||
* avr.c (avr_write_byte_default): Avoid the pre-write reading for
|
||||
the AT90S1200, as this appears to sometimes corrupt the high byte
|
||||
by pre-programming the low byte just written into it.
|
||||
|
||||
2011-08-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump version for post-5.11.
|
||||
|
||||
2011-08-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump version for releasing AVRDUDE 5.11.
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.1: Update the list of supported AVR devices.
|
||||
* doc/avrdude.texi: (Ditto).
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: add -lusb as "other libraries" when checking
|
||||
for libftdi.
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Juergen Weigert:
|
||||
patch #7056: adding support for mikrokopter bootloader to butterfly
|
||||
* butterfly.c: Add some specific logic to handle the
|
||||
mikrokopter.de butterfly bootloader.
|
||||
* butterfly.h: Add one related function declaration.
|
||||
* config_gram.y: Add butterfly_mk keyword.
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.conf.in: Add entry for butterfly_mk.
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Stefan Tomanek:
|
||||
patch #7542: add default_bitclock to configuration files
|
||||
* config.c: Add the new keyword and its handling.
|
||||
* config.h: (Ditto.)
|
||||
* config_gram.y: (Ditto.)
|
||||
* avrdude.conf.in: (Ditto.)
|
||||
* main.c: (Ditto.)
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.1: Document the change.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Brett Hagman:
|
||||
patch #7603: wiring - programmer type for Wiring boards
|
||||
(based on STK500v2)
|
||||
* wiring.c: New file.
|
||||
* wiring.h: (Ditto.)
|
||||
* Makefile.am: Add new files.
|
||||
* stk500v2_private.h: Reorganize so some functions and struct
|
||||
pdata are globally known.
|
||||
* stk500v2.c: (Ditto.)
|
||||
* stk500v2.h: (Ditto.)
|
||||
* lexer.l: Add new programmer keywords.
|
||||
* config_gram.y: (Ditto.)
|
||||
* avrdude.conf.in: Add "wiring" programmer entry.
|
||||
* avrdude.1: Document the new programmer.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
* AUTHORS: Add Brett Hagman.
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by an anonymous contributor on the mailinglist:
|
||||
* avrdude.conf (jtagkey): Add a definition for the Amontec
|
||||
JTAGKey
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Juergen Weigert:
|
||||
bug #22720: avrdude-5.5 ignores buff settings in avrdude.conf
|
||||
(Note that the actual bug the subject is about has been fixed
|
||||
long ago.)
|
||||
* update.c (do_op): fix a diagnostic message
|
||||
* pgm.h: add exit_datahigh field
|
||||
* par.c: set and act upon the exit_datahigh field
|
||||
* avrdude.1: document the new -E options
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #33811: Parallel make fails
|
||||
* Makefile.am (BUILT_SOURCES): Add this macro.
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #33114: Segfault after setting the DWEN fuse with Dragon
|
||||
* jtagII.c (jtagmkII_getsync): Instead of exit()ing from
|
||||
deep within the tree when detecting the "need debugWIRE"
|
||||
situation, properly pass this up as a return code.
|
||||
* jtagII_private.h (JTAGII_GETSYNC_FAIL_GRACEFUL): New constant.
|
||||
* stk500v2.c (stk500v2_jtagmkII_open): Don't tell anything
|
||||
anymore when receiving a JTAGII_GETSYNC_FAIL_GRACEFUL from
|
||||
jtagmkII_getsync(); silently give up (all necessary has been
|
||||
said already).
|
||||
|
||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Reported by Jason Hecker:
|
||||
* usbasp.c (libusb_to_errno): Conditionalize some error codes
|
||||
that apparently are lacking on MinGW.
|
||||
|
||||
2011-08-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Fix warnings.
|
||||
* ser_avrdoper.c: add <stdlib.h> so exit() is declared.
|
||||
* usbtiny.c (usbtiny_open): provide an initializer to a
|
||||
"may be used uninitialized" variable (since GCC could not
|
||||
fully detect the logic behind).
|
||||
|
||||
2011-08-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Add a check for FreeBSD's libusb-1.0
|
||||
compatible library that is found in libusb.a/.so on
|
||||
FreeBSD 8+.
|
||||
|
||||
2011-08-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Doug Springer, based on work by
|
||||
Wolfgang Moser, Ville Voipio, Hannes Weisbach
|
||||
patch #7486: Patch to add FT2232C/D, FT2232H, FT4232H,
|
||||
usbvid, usbpid, usbdev for USB support - Based on #7062
|
||||
* avrftdi.c: New file.
|
||||
* avrftdi.h: (Ditto.)
|
||||
* configure.ac: Add check for libftdi.
|
||||
* config_gram.y: Add AVRFTDI and per-programmer USB string
|
||||
keywords.
|
||||
* lexer.l: (Ditto.)
|
||||
* avrdude.conf.in: Add avrftdi and 2232HIO programmers.
|
||||
* pgm.h: Add USB parameters.
|
||||
* Makefile.am: Add avrftdi.c and avrftdi.h.
|
||||
* AUTHORS: Mention the new authors.
|
||||
* avrdude.1: Document the changes.
|
||||
* doc/avrdude.texi: (Ditto.)
|
||||
|
||||
2011-08-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29585: Fix license
|
||||
* doc/avrdude.texi: Add FDL as an option to the licensing
|
||||
statement, as the savannah administration would like it
|
||||
that way.
|
||||
|
||||
2011-08-23 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Darell Tan:
|
||||
patch #7244: TPI bitbang implementation
|
||||
* bitbang.c: Add TPI bitbang stuff.
|
||||
* bitbang.h: (Ditto.)
|
||||
* avr.c: (Ditto.)
|
||||
* avr.h: (Ditto.)
|
||||
* pgm.c: (Ditto.)
|
||||
* pgm.h: (Ditto.)
|
||||
* serbb_posix.c: Wire bitbang_cmd_tpi into the struct pgm.
|
||||
* serbb_win32.c: (Ditto.)
|
||||
* par.c: (Ditto.)
|
||||
* doc/avrdude.texi: Document the TPI bitbang support.
|
||||
|
||||
2011-08-17 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Grygoriy Fuchedzhy:
|
||||
bug #31779: Add support for addressing usbtinyisp with -P option
|
||||
* usbtiny.c (usbtiny_open): Add logic to distinguish multiple USBtinyISP
|
||||
programmers by their bus:device tuple.
|
||||
* doc/avrdude.texi: Document the new functionality.
|
||||
* avrdude.1: (Ditto.)
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Timon Van Overveldt:
|
||||
bug #30268: Debugwire broken in avrdude-5.10
|
||||
* jtagmkII.c (jtagmkII_initialize): only try setting up a JTAG chain when
|
||||
the programmer is using JTAG.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29636: AVRDude issues invalid CMD_CHECK_TARGET_CONNECTION
|
||||
on the AVRISP-MKII
|
||||
* stk500v2.c (stk500v2_program_enable): Rewrite the logic to
|
||||
explain ISP activation failures.
|
||||
* stk500v2_private.h: Fix the various STATUS_* constants;
|
||||
AVR069 and AVR079 disagreed in their values, even though they
|
||||
are apparently implementing the same logic behind.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29650: Programming timeouts in ATmega128RFA1 are too slow
|
||||
* avrdude.conf.in (ATmega128RFA1): Bump write delay values for flash and
|
||||
EEPROM to 50 ms.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega8515, ATmega8535, ATmega48, ATmega88, ATmega88P,
|
||||
ATtiny88, ATmega168, ATmega168P, ATmega328P): Bump delay value for STK500v2
|
||||
EEPROM write operation to 5, according to the respective XML files.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Darcy Houlahan:
|
||||
bug #29694: error in avrdude.conf for attiny84 eeprom
|
||||
* avrdude.conf.in (ATtiny84, ATtiny85): fix A7 bit in EEPROM write
|
||||
command.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Durant Gilles:
|
||||
* avrdude.conf.in (ATtiny4313): Fix flash addressing bits for manual ISP
|
||||
algorithm.
|
||||
|
||||
2011-08-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Philip:
|
||||
bug #31386: A "BUILD.svn" or similar "how to get started" doc would be helpful
|
||||
* BUILD-FROM-SVN: New file.
|
||||
|
||||
2011-08-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Nic Jones:
|
||||
bug #32539: [Documentation][Patch] Man page is misleading
|
||||
re: Dragon & PDI
|
||||
* doc/avrdude.texi: Update information about PDI connections
|
||||
on AVR Dragon
|
||||
|
||||
2011-08-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbasp.c: Add <stdint.h> so this actually compiles
|
||||
again.
|
||||
|
||||
2011-08-12 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Contributed by tixiv@gmx.net:
|
||||
bug #33345: File auto detection as binary doesn't open
|
||||
file in binary mode on Windows
|
||||
* fileio.c: Move the decision about opening files in
|
||||
binary mode until before the fopen() call.
|
||||
|
||||
2011-06-16 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
* avrdude.conf.in: Fix part id of ATtiny9.
|
||||
|
||||
2011-05-28 Thomas Fischl <tfischl@gmx.de>
|
||||
|
||||
Based on patch #7440 commited by Slawomir Fraś:
|
||||
* usbasp.c: added TPI support for USBasp
|
||||
* usbasp.h: (Ditto.)
|
||||
|
||||
2011-05-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Add support for ATmega168P.
|
||||
|
||||
2011-05-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Fix abbreviated name for ATmega324PA.
|
||||
|
||||
2011-05-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Lech Perczak:
|
||||
bug #30946: Added support for ATmega8/16/32U2
|
||||
* avrdude.conf.in: Add ATmega8/16/32U2 entries.
|
||||
|
||||
2011-05-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by David A Lyons:
|
||||
patch #7393: Adding ATtiny4313 Device to avrdude.conf.in
|
||||
* avrdude.conf.in: Add ATtiny4313 data.
|
||||
|
||||
2011-05-11 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usb_libusb.c: Bump timeout values to allow for slow clock
|
||||
speeds.
|
||||
* jtagmkII.c: (Ditto.)
|
||||
|
||||
2011-03-04 Eric B. Weddington <eric.weddington@atmel.com>
|
||||
|
||||
Thanks to Vitaly Chernookiy for the patch.
|
||||
* avrdude.conf.in: Add support for atmega324pa.
|
||||
* ChangeLog-2010: New file, rotate ChangeLog for new year.
|
||||
@@ -1,729 +0,0 @@
|
||||
2012-12-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbdefs.h (USBDEV_BULK_EP_WRITE_STK600)
|
||||
(USBDEV_BULK_EP_READ_STK600): new define values
|
||||
* stk500v2.c (stk600_open): use the STK600 EP values,
|
||||
as they are different from AVRISPmkII
|
||||
|
||||
2012-12-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #37942: Latest SVN can't program in dragon_jtag mode
|
||||
* jtagmkII.c (jtagmkII_initialize): For Xmega devices, and
|
||||
firmware >= 7.x, don't trigger a RESET, in order to work around a
|
||||
firmware bug that appears to be present in at least firmware 7.24
|
||||
for the Dragon.
|
||||
|
||||
2012-12-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* config_gram.y: Implement the "ocdrev" keyword
|
||||
* avrpart.c: (Dito)
|
||||
* avrpart.h: (Dito)
|
||||
* lexer.l: (Dito)
|
||||
* avrdude.conf.in: Add "ocdrev" key/value pairs, based
|
||||
on the AS6 XML file information.
|
||||
* jtag3.c: Use the ocdrev in the parameter block.
|
||||
|
||||
2012-12-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: Make jtag3_command() public
|
||||
* jtag3.h: (Dito.)
|
||||
* jtag3_private.h: Add two new commands
|
||||
* stk500v2.c: Implement the "MonCon disable" hack that
|
||||
allows temporarily falling back to ISP when trying to
|
||||
talk to a part that has debugWIRE enabled
|
||||
|
||||
2012-12-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* pickit2.c: reordered #includes for non-usb configuration
|
||||
|
||||
2012-12-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: Enable interactive adjustment of the various
|
||||
clock frequencies (JTAG Xmega, JTAG megaAVR, PDI Xmega)
|
||||
through the set_sck_period() callback.
|
||||
|
||||
2012-12-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: Remove unused code that was left over from
|
||||
cloning the jtagmkII.c implementation
|
||||
|
||||
2012-12-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* pgm_type.c: Add "jtagice3_isp" programmer hook
|
||||
* avrdude.conf.in: Add "jtag3isp" programmer
|
||||
* jtag3.c: jtag3_setparm() is now public
|
||||
* jtag3.h: (Dito)
|
||||
* stk500v2_private.h: Command 0x1D is CMD_SPI_MULTI only
|
||||
for STK500v2, AVRISPmkII, and JTAGICEmkII; for JTAGICE3,
|
||||
it's CMD_SET_SCK now; also add CMD_GET_SCK
|
||||
* avrpart.c (avr_get_output_index): New function
|
||||
* avrpart.h: (Dito)
|
||||
* stk500v2.c: Implement the pasthrough programmer glue logic
|
||||
for JTAGICE3 in ISP mode
|
||||
* stk500v2.h: (Dito)
|
||||
* avrdude.1: Document the JTAGICE3 support.
|
||||
|
||||
2012-11-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c (jtag3_read_byte, jtag3_write_byte): Remove the
|
||||
m->offset from addr, JTAGICE3 doesn't need it anymore (similar
|
||||
to JTAGICEmkII with 7+ firmware)
|
||||
* jtag3.c (jtag3_read_byte): Allow for full-page reads of
|
||||
EEPROM also for Xmega and debugWIRE, allow for signature
|
||||
read in debugWIRE
|
||||
|
||||
2012-11-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3_private.h: Add two more error detail codes I stumbled
|
||||
across during development
|
||||
* jtag3.c: (Dito.)
|
||||
* usb_libusb.c: Reduce timeouts from 100 to 10 s, still long
|
||||
enough, but not getting cold feet when something goes wrong.
|
||||
|
||||
2012-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: Handle events returned by the ICE
|
||||
* usbdevs.h: Add defines that mark an event in return
|
||||
from usb_recv_frame().
|
||||
* usb_libusb.c: (Dito.)
|
||||
|
||||
2012-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in: Remove "has_jtag" from Xmega A4 and D4
|
||||
devices, as they only have PDI.
|
||||
* jtag3.c (jtag3_page_erase): Actually implement this.
|
||||
|
||||
2012-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #37265: wrong page sizes for XMega64xx in avrdude.conf
|
||||
* avrdude.conf.in: Fix page sizes for all Xmega devices,
|
||||
by cross-checking against Atmel Studio's device XML files
|
||||
|
||||
2012-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtag3.c: Fill in the missing pieces for Xmega support (both,
|
||||
PDI and JTAG).
|
||||
* jtagmkII.c (jtagmkII_set_xmega_params): Use "fuse1" rather
|
||||
than "fuse0" memory space to fill in the NVM offset from, as
|
||||
there is no "fuse0" on some Xmega devices.
|
||||
|
||||
2012-11-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega256RFR2, ATmega128RFR2, ATmega64RFR2):
|
||||
New devices
|
||||
|
||||
2012-11-28 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
First support for Atmel JTAGICE3. Guessed from USB sniffer
|
||||
traces made by Knut Schwichtenberg, and by similarity to
|
||||
JTAGICEmkII.
|
||||
Still quite incomplete, just megaAVR/JTAG is done by now.
|
||||
* jtag3.c: New file.
|
||||
* jtag3.h: (Dito.)
|
||||
* jtag3_private.h: (Dito.)
|
||||
* pgm_type.c: Add new programmers
|
||||
* avrdude.conf.in: (Dito.)
|
||||
* usbdevs.h: Add new parameters
|
||||
* Makefile.am: Add new files
|
||||
* usb_libusb.c: Handle separate event endpoint, and larger
|
||||
(USB 2.0) packet sizes
|
||||
|
||||
2012-11-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c: Change all the USB details (endpoint numbers,
|
||||
max transfer size etc.) to a per-programmer adjustable value.
|
||||
* serial.h: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* usbdevs.h: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
|
||||
2012-11-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* buspirate.c: Replace outdated FSF postal address by a reference to
|
||||
the GPL info on their website.
|
||||
* jtagmkII.c: (Dito.)
|
||||
* avrftdi.c: (Dito.)
|
||||
* wiring.c: (Dito.)
|
||||
* linux_ppdev.h: (Dito.)
|
||||
* serbb.h: (Dito.)
|
||||
* usbtiny.h: (Dito.)
|
||||
* confwin.c: (Dito.)
|
||||
* buspirate.h: (Dito.)
|
||||
* avrftdi.h: (Dito.)
|
||||
* wiring.h: (Dito.)
|
||||
* jtagmkII.h: (Dito.)
|
||||
* pickit2.c: (Dito.)
|
||||
* config.c: (Dito.)
|
||||
* term.c: (Dito.)
|
||||
* confwin.h: (Dito.)
|
||||
* avrdude.1: (Dito.)
|
||||
* windows/Makefile.am: (Dito.)
|
||||
* config.h: (Dito.)
|
||||
* pickit2.h: (Dito.)
|
||||
* term.h: (Dito.)
|
||||
* tools/get-hv-params.xsl: (Dito.)
|
||||
* tools/get-stk600-cards.xsl: (Dito.)
|
||||
* tools/get-stk600-devices.xsl: (Dito.)
|
||||
* tools/get-dw-params.xsl: (Dito.)
|
||||
* butterfly.c: (Dito.)
|
||||
* configure.ac: (Dito.)
|
||||
* doc/Makefile.am: (Dito.)
|
||||
* pgm_type.c: (Dito.)
|
||||
* butterfly.h: (Dito.)
|
||||
* jtagmkI.c: (Dito.)
|
||||
* ft245r.c: (Dito.)
|
||||
* COPYING: (Dito.)
|
||||
* pgm_type.h: (Dito.)
|
||||
* jtagmkI.h: (Dito.)
|
||||
* pindefs.h: (Dito.)
|
||||
* config_gram.y: (Dito.)
|
||||
* arduino.c: (Dito.)
|
||||
* arduino.h: (Dito.)
|
||||
* ser_win32.c: (Dito.)
|
||||
* serbb_win32.c: (Dito.)
|
||||
* avr910.c: (Dito.)
|
||||
* stk500.c: (Dito.)
|
||||
* freebsd_ppi.h: (Dito.)
|
||||
* avr910.h: (Dito.)
|
||||
* solaris_ecpp.h: (Dito.)
|
||||
* stk500.h: (Dito.)
|
||||
* jtagmkII_private.h: (Dito.)
|
||||
* avrdude.h: (Dito.)
|
||||
* bitbang.c: (Dito.)
|
||||
* bitbang.h: (Dito.)
|
||||
* avrpart.c: (Dito.)
|
||||
* safemode.c: (Dito.)
|
||||
* stk500generic.c: (Dito.)
|
||||
* serial.h: (Dito.)
|
||||
* avrpart.h: (Dito.)
|
||||
* jtagmkI_private.h: (Dito.)
|
||||
* ppi.c: (Dito.)
|
||||
* avr.c: (Dito.)
|
||||
* safemode.h: (Dito.)
|
||||
* stk500generic.h: (Dito.)
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* avr.h: (Dito.)
|
||||
* ppi.h: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
* lists.c: (Dito.)
|
||||
* stk500v2.c: (Dito.)
|
||||
* my_ddk_hidsdi.h: (Dito.)
|
||||
* tpi.h: (Dito.)
|
||||
* usbasp.h: (Dito.)
|
||||
* lists.h: (Dito.)
|
||||
* stk500v2.h: (Dito.)
|
||||
* ppiwin.c: (Dito.)
|
||||
* fileio.c: (Dito.)
|
||||
* ser_posix.c: (Dito.)
|
||||
* fileio.h: (Dito.)
|
||||
* serbb_posix.c: (Dito.)
|
||||
* usbdevs.h: (Dito.)
|
||||
* par.c: (Dito.)
|
||||
* update.c: (Dito.)
|
||||
* pgm.c: (Dito.)
|
||||
* main.c: (Dito.)
|
||||
* par.h: (Dito.)
|
||||
* update.h: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* Makefile.am: (Dito.)
|
||||
* pgm.h: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
|
||||
2012-11-13 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #35186 inverting pins with "~" doesn't work for pin lists (i.e. vcc)
|
||||
bug #37727 Add support for LM3S811 dev board as a programmer
|
||||
* lexer.l,config_gram.y: accepting inverted pins at pin lists
|
||||
syntax: ~num or ~(num,num,...)
|
||||
* par.c: par_set_many_bits is now usable with inverted pins
|
||||
* avrftdi.c: fixed wrong index in ftdi_pin_name
|
||||
* avrdude.conf.in: added programmer lm3s811
|
||||
|
||||
2012-11-04 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* lexer.l,config_gram.y,config.[hc]: changed reading of numbers to integers
|
||||
except of default_bitclock which is the only real number.
|
||||
No signs are allowed as negative values do not make sense for current
|
||||
config values.
|
||||
* buspirate.c: include own header file buspirate.h
|
||||
* doc/.cvsignore: add programmers.texi to ignore list
|
||||
|
||||
2012-09-06 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* doc/Makefile.am: add EXTRA_DIST, replace $(srcdir) by
|
||||
$(builddir) for generated files, so "make distcheck"
|
||||
works again
|
||||
|
||||
2012-09-05 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* doc/Makefile.am: add $(srcdir) to name of generated files, so BSD make
|
||||
find the files ( GNU make sees no difference if the
|
||||
file is called version.texi or ./version.texi )
|
||||
|
||||
2012-08-15 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7184 Support for PICKit2 programmer
|
||||
* Makefile.am: add pickit2 files
|
||||
* pickit2.[ch]: new programmer implementation
|
||||
* pgm_type.c: add pickit to list
|
||||
* avrdude.1: documentation for pickit2
|
||||
* doc/avrdude.texi: documentation for pickit2
|
||||
* avrdude.conf.in: add pickit2 programmer entry
|
||||
|
||||
2012-08-15 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #30559 Ft232 bit-bang support, see comment #30
|
||||
* ft245r.c: added semaphore workaround for MacOS X,
|
||||
added pthread_testcancel in reader thread
|
||||
|
||||
* configure.ac: added check for TYPE_232H in libftdi (not in libftdi < 0.20)
|
||||
* avrftdi.c: do not use TYPE_232H if not declared
|
||||
|
||||
2012-08-13 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrftdi.c: fixes pin_limit for different FTDI devices (there was a mixup
|
||||
between 2232C and 2232H)
|
||||
|
||||
2012-07-29 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrftdi.c: bugfixes (synchronisation) and maintenance (paged programming,
|
||||
nicer output, separation of parameter checking and actual code)
|
||||
|
||||
2012-07-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c (jtagmkII_memtype): return MTYPE_FLASH rather than
|
||||
MTYPE_SPM for non-Xmega flash regions
|
||||
|
||||
2012-07-20 Hannes Weisbach <hannes_weisbach@gmx.net>
|
||||
|
||||
* avrpart.c, avrpart.h: adds avr_pin_name()
|
||||
|
||||
2012-07-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: check for libelf.h also in libelf/
|
||||
* fileio.c: include <libelf/libelf.h> if configure found this
|
||||
to be the case
|
||||
|
||||
2012-06-13 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* configure.ac: Check for presence of <pthread.h>
|
||||
* ft245r.c: Depend on HAVE_PTHREAD_H
|
||||
* Makefile.am: Add -lpthread if needed.
|
||||
|
||||
2012-06-07 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* usbtiny.c (usbtiny_paged_load, usbtiny_paged_write):
|
||||
fix breakage introduced by the recent page handling reorg;
|
||||
it used to cause an infinite loop
|
||||
|
||||
2012-05-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Xmega page erase implementation for XPROG (AVRISPmkII, STK600)
|
||||
* stk500v2.c (stk600_xprog_page_erase): New function.
|
||||
|
||||
2012-05-04 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Xmega page erase implementation for JTAGICEmkII
|
||||
* jtagmkII.c: Handle flash pages sizes > 256 bytes, implement
|
||||
page_erase() method
|
||||
* avrdude.conf.in: Change flash pagesize for all Xmega devices
|
||||
to 512 bytes
|
||||
* avr.c: Implement auto_erase, using page_erase if available
|
||||
* avr.h: Remove unused parameters from avr_read(), replace
|
||||
unused parameter in avr_write)() by auto_erase
|
||||
* stk500v2.c: Handle flash page sizes > 256 bytes
|
||||
* update.c (do_op): Handle new updateflags parameter
|
||||
* main.c: Implement auto_erase as page_erase if possible
|
||||
* update.h (enum updateflags): New enum
|
||||
* pgm.h (struct programmer_t): Add page_erase method
|
||||
|
||||
2012-04-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c (jtagmkII_paged_load, jtagmkII_paged_write): fix bug
|
||||
in memory type calculation for Xmega "boot" memory region.
|
||||
|
||||
2012-04-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* update.c (parse_op): do not assume default memtype here
|
||||
* main.c: after locating the part information, determine default
|
||||
memtype for all update options that didn't have a memtype
|
||||
specified; this is "application" for Xmega parts, and "flash" for
|
||||
everything else.
|
||||
|
||||
2012-04-24 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c: Rework the way ELF file sections are considered: while
|
||||
scanning the program header table, the offsets from a program
|
||||
header entry must never be used directly when checking the bounds
|
||||
of the current AVR memory region. Instead, they must always be
|
||||
checked based on the corresponding section's entry. That way,
|
||||
Xmega devices now properly take into account whether the segment
|
||||
fits into any of the application/apptable/boot memory region.
|
||||
|
||||
2012-04-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #30756: When setting SUT to 64ms on XMEGA, avrdude doesn't
|
||||
read device signature
|
||||
* main.c: When reading the signature yields 0x000000 or 0xffffff,
|
||||
retry (up to twice) after some progressive delay.
|
||||
|
||||
2012-04-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATxmega16D4, ATxmega32D4, ATxmega64D4,
|
||||
ATxmega128D4): New devices. As Xmega D doesn't feature a fuse0
|
||||
memory cell, move that one out from the generic .xmega part into
|
||||
the individual Xmega A parts.
|
||||
|
||||
2012-04-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #29019: pagel/bs2 warning when uploading using stk500 to xmega
|
||||
* stk500.c (stk500_initialize): Insert dummy values for PAGEL and
|
||||
BS2 if they are not present in the config file, in order to be able
|
||||
to proceed with the stk500_set_extended_parms() anyway.
|
||||
|
||||
2012-04-19 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2_private.h (struct pdata): add boot_start
|
||||
* stk500v2.c: For the "flash" pseudo-memory of Xmega devices,
|
||||
distinguish addresses between "application" and "boot" area.
|
||||
|
||||
2012-04-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c (elf2b): When checking the bounds of the current
|
||||
program header segment, subtract `low' from ph[n].p_paddr in order
|
||||
to correct the magic section offsets for the AVR's non-flash
|
||||
memory regions.
|
||||
|
||||
2012-04-18 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c (elf_get_scn): Rather than trying to just match whether
|
||||
any given section maps straight to a program header segment, use a
|
||||
more sophisticated decision that matches any section as long as it
|
||||
fits into the segment. This is needed for situations where the
|
||||
program header segment spans a larger area than the section data
|
||||
provided. (This can e.g. happen in an ELF file that contains no
|
||||
data at address 0, like a bootloader only.)
|
||||
|
||||
2012-04-13 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #28744: Can't load bootloader to xmega128a1 (part 2, fix for
|
||||
firmware >= V7.x)
|
||||
* jtagmkII.c: Add firmware-version dependent handling of Xmega parameters.
|
||||
V7.x firmware expects the NVM offsets being specified through the Xmega
|
||||
parameters command, but left out as part of the memory address itself.
|
||||
* jtagmkII_private.h: Add CMND_SET_XMEGA_PARAMS, and struct xmega_device_desc.
|
||||
* config_gram.y: Add mcu_base keyword.
|
||||
* avrpart.h: (Dito.)
|
||||
* lexer.l: (Dito.)
|
||||
* avrdude.conf.in (.xmega): add mcu_base, and data memory segment.
|
||||
|
||||
2012-03-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #28744: Can't load bootloader to xmega128a1 (part 1, fix for
|
||||
firmware < V7.x)
|
||||
* jtagmkII.c: When going to write to the boot section of flash,
|
||||
use MTYPE_BOOT_FLASH rather than MTYPE_FLASH
|
||||
* jtagmkII_private.h: add MTYPE_BOOT_FLASH constant
|
||||
|
||||
2012-03-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII_private.h: Sort commands, response codes and events
|
||||
into numerical order.
|
||||
|
||||
2012-03-29 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #30451: Accessing some Xmega memory sections gives not
|
||||
supported error
|
||||
* stk500v2.c: Handle all Xmega memory sections (except
|
||||
"prodsig" which is not documented in AVR079)
|
||||
* fileio.c: Treat the "boot", "application", and "apptable"
|
||||
regions (which are actually subregions of "flash") all as
|
||||
being flash, i.e. suppress trailing 0xFF bytes when reading
|
||||
them
|
||||
* avr.c: (Dito.)
|
||||
|
||||
2012-03-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* jtagmkII.c (jtagmkII_close): The GO command before signing off
|
||||
turned out to be not required for normal megaAVR devices, and to
|
||||
cause the exact opposite (i.e. the target stopping) on Xmega
|
||||
devices being programmed to JTAG. However, programming Xmega
|
||||
devcies through PDI *does* need the GO command.
|
||||
|
||||
2012-03-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Print a configuration summary at the end of the
|
||||
configure run
|
||||
|
||||
2012-02-11 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7718: Merge global data of avrftdi in a private data structure
|
||||
* avrftdi.[ch]: moved global data into private data structure, moved
|
||||
private defines from header file into source file
|
||||
|
||||
2012-02-06 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7720 Bug in EEPROM write
|
||||
* avrftdi.c: fixed wrong buffer address initialization in paged_write
|
||||
* fileio.c: added #include <stdint.h>
|
||||
|
||||
2012-02-05 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #30559 Ft232 bit-bang support
|
||||
* ft245r.c: cancel reader thread before exiting program
|
||||
|
||||
2012-02-04 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7717 avrftdi_flash_write is broken
|
||||
* avrftdi.c: fixed wrong buffer address initialization in paged_write
|
||||
bug #35296 Extraneous newlines in output.
|
||||
* main.c: fixed output of newlines at 100% progress
|
||||
|
||||
2012-02-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7715 FT4232H support
|
||||
* avrdude.conf.in: added programmer 4232h
|
||||
|
||||
2012-02-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7687: Autogenerating programmers and parts lists for docs
|
||||
(generating the programmers lists)
|
||||
* doc/avrdude.texi: Add include of generated table of programmers
|
||||
* doc/Makefile.am: Add generating of table of programmers in programmers.texi
|
||||
|
||||
2012-02-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #34768 Proposition: Change the name of the AVR32 devices
|
||||
* avrdude.conf.in: renamed ucr2 to uc3a0512
|
||||
* avrpart.c: added cast to avoid compiler warning
|
||||
|
||||
2012-02-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* fileio.c (fileio_elf): Fix a copy'n-paste-o.
|
||||
|
||||
2012-02-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* par.c (par_desc): Move to end of file, outside the #if
|
||||
HAVE_PARPORT
|
||||
|
||||
2012-02-02 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Implement ELF file reading (finally). Requires libelf(3) to be
|
||||
present on the host system.
|
||||
* configure.ac (HAVE_LIBELF): Add logic to detect presence of
|
||||
libelf(3)
|
||||
* Makefile.am (avrdude_LDADD): Add @LIBELF@
|
||||
* fileio.h (FILEFMT): add FMT_ELF
|
||||
* fileio.c: Implement ELF file reader.
|
||||
* update.c (parse_op): add 'e' format specifier
|
||||
* avrdude.1: Document the ELF file reading capability
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2012-02-01 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #30559 Ft232 bit-bang support
|
||||
* ft245r.[ch]: new programmer type implementation
|
||||
* configure.ac: add pthread as link library
|
||||
* avrdude.conf.in: added some new programmers
|
||||
* Makefile.am: added new source files to compile
|
||||
* pindefs.h: change PIN_MASK, PIN_INVERSE to highest bit of unsigned int
|
||||
* pgm.[ch]: added generic function to print pin assignments (taken from par.c)
|
||||
* par.c: moved pin assigment print function to pgm.c
|
||||
|
||||
2012-02-01 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* lexer.l: Sort keyword tokens into alphabetic order.
|
||||
|
||||
2012-01-31 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* config_gram.y, lexer.l: removed unused ID/TKN_ID definitions
|
||||
* config.[hc]: removed unused function id(), use value.type to select
|
||||
values
|
||||
|
||||
2012-01-31 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7437 modifications to Bus Pirate module
|
||||
patch #7686 Updating buspirate ascii mode to current firmware, use AUX
|
||||
as clock generator, and setting of serial receive timeout
|
||||
* buspirate.c: added paged_write, changed binary mode setup/detection,
|
||||
added clock output on AUX pin
|
||||
* avrdude.1: updated documentation
|
||||
* doc/avrdude.texi: updated documentation
|
||||
|
||||
2012-01-31 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
Parser does not need to know all programmer types now, new programmers
|
||||
will update only the table in pgm_type.c.
|
||||
* config_gram.y, lexer.l: removed programmer type keywords,
|
||||
use now locate_programmer_type() function
|
||||
* pgm_type.[ch]: added new files for table of programmer types
|
||||
* main.c: allow list of programmer types by -c ?type
|
||||
* avrdude.conf.in: changed all type keywords to quoted strings
|
||||
* doc/avrdude.texi: changed description of type definition, list
|
||||
of valid types is now included from generated file
|
||||
* doc/Makefile.am: generate list of programmer types for doc
|
||||
* all programmers [hc]: add xxx_desc string for description of programmer
|
||||
|
||||
2012-01-30 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* configure.ac: fixed detection of yylex_destroy availability
|
||||
by checking the version number of flex; bump required autoconf
|
||||
version to 2.60 (for AC_PROG_SED)
|
||||
|
||||
2012-01-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* lexer.l: Replace the old, now-defunct #define YY_NO_UNPUT by
|
||||
the new %option nounput. This gets rid of a compiler warning.
|
||||
|
||||
2012-01-30 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Add a connection_type attribute to each programmer, rather than
|
||||
trying to hard-code the default port name in main.c.
|
||||
* pgm.h: Add conntype to struct pgm.
|
||||
* lexer.l: Extend grammar for connection_type.
|
||||
* config_gram.y: (Dito.)
|
||||
* config.h: Add DEFAULT_USB, for symmetry with default_parallel
|
||||
and default_serial.
|
||||
* main.c: Replace old default portname hack by avrdude.conf-based
|
||||
knowledge.
|
||||
* usbtiny.c: Drop an old hack that's no longer necessary.
|
||||
* avrdude.conf.in: Add connection_type to each programmer
|
||||
definition.
|
||||
|
||||
2012-01-27 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* avrdude.conf.in: used parent parts for some other parts, added
|
||||
abstract .xmega part as parent for xmegas
|
||||
* main.c: hide parts starting with '.' from parts list
|
||||
|
||||
2012-01-22 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7688: Implement parent programmers feature
|
||||
* avrdude.conf.in: updated documentation comment and some programmers
|
||||
have now parents
|
||||
* config_gram.y: initpgm will now called at first use of programmer
|
||||
in main. parser sets only the function pointer in the pgm structure.
|
||||
Pin and pin lists definitions can now be empty to remove the parents
|
||||
setting.
|
||||
* doc/avrdude.texi: updated documentation
|
||||
* main.c: added call to pgm->initpgm after locate_programmer
|
||||
* pgm.[hc]: added field initpgm in structure, added function pgm_dup
|
||||
|
||||
2012-01-21 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #21797: AT90PWM316: New part description
|
||||
* avrdude.conf.in: added pwm316 with parent pwm3b but 16KB flash
|
||||
|
||||
2012-01-20 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Check for presence of lusb_usb.h as an alternative
|
||||
to usb.h; libusb-win32 switched to this name in version 1.2.5.0.
|
||||
* avrftdi.c: Decide whether to include <usb.h>, or <lusb0_usb.h>.
|
||||
* ser_avrdoper.c: (Dito.)
|
||||
* usbasp.c: (Dito.)
|
||||
* usb_libusb.c: (Dito.)
|
||||
* usbtiny.c: (Dito.)
|
||||
|
||||
2012-01-19 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* avr.c: Unsigned variable was used for return code of paged_write/load
|
||||
functions. So a negative return code led never to a fallback to byte
|
||||
functions.
|
||||
|
||||
2012-01-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #34302: Feature request : device configuration with parent classes
|
||||
* config_gram.y: if memory section is overwritten old entry is removed
|
||||
|
||||
(not in original patch)
|
||||
* config_gram.y: if programmer or part is defined twice, a warning is
|
||||
output and the first instance is removed
|
||||
|
||||
General cleanup and free functions, so valgrind does not report any lost
|
||||
blocks at program end.
|
||||
* avrpart.[hc]: added avr_free_(opcode|mem|part) functions
|
||||
* pgm.[hc]: added pgm_free function
|
||||
* update.[hc]: added free_update functions
|
||||
* config.[hc]: added cleanup_config function, use yylex_destroy to reset
|
||||
the lexer after usage. (So it can be reused.)
|
||||
* main.c: add cleanup_main function which is called by atexit() (This
|
||||
frees all lists so that at program exit only really lost memory is
|
||||
reported by valgrind.)
|
||||
* usbasp.c: added libusb_free_device_list() and libusb_exit() calls to
|
||||
avoid lost memory
|
||||
* buspirate.c: moved memory allocation from initpgm to setup and added
|
||||
free in teardown
|
||||
* configure.ac: add definition of HAVE_YYLEX_DESTROY if $LEX is flex.
|
||||
* Makefile.am: added . in front of SUBDIRS to build avrdude before trying
|
||||
to use it for creating the part list for the docs.
|
||||
|
||||
2012-01-17 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* usbasp.c: USB vid/pid/vendor/product from config file are used, for
|
||||
id "usbasp" nibobee and old usbasp are tried as they were currently
|
||||
implemented within usbasp
|
||||
* avrdude.conf.in: added usb params to "usbasp", added new entry "nibobee"
|
||||
with params which were hardcoded in usbasp.c, and added an entry
|
||||
"usbasb-clone" which only checks vid/pid.
|
||||
|
||||
2012-01-10 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #35261 avrftdi uses wrong interface in avrftdi_paged_(write|load)
|
||||
* avrftdi.c: Fixed interface and implementation of avrftdi_paged_(write|load)
|
||||
patch #7672 adding support for O-Link (FTDI based JTAG) as programmer
|
||||
* avrdude.conf.in: added o-link entry
|
||||
|
||||
2012-01-10 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7699 Read additional config files
|
||||
* main.c: Added reading of additional config files
|
||||
* avrdude.1: updated man page
|
||||
* doc/avrdude.texi: updated documentation
|
||||
|
||||
2012-01-10 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Bob Frazier:
|
||||
bug #35208: avrdude 5.11 on freebsd 8.2-STABLE does not reset
|
||||
Arduino Uno properly
|
||||
* arduino.c (arduino_open): Bump the timeout between pulling
|
||||
the DTR and RTS lines low and high.
|
||||
|
||||
2012-01-08 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
Fixed following findings reported by cppcheck
|
||||
* avr910.c:625 (error) Possible null pointer dereference: cmd - otherwise it is redundant to check if cmd is null at line 624
|
||||
* avr910.c:626 (error) Possible null pointer dereference: cmd - otherwise it is redundant to check if cmd is null at line 624
|
||||
* avr910.c:168 (information) The scope of the variable 'devtype_1st' can be reduced
|
||||
* avr910.c:169 (information) The scope of the variable 'dev_supported' can be reduced
|
||||
* avrftdi.c:647 (error) Using sizeof for array given as function argument returns the size of pointer.
|
||||
* stk500v2.c:3347 (error) Memory leak: b
|
||||
* stk500v2.c:3452 (error) Memory leak: b
|
||||
* usbasp.c:554 (error) Using sizeof for array given as function argument returns the size of pointer.
|
||||
* usbasp.c:485 (information) The scope of the variable 'dly' can be reduced
|
||||
|
||||
2012-01-03 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Reported by Jason Kotzin:
|
||||
* usbasp.c (usbasp_spi_paged_load, usbasp_spi_paged_write):
|
||||
Fix buffer address calculation.
|
||||
|
||||
2012-01-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
patch #7629 add support for atmega48p
|
||||
* avrdude.conf.in: Added m48p with parent m48 + different signature
|
||||
|
||||
* avrdude.conf.in: made part parents (m88p = m88 + different signature,
|
||||
m168p = m168 + different signature)
|
||||
|
||||
2012-01-02 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #21663 AT90PWM efuse incorrect
|
||||
bug #30438 efuse bits written as 0 on at90pwmxx parts
|
||||
* avrdude.conf.in: (pwm2, pwm2b, pwm3, pwm3b) <efuse.write>: Write
|
||||
eight bits
|
||||
|
||||
* avrdude.conf.in: made part parents (pwm3 = pwm2, pwm3b = pwm2b,
|
||||
pwm2b = pwm2 + different signature)
|
||||
|
||||
* ChangeLog-2011: New file, rotate ChangeLog for new year.
|
||||
@@ -13,7 +13,8 @@
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
#
|
||||
@@ -25,13 +26,6 @@ EXTRA_DIST = \
|
||||
ChangeLog-2001 \
|
||||
ChangeLog-2002 \
|
||||
ChangeLog-2003 \
|
||||
ChangeLog-2004-2006 \
|
||||
ChangeLog-2007 \
|
||||
ChangeLog-2008 \
|
||||
ChangeLog-2009 \
|
||||
ChangeLog-2010 \
|
||||
ChangeLog-2011 \
|
||||
ChangeLog-2012 \
|
||||
avrdude.1 \
|
||||
avrdude.spec \
|
||||
bootstrap
|
||||
@@ -41,70 +35,31 @@ CLEANFILES = \
|
||||
config_gram.h \
|
||||
lexer.c
|
||||
|
||||
BUILT_SOURCES = $(CLEANFILES)
|
||||
|
||||
#SUBDIRS = doc @WINDOWS_DIRS@
|
||||
#DIST_SUBDIRS = doc windows
|
||||
|
||||
# . lets build this directory before the following in SUBDIRS
|
||||
SUBDIRS = .
|
||||
# doc comes here, and we want to use the built avrdude to generate the parts list
|
||||
SUBDIRS += @SUBDIRS_AC@
|
||||
SUBDIRS += @WINDOWS_DIRS@
|
||||
SUBDIRS = @SUBDIRS_AC@
|
||||
DIST_SUBDIRS = @DIST_SUBDIRS_AC@
|
||||
|
||||
AM_YFLAGS = -d
|
||||
|
||||
avrdude_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
|
||||
|
||||
libavrdude_a_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
|
||||
|
||||
avrdude_CFLAGS = @ENABLE_WARNINGS@
|
||||
|
||||
libavrdude_a_CFLAGS = @ENABLE_WARNINGS@
|
||||
|
||||
avrdude_LDADD = $(top_builddir)/$(noinst_LIBRARIES) @LIBUSB_1_0@ @LIBUSB@ @LIBFTDI1@ @LIBFTDI@ @LIBHID@ @LIBELF@ @LIBPTHREAD@ -lm
|
||||
avrdude_CFLAGS = @ENABLE_WARNINGS@
|
||||
|
||||
bin_PROGRAMS = avrdude
|
||||
|
||||
noinst_LIBRARIES = libavrdude.a
|
||||
|
||||
# automake thinks these generated files should be in the distribution,
|
||||
# but this might cause trouble for some users, so we rather don't want
|
||||
# to have them there.
|
||||
#
|
||||
# See
|
||||
#
|
||||
# https://savannah.nongnu.org/bugs/index.php?func=detailitem&item_id=15536
|
||||
#
|
||||
# for why we don't want to have them.
|
||||
dist-hook:
|
||||
rm -f \
|
||||
$(distdir)/lexer.c \
|
||||
$(distdir)/config_gram.c \
|
||||
$(distdir)/config_gram.h
|
||||
|
||||
libavrdude_a_SOURCES = \
|
||||
avrdude_SOURCES = \
|
||||
config_gram.y \
|
||||
lexer.l \
|
||||
arduino.h \
|
||||
arduino.c \
|
||||
avr.c \
|
||||
avr.h \
|
||||
avr910.c \
|
||||
avr910.h \
|
||||
avrdude.h \
|
||||
avrftdi.c \
|
||||
avrftdi.h \
|
||||
avrftdi_private.h \
|
||||
avrftdi_tpi.c \
|
||||
avrftdi_tpi.h \
|
||||
avrpart.c \
|
||||
avrpart.h \
|
||||
bitbang.c \
|
||||
bitbang.h \
|
||||
buspirate.c \
|
||||
buspirate.h \
|
||||
butterfly.c \
|
||||
butterfly.h \
|
||||
config.c \
|
||||
@@ -116,32 +71,20 @@ libavrdude_a_SOURCES = \
|
||||
fileio.c \
|
||||
fileio.h \
|
||||
freebsd_ppi.h \
|
||||
ft245r.c \
|
||||
ft245r.h \
|
||||
jtagmkI.c \
|
||||
jtagmkI.h \
|
||||
jtagmkI_private.h \
|
||||
jtagmkII.c \
|
||||
jtagmkII.h \
|
||||
jtagmkII_private.h \
|
||||
jtag3.c \
|
||||
jtag3.h \
|
||||
jtag3_private.h \
|
||||
linuxgpio.c \
|
||||
linuxgpio.h \
|
||||
linux_ppdev.h \
|
||||
lists.c \
|
||||
lists.h \
|
||||
my_ddk_hidsdi.h \
|
||||
main.c \
|
||||
par.c \
|
||||
par.h \
|
||||
pgm.c \
|
||||
pgm.h \
|
||||
pgm_type.c \
|
||||
pgm_type.h \
|
||||
pickit2.c \
|
||||
pickit2.h \
|
||||
pindefs.c \
|
||||
pindefs.h \
|
||||
ppi.c \
|
||||
ppi.h \
|
||||
@@ -152,7 +95,6 @@ libavrdude_a_SOURCES = \
|
||||
serbb.h \
|
||||
serbb_posix.c \
|
||||
serbb_win32.c \
|
||||
ser_avrdoper.c \
|
||||
ser_posix.c \
|
||||
ser_win32.c \
|
||||
solaris_ecpp.h \
|
||||
@@ -162,24 +104,10 @@ libavrdude_a_SOURCES = \
|
||||
stk500v2.c \
|
||||
stk500v2.h \
|
||||
stk500v2_private.h \
|
||||
stk500generic.c \
|
||||
stk500generic.h \
|
||||
tpi.h \
|
||||
usbasp.c \
|
||||
usbasp.h \
|
||||
usbdevs.h \
|
||||
usb_libusb.c \
|
||||
usbtiny.h \
|
||||
usbtiny.c \
|
||||
update.h \
|
||||
update.c \
|
||||
wiring.h \
|
||||
wiring.c
|
||||
|
||||
avrdude_SOURCES = \
|
||||
main.c \
|
||||
term.c \
|
||||
term.h
|
||||
term.h \
|
||||
usbdevs.h \
|
||||
usb_libusb.c
|
||||
|
||||
man_MANS = avrdude.1
|
||||
|
||||
|
||||
394
avrdude/NEWS
394
avrdude/NEWS
@@ -5,400 +5,6 @@ Approximate change log for AVRDUDE by version.
|
||||
(For more detailed changes, see the ChangeLog file.)
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Version 6.0:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
|
||||
- Programmer types in configuration file are no longer keywords but
|
||||
specified as string.
|
||||
|
||||
So you need to change 'type = XYZ;' to 'type = "XYZ";' in own
|
||||
config files. (internal: The parser does not need to know all
|
||||
programmer types now, new programmers will update only the table
|
||||
in pgm_type.c.)
|
||||
|
||||
- The erase cycle counter (formerly options -y / -Y) has been
|
||||
removed.
|
||||
|
||||
- Specifying a -U option without a memory type (short form of
|
||||
option argument list) now defaults to "application" memory for
|
||||
Xmega devices, and "flash" for everything else. This ensures
|
||||
the Xmega bootloader is not accidentally touched.
|
||||
|
||||
- For programmers that support it, the default erase method is a
|
||||
page erase now, rather than a chip erase (Xmega only).
|
||||
|
||||
- Keep track of input file contents
|
||||
|
||||
Memory segments are being tracked to remember whether they've
|
||||
been actually read from a file. Only segments that came from a
|
||||
file are being programmed into the device, or considered for
|
||||
verification. This drastically improves handling speed for
|
||||
sparse files (e.g. files that have a second bootloader segment),
|
||||
and it ensures the device contents is actually compared for
|
||||
everything mentioned in the file (even in case the file has
|
||||
large 0xFF blocks).
|
||||
|
||||
- The -U option now accepts ELF files as input files, and extracts
|
||||
the appropriate section contents that matches the requested memory
|
||||
region. To enable this feature, the host system used for the
|
||||
compilation must have a libelf around, including the respective
|
||||
header files (i.e., package "libelf-devel" on many Linux systems).
|
||||
|
||||
- Programmers and parts lists
|
||||
|
||||
They are now sorted at output with '-c ?'/'-p ?'. (patch #7671:
|
||||
Sorting programmers and parts lists for console output)
|
||||
|
||||
Programmers and parts lists in documentation generated from lists
|
||||
mentioned above. (patch #7687: Autogenerating programmers and
|
||||
parts lists for docs)
|
||||
|
||||
Output list of programmer types with '-c ?type', add list to
|
||||
documentation
|
||||
|
||||
- Configuration files now accepts parent parts/programmers, parts
|
||||
starting with '.' (eg. .xmega) are not included in output parts
|
||||
list and can be used as abstract parents
|
||||
|
||||
(bug #34302: Feature request : device configuration with parent classes)
|
||||
(patch #7688: Implement parent programmers feature)
|
||||
|
||||
- Additional config files which are read after default can be
|
||||
specified on command line using '-C +filename'
|
||||
|
||||
(patch #7699 Read additional config files)
|
||||
|
||||
- "Safemode" can now be turned off by default from within a
|
||||
configuration file (like ~/.avrduderc).
|
||||
|
||||
- The new option -l logfile allows to redirect diagnostic messages
|
||||
to a logfile rather than stderr. Useful to record debugging
|
||||
traces, in particular in environments which do not offer
|
||||
shell-style redirection functionality for standard streams.
|
||||
|
||||
- When leaving debugWIRE mode, immediately retry with ISP rather
|
||||
than bailing out completely.
|
||||
|
||||
- The USBasp programmer implementation now supports detailed traces
|
||||
with -vvv, and device communication traces with -vvvv.
|
||||
|
||||
- The "verbose" terminal mode command allows to query or modify the
|
||||
verbosity level.
|
||||
|
||||
* New devices supported:
|
||||
- ATmega48P (patch #7629 add support for atmega48p)
|
||||
- AT90PWM316 (bug #21797: AT90PWM316: New part description)
|
||||
- ATxmega16D4, ATxmega32D4, ATxmega64D4, ATxmega128D4
|
||||
- ATmega256RFR2, ATmega128RFR2, ATmega64RFR2, ATmega2564RFR2,
|
||||
ATmega1284RFR2, ATmega644RFR2
|
||||
- ATtiny1634
|
||||
- ATxmega128A1U, ATxmega128A3U, ATxmega128A4U, ATxmega128B1,
|
||||
ATxmega128B3, ATxmega128C3, ATxmega128D3, ATxmega16A4U,
|
||||
ATxmega16C4, ATxmega192A3U, ATxmega192C3, ATxmega192D3,
|
||||
ATxmega256A3BU, ATxmega256A3U, ATxmega256C3, ATxmega256D3,
|
||||
ATxmega32A4U, ATxmega32C4, ATxmega384C3, ATxmega384D3,
|
||||
ATxmega64A1U, ATxmega64A3U, ATxmega64A4U, ATxmega64B1,
|
||||
ATxmega64B3, ATxmega64C3, ATxmega64D3
|
||||
- ATtiny43U
|
||||
- ATmega406
|
||||
- ATxmega8E5, ATxmega16E5, ATxmega32E5
|
||||
- ATtiny20, ATtiny40
|
||||
|
||||
|
||||
* New programmers supported:
|
||||
- linuxgpio
|
||||
+ any (embedded) Linux system with 4 GPIOs available can be used
|
||||
as a programmer with little or no additional hardware.
|
||||
|
||||
- avrftdi
|
||||
+ o-link (patch #7672 adding support for O-Link (FTDI based
|
||||
JTAG) as programmer)
|
||||
+ 4232h (patch #7715 FT4232H support)
|
||||
- TPI support
|
||||
+ openmoko (bug #37977 Support for Openmoko Debug Board)
|
||||
|
||||
- usbasp
|
||||
+ nibobee (previously specified as '-c usbasp -P nibobee)
|
||||
+ usbasp-clone (same as usbasp but ignores vendor and product
|
||||
string, checks only vid/pid)
|
||||
|
||||
- ftdi_syncbb (new type for synchronous bitbanging with ft232r/ft245r)
|
||||
+ ft245r (FT245R Synchronous BitBang, miso = D1, sck = D0, mosi
|
||||
= D2, reset = D4)
|
||||
+ ft232r (FT232R Synchronous BitBang, miso = RxD, sck = RTS,
|
||||
mosi = TxD, reset = DTR)
|
||||
+ bwmega (BitWizard ftdi_atmega builtin programmer, miso = DSR,
|
||||
sck = DCD, mosi = CTS, reset = RI)
|
||||
+ arduino-ft232r (Arduino: FT232R connected to ISP, miso = CTS
|
||||
X3(1), sck = DSR X3(2), mosi = DCD X3(3), reset = RI X3(4))
|
||||
+ diecimila (alias for arduino-ft232r)
|
||||
|
||||
- pickit2
|
||||
|
||||
- Atmel JTAGICE3
|
||||
|
||||
- buspirate_bb (TPI programming using the BusPirate in bitbang mode)
|
||||
|
||||
* Bugfixes
|
||||
- bug #34027: avrdude AT90S1200 Problem
|
||||
- bug #34518: loading intel hex files > 64k using record-type 4
|
||||
- patch #7667: Minor memory handling fixes
|
||||
- patch #7680: Fixing timeout problem in ser_recv in ser_win32.c
|
||||
- patch #7693: Fix config file atmel URLs (+ URLs in
|
||||
avrdude.texi and avrpart.h)
|
||||
- bug #21663: AT90PWM efuse incorrect, bug #30438: efuse bits
|
||||
written as 0 on at90pwmxx parts
|
||||
- bug #35261: avrftdi uses wrong interface in avrftdi_paged_(write|load)
|
||||
- patch #7437 modifications to Bus Pirate module
|
||||
- patch #7686 Updating buspirate ascii mode to current firmware,
|
||||
use AUX as clock generator, and setting of serial receive
|
||||
timeout
|
||||
- bug #34768 Proposition: Change the name of the AVR32 devices
|
||||
- patch #7718: Merge global data of avrftdi in a private data
|
||||
structure
|
||||
- bug #35208: avrdude 5.11 on freebsd 8.2-STABLE does not reset
|
||||
Arduino Uno properly
|
||||
- bug #34518: loading intel hex files > 64k using record-type 4
|
||||
(Extended Linear Address Record)
|
||||
- bug #34027: avrdude AT90S1200 Problem
|
||||
- bug #30451: Accessing some Xmega memory sections gives not
|
||||
supported error
|
||||
- bug #28744: Can't load bootloader to xmega128a1
|
||||
- bug #29019: pagel/bs2 warning when uploading using stk500 to xmega
|
||||
- bug #30756: When setting SUT to 64ms on XMEGA, avrdude doesn't
|
||||
read device signature
|
||||
- bug #37265: wrong page sizes for XMega64xx in avrdude.conf
|
||||
- bug #37942: Latest SVN can't program in dragon_jtag mode
|
||||
- patch #7876 JTAGICE mkII fails to connect to attiny if debugwire
|
||||
is enabled AND target has a very slow clock
|
||||
- bug #39893: Verification failure with AVRISPmkII and Xmega
|
||||
- bug #38713: Compilation of the documentation breaks with texinfo-5
|
||||
- bug #38023: avrdude doesn't return an error code when attempting
|
||||
to upload an invalid Intel HEX file
|
||||
- bug #39794: warnings when building avrdude 6.0rc1 under CentOS 6.4
|
||||
- bug #35800: Compilation error on certain systems if parport is disabled
|
||||
- bug #38307: Can't write usersig of an xmega256a3
|
||||
- bug #38580: Current svn head, xmega and fuses, all fuses tied to fuse0
|
||||
- bug #39691: Buffer overrun when reading EEPROM byte with JTAGICE3
|
||||
- bug #38951: AVR109 use byte offset instead of word offset
|
||||
- patch #7769: Write flash fails for AVR910 programmers
|
||||
- bug #38732: Support for ATtiny1634
|
||||
- bug #36901: flashing Atmega32U4 EEPROM produces garbage on chip
|
||||
- bug #28344: chip_erase_delay too short for ATmega324P, 644, 644P, and 1284P
|
||||
- bug #34277: avrdude reads wrong byte order if using avr911 (aka butterfly)
|
||||
- bug #35456: The progress bar for STK500V2 programmer is "wrong".
|
||||
- patch #5708: avrdude should make 10 synchronization attempts instead of just one
|
||||
- patch #7606: ATtiny43u support
|
||||
- patch #7657: Add ATmega406 support for avrdude using DRAGON + JTAG
|
||||
- bug #35474: Feature request: print fuse values in safemode output.
|
||||
- patch #7710: usb_libusb: Check VID/PID before opening device
|
||||
- [no-id]: Fix SCK period adjustment for STK500v2
|
||||
- bug #40040: Support for ATtiny20 and ATtiny40
|
||||
|
||||
* Internals:
|
||||
|
||||
- Restructuring and compacting programmer definition part of
|
||||
grammar for config file.
|
||||
- Cleanup of parser code, removing unused definitions/
|
||||
functions. Using yylex_destroy if available.
|
||||
- Fixed some more memory leaks, added cleanup code at program exit
|
||||
(to minimize the number of non-freed memory blocks reported by
|
||||
valgrind)
|
||||
- Fixed some findings reported by cppcheck.
|
||||
|
||||
Version 5.11:
|
||||
|
||||
* New devices supported:
|
||||
- ATmega88P/168P
|
||||
- ATmega8U2/16U2/32U2
|
||||
- ATtiny4313
|
||||
|
||||
* New programmers supported:
|
||||
- TPI programming through bitbang programmers (both, serial
|
||||
and parallel ones)
|
||||
- FT2232 (and relatives) based programmers (MPSSE bitbang mode)
|
||||
- Wiring environment (http://wiring.org.co/)
|
||||
- butterfly-style bootloader of the Mikrokopter.de device
|
||||
|
||||
* Bugfixes
|
||||
|
||||
|
||||
Version 5.10:
|
||||
|
||||
* Bugfixes
|
||||
- bug #28660: Problem with loading intel hex rom files that exceed
|
||||
0x10000 bytes
|
||||
- see ChangeLog for further details
|
||||
|
||||
* New Features
|
||||
- (JTAG ICE / AVR Dragon) apply external reset if JTAG ID could
|
||||
not be read
|
||||
|
||||
Version 5.9:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- AVR32A0512 (JTAGMKII only)
|
||||
- ATmega32U4
|
||||
- ATtiny4
|
||||
- ATtiny5
|
||||
- ATtiny9
|
||||
- ATtiny10
|
||||
|
||||
* New programmers supported:
|
||||
|
||||
- BusPirate
|
||||
- Arduino
|
||||
- JTAGICEmkII and AVR Dragon in PDI mode (ATxmega devices)
|
||||
- STK600 and AVRISP mkII in TPI mode (ATtiny4/5/9/10)
|
||||
|
||||
* Bugfixes
|
||||
|
||||
- see ChangeLog and ChangeLog-2009 for details
|
||||
|
||||
Version 5.8:
|
||||
|
||||
* Bugfixes; most importantly, fix a serious memory corruption for
|
||||
that JTAG ICE mkII and AVR Dragon in ISP/HVSP/PP mode.
|
||||
|
||||
Version 5.7:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- ATXMEGA64A1
|
||||
- ATXMEGA192A1
|
||||
- ATXMEGA256A1
|
||||
- ATXMEGA64A3
|
||||
- ATXMEGA128A3
|
||||
- ATXMEGA192A3
|
||||
- ATXMEGA256A3
|
||||
- ATXMEGA256A3B
|
||||
- ATXMEGA16A4
|
||||
- ATXMEGA32A4
|
||||
- ATXMEGA64A4
|
||||
- ATXMEGA128A4
|
||||
|
||||
* Major Xmega fixes for the JTAG ICE mkII (patch #6825)
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
Version 5.6:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- AT90USB82
|
||||
- AT90USB162
|
||||
- ATtiny88
|
||||
- ATmega328P
|
||||
- ATmega1284P
|
||||
- ATmega128RFA1
|
||||
- ATxmega128A1 rev D
|
||||
- ATxmega128A1
|
||||
- ATxmega256A3
|
||||
|
||||
* New programmers supported:
|
||||
|
||||
- AT89ISP cable (patch #6069)
|
||||
- Arduino
|
||||
|
||||
* Add support for the -x option to pass extended parameters to the
|
||||
programmer backend.
|
||||
|
||||
* Add support for JTAG daisy-chains, using the -x daisychain=
|
||||
option.
|
||||
|
||||
* Add support for the Atmel STK600 for "classic" AVRs (AT90, ATtiny,
|
||||
ATmega), using either ISP or high-voltage programming modes.
|
||||
|
||||
* Add support for the -x devcode extended parameter to the avr910
|
||||
programmer, to allow overriding the device code sent to the
|
||||
programmer.
|
||||
|
||||
* Add support for the Crossbow MIB510 programmer (patch #6074, #6542).
|
||||
|
||||
* Add support to bootstrap with GNU autoconf 2.61, and automake 1.10,
|
||||
respectively.
|
||||
|
||||
* Add support for ATxmega128A1 (including the revision D engineering
|
||||
samples) for STK600 and AVRISPmkII tools using PDI
|
||||
|
||||
* The option combination -tF now enters terminal mode even if the
|
||||
device initialization failed, so the user can modify programmer
|
||||
parameters (like Vtarget).
|
||||
|
||||
* Add preliminary support for ATxmega128A1 for the JTAG ICE mkII using
|
||||
JTAG.
|
||||
|
||||
* Add support for direct SPI transfers (bug #25156).
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
Version 5.5:
|
||||
|
||||
* Add support for the USBtinyISP programmer (patch #6233)
|
||||
|
||||
* Add support for the C2N232I serial bitbang programmer (patch #6121)
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
Version 5.4:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- AT90PWM2B/AT90PWM3B
|
||||
|
||||
* Bugfixes.
|
||||
|
||||
* Source code rearranged so that the functionality is now built
|
||||
into a libavrdude.a library where main.c is currently the only
|
||||
existing frontend.
|
||||
|
||||
* Implement ATmega256x support for butterfly/avr109.
|
||||
|
||||
Version 5.3.1:
|
||||
|
||||
* Add support for the AVR Dragon (all modes: ISP, JTAG, HVSP, PP,
|
||||
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:
|
||||
|
||||
@@ -4,43 +4,3 @@ The latest version of AVRDUDE is always available here:
|
||||
|
||||
http://savannah.nongnu.org/projects/avrdude
|
||||
|
||||
|
||||
Important environment variables for ./configure:
|
||||
================================================
|
||||
|
||||
CPPFLAGS: C preprocessor flags (*not* "C++")
|
||||
|
||||
This is the place to put additional (non-standard) -I options into.
|
||||
For example, if your Windows system has LibUSB-Win32 installed into
|
||||
\\WINDOWS\ProgramFiles\LibUSB-Win32, use
|
||||
|
||||
CPPFLAGS=-I/WINDOWS/ProgramFiles/LibUSB-Win32/include
|
||||
|
||||
to tell configure where to search for the header files. (The use of
|
||||
forward slashes rather than backslashes can often simplify things.
|
||||
Note that the Windows system services internally treat both the same.
|
||||
It's only cmd.exe which requires backslashes as the directory
|
||||
separator.)
|
||||
|
||||
LDFLAGS: Linker options
|
||||
|
||||
This is the place to make additional library locations known to the
|
||||
linker. To continue the above example, use
|
||||
|
||||
LDFLAGS=-L/WINDOWS/ProgramFiles/LibUSB-Win32/lib/gcc
|
||||
|
||||
to make the linker search for "libusb.a" in that directory.
|
||||
|
||||
|
||||
Linux users: make sure the header files are installed
|
||||
=====================================================
|
||||
|
||||
While many Linux distributions install the libraries needed by AVRDUDE
|
||||
(libusb, libelf) by default, they leave out the corresponding header
|
||||
files. Consequently, the configure script won't find them, so these
|
||||
libraries could not be used.
|
||||
|
||||
Usually, the packages with the header files (and static libraries) are
|
||||
derived from the regular package name by appending "-devel". Thus,
|
||||
make sure you have "libusb-devel" and "libelf-devel" installed before
|
||||
running the configure script. (Same goes for libftdi.)
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2009 Lars Immisch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* avrdude interface for Arduino programmer
|
||||
*
|
||||
* The Arduino programmer is mostly a STK500v1, just the signature bytes
|
||||
* are read differently.
|
||||
*/
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "pgm.h"
|
||||
#include "stk500_private.h"
|
||||
#include "stk500.h"
|
||||
#include "serial.h"
|
||||
#include "arduino.h"
|
||||
|
||||
/* read signature bytes - arduino version */
|
||||
static int arduino_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
|
||||
{
|
||||
unsigned char buf[32];
|
||||
|
||||
/* Signature byte reads are always 3 bytes. */
|
||||
|
||||
if (m->size < 3) {
|
||||
fprintf(stderr, "%s: memsize too small for sig byte read", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf[0] = Cmnd_STK_READ_SIGN;
|
||||
buf[1] = Sync_CRC_EOP;
|
||||
|
||||
serial_send(&pgm->fd, buf, 2);
|
||||
|
||||
if (serial_recv(&pgm->fd, buf, 5) < 0)
|
||||
return -1;
|
||||
if (buf[0] == Resp_STK_NOSYNC) {
|
||||
fprintf(stderr, "%s: stk500_cmd(): programmer is out of sync\n",
|
||||
progname);
|
||||
return -1;
|
||||
} else if (buf[0] != Resp_STK_INSYNC) {
|
||||
fprintf(stderr,
|
||||
"\n%s: arduino_read_sig_bytes(): (a) protocol error, "
|
||||
"expect=0x%02x, resp=0x%02x\n",
|
||||
progname, Resp_STK_INSYNC, buf[0]);
|
||||
return -2;
|
||||
}
|
||||
if (buf[4] != Resp_STK_OK) {
|
||||
fprintf(stderr,
|
||||
"\n%s: arduino_read_sig_bytes(): (a) protocol error, "
|
||||
"expect=0x%02x, resp=0x%02x\n",
|
||||
progname, Resp_STK_OK, buf[4]);
|
||||
return -3;
|
||||
}
|
||||
|
||||
m->buf[0] = buf[1];
|
||||
m->buf[1] = buf[2];
|
||||
m->buf[2] = buf[3];
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int arduino_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
strcpy(pgm->port, port);
|
||||
if (serial_open(port, pgm->baudrate? pgm->baudrate: 115200, &pgm->fd)==-1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Clear DTR and RTS to unload the RESET capacitor
|
||||
* (for example in Arduino) */
|
||||
serial_set_dtr_rts(&pgm->fd, 0);
|
||||
usleep(250*1000);
|
||||
/* Set DTR and RTS back to high */
|
||||
serial_set_dtr_rts(&pgm->fd, 1);
|
||||
usleep(50*1000);
|
||||
|
||||
/*
|
||||
* drain any extraneous input
|
||||
*/
|
||||
stk500_drain(pgm, 0);
|
||||
|
||||
if (stk500_getsync(pgm) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void arduino_close(PROGRAMMER * pgm)
|
||||
{
|
||||
serial_set_dtr_rts(&pgm->fd, 0);
|
||||
serial_close(&pgm->fd);
|
||||
pgm->fd.ifd = -1;
|
||||
}
|
||||
|
||||
const char arduino_desc[] = "Arduino programmer";
|
||||
|
||||
void arduino_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
/* This is mostly a STK500; just the signature is read
|
||||
differently than on real STK500v1
|
||||
and the DTR signal is set when opening the serial port
|
||||
for the Auto-Reset feature */
|
||||
stk500_initpgm(pgm);
|
||||
|
||||
strcpy(pgm->type, "Arduino");
|
||||
pgm->read_sig_bytes = arduino_read_sig_bytes;
|
||||
pgm->open = arduino_open;
|
||||
pgm->close = arduino_close;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2009 Lars Immisch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef arduino_h__
|
||||
#define arduino_h__
|
||||
|
||||
extern const char arduino_desc[];
|
||||
void arduino_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
759
avrdude/avr.c
759
avrdude/avr.c
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2011 Darell Tan <darell.tan@gmail.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
|
||||
@@ -14,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -28,159 +28,22 @@
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
|
||||
#include "avr.h"
|
||||
#include "lists.h"
|
||||
#include "pindefs.h"
|
||||
#include "ppi.h"
|
||||
#include "safemode.h"
|
||||
#include "update.h"
|
||||
#include "tpi.h"
|
||||
|
||||
FP_UpdateProgress update_progress;
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
/* TPI: returns 1 if NVM controller busy, 0 if free */
|
||||
int avr_tpi_poll_nvmbsy(PROGRAMMER *pgm)
|
||||
{
|
||||
unsigned char cmd;
|
||||
unsigned char res;
|
||||
extern char * progname;
|
||||
extern char progbuf[];
|
||||
extern PROGRAMMER * pgm;
|
||||
|
||||
cmd = TPI_CMD_SIN | TPI_SIO_ADDR(TPI_IOREG_NVMCSR);
|
||||
(void)pgm->cmd_tpi(pgm, &cmd, 1, &res, 1);
|
||||
return (res & TPI_IOREG_NVMCSR_NVMBSY);
|
||||
}
|
||||
|
||||
/* TPI chip erase sequence */
|
||||
int avr_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
int err;
|
||||
AVRMEM *mem;
|
||||
extern int do_cycles;
|
||||
|
||||
if (p->flags & AVRPART_HAS_TPI) {
|
||||
pgm->pgm_led(pgm, ON);
|
||||
|
||||
/* Set Pointer Register */
|
||||
mem = avr_locate_mem(p, "flash");
|
||||
if (mem == NULL) {
|
||||
fprintf(stderr, "No flash memory to erase for part %s\n",
|
||||
p->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned char cmd[] = {
|
||||
/* write pointer register high byte */
|
||||
(TPI_CMD_SSTPR | 0),
|
||||
((mem->offset & 0xFF) | 1),
|
||||
/* and low byte */
|
||||
(TPI_CMD_SSTPR | 1),
|
||||
((mem->offset >> 8) & 0xFF),
|
||||
/* write CHIP_ERASE command to NVMCMD register */
|
||||
(TPI_CMD_SOUT | TPI_SIO_ADDR(TPI_IOREG_NVMCMD)),
|
||||
TPI_NVMCMD_CHIP_ERASE,
|
||||
/* write dummy value to start erase */
|
||||
TPI_CMD_SST,
|
||||
0xFF
|
||||
};
|
||||
|
||||
while (avr_tpi_poll_nvmbsy(pgm));
|
||||
|
||||
err = pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0);
|
||||
if(err)
|
||||
return err;
|
||||
|
||||
while (avr_tpi_poll_nvmbsy(pgm));
|
||||
|
||||
pgm->pgm_led(pgm, OFF);
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
fprintf(stderr, "%s called for a part that has no TPI\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* TPI program enable sequence */
|
||||
int avr_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p, unsigned char guard_time)
|
||||
{
|
||||
int err, retry;
|
||||
unsigned char cmd[2];
|
||||
unsigned char response;
|
||||
|
||||
if(p->flags & AVRPART_HAS_TPI) {
|
||||
/* set guard time */
|
||||
cmd[0] = (TPI_CMD_SSTCS | TPI_REG_TPIPCR);
|
||||
cmd[1] = guard_time;
|
||||
|
||||
err = pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0);
|
||||
if(err)
|
||||
return err;
|
||||
|
||||
/* read TPI ident reg */
|
||||
cmd[0] = (TPI_CMD_SLDCS | TPI_REG_TPIIR);
|
||||
err = pgm->cmd_tpi(pgm, cmd, 1, &response, sizeof(response));
|
||||
if (err || response != TPI_IDENT_CODE) {
|
||||
fprintf(stderr, "TPIIR not correct\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* send SKEY command + SKEY */
|
||||
err = pgm->cmd_tpi(pgm, tpi_skey_cmd, sizeof(tpi_skey_cmd), NULL, 0);
|
||||
if(err)
|
||||
return err;
|
||||
|
||||
/* check if device is ready */
|
||||
for(retry = 0; retry < 10; retry++)
|
||||
{
|
||||
cmd[0] = (TPI_CMD_SLDCS | TPI_REG_TPISR);
|
||||
err = pgm->cmd_tpi(pgm, cmd, 1, &response, sizeof(response));
|
||||
if(err || !(response & TPI_REG_TPISR_NVMEN))
|
||||
continue;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Error enabling TPI external programming mode:");
|
||||
fprintf(stderr, "Target does not reply\n");
|
||||
return -1;
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "%s called for a part that has no TPI\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* TPI: setup NVMCMD register and pointer register (PR) for read/write/erase */
|
||||
static int avr_tpi_setup_rw(PROGRAMMER * pgm, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char nvmcmd)
|
||||
{
|
||||
unsigned char cmd[4];
|
||||
int rc;
|
||||
|
||||
/* set NVMCMD register */
|
||||
cmd[0] = TPI_CMD_SOUT | TPI_SIO_ADDR(TPI_IOREG_NVMCMD);
|
||||
cmd[1] = nvmcmd;
|
||||
rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
|
||||
if (rc == -1)
|
||||
return -1;
|
||||
|
||||
/* set Pointer Register (PR) */
|
||||
cmd[0] = TPI_CMD_SSTPR | 0;
|
||||
cmd[1] = (mem->offset + addr) & 0xFF;
|
||||
rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
|
||||
if (rc == -1)
|
||||
return -1;
|
||||
|
||||
cmd[0] = TPI_CMD_SSTPR | 1;
|
||||
cmd[1] = ((mem->offset + addr) >> 8) & 0xFF;
|
||||
rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
|
||||
if (rc == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char * value)
|
||||
@@ -188,41 +51,11 @@ int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned char cmd[4];
|
||||
unsigned char res[4];
|
||||
unsigned char data;
|
||||
int r;
|
||||
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;
|
||||
}
|
||||
OPCODE * readop;
|
||||
|
||||
pgm->pgm_led(pgm, ON);
|
||||
pgm->err_led(pgm, OFF);
|
||||
|
||||
if (p->flags & AVRPART_HAS_TPI) {
|
||||
if (pgm->cmd_tpi == NULL) {
|
||||
fprintf(stderr, "%s: Error: %s programmer does not support TPI\n",
|
||||
progname, pgm->type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (avr_tpi_poll_nvmbsy(pgm));
|
||||
|
||||
/* setup for read */
|
||||
avr_tpi_setup_rw(pgm, mem, addr, TPI_NVMCMD_NO_OPERATION);
|
||||
|
||||
/* load byte */
|
||||
cmd[0] = TPI_CMD_SLD;
|
||||
r = pgm->cmd_tpi(pgm, cmd, 1, value, 1);
|
||||
if (r == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* figure out what opcode to use
|
||||
*/
|
||||
@@ -241,32 +74,16 @@ int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
#if DEBUG
|
||||
fprintf(stderr,
|
||||
"avr_read_byte(): operation not supported on memory type \"%s\"\n",
|
||||
mem->desc);
|
||||
p->desc);
|
||||
#endif
|
||||
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);
|
||||
r = pgm->cmd(pgm, cmd, res);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
|
||||
avr_set_bits(readop, cmd);
|
||||
avr_set_addr(readop, cmd, addr);
|
||||
r = pgm->cmd(pgm, cmd, res);
|
||||
if (r < 0)
|
||||
return r;
|
||||
pgm->cmd(pgm, cmd, res);
|
||||
data = 0;
|
||||
avr_get_output(readop, res, &data);
|
||||
|
||||
@@ -278,6 +95,26 @@ 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
|
||||
@@ -307,131 +144,59 @@ int avr_mem_hiaddr(AVRMEM * mem)
|
||||
|
||||
/*
|
||||
* Read the entirety of the specified memory type into the
|
||||
* corresponding buffer of the avrpart pointed to by 'p'.
|
||||
* If v is non-NULL, verify against v's memory area, only
|
||||
* those cells that are tagged TAG_ALLOCATED are verified.
|
||||
* corresponding buffer of the avrpart pointed to by 'p'. If size =
|
||||
* 0, read the entire contents, otherwise, read 'size' bytes.
|
||||
*
|
||||
* Return the number of bytes read, or < 0 if an error occurs.
|
||||
*/
|
||||
int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
|
||||
AVRPART * v)
|
||||
int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
int verbose)
|
||||
{
|
||||
unsigned long i, lastaddr;
|
||||
unsigned char cmd[4];
|
||||
AVRMEM * mem, * vmem = NULL;
|
||||
unsigned char rbyte;
|
||||
unsigned long i;
|
||||
unsigned char * buf;
|
||||
AVRMEM * mem;
|
||||
int rc;
|
||||
|
||||
mem = avr_locate_mem(p, memtype);
|
||||
if (v != NULL)
|
||||
vmem = avr_locate_mem(v, memtype);
|
||||
if (mem == NULL) {
|
||||
fprintf(stderr, "No \"%s\" memory for part %s\n",
|
||||
memtype, p->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf = mem->buf;
|
||||
if (size == 0) {
|
||||
size = mem->size;
|
||||
}
|
||||
|
||||
/*
|
||||
* start with all 0xff
|
||||
*/
|
||||
memset(mem->buf, 0xff, mem->size);
|
||||
memset(buf, 0xff, size);
|
||||
|
||||
/* supports "paged load" thru post-increment */
|
||||
if ((p->flags & AVRPART_HAS_TPI) && mem->page_size != 0 &&
|
||||
pgm->cmd_tpi != NULL) {
|
||||
|
||||
while (avr_tpi_poll_nvmbsy(pgm));
|
||||
|
||||
/* setup for read (NOOP) */
|
||||
avr_tpi_setup_rw(pgm, mem, 0, TPI_NVMCMD_NO_OPERATION);
|
||||
|
||||
/* load bytes */
|
||||
for (lastaddr = i = 0; i < mem->size; i++) {
|
||||
if (vmem == NULL ||
|
||||
(vmem->tags[i] & TAG_ALLOCATED) != 0)
|
||||
{
|
||||
if (lastaddr != i) {
|
||||
/* need to setup new address */
|
||||
avr_tpi_setup_rw(pgm, mem, i, TPI_NVMCMD_NO_OPERATION);
|
||||
lastaddr = i;
|
||||
}
|
||||
cmd[0] = TPI_CMD_SLD_PI;
|
||||
rc = pgm->cmd_tpi(pgm, cmd, 1, mem->buf + i, 1);
|
||||
lastaddr++;
|
||||
if (rc == -1) {
|
||||
fprintf(stderr, "avr_read(): error reading address 0x%04lx\n", i);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
report_progress(i, mem->size, NULL);
|
||||
}
|
||||
return avr_mem_hiaddr(mem);
|
||||
}
|
||||
|
||||
if (pgm->paged_load != NULL && mem->page_size != 0) {
|
||||
/*
|
||||
* the programmer supports a paged mode read
|
||||
*/
|
||||
int need_read, failure;
|
||||
unsigned int pageaddr;
|
||||
unsigned int npages, nread;
|
||||
|
||||
/* quickly scan number of pages to be written to first */
|
||||
for (pageaddr = 0, npages = 0;
|
||||
pageaddr < mem->size;
|
||||
pageaddr += mem->page_size) {
|
||||
/* check whether this page must be read */
|
||||
for (i = pageaddr;
|
||||
i < pageaddr + mem->page_size;
|
||||
i++)
|
||||
if (vmem == NULL /* no verify, read everything */ ||
|
||||
(mem->tags[i] & TAG_ALLOCATED) != 0 /* verify, do only
|
||||
read pages that
|
||||
are needed in
|
||||
input file */) {
|
||||
npages++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (pageaddr = 0, failure = 0, nread = 0;
|
||||
!failure && pageaddr < mem->size;
|
||||
pageaddr += mem->page_size) {
|
||||
/* check whether this page must be read */
|
||||
for (i = pageaddr, need_read = 0;
|
||||
i < pageaddr + mem->page_size;
|
||||
i++)
|
||||
if (vmem == NULL /* no verify, read everything */ ||
|
||||
(vmem->tags[i] & TAG_ALLOCATED) != 0 /* verify, do only
|
||||
read pages that
|
||||
are needed in
|
||||
input file */) {
|
||||
need_read = 1;
|
||||
break;
|
||||
}
|
||||
if (need_read) {
|
||||
rc = pgm->paged_load(pgm, p, mem, mem->page_size,
|
||||
pageaddr, mem->page_size);
|
||||
if ((strcmp(mem->desc, "flash")==0) || (strcmp(mem->desc, "eeprom")==0)) {
|
||||
if (pgm->paged_load != NULL) {
|
||||
/*
|
||||
* the programmer supports a paged mode read, perhaps more
|
||||
* efficiently than we can read it directly, so use its routine
|
||||
* instead
|
||||
*/
|
||||
if (mem->paged) {
|
||||
rc = pgm->paged_load(pgm, p, mem, mem->page_size, size);
|
||||
if (rc < 0)
|
||||
/* paged load failed, fall back to byte-at-a-time read below */
|
||||
failure = 1;
|
||||
} else if (verbose >= 3) {
|
||||
fprintf(stderr,
|
||||
"%s: avr_read(): skipping page %u: no interesting data\n",
|
||||
progname, pageaddr / mem->page_size);
|
||||
return rc;
|
||||
}
|
||||
nread++;
|
||||
report_progress(nread, npages, NULL);
|
||||
}
|
||||
if (!failure) {
|
||||
if (strcasecmp(mem->desc, "flash") == 0 ||
|
||||
strcasecmp(mem->desc, "application") == 0 ||
|
||||
strcasecmp(mem->desc, "apptable") == 0 ||
|
||||
strcasecmp(mem->desc, "boot") == 0)
|
||||
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 mem->size;
|
||||
return rc;
|
||||
}
|
||||
/* else: fall back to byte-at-a-time write, for historical reasons */
|
||||
}
|
||||
|
||||
if (strcmp(mem->desc, "signature") == 0) {
|
||||
@@ -440,27 +205,21 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i < mem->size; i++) {
|
||||
if (vmem == NULL ||
|
||||
(vmem->tags[i] & TAG_ALLOCATED) != 0)
|
||||
{
|
||||
rc = pgm->read_byte(pgm, p, mem, i, mem->buf + i);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "avr_read(): error reading address 0x%04lx\n", i);
|
||||
if (rc == -1)
|
||||
fprintf(stderr,
|
||||
" read operation not supported for memory \"%s\"\n",
|
||||
memtype);
|
||||
return -2;
|
||||
}
|
||||
for (i=0; i<size; i++) {
|
||||
rc = avr_read_byte(pgm, p, mem, i, &rbyte);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "avr_read(): error reading address 0x%04lx\n", i);
|
||||
if (rc == -1)
|
||||
fprintf(stderr,
|
||||
" read operation not supported for memory \"%s\"\n",
|
||||
memtype);
|
||||
return -2;
|
||||
}
|
||||
report_progress(i, mem->size, NULL);
|
||||
buf[i] = rbyte;
|
||||
report_progress(i, size, NULL);
|
||||
}
|
||||
|
||||
if (strcasecmp(mem->desc, "flash") == 0 ||
|
||||
strcasecmp(mem->desc, "application") == 0 ||
|
||||
strcasecmp(mem->desc, "apptable") == 0 ||
|
||||
strcasecmp(mem->desc, "boot") == 0)
|
||||
if (strcasecmp(mem->desc, "flash") == 0)
|
||||
return avr_mem_hiaddr(mem);
|
||||
else
|
||||
return i;
|
||||
@@ -475,15 +234,7 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
{
|
||||
unsigned char cmd[4];
|
||||
unsigned char res[4];
|
||||
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;
|
||||
}
|
||||
OPCODE * wp;
|
||||
|
||||
wp = mem->op[AVR_OP_WRITEPAGE];
|
||||
if (wp == NULL) {
|
||||
@@ -503,18 +254,6 @@ 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);
|
||||
@@ -549,73 +288,13 @@ 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 (p->flags & AVRPART_HAS_TPI) {
|
||||
if (pgm->cmd_tpi == NULL) {
|
||||
fprintf(stderr, "%s: Error: %s programmer does not support TPI\n",
|
||||
progname, pgm->type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strcmp(mem->desc, "flash") == 0) {
|
||||
fprintf(stderr, "Writing a byte to flash is not supported for %s\n", p->desc);
|
||||
return -1;
|
||||
} else if ((mem->offset + addr) & 1) {
|
||||
fprintf(stderr, "Writing a byte to an odd location is not supported for %s\n", p->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (avr_tpi_poll_nvmbsy(pgm));
|
||||
|
||||
/* must erase fuse first */
|
||||
if (strcmp(mem->desc, "fuse") == 0) {
|
||||
/* setup for SECTION_ERASE (high byte) */
|
||||
avr_tpi_setup_rw(pgm, mem, addr | 1, TPI_NVMCMD_SECTION_ERASE);
|
||||
|
||||
/* write dummy byte */
|
||||
cmd[0] = TPI_CMD_SST;
|
||||
cmd[1] = 0xFF;
|
||||
rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
|
||||
|
||||
while (avr_tpi_poll_nvmbsy(pgm));
|
||||
}
|
||||
|
||||
/* setup for WORD_WRITE */
|
||||
avr_tpi_setup_rw(pgm, mem, addr, TPI_NVMCMD_WORD_WRITE);
|
||||
|
||||
cmd[0] = TPI_CMD_SST_PI;
|
||||
cmd[1] = data;
|
||||
rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
|
||||
/* dummy high byte to start WORD_WRITE */
|
||||
cmd[0] = TPI_CMD_SST_PI;
|
||||
cmd[1] = data;
|
||||
rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
|
||||
|
||||
while (avr_tpi_poll_nvmbsy(pgm));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!mem->paged &&
|
||||
(p->flags & AVRPART_IS_AT90S1200) == 0) {
|
||||
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.
|
||||
*
|
||||
* For mysterious reasons, on the AT90S1200, this read operation
|
||||
* sometimes causes the high byte of the same word to be
|
||||
* programmed to the value of the low byte that has just been
|
||||
* programmed before. Avoid that optimization on this device.
|
||||
*/
|
||||
rc = pgm->read_byte(pgm, p, mem, addr, &b);
|
||||
rc = avr_read_byte(pgm, p, mem, addr, &b);
|
||||
if (rc != 0) {
|
||||
if (rc != -1) {
|
||||
return -2;
|
||||
@@ -642,7 +321,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->paged && mem->op[AVR_OP_LOADPAGE_LO]) {
|
||||
else if (mem->op[AVR_OP_LOADPAGE_LO]) {
|
||||
if (addr & 0x01)
|
||||
writeop = mem->op[AVR_OP_LOADPAGE_HI];
|
||||
else
|
||||
@@ -707,7 +386,7 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
* specified for the chip.
|
||||
*/
|
||||
usleep(mem->max_write_delay);
|
||||
rc = pgm->read_byte(pgm, p, mem, addr, &r);
|
||||
rc = avr_read_byte(pgm, p, mem, addr, &r);
|
||||
if (rc != 0) {
|
||||
pgm->pgm_led(pgm, OFF);
|
||||
pgm->err_led(pgm, OFF);
|
||||
@@ -721,7 +400,7 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
/*
|
||||
* Do polling, but timeout after max_write_delay.
|
||||
*/
|
||||
rc = pgm->read_byte(pgm, p, mem, addr, &r);
|
||||
rc = avr_read_byte(pgm, p, mem, addr, &r);
|
||||
if (rc != 0) {
|
||||
pgm->pgm_led(pgm, OFF);
|
||||
pgm->err_led(pgm, ON);
|
||||
@@ -806,6 +485,7 @@ 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);
|
||||
@@ -825,7 +505,15 @@ int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
|
||||
safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
|
||||
|
||||
return pgm->write_byte(pgm, p, mem, addr, data);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -839,15 +527,13 @@ int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
* Return the number of bytes written, or -1 if an error occurs.
|
||||
*/
|
||||
int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
int auto_erase)
|
||||
int verbose)
|
||||
{
|
||||
int rc;
|
||||
int newpage, page_tainted, flush_page, do_write;
|
||||
int wsize;
|
||||
unsigned int i, lastaddr;
|
||||
unsigned long i;
|
||||
unsigned char data;
|
||||
int werror;
|
||||
unsigned char cmd[4];
|
||||
AVRMEM * m;
|
||||
|
||||
m = avr_locate_mem(p, memtype);
|
||||
@@ -874,173 +560,51 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
progbuf, wsize);
|
||||
}
|
||||
|
||||
|
||||
if ((p->flags & AVRPART_HAS_TPI) && m->page_size != 0 &&
|
||||
pgm->cmd_tpi != NULL) {
|
||||
|
||||
while (avr_tpi_poll_nvmbsy(pgm));
|
||||
|
||||
/* setup for WORD_WRITE */
|
||||
avr_tpi_setup_rw(pgm, m, 0, TPI_NVMCMD_WORD_WRITE);
|
||||
|
||||
/* make sure it's aligned to a word boundary */
|
||||
if (wsize & 0x1) {
|
||||
wsize++;
|
||||
if ((strcmp(m->desc, "flash")==0) || (strcmp(m->desc, "eeprom")==0)) {
|
||||
if (pgm->paged_write != NULL) {
|
||||
/*
|
||||
* the programmer supports a paged mode write, perhaps more
|
||||
* efficiently than we can read it directly, so use its routine
|
||||
* instead
|
||||
*/
|
||||
return pgm->paged_write(pgm, p, m, m->page_size, size);
|
||||
}
|
||||
|
||||
/* write words, low byte first */
|
||||
for (lastaddr = i = 0; i < wsize; i += 2) {
|
||||
if ((m->tags[i] & TAG_ALLOCATED) != 0 ||
|
||||
(m->tags[i + 1] & TAG_ALLOCATED) != 0) {
|
||||
|
||||
if (lastaddr != i) {
|
||||
/* need to setup new address */
|
||||
avr_tpi_setup_rw(pgm, m, i, TPI_NVMCMD_WORD_WRITE);
|
||||
lastaddr = i;
|
||||
}
|
||||
|
||||
cmd[0] = TPI_CMD_SST_PI;
|
||||
cmd[1] = m->buf[i];
|
||||
rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
|
||||
|
||||
cmd[1] = m->buf[i + 1];
|
||||
rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
|
||||
|
||||
lastaddr += 2;
|
||||
|
||||
while (avr_tpi_poll_nvmbsy(pgm));
|
||||
}
|
||||
report_progress(i, wsize, NULL);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
if (pgm->paged_write != NULL && m->page_size != 0) {
|
||||
/*
|
||||
* the programmer supports a paged mode write
|
||||
*/
|
||||
int need_write, failure;
|
||||
unsigned int pageaddr;
|
||||
unsigned int npages, nwritten;
|
||||
|
||||
/* quickly scan number of pages to be written to first */
|
||||
for (pageaddr = 0, npages = 0;
|
||||
pageaddr < wsize;
|
||||
pageaddr += m->page_size) {
|
||||
/* check whether this page must be written to */
|
||||
for (i = pageaddr;
|
||||
i < pageaddr + m->page_size;
|
||||
i++)
|
||||
if ((m->tags[i] & TAG_ALLOCATED) != 0) {
|
||||
npages++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (pageaddr = 0, failure = 0, nwritten = 0;
|
||||
!failure && pageaddr < wsize;
|
||||
pageaddr += m->page_size) {
|
||||
/* check whether this page must be written to */
|
||||
for (i = pageaddr, need_write = 0;
|
||||
i < pageaddr + m->page_size;
|
||||
i++)
|
||||
if ((m->tags[i] & TAG_ALLOCATED) != 0) {
|
||||
need_write = 1;
|
||||
break;
|
||||
}
|
||||
if (need_write) {
|
||||
rc = 0;
|
||||
if (auto_erase)
|
||||
rc = pgm->page_erase(pgm, p, m, pageaddr);
|
||||
if (rc >= 0)
|
||||
rc = pgm->paged_write(pgm, p, m, m->page_size, pageaddr, m->page_size);
|
||||
if (rc < 0)
|
||||
/* paged write failed, fall back to byte-at-a-time write below */
|
||||
failure = 1;
|
||||
} else if (verbose >= 3) {
|
||||
fprintf(stderr,
|
||||
"%s: avr_write(): skipping page %u: no interesting data\n",
|
||||
progname, pageaddr / m->page_size);
|
||||
}
|
||||
nwritten++;
|
||||
report_progress(nwritten, npages, NULL);
|
||||
}
|
||||
if (!failure)
|
||||
return wsize;
|
||||
/* else: fall back to byte-at-a-time write, for historical reasons */
|
||||
}
|
||||
|
||||
if (pgm->write_setup) {
|
||||
pgm->write_setup(pgm, p, m);
|
||||
}
|
||||
|
||||
newpage = 1;
|
||||
page_tainted = 0;
|
||||
flush_page = 0;
|
||||
|
||||
for (i=0; i<wsize; i++) {
|
||||
data = m->buf[i];
|
||||
report_progress(i, wsize, NULL);
|
||||
|
||||
/*
|
||||
* Find out whether the write action must be invoked for this
|
||||
* byte.
|
||||
*
|
||||
* For non-paged memory, this only happens if TAG_ALLOCATED is
|
||||
* set for the byte.
|
||||
*
|
||||
* For paged memory, TAG_ALLOCATED also invokes the write
|
||||
* operation, which is actually a page buffer fill only. This
|
||||
* "taints" the page, and upon encountering the last byte of each
|
||||
* tainted page, the write operation must also be invoked in order
|
||||
* to actually write the page buffer to memory.
|
||||
*/
|
||||
do_write = (m->tags[i] & TAG_ALLOCATED) != 0;
|
||||
rc = avr_write_byte(pgm, p, m, i, data);
|
||||
if (rc) {
|
||||
fprintf(stderr, " ***failed; ");
|
||||
fprintf(stderr, "\n");
|
||||
pgm->err_led(pgm, ON);
|
||||
werror = 1;
|
||||
}
|
||||
|
||||
if (m->paged) {
|
||||
if (newpage) {
|
||||
page_tainted = do_write;
|
||||
} else {
|
||||
page_tainted |= do_write;
|
||||
}
|
||||
if (i % m->page_size == m->page_size - 1 ||
|
||||
i == wsize - 1) {
|
||||
/* last byte this page */
|
||||
flush_page = page_tainted;
|
||||
newpage = 1;
|
||||
} else {
|
||||
flush_page = newpage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!do_write && !flush_page) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (do_write) {
|
||||
rc = avr_write_byte(pgm, p, m, i, data);
|
||||
if (rc) {
|
||||
fprintf(stderr, " ***failed; ");
|
||||
fprintf(stderr, "\n");
|
||||
pgm->err_led(pgm, ON);
|
||||
werror = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* check to see if it is time to flush the page with a page
|
||||
* write
|
||||
*/
|
||||
if (flush_page) {
|
||||
rc = avr_write_page(pgm, p, m, i);
|
||||
if (rc) {
|
||||
fprintf(stderr,
|
||||
" *** page %d (addresses 0x%04x - 0x%04x) failed "
|
||||
"to write\n",
|
||||
i % m->page_size,
|
||||
i - m->page_size + 1, i);
|
||||
fprintf(stderr, "\n");
|
||||
pgm->err_led(pgm, ON);
|
||||
/*
|
||||
* check to see if it is time to flush the page with a page
|
||||
* write
|
||||
*/
|
||||
if (((i % m->page_size) == m->page_size-1) ||
|
||||
(i == wsize-1)) {
|
||||
rc = avr_write_page(pgm, p, m, i);
|
||||
if (rc) {
|
||||
fprintf(stderr,
|
||||
" *** page %ld (addresses 0x%04lx - 0x%04lx) failed "
|
||||
"to write\n",
|
||||
i % m->page_size,
|
||||
i - m->page_size + 1, i);
|
||||
fprintf(stderr, "\n");
|
||||
pgm->err_led(pgm, ON);
|
||||
werror = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1066,7 +630,7 @@ int avr_signature(PROGRAMMER * pgm, AVRPART * p)
|
||||
int rc;
|
||||
|
||||
report_progress (0,1,"Reading");
|
||||
rc = avr_read(pgm, p, "signature", 0);
|
||||
rc = avr_read(pgm, p, "signature", 0, 0);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: error reading signature data for part \"%s\", rc=%d\n",
|
||||
@@ -1125,8 +689,7 @@ int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
|
||||
}
|
||||
|
||||
for (i=0; i<size; i++) {
|
||||
if ((b->tags[i] & TAG_ALLOCATED) != 0 &&
|
||||
buf1[i] != buf2[i]) {
|
||||
if (buf1[i] != buf2[i]) {
|
||||
fprintf(stderr,
|
||||
"%s: verification error, first mismatch at byte 0x%04x\n"
|
||||
"%s0x%02x != 0x%02x\n",
|
||||
@@ -1154,7 +717,7 @@ int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles)
|
||||
}
|
||||
|
||||
for (i=4; i>0; i--) {
|
||||
rc = pgm->read_byte(pgm, p, a, a->size-i, &v1);
|
||||
rc = avr_read_byte(pgm, p, a, a->size-i, &v1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n",
|
||||
progname, rc);
|
||||
@@ -1208,60 +771,30 @@ int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles)
|
||||
|
||||
int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
int cycles;
|
||||
int rc;
|
||||
|
||||
if (do_cycles) {
|
||||
rc = avr_get_cycle_count(pgm, p, &cycles);
|
||||
/*
|
||||
* Don't update the cycle counter, if read failed
|
||||
*/
|
||||
if(rc != 0) {
|
||||
do_cycles = 0;
|
||||
}
|
||||
}
|
||||
|
||||
rc = pgm->chip_erase(pgm, p);
|
||||
|
||||
/*
|
||||
* Don't update the cycle counter, if erase failed
|
||||
*/
|
||||
if (do_cycles && (rc == 0)) {
|
||||
cycles++;
|
||||
fprintf(stderr, "%s: erase-rewrite cycle count is now %d\n",
|
||||
progname, cycles);
|
||||
avr_put_cycle_count(pgm, p, cycles);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Report the progress of a read or write operation from/to the
|
||||
* device.
|
||||
*
|
||||
* The first call of report_progress() should look like this (for a write op):
|
||||
*
|
||||
* report_progress (0, 1, "Writing");
|
||||
*
|
||||
* Then hdr should be passed NULL on subsequent calls while the
|
||||
* operation is progressing. Once the operation is complete, a final
|
||||
* call should be made as such to ensure proper termination of the
|
||||
* progress report:
|
||||
*
|
||||
* report_progress (1, 1, NULL);
|
||||
*
|
||||
* It would be nice if we could reduce the usage to one and only one
|
||||
* call for each of start, during and end cases. As things stand now,
|
||||
* that is not possible and makes maintenance a bit more work.
|
||||
*/
|
||||
void report_progress (int completed, int total, char *hdr)
|
||||
{
|
||||
static int last = 0;
|
||||
static double start_time;
|
||||
int percent = (completed * 100) / total;
|
||||
struct timeval tv;
|
||||
double t;
|
||||
|
||||
if (update_progress == NULL)
|
||||
return;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
t = tv.tv_sec + ((double)tv.tv_usec)/1000000;
|
||||
|
||||
if (hdr) {
|
||||
last = 0;
|
||||
start_time = t;
|
||||
update_progress (percent, t - start_time, hdr);
|
||||
}
|
||||
|
||||
if (percent > 100)
|
||||
percent = 100;
|
||||
|
||||
if (percent > last) {
|
||||
last = percent;
|
||||
update_progress (percent, t - start_time, hdr);
|
||||
}
|
||||
|
||||
if (percent == 100)
|
||||
last = 0; /* Get ready for next time. */
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -26,23 +27,16 @@
|
||||
#include "avrpart.h"
|
||||
#include "pgm.h"
|
||||
|
||||
typedef void (*FP_UpdateProgress)(int percent, double etime, char *hdr);
|
||||
|
||||
|
||||
extern struct avrpart parts[];
|
||||
|
||||
extern FP_UpdateProgress update_progress;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char * value);
|
||||
|
||||
int avr_tpi_poll_nvmbsy(PROGRAMMER *pgm);
|
||||
int avr_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p);
|
||||
int avr_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p, unsigned char guard_time);
|
||||
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, AVRPART * v);
|
||||
int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
|
||||
int verbose);
|
||||
|
||||
int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr);
|
||||
@@ -50,11 +44,8 @@ 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 auto_erase);
|
||||
int verbose);
|
||||
|
||||
int avr_signature(PROGRAMMER * pgm, AVRPART * p);
|
||||
|
||||
@@ -62,16 +53,12 @@ int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size);
|
||||
|
||||
int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles);
|
||||
|
||||
int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);
|
||||
int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);;
|
||||
|
||||
int avr_mem_hiaddr(AVRMEM * mem);
|
||||
|
||||
int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p);
|
||||
|
||||
void report_progress (int completed, int total, char *hdr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
extern void report_progress (int completed, int total, char *hdr);
|
||||
|
||||
#endif
|
||||
|
||||
408
avrdude/avr910.c
408
avrdude/avr910.c
@@ -1,8 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
|
||||
* Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
* Copyright 2008 Klaus Leidinger <klaus@mikrocontroller-projekte.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -15,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -31,52 +30,23 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "config.h"
|
||||
#include "pgm.h"
|
||||
#include "avr910.h"
|
||||
#include "serial.h"
|
||||
|
||||
/*
|
||||
* Private data for this programmer.
|
||||
*/
|
||||
struct pdata
|
||||
{
|
||||
char has_auto_incr_addr;
|
||||
unsigned char devcode;
|
||||
unsigned int buffersize;
|
||||
unsigned char test_blockmode;
|
||||
unsigned char use_blockmode;
|
||||
};
|
||||
extern char * progname;
|
||||
extern int do_cycles;
|
||||
|
||||
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
||||
|
||||
static void avr910_setup(PROGRAMMER * pgm)
|
||||
{
|
||||
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: avr910_setup(): Out of memory allocating private data\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
memset(pgm->cookie, 0, sizeof(struct pdata));
|
||||
PDATA(pgm)->test_blockmode = 1;
|
||||
}
|
||||
|
||||
static void avr910_teardown(PROGRAMMER * pgm)
|
||||
{
|
||||
free(pgm->cookie);
|
||||
}
|
||||
static 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +54,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",
|
||||
@@ -97,7 +67,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -165,6 +135,7 @@ static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
char buf[10];
|
||||
char type;
|
||||
char c;
|
||||
int dev_supported = 0;
|
||||
AVRPART * part;
|
||||
|
||||
/* Get the programmer identifier. Programmer returns exactly 7 chars
|
||||
@@ -194,85 +165,44 @@ static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
/* See if programmer supports autoincrement of address. */
|
||||
|
||||
avr910_send(pgm, "a", 1);
|
||||
avr910_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1);
|
||||
if (PDATA(pgm)->has_auto_incr_addr == 'Y')
|
||||
avr910_recv(pgm, &has_auto_incr_addr, 1);
|
||||
if (has_auto_incr_addr == 'Y')
|
||||
fprintf(stderr, "Programmer supports auto addr increment.\n");
|
||||
|
||||
/* Check support for buffered memory access, ignore if not available */
|
||||
/* Get list of devices that the programmer supports. */
|
||||
|
||||
if (PDATA(pgm)->test_blockmode == 1) {
|
||||
avr910_send(pgm, "b", 1);
|
||||
avr910_send(pgm, "t", 1);
|
||||
fprintf(stderr, "\nProgrammer supports the following devices:\n");
|
||||
while (1) {
|
||||
avr910_recv(pgm, &c, 1);
|
||||
if (c == 'Y') {
|
||||
avr910_recv(pgm, &c, 1);
|
||||
PDATA(pgm)->buffersize = (unsigned int)(unsigned char)c<<8;
|
||||
avr910_recv(pgm, &c, 1);
|
||||
PDATA(pgm)->buffersize += (unsigned int)(unsigned char)c;
|
||||
fprintf(stderr,
|
||||
"Programmer supports buffered memory access with "
|
||||
"buffersize = %u bytes.\n",
|
||||
PDATA(pgm)->buffersize);
|
||||
PDATA(pgm)->use_blockmode = 1;
|
||||
} else {
|
||||
PDATA(pgm)->use_blockmode = 0;
|
||||
}
|
||||
} else {
|
||||
PDATA(pgm)->use_blockmode = 0;
|
||||
}
|
||||
if (c == 0)
|
||||
break;
|
||||
part = locate_part_by_avr910_devcode(part_list, c);
|
||||
|
||||
if (PDATA(pgm)->devcode == 0) {
|
||||
char devtype_1st;
|
||||
int dev_supported = 0;
|
||||
fprintf(stderr, " Device code: 0x%02x = %s\n", c, part ? part->desc : "(unknown)");
|
||||
|
||||
/* Get list of devices that the programmer supports. */
|
||||
/* FIXME: Need to lookup devcode and report the device. */
|
||||
|
||||
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);
|
||||
if (p->avr910_devcode == c)
|
||||
dev_supported = 1;
|
||||
};
|
||||
fprintf(stderr,"\n");
|
||||
|
||||
fprintf(stderr, " Device code: 0x%02x = %s\n", c, part ? part->desc : "(unknown)");
|
||||
|
||||
/* FIXME: Need to lookup devcode and report the device. */
|
||||
|
||||
if (p->avr910_devcode == c)
|
||||
dev_supported = 1;
|
||||
};
|
||||
fprintf(stderr,"\n");
|
||||
|
||||
if (!dev_supported) {
|
||||
fprintf(stderr,
|
||||
"%s: %s: selected device is not supported by programmer: %s\n",
|
||||
progname, ovsigck? "warning": "error", p->id);
|
||||
if (!ovsigck)
|
||||
exit(1);
|
||||
}
|
||||
/* If the user forced the selection, use the first device
|
||||
type that is supported by the programmer. */
|
||||
buf[1] = ovsigck? devtype_1st: p->avr910_devcode;
|
||||
} else {
|
||||
/* devcode overridden by -x devcode= option */
|
||||
buf[1] = (char)(PDATA(pgm)->devcode);
|
||||
if (!dev_supported) {
|
||||
fprintf(stderr,
|
||||
"%s: error: selected device is not supported by programmer: %s\n",
|
||||
progname, p->id);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Tell the programmer which part we selected. */
|
||||
|
||||
buf[0] = 'T';
|
||||
/* buf[1] has been set up above */
|
||||
buf[1] = p->avr910_devcode;
|
||||
|
||||
avr910_send(pgm, buf, 2);
|
||||
avr910_vfy_cmd_sent(pgm, "select device");
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
"%s: avr910_devcode selected: 0x%02x\n",
|
||||
progname, (unsigned)buf[1]);
|
||||
|
||||
avr910_enter_prog_mode(pgm);
|
||||
|
||||
return 0;
|
||||
@@ -299,8 +229,8 @@ static void avr910_enable(PROGRAMMER * pgm)
|
||||
* transmit an AVR device command and return the results; 'cmd' and
|
||||
* 'res' must point to at least a 4 byte data buffer
|
||||
*/
|
||||
static int avr910_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
unsigned char *res)
|
||||
static int avr910_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4])
|
||||
{
|
||||
char buf[5];
|
||||
|
||||
@@ -324,55 +254,6 @@ static int avr910_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
}
|
||||
|
||||
|
||||
static int avr910_parseextparms(PROGRAMMER * pgm, LISTID extparms)
|
||||
{
|
||||
LNODEID ln;
|
||||
const char *extended_param;
|
||||
int rv = 0;
|
||||
|
||||
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
|
||||
extended_param = ldata(ln);
|
||||
|
||||
if (strncmp(extended_param, "devcode=", strlen("devcode=")) == 0) {
|
||||
int devcode;
|
||||
if (sscanf(extended_param, "devcode=%i", &devcode) != 1 ||
|
||||
devcode <= 0 || devcode > 255) {
|
||||
fprintf(stderr,
|
||||
"%s: avr910_parseextparms(): invalid devcode '%s'\n",
|
||||
progname, extended_param);
|
||||
rv = -1;
|
||||
continue;
|
||||
}
|
||||
if (verbose >= 2) {
|
||||
fprintf(stderr,
|
||||
"%s: avr910_parseextparms(): devcode overwritten as 0x%02x\n",
|
||||
progname, devcode);
|
||||
}
|
||||
PDATA(pgm)->devcode = devcode;
|
||||
|
||||
continue;
|
||||
}
|
||||
if (strncmp(extended_param, "no_blockmode", strlen("no_blockmode")) == 0) {
|
||||
if (verbose >= 2) {
|
||||
fprintf(stderr,
|
||||
"%s: avr910_parseextparms(-x): no testing for Blockmode\n",
|
||||
progname);
|
||||
}
|
||||
PDATA(pgm)->test_blockmode = 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"%s: avr910_parseextparms(): invalid extended parameter '%s'\n",
|
||||
progname, extended_param);
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
/*
|
||||
@@ -383,9 +264,7 @@ static int avr910_open(PROGRAMMER * pgm, char * port)
|
||||
}
|
||||
|
||||
strcpy(pgm->port, port);
|
||||
if (serial_open(port, pgm->baudrate, &pgm->fd)==-1) {
|
||||
return -1;
|
||||
}
|
||||
pgm->fd = serial_open(port, pgm->baudrate);
|
||||
|
||||
/*
|
||||
* drain any extraneous input
|
||||
@@ -399,12 +278,12 @@ static void avr910_close(PROGRAMMER * pgm)
|
||||
{
|
||||
avr910_leave_prog_mode(pgm);
|
||||
|
||||
serial_close(&pgm->fd);
|
||||
pgm->fd.ifd = -1;
|
||||
serial_close(pgm->fd);
|
||||
pgm->fd = -1;
|
||||
}
|
||||
|
||||
|
||||
static void avr910_display(PROGRAMMER * pgm, const char * p)
|
||||
static void avr910_display(PROGRAMMER * pgm, char * p)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -442,7 +321,7 @@ static int avr910_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
cmd[0] = 'D';
|
||||
}
|
||||
else {
|
||||
return avr_write_byte_default(pgm, p, m, addr, value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[1] = value;
|
||||
@@ -459,20 +338,33 @@ static int avr910_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
static int avr910_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char * value)
|
||||
{
|
||||
char buf[2];
|
||||
static int cached = 0;
|
||||
static unsigned char cvalue;
|
||||
static unsigned long caddr;
|
||||
|
||||
avr910_set_addr(pgm, addr >> 1);
|
||||
|
||||
avr910_send(pgm, "R", 1);
|
||||
|
||||
/* Read back the program mem word (MSB first) */
|
||||
avr910_recv(pgm, buf, sizeof(buf));
|
||||
|
||||
if ((addr & 0x01) == 0) {
|
||||
*value = buf[1];
|
||||
if (cached && ((caddr + 1) == addr)) {
|
||||
*value = cvalue;
|
||||
cached = 0;
|
||||
}
|
||||
else {
|
||||
*value = buf[0];
|
||||
char buf[2];
|
||||
|
||||
avr910_set_addr(pgm, addr >> 1);
|
||||
|
||||
avr910_send(pgm, "R", 1);
|
||||
|
||||
/* Read back the program mem word (MSB first) */
|
||||
avr910_recv(pgm, buf, sizeof(buf));
|
||||
|
||||
if ((addr & 0x01) == 0) {
|
||||
*value = buf[1];
|
||||
// cached = 1;
|
||||
cvalue = buf[0];
|
||||
caddr = addr;
|
||||
}
|
||||
else {
|
||||
*value = buf[0];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -501,17 +393,17 @@ static int avr910_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
return avr910_read_byte_eeprom(pgm, p, m, addr, value);
|
||||
}
|
||||
|
||||
return avr_read_byte_default(pgm, p, m, addr, value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes)
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
unsigned char cmd[] = {'c', 'C'};
|
||||
char buf[2];
|
||||
unsigned int max_addr = addr + n_bytes;
|
||||
unsigned int addr = 0;
|
||||
unsigned int max_addr = n_bytes;
|
||||
unsigned int page_addr;
|
||||
int page_bytes = page_size;
|
||||
int page_wr_cmd_pending = 0;
|
||||
@@ -545,9 +437,11 @@ static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
page_addr = addr;
|
||||
page_bytes = page_size;
|
||||
}
|
||||
else if ((PDATA(pgm)->has_auto_incr_addr != 'Y') && ((addr & 0x01) == 0)) {
|
||||
else if ((has_auto_incr_addr != 'Y') && ((addr & 0x01) == 0)) {
|
||||
avr910_set_addr(pgm, addr>>1);
|
||||
}
|
||||
|
||||
report_progress (addr, max_addr, NULL);
|
||||
}
|
||||
|
||||
/* If we didn't send the page wr cmd after the last byte written in the
|
||||
@@ -565,12 +459,11 @@ static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
|
||||
|
||||
static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
|
||||
AVRMEM * m,
|
||||
unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes)
|
||||
AVRMEM * m, int page_size, int n_bytes)
|
||||
{
|
||||
char cmd[2];
|
||||
unsigned int max_addr = addr + n_bytes;
|
||||
unsigned int addr = 0;
|
||||
unsigned int max_addr = n_bytes;
|
||||
|
||||
avr910_set_addr(pgm, addr);
|
||||
|
||||
@@ -584,9 +477,11 @@ static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
|
||||
|
||||
addr++;
|
||||
|
||||
if (PDATA(pgm)->has_auto_incr_addr != 'Y') {
|
||||
if (has_auto_incr_addr != 'Y') {
|
||||
avr910_set_addr(pgm, addr);
|
||||
}
|
||||
|
||||
report_progress (addr, max_addr, NULL);
|
||||
}
|
||||
|
||||
return addr;
|
||||
@@ -594,146 +489,74 @@ static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
|
||||
|
||||
|
||||
static int avr910_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes)
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
int rval = 0;
|
||||
if (PDATA(pgm)->use_blockmode == 0) {
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
rval = avr910_paged_write_flash(pgm, p, m, page_size, addr, n_bytes);
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
rval = avr910_paged_write_eeprom(pgm, p, m, page_size, addr, n_bytes);
|
||||
} else {
|
||||
rval = -2;
|
||||
}
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
return avr910_paged_write_flash(pgm, p, m, page_size, n_bytes);
|
||||
}
|
||||
|
||||
if (PDATA(pgm)->use_blockmode == 1) {
|
||||
unsigned int max_addr = addr + n_bytes;
|
||||
char *cmd;
|
||||
unsigned int blocksize = PDATA(pgm)->buffersize;
|
||||
int wr_size;
|
||||
|
||||
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
|
||||
return -2;
|
||||
|
||||
if (m->desc[0] == 'e') {
|
||||
blocksize = 1; /* Write to eeprom single bytes only */
|
||||
wr_size = 1;
|
||||
} else {
|
||||
wr_size = 2;
|
||||
}
|
||||
|
||||
avr910_set_addr(pgm, addr / wr_size);
|
||||
|
||||
cmd = malloc(4 + blocksize);
|
||||
if (!cmd) return -1;
|
||||
|
||||
cmd[0] = 'B';
|
||||
cmd[3] = toupper((int)(m->desc[0]));
|
||||
|
||||
while (addr < max_addr) {
|
||||
if ((max_addr - addr) < blocksize) {
|
||||
blocksize = max_addr - addr;
|
||||
};
|
||||
memcpy(&cmd[4], &m->buf[addr], blocksize);
|
||||
cmd[1] = (blocksize >> 8) & 0xff;
|
||||
cmd[2] = blocksize & 0xff;
|
||||
|
||||
avr910_send(pgm, cmd, 4 + blocksize);
|
||||
avr910_vfy_cmd_sent(pgm, "write block");
|
||||
|
||||
addr += blocksize;
|
||||
} /* while */
|
||||
free(cmd);
|
||||
|
||||
rval = addr;
|
||||
else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
return avr910_paged_write_eeprom(pgm, p, m, page_size, n_bytes);
|
||||
}
|
||||
else {
|
||||
return -2;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
||||
static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes)
|
||||
static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
char cmd[4];
|
||||
char cmd;
|
||||
int rd_size;
|
||||
unsigned int addr = 0;
|
||||
unsigned int max_addr;
|
||||
char buf[2];
|
||||
int rval=0;
|
||||
|
||||
max_addr = addr + n_bytes;
|
||||
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
cmd[0] = 'R';
|
||||
cmd = 'R';
|
||||
rd_size = 2; /* read two bytes per addr */
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
cmd[0] = 'd';
|
||||
}
|
||||
else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
cmd = 'd';
|
||||
rd_size = 1;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (PDATA(pgm)->use_blockmode) {
|
||||
/* use buffered mode */
|
||||
int blocksize = PDATA(pgm)->buffersize;
|
||||
max_addr = n_bytes/rd_size;
|
||||
|
||||
cmd[0] = 'g';
|
||||
cmd[3] = toupper((int)(m->desc[0]));
|
||||
avr910_set_addr(pgm, addr);
|
||||
|
||||
avr910_set_addr(pgm, addr / rd_size);
|
||||
|
||||
while (addr < max_addr) {
|
||||
if ((max_addr - addr) < blocksize) {
|
||||
blocksize = max_addr - addr;
|
||||
}
|
||||
cmd[1] = (blocksize >> 8) & 0xff;
|
||||
cmd[2] = blocksize & 0xff;
|
||||
|
||||
avr910_send(pgm, cmd, 4);
|
||||
avr910_recv(pgm, (char *)&m->buf[addr], blocksize);
|
||||
|
||||
addr += blocksize;
|
||||
while (addr < max_addr) {
|
||||
avr910_send(pgm, &cmd, 1);
|
||||
if (cmd == 'R') {
|
||||
/* The 'R' command returns two bytes, MSB first, we need to put the data
|
||||
into the memory buffer LSB first. */
|
||||
avr910_recv(pgm, buf, 2);
|
||||
m->buf[addr*2] = buf[1]; /* LSB */
|
||||
m->buf[addr*2+1] = buf[0]; /* MSB */
|
||||
}
|
||||
else {
|
||||
avr910_recv(pgm, (char *)&m->buf[addr], 1);
|
||||
}
|
||||
|
||||
rval = addr;
|
||||
} else {
|
||||
addr++;
|
||||
|
||||
avr910_set_addr(pgm, addr / rd_size);
|
||||
|
||||
while (addr < max_addr) {
|
||||
avr910_send(pgm, cmd, 1);
|
||||
if (rd_size == 2) {
|
||||
/* The 'R' command returns two bytes, MSB first, we need to put the data
|
||||
into the memory buffer LSB first. */
|
||||
avr910_recv(pgm, buf, 2);
|
||||
m->buf[addr] = buf[1]; /* LSB */
|
||||
m->buf[addr + 1] = buf[0]; /* MSB */
|
||||
}
|
||||
else {
|
||||
avr910_recv(pgm, (char *)&m->buf[addr], 1);
|
||||
}
|
||||
|
||||
addr += rd_size;
|
||||
|
||||
if (PDATA(pgm)->has_auto_incr_addr != 'Y') {
|
||||
avr910_set_addr(pgm, addr / rd_size);
|
||||
}
|
||||
if (has_auto_incr_addr != 'Y') {
|
||||
avr910_set_addr(pgm, addr);
|
||||
}
|
||||
|
||||
rval = addr;
|
||||
report_progress (addr, max_addr, NULL);
|
||||
}
|
||||
|
||||
return rval;
|
||||
return addr * rd_size;
|
||||
}
|
||||
|
||||
/* Signature byte reads are always 3 bytes. */
|
||||
|
||||
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;
|
||||
@@ -741,15 +564,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;
|
||||
}
|
||||
|
||||
const char avr910_desc[] = "Serial programmers using protocol described in application note AVR910";
|
||||
|
||||
void avr910_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
@@ -779,8 +597,4 @@ void avr910_initpgm(PROGRAMMER * pgm)
|
||||
pgm->paged_load = avr910_paged_load;
|
||||
|
||||
pgm->read_sig_bytes = avr910_read_sig_bytes;
|
||||
|
||||
pgm->parseextparams = avr910_parseextparms;
|
||||
pgm->setup = avr910_setup;
|
||||
pgm->teardown = avr910_teardown;
|
||||
}
|
||||
|
||||
@@ -13,25 +13,17 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef avr910_h
|
||||
#define avr910_h
|
||||
#ifndef __avr910_h__
|
||||
#define __avr910_h__
|
||||
|
||||
#include "avrpart.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char avr910_desc[];
|
||||
void avr910_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* avr910_h */
|
||||
#endif /* __avr910_h__ */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\"
|
||||
.\" avrdude - A Downloader/Uploader for AVR device programmers
|
||||
.\" Copyright (C) 2001, 2002, 2003, 2005 - 2013 Joerg Wunsch
|
||||
.\" Copyright (C) 2001, 2002, 2003, 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
|
||||
@@ -13,12 +13,13 @@
|
||||
.\" 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, see <http://www.gnu.org/licenses/>.
|
||||
.\" along with this program; if not, write to the Free Software
|
||||
.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
.\"
|
||||
.\"
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd DATE September 13, 2013
|
||||
.Dd DATE November 29, 2005
|
||||
.Os
|
||||
.Dt AVRDUDE 1
|
||||
.Sh NAME
|
||||
@@ -37,10 +38,7 @@
|
||||
.Op \&, Ns Ar exitspec
|
||||
.Oc
|
||||
.Op Fl F
|
||||
.Op Fl i Ar delay
|
||||
.Op Fl n logfile
|
||||
.Op Fl n
|
||||
.Op Fl O
|
||||
.Op Fl P Ar port
|
||||
.Op Fl q
|
||||
.Op Fl s
|
||||
@@ -48,8 +46,9 @@
|
||||
.Op Fl u
|
||||
.Op Fl U Ar memtype:op:filename:filefmt
|
||||
.Op Fl v
|
||||
.Op Fl x Ar extended_param
|
||||
.Op Fl V
|
||||
.Op Fl y
|
||||
.Op Fl Y
|
||||
.Sh DESCRIPTION
|
||||
.Nm Avrdude
|
||||
is a program for downloading code and data to Atmel AVR
|
||||
@@ -57,8 +56,7 @@ microcontrollers.
|
||||
.Nm Avrdude
|
||||
supports Atmel's STK500 programmer,
|
||||
Atmel's AVRISP and AVRISP mkII devices,
|
||||
Atmel's STK600,
|
||||
Atmel's JTAG ICE (mkI, mkII and 3, the latter two also in ISP mode),
|
||||
Atmel's JTAG ICE (both mkI and mkII),
|
||||
programmers complying to AppNote AVR910 and AVR109 (including the Butterfly),
|
||||
as well as a simple hard-wired
|
||||
programmer connected directly to a
|
||||
@@ -82,7 +80,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
|
||||
stand-alone programming device. Some status LEDs indicating the
|
||||
standalone 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
|
||||
@@ -97,83 +95,18 @@ port.
|
||||
Connecting to a serial port emulated on top of USB is likely to not
|
||||
work at all, or to work abysmally slow.
|
||||
.Pp
|
||||
If you happen to have a Linux system with at least 4 hardware GPIOs
|
||||
available (like almost all embedded Linux boards) you can do without
|
||||
any additional hardware - just connect them to the MOSI, MISO, RESET
|
||||
and SCK pins on the AVR and use the linuxgpio programmer type. It bitbangs
|
||||
the lines using the Linux sysfs GPIO interface. Of course, care should
|
||||
be taken about voltage level compatibility. Also, although not strictrly
|
||||
required, it is strongly advisable to protect the GPIO pins from
|
||||
overcurrent situations in some way. The simplest would be to just put
|
||||
some resistors in series or better yet use a 3-state buffer driver like
|
||||
the 74HC244. Have a look at http://kolev.info/avrdude-linuxgpio for a more
|
||||
detailed tutorial about using this programmer type.
|
||||
.Pp
|
||||
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
|
||||
Wiring boards are supported, utilizing STK500 V2.x protocol, but
|
||||
a simple DTR/RTS toggle is used to set the boards into programming mode.
|
||||
The programmer type is ``wiring''.
|
||||
.Pp
|
||||
The Arduino (which is very similar to the STK500 1.x) is supported via
|
||||
its own programmer type specification ``arduino''.
|
||||
.Pp
|
||||
The BusPirate is a versatile tool that can also be used as an AVR programmer.
|
||||
A single BusPirate can be connected to up to 3 independent AVRs. See
|
||||
the section on
|
||||
.Em extended parameters
|
||||
below for details.
|
||||
.Pp
|
||||
Atmel's STK600 programmer is supported in ISP and high-voltage
|
||||
programming modes, and connects through the USB.
|
||||
For ATxmega devices, the STK600 is supported in PDI mode.
|
||||
For ATtiny4/5/9/10 devices, the STK600 and AVRISP mkII are supported in TPI mode.
|
||||
.Pp
|
||||
The simple serial programmer described in Atmel's application note
|
||||
AVR910, and the bootloader described in Atmel's application note
|
||||
AVR109 (which is also used by the AVR Butterfly evaluation board), are
|
||||
supported on a serial port.
|
||||
.Pp
|
||||
Atmel's JTAG ICE (mkI, mkII, and 3) 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, provided
|
||||
it has a firmware revision of at least 4.14 (decimal).
|
||||
JTAGICE3 also supports all of JTAG, debugWIRE, and ISP mode.
|
||||
See below for the limitations of debugWire.
|
||||
For ATxmega devices, the JTAG ICE mkII is supported in PDI mode, provided it
|
||||
has a revision 1 hardware and firmware version of at least 5.37 (decimal).
|
||||
For ATxmega devices, the JTAGICE3 is supported in PDI mode.
|
||||
.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.
|
||||
For ATxmega devices, the AVR Dragon is supported in PDI mode, provided it
|
||||
has a firmware version of at least 6.11 (decimal).
|
||||
.Pp
|
||||
The avrftdi, USBasp ISP and USBtinyISP adapters are also supported, provided
|
||||
.Nm avrdude
|
||||
has been compiled with libusb support.
|
||||
USBasp ISP and USBtinyISP both feature simple firmware-only USB implementations,
|
||||
running on an ATmega8 (or ATmega88), or ATtiny2313, respectively. If libftdi has
|
||||
has been compiled in
|
||||
.Nm avrdude ,
|
||||
the avrftdi device adds support for many programmers using FTDI's 2232C/D/H
|
||||
and 4232H parts running in MPSSE mode, which hard-codes (in the chip)
|
||||
SCK to bit 1, MOSI to bit 2, and MISO to bit 3. Reset is usually bit 4.
|
||||
.Pp
|
||||
Input files can be provided, and output files can be written in
|
||||
different file formats, such as raw binary files containing the data
|
||||
@@ -185,20 +118,12 @@ as a standalone assembler, or
|
||||
.Xr avr-objcopy 1
|
||||
for the final stage of the GNU toolchain for the AVR microcontroller.
|
||||
.Pp
|
||||
Provided
|
||||
.Xr libelf 3
|
||||
was present when compiling
|
||||
.Nm avrdude ,
|
||||
the input file can also be the final ELF file as produced by the linker.
|
||||
The appropriate ELF section(s) will be examined, according to the memory
|
||||
area to write to.
|
||||
.Pp
|
||||
.Nm Avrdude
|
||||
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 separate memory types and can be programmed using data from a file
|
||||
as seperate memory types and can be programmed using data from a file
|
||||
(see the
|
||||
.Fl m
|
||||
option) or from terminal mode (see the
|
||||
@@ -210,7 +135,7 @@ been code-protected previously, of course) and store the data in a
|
||||
file. Finally, a ``terminal'' mode is available that allows one to
|
||||
interactively communicate with the MCU, and to display or program
|
||||
individual memory cells.
|
||||
On the STK500 and STK600 programmer, several operational parameters (target supply
|
||||
On the STK500 programmer, several operational parameters (target supply
|
||||
voltage, target Aref voltage, master clock) can be examined and changed
|
||||
from within terminal mode as well.
|
||||
.Ss Options
|
||||
@@ -226,31 +151,65 @@ It specifies the type of the MCU connected to the programmer. These are read fr
|
||||
does not know about a part that you have, simply add it to the config
|
||||
file (be sure and submit a patch back to the author so that it can be
|
||||
incorporated for the next version). See the sample config file for
|
||||
the format.
|
||||
For currently supported MCU types use ? as partno, this will print a list of partno ids and official part names on the terminal. (Both can be used with the -p option.)
|
||||
the format. Currently, the following MCU types are understood:
|
||||
.Pp
|
||||
Following parts need special attention:
|
||||
.Bl -tag -width "ATmega1234"
|
||||
.It "AT90S1200"
|
||||
The ISP programming protocol of the AT90S1200 differs in subtle ways
|
||||
from that of other AVRs. Thus, not all programmers support this
|
||||
device. Known to work are all direct bitbang programmers, and all
|
||||
programmers talking the STK500v2 protocol.
|
||||
.It "AT90S2343"
|
||||
.TS
|
||||
ll.
|
||||
\fBOption tag\fP \fBOfficial part name\fP
|
||||
c128 AT90CAN128
|
||||
pwm2 AT90PWM2
|
||||
pwm3 AT90PWM3
|
||||
1200 AT90S1200
|
||||
2313 AT90S2313
|
||||
2333 AT90S2333
|
||||
2343 AT90S2343 (*)
|
||||
4414 AT90S4414
|
||||
4433 AT90S4433
|
||||
4434 AT90S4434
|
||||
8515 AT90S8515
|
||||
8535 AT90S8535
|
||||
m103 ATmega103
|
||||
m128 ATmega128
|
||||
m1280 ATmega1280
|
||||
m1281 ATmega1281
|
||||
m16 ATmega16
|
||||
m161 ATmega161
|
||||
m162 ATmega162
|
||||
m163 ATmega163
|
||||
m164 ATmega164
|
||||
m169 ATmega169
|
||||
m32 ATmega32
|
||||
m324 ATmega324
|
||||
m329 ATmega329
|
||||
m3290 ATmega3290
|
||||
m48 ATmega48
|
||||
m64 ATmega64
|
||||
m640 ATmega640
|
||||
m644 ATmega644
|
||||
m649 ATmega649
|
||||
m6490 ATmega6490
|
||||
m8 ATmega8
|
||||
m8515 ATmega8515
|
||||
m8535 ATmega8535
|
||||
m88 ATmega88
|
||||
t12 ATtiny12
|
||||
t13 ATtiny13
|
||||
t15 ATtiny15
|
||||
t2313 ATtiny2313
|
||||
t25 ATtiny25
|
||||
t26 ATtiny26
|
||||
t45 ATtiny45
|
||||
t85 ATtiny85
|
||||
.TE
|
||||
.Bl -tag -width "(*) "
|
||||
.It "(*)"
|
||||
The AT90S2323 and ATtiny22 use the same algorithm.
|
||||
.It "ATmega2560, ATmega2561"
|
||||
Flash addressing above 128 KB is not supported by all
|
||||
programming hardware. Known to work are jtag2, stk500v2,
|
||||
and bit-bang programmers.
|
||||
.It "ATtiny11"
|
||||
The ATtiny11 can only be
|
||||
programmed in high-voltage serial mode.
|
||||
.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 or the ISP clock (JTAG ICE only).
|
||||
Specify the bit clock period for the JTAG interface (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
|
||||
@@ -259,12 +218,8 @@ Unlike certain parameters in the STK500, the JTAG ICE resets all its
|
||||
parameters to default values when the programming software signs
|
||||
off from the ICE, so for MCUs running at lower clock speeds, this
|
||||
parameter must be specified on the command-line.
|
||||
You can use the 'default_bitclock' keyword in your
|
||||
.Pa ${HOME}/.avrduderc
|
||||
file to assign a default value to keep from having to specify this
|
||||
option on every invocation.
|
||||
.It Fl c Ar programmer-id
|
||||
Use the programmer specified by the argument. Programmers and their pin
|
||||
Use the pin configuration specified by the argument. Pin
|
||||
configurations are read from the config file (see the
|
||||
.Fl C
|
||||
option). New pin configurations can be easily added or modified
|
||||
@@ -276,8 +231,6 @@ keyword in your
|
||||
.Pa ${HOME}/.avrduderc
|
||||
file to assign a default programmer to keep from having to specify
|
||||
this option on every invocation.
|
||||
A full list of all supported programmers is output to the terminal
|
||||
by using ? as programmer-id.
|
||||
.It Fl C Ar config-file
|
||||
Use the specified config file to load configuration data. This file
|
||||
contains all programmer and part definitions that
|
||||
@@ -289,16 +242,6 @@ submit a patch back to the author so that it can be incorporated for
|
||||
the next version). See the config file, located at
|
||||
.Pa ${PREFIX}/etc/avrdude.conf ,
|
||||
which contains a description of the format.
|
||||
.Pp
|
||||
If
|
||||
.Ar config-file
|
||||
is written as
|
||||
.Pa +filename
|
||||
then this file is read after the system wide and user configuration
|
||||
files. This can be used to add entries to the configuration
|
||||
without patching your system wide configuration file. It can be used
|
||||
several times, the files are read in same order as given on the command
|
||||
line.
|
||||
.It Fl D
|
||||
Disable auto erase for flash. When the
|
||||
.Fl U
|
||||
@@ -307,18 +250,11 @@ option with flash memory is specified,
|
||||
will perform a chip erase before starting any of the programming
|
||||
operations, since it generally is a mistake to program the flash
|
||||
without performing an erase first. This option disables that.
|
||||
Auto erase is not used for ATxmega devices as these devices can
|
||||
use page erase before writing each page so no explicit chip erase
|
||||
is required.
|
||||
Note however that any page not affected by the current operation
|
||||
will retain its previous contents.
|
||||
.It Fl e
|
||||
Causes a chip erase to be executed. This will reset the contents of the
|
||||
flash ROM and EEPROM to the value
|
||||
.Ql 0xff ,
|
||||
and clear all lock bits.
|
||||
Except for ATxmega devices which can use page erase,
|
||||
it is basically a prerequisite command before the flash ROM can be
|
||||
and is basically a prerequisite command before the flash ROM can be
|
||||
reprogrammed again. The only exception would be if the new
|
||||
contents would exclusively cause bits to be programmed from the value
|
||||
.Ql 1
|
||||
@@ -372,12 +308,6 @@ power to the MCU.
|
||||
This option will pull the
|
||||
.Ql Vcc
|
||||
pins of the parallel port down at program exit.
|
||||
.It Ar d_high
|
||||
This option will leave the 8 data pins on the parallel port active.
|
||||
.Pq \&i. \&e. Em high
|
||||
.It Ar d_low
|
||||
This option will leave the 8 data pins on the parallel port inactive.
|
||||
.Pq \&i. \&e. Em low
|
||||
.El
|
||||
.Pp
|
||||
Multiple
|
||||
@@ -391,50 +321,10 @@ reasonable before continuing. Since it can happen from time to time
|
||||
that a device has a broken (erased or overwritten) device signature
|
||||
but is otherwise operating normally, this options is provided to
|
||||
override the check.
|
||||
Also, for programmers like the Atmel STK500 and STK600 which can
|
||||
adjust parameters local to the programming tool (independent of an
|
||||
actual connection to a target controller), this option can be used
|
||||
together with
|
||||
.Fl t
|
||||
to continue in terminal mode.
|
||||
.It Fl i Ar delay
|
||||
For bitbang-type programmers, delay for approximately
|
||||
.Ar delay
|
||||
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 l Ar logfile
|
||||
Use
|
||||
.Ar logfile
|
||||
rather than
|
||||
.Va stderr
|
||||
for diagnostics output.
|
||||
Note that initial diagnostic messages (during option parsing) are still
|
||||
written to
|
||||
.Va stderr
|
||||
anyway.
|
||||
.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
|
||||
@@ -447,23 +337,15 @@ serial port, the
|
||||
port is the default. If you need to use a different parallel or
|
||||
serial port, use this option to specify the alternate port name.
|
||||
.Pp
|
||||
On Win32 operating systems, the parallel ports are referred to as lpt1
|
||||
through lpt3, referring to the addresses 0x378, 0x278, and 0x3BC,
|
||||
respectively. If the parallel port can be accessed through a different
|
||||
address, this address can be specified directly, using the common C
|
||||
language notation (i. e., hexadecimal values are prefixed by
|
||||
.Ql 0x
|
||||
).
|
||||
.Pp
|
||||
For the JTAG ICE mkII and JTAGICE3, if
|
||||
For the JTAG ICE mkII, if
|
||||
.Nm
|
||||
has been configured with libusb support,
|
||||
.Ar port
|
||||
can alternatively be specified as
|
||||
.Pa usb Ns Op \&: Ns Ar serialno .
|
||||
.Ar usb Ns Op \&: Ns Ar serialno .
|
||||
This will cause
|
||||
.Nm
|
||||
to search the programmer on USB.
|
||||
to search a JTAG ICE mkII on USB.
|
||||
If
|
||||
.Ar serialno
|
||||
is also specified, it will be matched against the serial number read
|
||||
@@ -474,37 +356,6 @@ 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 the USBtinyISP, which is a simplicistic device not implementing
|
||||
serial numbers, multiple devices can be distinguished by their
|
||||
location in the USB hierarchy. See the the respective
|
||||
.Em Troubleshooting
|
||||
entry in the detailed documentation for examples.
|
||||
.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.
|
||||
@@ -531,17 +382,6 @@ prompt for instructions, unless the terminal is non-interactive, in
|
||||
which case safemode is disabled. See the
|
||||
.Fl s
|
||||
option to disable safemode prompting.
|
||||
.Pp
|
||||
If one of the configuration files has a line
|
||||
.Dl "default_safemode = no;"
|
||||
safemode is disabled by default.
|
||||
The
|
||||
.Fl u
|
||||
option's effect is negated in that case, i. e. it
|
||||
.Em enables
|
||||
safemode.
|
||||
.Pp
|
||||
Safemode is always disabled for AVR32, Xmega and TPI devices.
|
||||
.It Xo Fl U Ar memtype Ns
|
||||
.Ar \&: Ns Ar op Ns
|
||||
.Ar \&: Ns Ar filename Ns
|
||||
@@ -550,7 +390,7 @@ Safemode is always disabled for AVR32, Xmega and TPI devices.
|
||||
Perform a memory operation as indicated. The
|
||||
.Ar memtype
|
||||
field specifies the memory type to operate on.
|
||||
The available memory types are device-dependent, the actual
|
||||
The available memory types are device-dependant, the actual
|
||||
configuration can be viewed with the
|
||||
.Cm part
|
||||
command in terminal mode.
|
||||
@@ -579,21 +419,6 @@ The low fuse byte.
|
||||
The lock byte.
|
||||
.It signature
|
||||
The three device signature bytes (device ID).
|
||||
.It fuse Ns Em N
|
||||
The fuse bytes of ATxmega devices,
|
||||
.Em N
|
||||
is an integer number
|
||||
for each fuse supported by the device.
|
||||
.It application
|
||||
The application flash area of ATxmega devices.
|
||||
.It apptable
|
||||
The application table flash area of ATxmega devices.
|
||||
.It boot
|
||||
The boot flash area of ATxmega devices.
|
||||
.It prodsig
|
||||
The production signature (calibration) area of ATxmega devices.
|
||||
.It usersig
|
||||
The user signature area of ATxmega devices.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
@@ -624,34 +449,14 @@ Intel Hex
|
||||
Motorola S-record
|
||||
.It Ar r
|
||||
raw binary; little-endian byte order, in the case of the flash ROM data
|
||||
.It Ar e
|
||||
ELF (Executable and Linkable Format)
|
||||
.It Ar m
|
||||
immediate; actual byte values specified on the command line, separated
|
||||
immediate; actual byte values specified on the command line, seperated
|
||||
by commas or spaces. This is good for programming fuse bytes without
|
||||
having to create a single-byte file or enter terminal mode.
|
||||
.It Ar a
|
||||
auto detect; valid for input only, and only if the input is not
|
||||
provided at
|
||||
.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
|
||||
@@ -663,28 +468,34 @@ 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.
|
||||
More
|
||||
.Fl v
|
||||
options increase verbosity level.
|
||||
.It Fl V
|
||||
Disable automatic verify check when uploading data.
|
||||
.It Fl x Ar extended_param
|
||||
Pass
|
||||
.Ar extended_param
|
||||
to the chosen programmer implementation as an extended parameter.
|
||||
The interpretation of the extended parameter depends on the
|
||||
programmer itself.
|
||||
See below for a list of programmers accepting extended parameters.
|
||||
.It Fl y
|
||||
Tells
|
||||
.Nm
|
||||
to use the last four bytes of the connected parts' EEPROM memory to
|
||||
track the number of times the device has been erased. When this
|
||||
option is used and the
|
||||
.Fl e
|
||||
flag is specified to generate a chip erase, the previous counter will
|
||||
be saved before the chip erase, it is then incremented, and written
|
||||
back after the erase cycle completes. Presumably, the device would
|
||||
only be erased just before being programmed, and thus, this can be
|
||||
utilized to give an indication of how many erase-rewrite cycles the
|
||||
part has undergone. Since the FLASH memory can only endure a finite
|
||||
number of erase-rewrite cycles, one can use this option to track when
|
||||
a part is nearing the limit. The typical limit for Atmel AVR FLASH is
|
||||
1000 cycles. Of course, if the application needs the last four bytes
|
||||
of EEPROM memory, this option should not be used.
|
||||
.It Fl Y Ar cycles
|
||||
Instructs
|
||||
.Nm
|
||||
to initialize the erase-rewrite cycle counter residing at the last four
|
||||
bytes of EEPROM memory to the specified value. If the application
|
||||
needs the last four bytes of EEPROM memory, this option should not be
|
||||
used.
|
||||
.El
|
||||
.Ss Terminal mode
|
||||
In this mode,
|
||||
@@ -725,38 +536,26 @@ feature of an AVR part that is not directly supported by
|
||||
.Nm ,
|
||||
this command allows you to use it, even though
|
||||
.Nm
|
||||
does not implement the command. When using direct SPI mode, up to 3 bytes
|
||||
can be omitted.
|
||||
does not implement the command.
|
||||
.It Ar sig
|
||||
Display the device signature bytes.
|
||||
.It Ar spi
|
||||
Enter direct SPI mode. The
|
||||
.Em pgmled
|
||||
pin acts as slave select.
|
||||
.Em Only supported on parallel bitbang programmers.
|
||||
.It Ar part
|
||||
Display the current part settings and parameters. Includes chip
|
||||
specific information including all memory types supported by the
|
||||
device, read/write timing, etc.
|
||||
.It Ar pgm
|
||||
Return to programming mode (from direct SPI mode).
|
||||
.It Ar vtarg voltage
|
||||
Set the target's supply voltage to
|
||||
.Ar voltage
|
||||
Volts.
|
||||
.Em Only supported on the STK500 and STK600 programmer.
|
||||
.It Ar varef Oo Ar channel Oc Ar voltage
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.It Ar varef voltage
|
||||
Set the adjustable voltage source to
|
||||
.Ar voltage
|
||||
Volts.
|
||||
This voltage is normally used to drive the target's
|
||||
.Em Aref
|
||||
input on the STK500.
|
||||
On the Atmel STK600, two reference voltages are available, which
|
||||
can be selected by the optional
|
||||
.Ar channel
|
||||
argument (either 0 or 1).
|
||||
.Em Only supported on the STK500 and STK600 programmer.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.It Ar fosc freq Ns Op M Ns \&| Ns k
|
||||
Set the master oscillator to
|
||||
.Ar freq
|
||||
@@ -766,12 +565,12 @@ An optional trailing letter
|
||||
multiplies by 1E6, a trailing letter
|
||||
.Ar \&k
|
||||
by 1E3.
|
||||
.Em Only supported on the STK500 and STK600 programmer.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.It Ar fosc off
|
||||
Turn the master oscillator off.
|
||||
.Em Only supported on the STK500 and STK600 programmer.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.It Ar sck period
|
||||
.Em STK500 and STK600 programmer only:
|
||||
.Em STK500 programmer only:
|
||||
Set the SCK clock period to
|
||||
.Ar period
|
||||
microseconds.
|
||||
@@ -783,21 +582,12 @@ 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 and JTAGICE3 to specify the
|
||||
ISP clock period when operating the ICE in ISP mode.
|
||||
.It Ar parms
|
||||
.Em STK500 and STK600 programmer only:
|
||||
.Em STK500 programmer only:
|
||||
Display the current voltage and master oscillator parameters.
|
||||
.Pp
|
||||
.Em JTAG ICE only:
|
||||
Display the current target supply voltage and JTAG bit clock rate/period.
|
||||
.It Ar verbose Op Ar level
|
||||
Change (when
|
||||
.Ar level
|
||||
is provided), or display the verbosity level.
|
||||
The initial verbosity level is controlled by the number of
|
||||
.Fl v
|
||||
options given on the commandline.
|
||||
.It Ar \&?
|
||||
.It Ar help
|
||||
Give a short on-line summary of the available commands.
|
||||
@@ -819,192 +609,6 @@ 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 intended 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.
|
||||
.Ss Programmers accepting extended parameters
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar JTAG ICE mkII
|
||||
.It Ar JTAGICE3
|
||||
.It Ar AVR Dragon
|
||||
When using the JTAG ICE mkII, JTAGICE3 or AVR Dragon in JTAG mode, the
|
||||
following extended parameter is accepted:
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar jtagchain=UB,UA,BB,BA
|
||||
Setup the JTAG scan chain for
|
||||
.Ar UB
|
||||
units before,
|
||||
.Ar UA
|
||||
units after,
|
||||
.Ar BB
|
||||
bits before, and
|
||||
.Ar BA
|
||||
bits after the target AVR, respectively.
|
||||
Each AVR unit within the chain shifts by 4 bits.
|
||||
Other JTAG units might require a different bit shift count.
|
||||
.El
|
||||
.It Ar AVR910
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar devcode=VALUE
|
||||
Override the device code selection by using
|
||||
.Ar VALUE
|
||||
as the device code.
|
||||
The programmer is not queried for the list of supported
|
||||
device codes, and the specified
|
||||
.Ar VALUE
|
||||
is not verified but used directly within the
|
||||
.Ql T
|
||||
command sent to the programmer.
|
||||
.Ar VALUE
|
||||
can be specified using the conventional number notation of the
|
||||
C programming language.
|
||||
.El
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar no_blockmode
|
||||
Disables the default checking for block transfer capability.
|
||||
Use
|
||||
.Ar no_blockmode
|
||||
only if your
|
||||
.Ar AVR910
|
||||
programmer creates errors during initial sequence.
|
||||
.El
|
||||
.It Ar buspirate
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar reset={cs,aux,aux2}
|
||||
The default setup assumes the BusPirate's CS output pin connected to
|
||||
the RESET pin on AVR side. It is however possible to have multiple AVRs
|
||||
connected to the same BP with MISO, MOSI and SCK lines common for all of them.
|
||||
In such a case one AVR should have its RESET connected to BusPirate's
|
||||
.Pa CS
|
||||
pin, second AVR's RESET connected to BusPirate's
|
||||
.Pa AUX
|
||||
pin and if your BusPirate has an
|
||||
.Pa AUX2
|
||||
pin (only available on BusPirate version v1a with firmware 3.0 or newer)
|
||||
use that to activate RESET on the third AVR.
|
||||
.Pp
|
||||
It may be a good idea to decouple the BusPirate and the AVR's SPI buses from
|
||||
each other using a 3-state bus buffer. For example 74HC125 or 74HC244 are some
|
||||
good candidates with the latches driven by the appropriate reset pin (cs,
|
||||
aux or aux2). Otherwise the SPI traffic in one active circuit may interfere
|
||||
with programming the AVR in the other design.
|
||||
.It Ar spifreq=<0..7>
|
||||
The SPI speed for the Bus Pirate's binary SPI mode:
|
||||
.Bd -literal
|
||||
0 .. 30 kHz (default)
|
||||
1 .. 125 kHz
|
||||
2 .. 250 kHz
|
||||
3 .. 1 MHz
|
||||
4 .. 2 MHz
|
||||
5 .. 2.6 MHz
|
||||
6 .. 4 MHz
|
||||
7 .. 8 MHz
|
||||
.Ed
|
||||
.It Ar rawfreq=<0..3>
|
||||
Sets the SPI speed and uses the Bus Pirate's binary "raw-wire" mode:
|
||||
.Bd -literal
|
||||
0 .. 5 kHz
|
||||
1 .. 50 kHz
|
||||
2 .. 100 kHz (Firmware v4.2+ only)
|
||||
3 .. 400 kHz (v4.2+)
|
||||
.Ed
|
||||
.Pp
|
||||
The only advantage of the "raw-wire" mode is the different SPI frequencies
|
||||
available. Paged writing is not implemented in this mode.
|
||||
.It Ar ascii
|
||||
Attempt to use ASCII mode even when the firmware supports BinMode (binary
|
||||
mode).
|
||||
BinMode is supported in firmware 2.7 and newer, older FW's either don't
|
||||
have BinMode or their BinMode is buggy. ASCII mode is slower and makes
|
||||
the above
|
||||
.Ar reset= , spifreq=
|
||||
and
|
||||
.Ar rawfreq=
|
||||
parameters unavailable. Be aware that ASCII mode is not guaranteed to work
|
||||
with newer firmware versions, and is retained only to maintain compatability
|
||||
with older firmware versions.
|
||||
.It Ar nopagedwrite
|
||||
Firmware versions 5.10 and newer support a binary mode SPI command that enables
|
||||
whole pages to be written to AVR flash memory at once, resulting in a
|
||||
significant write speed increase. If use of this mode is not desirable for some
|
||||
reason, this option disables it.
|
||||
.It Ar nopagedread
|
||||
Newer firmware versions support in binary mode SPI command some AVR Extended
|
||||
Commands. Using the "Bulk Memory Read from Flash" results in a
|
||||
significant read speed increase. If use of this mode is not desirable for some
|
||||
reason, this option disables it.
|
||||
.It Ar cpufreq=<125..4000>
|
||||
This sets the AUX pin to output a frequency of
|
||||
.Ar n
|
||||
kHz. Connecting
|
||||
the AUX pin to the XTAL1 pin of your MCU, you can provide it a clock,
|
||||
for example when it needs an external clock because of wrong fuses settings.
|
||||
This setting is only available in ASCII mode. (The lower limit was chosen so
|
||||
the CPU frequency is at least for four times the SPI frequency which is in
|
||||
ASCII mode 30kHz.)
|
||||
.It Ar serial_recv_timeout=<1...>
|
||||
This sets the serial receive timeout to the given value.
|
||||
The timeout happens every time avrdude waits for the BusPirate prompt.
|
||||
Especially in ascii mode this happens very often, so setting a smaller value
|
||||
can speed up programming a lot.
|
||||
The default value is 100ms. Using 10ms might work in most cases.
|
||||
.El
|
||||
.It Ar Wiring
|
||||
When using the Wiring programmer type, the
|
||||
following optional extended parameter is accepted:
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar snooze=<0..32767>
|
||||
After performing the port open phase, AVRDUDE will wait/snooze for
|
||||
.Ar snooze
|
||||
milliseconds before continuing to the protocol sync phase.
|
||||
No toggling of DTR/RTS is performed if
|
||||
.Ar snooze
|
||||
is greater than 0.
|
||||
.El
|
||||
.It Ar PICkit2
|
||||
Connection to the PICkit2 programmer:
|
||||
.Bd -literal
|
||||
(AVR) (PICkit2)
|
||||
RST - VPP/MCLR (1)
|
||||
VDD - VDD Target (2) -- possibly optional if AVR self powered
|
||||
GND - GND (3)
|
||||
MISO - PGD (4)
|
||||
SCLK - PDC (5)
|
||||
MOSI - AUX (6)
|
||||
|
||||
.Ed
|
||||
Extended commandline parameters:
|
||||
.Bl -tag -offset indent -width indent
|
||||
.It Ar clockrate=<rate>
|
||||
Sets the SPI clocking rate in Hz (default is 100kHz). Alternately the -B or -i options can be used to set the period.
|
||||
.It Ar timeout=<usb-transaction-timeout>
|
||||
Sets the timeout for USB reads and writes in milliseconds (default is 1500 ms).
|
||||
.El
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -offset indent -width /dev/ppi0XXX
|
||||
.It Pa /dev/ppi0
|
||||
@@ -1022,35 +626,10 @@ library
|
||||
Schematic of programming hardware
|
||||
.El
|
||||
.\" .Sh EXAMPLES
|
||||
.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 DIAGNOSTICS
|
||||
.Sh SEE ALSO
|
||||
.Xr avr-objcopy 1 ,
|
||||
.Xr ppi 4 ,
|
||||
.Xr libelf 3,
|
||||
.Xr readline 3
|
||||
.Pp
|
||||
The AVR microcontroller product description can be found at
|
||||
@@ -1077,14 +656,10 @@ 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 and STK600 in parallel programming mode.
|
||||
.Pp
|
||||
The USBasp and USBtinyISP drivers do not offer any option to distinguish multiple
|
||||
devices connected simultaneously, so effectively only a single device
|
||||
is supported.
|
||||
.Pp
|
||||
The avrftdi driver allows to select specific devices using any combination of vid,pid
|
||||
serial number (usbsn) vendor description (usbvendoror part description (usbproduct)
|
||||
as seen with lsusb or whatever tool used to view USB device information. Multiple
|
||||
devices can be on the bus at the same time. For the H parts, which have multiple MPSSE
|
||||
interfaces, the interface can also be selected. It defaults to interface 'A'.
|
||||
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 anyway.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2007 Joerg Wunsch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef avrdude_h
|
||||
#define avrdude_h
|
||||
|
||||
extern char * progname; /* name of program, for messages */
|
||||
extern char progbuf[]; /* spaces same length as progname */
|
||||
|
||||
extern int ovsigck; /* override signature check (-F) */
|
||||
extern int verbose; /* verbosity level (-v, -vv, ...) */
|
||||
extern int quell_progress; /* quiteness level (-q, -qq) */
|
||||
|
||||
#if defined(WIN32NATIVE)
|
||||
|
||||
#include "ac_cfg.h"
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_USLEEP)
|
||||
int usleep(unsigned int us);
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_GETTIMEOFDAY)
|
||||
struct timezone;
|
||||
int gettimeofday(struct timeval *tv, struct timezone *tz);
|
||||
#endif /* HAVE_GETTIMEOFDAY */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* defined(WIN32NATIVE) */
|
||||
|
||||
#endif
|
||||
1379
avrdude/avrftdi.c
1379
avrdude/avrftdi.c
File diff suppressed because it is too large
Load Diff
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* avrftdi - extension for avrdude, Wolfgang Moser, Ville Voipio
|
||||
* Copyright (C) 2011 Hannes Weisbach, Doug Springer
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef avrftdi_h
|
||||
#define avrfdti_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
extern const char avrftdi_desc[];
|
||||
void avrftdi_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
#pragma once
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(HAVE_LIBFTDI1) && defined(HAVE_LIBUSB_1_0)
|
||||
# if defined(HAVE_LIBUSB_1_0_LIBUSB_H)
|
||||
# include <libusb-1.0/libusb.h>
|
||||
# else
|
||||
# include <libusb.h>
|
||||
# endif
|
||||
# include <libftdi1/ftdi.h>
|
||||
# undef HAVE_LIBFTDI_TYPE_232H
|
||||
# define HAVE_LIBFTDI_TYPE_232H 1
|
||||
#elif defined(HAVE_LIBFTDI) && defined(HAVE_USB_H)
|
||||
/* ftdi.h includes usb.h */
|
||||
#include <ftdi.h>
|
||||
#else
|
||||
#warning No libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.
|
||||
#define DO_NOT_BUILD_AVRFTDI
|
||||
#endif
|
||||
|
||||
#ifndef DO_NOT_BUILD_AVRFTDI
|
||||
|
||||
#include "pgm.h"
|
||||
#include "pindefs.h"
|
||||
|
||||
enum { ERR, WARN, INFO, DEBUG, TRACE };
|
||||
|
||||
#define __log(lvl, fmt, ...) \
|
||||
do { \
|
||||
avrftdi_log(lvl, __func__, __LINE__, fmt, ##__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define log_err(fmt, ...) __log(ERR, fmt, ##__VA_ARGS__)
|
||||
#define log_warn(fmt, ...) __log(WARN, fmt, ##__VA_ARGS__)
|
||||
#define log_info(fmt, ...) __log(INFO, fmt, ##__VA_ARGS__)
|
||||
#define log_debug(fmt, ...) __log(DEBUG, fmt, ##__VA_ARGS__)
|
||||
#define log_trace(fmt, ...) __log(TRACE, fmt, ##__VA_ARGS__)
|
||||
|
||||
#define E(x, ftdi) \
|
||||
do { \
|
||||
if ((x)) \
|
||||
{ \
|
||||
fprintf(stderr, "%s:%d %s() %s: %s (%d)\n\t%s\n", \
|
||||
__FILE__, __LINE__, __FUNCTION__, \
|
||||
#x, strerror(errno), errno, ftdi_get_error_string(ftdi)); \
|
||||
return -1; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define E_VOID(x, ftdi) \
|
||||
do { \
|
||||
if ((x)) \
|
||||
{ \
|
||||
fprintf(stderr, "%s:%d %s() %s: %s (%d)\n\t%s\n", \
|
||||
__FILE__, __LINE__, __FUNCTION__, \
|
||||
#x, strerror(errno), errno, ftdi_get_error_string(ftdi)); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define to_pdata(pgm) \
|
||||
((avrftdi_t *)((pgm)->cookie))
|
||||
|
||||
typedef struct avrftdi_s {
|
||||
/* pointer to struct maintained by libftdi to identify the device */
|
||||
struct ftdi_context* ftdic;
|
||||
/* bitmask of values for pins. bit 0 represents pin 0 ([A|B]DBUS0) */
|
||||
uint16_t pin_value;
|
||||
/* bitmask of pin direction. a '1' make a pin an output.
|
||||
* bit 0 corresponds to pin 0. */
|
||||
uint16_t pin_direction;
|
||||
/* don't know. not useful. someone put it in. */
|
||||
uint16_t led_mask;
|
||||
/* total number of pins supported by a programmer. varies with FTDI chips */
|
||||
int pin_limit;
|
||||
/* internal RX buffer of the device. needed for INOUT transfers */
|
||||
int rx_buffer_size;
|
||||
int tx_buffer_size;
|
||||
/* use bitbanging instead of mpsse spi */
|
||||
bool use_bitbanging;
|
||||
} avrftdi_t;
|
||||
|
||||
void avrftdi_log(int level, const char * func, int line, const char * fmt, ...);
|
||||
|
||||
#endif /* DO_NOT_BUILD_AVRFDTI */
|
||||
|
||||
@@ -1,256 +0,0 @@
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "avr.h"
|
||||
#include "pgm.h"
|
||||
#include "avrpart.h"
|
||||
#include "pindefs.h"
|
||||
#include "tpi.h"
|
||||
#include "usbasp.h"
|
||||
|
||||
#include "avrftdi_tpi.h"
|
||||
#include "avrftdi_private.h"
|
||||
|
||||
#ifndef DO_NOT_BUILD_AVRFTDI
|
||||
|
||||
static void avrftdi_tpi_disable(PROGRAMMER *);
|
||||
static int avrftdi_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p);
|
||||
|
||||
#ifdef notyet
|
||||
static void
|
||||
avrftdi_debug_frame(uint16_t frame)
|
||||
{
|
||||
static char bit_name[] = "IDLES01234567PSS";
|
||||
//static char bit_name[] = "SSP76543210SELDI";
|
||||
char line0[34], line1[34], line2[34];
|
||||
int bit, pos;
|
||||
|
||||
for(bit = 0; bit < 16; bit++)
|
||||
{
|
||||
pos = 16 - bit - 1;
|
||||
if(frame & (1 << pos))
|
||||
{
|
||||
line0[2*pos] = '_';
|
||||
line0[2*pos+1] = ' ';
|
||||
|
||||
line2[2*pos] = ' ';
|
||||
line2[2*pos+1] = ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
line0[2*pos] = ' ';
|
||||
line0[2*pos+1] = ' ';
|
||||
|
||||
line2[2*pos] = '-';
|
||||
line2[2*pos+1] = ' ';
|
||||
}
|
||||
|
||||
line1[2*pos] = bit_name[pos];
|
||||
line1[2*pos+1] = ' ';
|
||||
|
||||
}
|
||||
|
||||
line0[32] = 0;
|
||||
line1[32] = 0;
|
||||
line2[32] = 0;
|
||||
|
||||
log_debug("%s\n", line0);
|
||||
log_debug("%s\n", line1);
|
||||
//log_debug("%s\n", line2);
|
||||
}
|
||||
#endif /* notyet */
|
||||
|
||||
int
|
||||
avrftdi_tpi_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
int ret;
|
||||
|
||||
avrftdi_t* pdata = to_pdata(pgm);
|
||||
unsigned char buf[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 0x01, 0x00, 0xff, 0xff };
|
||||
|
||||
log_info("Using TPI interface\n");
|
||||
|
||||
pgm->program_enable = avrftdi_tpi_program_enable;
|
||||
pgm->cmd_tpi = avrftdi_cmd_tpi;
|
||||
pgm->chip_erase = avr_tpi_chip_erase;
|
||||
pgm->disable = avrftdi_tpi_disable;
|
||||
|
||||
pgm->paged_load = NULL;
|
||||
pgm->paged_write = NULL;
|
||||
|
||||
log_info("Setting /Reset pin low\n");
|
||||
pgm->setpin(pgm, PIN_AVR_RESET, OFF);
|
||||
pgm->setpin(pgm, PIN_AVR_SCK, OFF);
|
||||
pgm->setpin(pgm, PIN_AVR_MOSI, ON);
|
||||
usleep(20 * 1000);
|
||||
|
||||
pgm->setpin(pgm, PIN_AVR_RESET, ON);
|
||||
/* worst case 128ms */
|
||||
usleep(2 * 128 * 1000);
|
||||
|
||||
/*setting rst back to 0 */
|
||||
pgm->setpin(pgm, PIN_AVR_RESET, OFF);
|
||||
/*wait at least 20ms bevor issuing spi commands to avr */
|
||||
usleep(20 * 1000);
|
||||
|
||||
log_info("Sending 16 init clock cycles ...\n");
|
||||
ret = ftdi_write_data(pdata->ftdic, buf, sizeof(buf));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define TPI_PARITY_MASK 0x2000
|
||||
|
||||
static uint16_t
|
||||
tpi_byte2frame(uint8_t byte)
|
||||
{
|
||||
uint16_t frame = 0xc00f;
|
||||
int parity = __builtin_popcount(byte) & 1;
|
||||
|
||||
frame |= ((byte << 5) & 0x1fe0);
|
||||
|
||||
if(parity)
|
||||
frame |= TPI_PARITY_MASK;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
static int
|
||||
tpi_frame2byte(uint16_t frame, uint8_t * byte)
|
||||
{
|
||||
/* drop idle and start bit(s) */
|
||||
*byte = (frame >> 5) & 0xff;
|
||||
|
||||
int parity = __builtin_popcount(*byte) & 1;
|
||||
int parity_rcvd = (frame & TPI_PARITY_MASK) ? 1 : 0;
|
||||
|
||||
return parity != parity_rcvd;
|
||||
}
|
||||
|
||||
#ifdef notyet
|
||||
static int
|
||||
avrftdi_tpi_break(PROGRAMMER * pgm)
|
||||
{
|
||||
unsigned char buffer[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 1, 0, 0, 0 };
|
||||
E(ftdi_write_data(to_pdata(pgm)->ftdic, buffer, sizeof(buffer)) != sizeof(buffer), to_pdata(pgm)->ftdic);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* notyet */
|
||||
|
||||
static int
|
||||
avrftdi_tpi_write_byte(PROGRAMMER * pgm, unsigned char byte)
|
||||
{
|
||||
uint16_t frame;
|
||||
|
||||
struct ftdi_context* ftdic = to_pdata(pgm)->ftdic;
|
||||
|
||||
unsigned char buffer[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 1, 0, 0, 0 };
|
||||
|
||||
frame = tpi_byte2frame(byte);
|
||||
|
||||
buffer[3] = frame & 0xff;
|
||||
buffer[4] = frame >> 8;
|
||||
|
||||
log_trace("Byte %02x, frame: %04x, MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
|
||||
byte, frame, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4]);
|
||||
|
||||
//avrftdi_debug_frame(frame);
|
||||
|
||||
E(ftdi_write_data(ftdic, buffer, sizeof(buffer)) != sizeof(buffer), ftdic);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TPI_FRAME_SIZE 12
|
||||
#define TPI_IDLE_BITS 2
|
||||
|
||||
static int
|
||||
avrftdi_tpi_read_byte(PROGRAMMER * pgm, unsigned char * byte)
|
||||
{
|
||||
uint16_t frame;
|
||||
|
||||
/* use 2 guard bits, 2 default idle bits + 12 frame bits = 16 bits total */
|
||||
const int bytes = 3;
|
||||
int err, i = 0;
|
||||
|
||||
unsigned char buffer[4];
|
||||
|
||||
buffer[0] = MPSSE_DO_READ | MPSSE_LSB;
|
||||
buffer[1] = (bytes-1) & 0xff;
|
||||
buffer[2] = ((bytes-1) >> 8) & 0xff;
|
||||
buffer[3] = SEND_IMMEDIATE;
|
||||
|
||||
log_trace("MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x (Read frame)\n",
|
||||
buffer[0], buffer[1], buffer[2], buffer[3]);
|
||||
|
||||
ftdi_write_data(to_pdata(pgm)->ftdic, buffer, 4);
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
int err = ftdi_read_data(to_pdata(pgm)->ftdic, &buffer[i], bytes - i);
|
||||
E(err < 0, to_pdata(pgm)->ftdic);
|
||||
i += err;
|
||||
} while(i < bytes);
|
||||
|
||||
|
||||
log_trace("MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x (Read frame)\n",
|
||||
buffer[0], buffer[1], buffer[2], buffer[3]);
|
||||
|
||||
|
||||
frame = buffer[0] | (buffer[1] << 8);
|
||||
|
||||
err = tpi_frame2byte(frame, byte);
|
||||
log_trace("Frame: 0x%04x, byte: 0x%02x\n", frame, *byte);
|
||||
|
||||
//avrftdi_debug_frame(frame);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
avrftdi_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
return avr_tpi_program_enable(pgm, p, TPIPCR_GT_2b);
|
||||
}
|
||||
|
||||
int
|
||||
avrftdi_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd, int cmd_len,
|
||||
unsigned char *res, int res_len)
|
||||
{
|
||||
int i, err = 0;
|
||||
|
||||
for(i = 0; i < cmd_len; i++)
|
||||
{
|
||||
err = avrftdi_tpi_write_byte(pgm, cmd[i]);
|
||||
if(err)
|
||||
return err;
|
||||
}
|
||||
|
||||
for(i = 0; i < res_len; i++)
|
||||
{
|
||||
err = avrftdi_tpi_read_byte(pgm, &res[i]);
|
||||
if(err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
avrftdi_tpi_disable(PROGRAMMER * pgm)
|
||||
{
|
||||
unsigned char cmd[] = {TPI_OP_SSTCS(TPIPCR), 0};
|
||||
pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0);
|
||||
|
||||
log_info("Leaving Programming mode.\n");
|
||||
}
|
||||
|
||||
#endif /* DO_NOT_BUILD_AVRFTDI */
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "pgm.h"
|
||||
#include "avrpart.h"
|
||||
|
||||
//int avrftdi_tpi_write_byte(PROGRAMMER * pgm, unsigned char byte);
|
||||
//int avrftdi_tpi_read_byte(PROGRAMMER * pgm, unsigned char * byte);
|
||||
int avrftdi_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd, int cmd_len,
|
||||
unsigned char *res, int res_len);
|
||||
int avrftdi_tpi_initialize(PROGRAMMER * pgm, AVRPART * p);
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
/*
|
||||
* 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
|
||||
@@ -15,7 +14,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -23,10 +23,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avrpart.h"
|
||||
#include "pindefs.h"
|
||||
|
||||
extern char * progname;
|
||||
|
||||
|
||||
/***
|
||||
*** Elementary functions dealing with OPCODE structures
|
||||
***/
|
||||
@@ -46,30 +48,6 @@ OPCODE * avr_new_opcode(void)
|
||||
return m;
|
||||
}
|
||||
|
||||
static OPCODE * avr_dup_opcode(OPCODE * op)
|
||||
{
|
||||
OPCODE * m;
|
||||
|
||||
/* this makes life easier */
|
||||
if (op == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m = (OPCODE *)malloc(sizeof(*m));
|
||||
if (m == NULL) {
|
||||
fprintf(stderr, "avr_dup_opcode(): out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memcpy(m, op, sizeof(*m));
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
void avr_free_opcode(OPCODE * op)
|
||||
{
|
||||
free(op);
|
||||
}
|
||||
|
||||
/*
|
||||
* avr_set_bits()
|
||||
@@ -185,28 +163,7 @@ int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* avr_get_output_index()
|
||||
*
|
||||
* Calculate the byte number of the output data based on the
|
||||
* opcode data.
|
||||
*/
|
||||
int avr_get_output_index(OPCODE * op)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i=0; i<32; i++) {
|
||||
if (op->bit[i].type == AVR_CMDBIT_OUTPUT) {
|
||||
j = 3 - i / 8;
|
||||
return j;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static char * avr_op_str(int op)
|
||||
char * avr_op_str(int op)
|
||||
{
|
||||
switch (op) {
|
||||
case AVR_OP_READ : return "READ"; break;
|
||||
@@ -217,7 +174,6 @@ static 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;
|
||||
@@ -226,7 +182,7 @@ static char * avr_op_str(int op)
|
||||
}
|
||||
|
||||
|
||||
static char * bittype(int type)
|
||||
char * bittype(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case AVR_CMDBIT_IGNORE : return "IGNORE"; break;
|
||||
@@ -277,12 +233,6 @@ int avr_initmem(AVRPART * p)
|
||||
progname, m->desc, m->size);
|
||||
return -1;
|
||||
}
|
||||
m->tags = (unsigned char *) malloc(m->size);
|
||||
if (m->tags == NULL) {
|
||||
fprintf(stderr, "%s: can't alloc buffer for %s size of %d bytes\n",
|
||||
progname, m->desc, m->size);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -292,62 +242,23 @@ int avr_initmem(AVRPART * p)
|
||||
AVRMEM * avr_dup_mem(AVRMEM * m)
|
||||
{
|
||||
AVRMEM * n;
|
||||
int i;
|
||||
|
||||
n = avr_new_memtype();
|
||||
|
||||
*n = *m;
|
||||
|
||||
if (m->buf != NULL) {
|
||||
n->buf = (unsigned char *)malloc(n->size);
|
||||
if (n->buf == NULL) {
|
||||
fprintf(stderr,
|
||||
"avr_dup_mem(): out of memory (memsize=%d)\n",
|
||||
n->size);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(n->buf, m->buf, n->size);
|
||||
}
|
||||
|
||||
if (m->tags != NULL) {
|
||||
n->tags = (unsigned char *)malloc(n->size);
|
||||
if (n->tags == NULL) {
|
||||
fprintf(stderr,
|
||||
"avr_dup_mem(): out of memory (memsize=%d)\n",
|
||||
n->size);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(n->tags, m->tags, n->size);
|
||||
}
|
||||
|
||||
for (i = 0; i < AVR_OP_MAX; i++) {
|
||||
n->op[i] = avr_dup_opcode(n->op[i]);
|
||||
n->buf = (unsigned char *)malloc(n->size);
|
||||
if (n->buf == NULL) {
|
||||
fprintf(stderr,
|
||||
"avr_dup_mem(): out of memory (memsize=%d)\n",
|
||||
n->size);
|
||||
exit(1);
|
||||
}
|
||||
memset(n->buf, 0, n->size);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void avr_free_mem(AVRMEM * m)
|
||||
{
|
||||
int i;
|
||||
if (m->buf != NULL) {
|
||||
free(m->buf);
|
||||
m->buf = NULL;
|
||||
}
|
||||
if (m->tags != NULL) {
|
||||
free(m->tags);
|
||||
m->tags = NULL;
|
||||
}
|
||||
for(i=0;i<sizeof(m->op)/sizeof(m->op[0]);i++)
|
||||
{
|
||||
if (m->op[i] != NULL)
|
||||
{
|
||||
avr_free_opcode(m->op[i]);
|
||||
m->op[i] = NULL;
|
||||
}
|
||||
}
|
||||
free(m);
|
||||
}
|
||||
|
||||
AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
|
||||
{
|
||||
@@ -374,7 +285,7 @@ AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
|
||||
}
|
||||
|
||||
|
||||
void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, int type,
|
||||
void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
|
||||
int verbose)
|
||||
{
|
||||
int i, j;
|
||||
@@ -406,7 +317,7 @@ void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, int type,
|
||||
m->max_write_delay,
|
||||
m->readback[0],
|
||||
m->readback[1]);
|
||||
if (verbose > 4) {
|
||||
if (verbose > 2) {
|
||||
fprintf(stderr,
|
||||
"%s Memory Ops:\n"
|
||||
"%s Oeration Inst Bit Bit Type Bitno Value\n"
|
||||
@@ -458,9 +369,6 @@ 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->ocdrev = -1;
|
||||
|
||||
p->mem = lcreat(NULL, 0);
|
||||
|
||||
@@ -473,7 +381,6 @@ AVRPART * avr_dup_part(AVRPART * d)
|
||||
AVRPART * p;
|
||||
LISTID save;
|
||||
LNODEID ln;
|
||||
int i;
|
||||
|
||||
p = avr_new_part();
|
||||
save = p->mem;
|
||||
@@ -486,28 +393,9 @@ AVRPART * avr_dup_part(AVRPART * d)
|
||||
ladd(p->mem, avr_dup_mem(ldata(ln)));
|
||||
}
|
||||
|
||||
for (i = 0; i < AVR_OP_MAX; i++) {
|
||||
p->op[i] = avr_dup_opcode(p->op[i]);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void avr_free_part(AVRPART * d)
|
||||
{
|
||||
int i;
|
||||
ldestroy_cb(d->mem, (void(*)(void *))avr_free_mem);
|
||||
d->mem = NULL;
|
||||
for(i=0;i<sizeof(d->op)/sizeof(d->op[0]);i++)
|
||||
{
|
||||
if (d->op[i] != NULL)
|
||||
{
|
||||
avr_free_opcode(d->op[i]);
|
||||
d->op[i] = NULL;
|
||||
}
|
||||
}
|
||||
free(d);
|
||||
}
|
||||
|
||||
AVRPART * locate_part(LISTID parts, char * partdesc)
|
||||
{
|
||||
@@ -544,48 +432,22 @@ AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over the list of avrparts given as "avrparts", and
|
||||
* call the callback function cb for each entry found. cb is being
|
||||
* passed the following arguments:
|
||||
* . the name of the avrpart (for -p)
|
||||
* . the descriptive text given in the config file
|
||||
* . the name of the config file this avrpart has been defined in
|
||||
* . the line number of the config file this avrpart has been defined at
|
||||
* . the "cookie" passed into walk_avrparts() (opaque client data)
|
||||
*/
|
||||
void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie)
|
||||
void list_parts(FILE * f, char * prefix, LISTID parts)
|
||||
{
|
||||
LNODEID ln1;
|
||||
AVRPART * p;
|
||||
|
||||
for (ln1 = lfirst(avrparts); ln1; ln1 = lnext(ln1)) {
|
||||
for (ln1=lfirst(parts); ln1; ln1=lnext(ln1)) {
|
||||
p = ldata(ln1);
|
||||
cb(p->id, p->desc, p->config_file, p->lineno, cookie);
|
||||
fprintf(f, "%s%-4s = %-15s [%s:%d]\n",
|
||||
prefix, p->id, p->desc, p->config_file, p->lineno);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare function to sort the list of programmers
|
||||
*/
|
||||
static int sort_avrparts_compare(AVRPART * p1,AVRPART * p2)
|
||||
{
|
||||
if(p1 == NULL || p2 == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return strncasecmp(p1->desc,p2->desc,AVR_DESCLEN);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sort the list of programmers given as "programmers"
|
||||
*/
|
||||
void sort_avrparts(LISTID avrparts)
|
||||
{
|
||||
lsort(avrparts,(int (*)(void*, void*)) sort_avrparts_compare);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static char * reset_disp_str(int r)
|
||||
char * reset_disp_str(int r)
|
||||
{
|
||||
switch (r) {
|
||||
case RESET_DEDICATED : return "dedicated";
|
||||
@@ -595,37 +457,49 @@ static char * reset_disp_str(int r)
|
||||
}
|
||||
|
||||
|
||||
void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose)
|
||||
char * pin_name(int pinno)
|
||||
{
|
||||
switch (pinno) {
|
||||
case PIN_AVR_RESET : return "RESET";
|
||||
case PIN_AVR_MISO : return "MISO";
|
||||
case PIN_AVR_MOSI : return "MOSI";
|
||||
case PIN_AVR_SCK : return "SCK";
|
||||
default : return "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose)
|
||||
{
|
||||
int i;
|
||||
char * buf;
|
||||
const char * px;
|
||||
char * px;
|
||||
LNODEID ln;
|
||||
AVRMEM * m;
|
||||
|
||||
fprintf(f,
|
||||
"%sAVR Part : %s\n"
|
||||
"%sChip Erase delay : %d us\n"
|
||||
"%sPAGEL : P%02X\n"
|
||||
"%sBS2 : P%02X\n"
|
||||
"%sRESET disposition : %s\n"
|
||||
"%sRETRY pulse : %s\n"
|
||||
"%sserial program mode : %s\n"
|
||||
"%sparallel program mode : %s\n"
|
||||
"%sTimeout : %d\n"
|
||||
"%sStabDelay : %d\n"
|
||||
"%sCmdexeDelay : %d\n"
|
||||
"%sSyncLoops : %d\n"
|
||||
"%sByteDelay : %d\n"
|
||||
"%sPollIndex : %d\n"
|
||||
"%sPollValue : 0x%02x\n"
|
||||
"%sMemory Detail :\n\n",
|
||||
"%sAVR Part : %s\n"
|
||||
"%sChip Erase delay : %d us\n"
|
||||
"%sPAGEL : P%02X\n"
|
||||
"%sBS2 : P%02X\n"
|
||||
"%sRESET disposition : %s\n"
|
||||
"%sRETRY pulse : %s\n"
|
||||
"%sserial program mode : %s\n"
|
||||
"%sparallel program mode : %s\n"
|
||||
"%sTimeout : %d\n"
|
||||
"%sStabDelay : %d\n"
|
||||
"%sCmdexeDelay : %d\n"
|
||||
"%sSyncLoops : %d\n"
|
||||
"%sByteDelay : %d\n"
|
||||
"%sPollIndex : %d\n"
|
||||
"%sPollValue : 0x%02x\n"
|
||||
"%sMemory Detail :\n\n",
|
||||
prefix, p->desc,
|
||||
prefix, p->chip_erase_delay,
|
||||
prefix, p->pagel,
|
||||
prefix, p->bs2,
|
||||
prefix, reset_disp_str(p->reset_disposition),
|
||||
prefix, avr_pin_name(p->retry_pulse),
|
||||
prefix, pin_name(p->retry_pulse),
|
||||
prefix, (p->flags & AVRPART_SERIALOK) ? "yes" : "no",
|
||||
prefix, (p->flags & AVRPART_PARALLELOK) ?
|
||||
((p->flags & AVRPART_PSEUDOPARALLEL) ? "psuedo" : "yes") : "no",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
@@ -14,19 +13,22 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* 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 avrpart_h
|
||||
#define avrpart_h
|
||||
#ifndef __avrpart_h__
|
||||
#define __avrpart_h__
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "lists.h"
|
||||
|
||||
|
||||
extern LISTID part_list;
|
||||
|
||||
/*
|
||||
* AVR serial programming instructions
|
||||
*/
|
||||
@@ -39,7 +41,6 @@ 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,
|
||||
@@ -60,12 +61,6 @@ 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
|
||||
*/
|
||||
@@ -86,22 +81,9 @@ 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 AVRPART_HAS_PDI 0x0080 /* part has PDI i/f rather than ISP (ATxmega) */
|
||||
#define AVRPART_AVR32 0x0100 /* part is in AVR32 family */
|
||||
#define AVRPART_INIT_SMC 0x0200 /* part will undergo chip erase */
|
||||
#define AVRPART_WRITE 0x0400 /* at least one write operation specified */
|
||||
#define AVRPART_HAS_TPI 0x0800 /* part has TPI i/f rather than ISP (ATtiny4/5/9/10) */
|
||||
#define AVRPART_IS_AT90S1200 0x1000 /* part is an AT90S1200 (needs special treatment) */
|
||||
|
||||
#define AVR_DESCLEN 64
|
||||
#define AVR_IDLEN 32
|
||||
#define CTL_STACK_SIZE 32
|
||||
#define FLASH_INSTR_SIZE 3
|
||||
#define EEPROM_INSTR_SIZE 20
|
||||
|
||||
#define TAG_ALLOCATED 1 /* memory byte is allocated */
|
||||
|
||||
typedef struct avrpart {
|
||||
char desc[AVR_DESCLEN]; /* long part name */
|
||||
char id[AVR_IDLEN]; /* short part name */
|
||||
@@ -110,7 +92,6 @@ 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_*) */
|
||||
@@ -127,37 +108,10 @@ 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 */
|
||||
unsigned short eecr; /* JTAC ICE mkII XML file parameter */
|
||||
unsigned int mcu_base; /* Base address of MCU control block in ATxmega devices */
|
||||
unsigned int nvm_base; /* Base address of NVM controller in ATxmega devices */
|
||||
int ocdrev; /* OCD revision (JTAGICE3 parameter, from AS6 XML files) */
|
||||
|
||||
OPCODE * op[AVR_OP_MAX]; /* opcodes */
|
||||
|
||||
@@ -173,13 +127,12 @@ typedef struct avrmem {
|
||||
int size; /* total memory size in bytes */
|
||||
int page_size; /* size of memory page (if page addressed) */
|
||||
int num_pages; /* number of pages (if page addressed) */
|
||||
unsigned int offset; /* offset in IO memory (ATxmega) */
|
||||
int min_write_delay; /* microseconds */
|
||||
int max_write_delay; /* microseconds */
|
||||
int pwroff_after_write; /* after this memory type is written to,
|
||||
the device must be powered off and
|
||||
back on, see errata
|
||||
http://www.atmel.com/dyn/resources/prod_documents/doc1280.pdf */
|
||||
http://www.atmel.com/atmel/acrobat/doc1280.pdf */
|
||||
unsigned char readback[2]; /* polled read-back values */
|
||||
|
||||
int mode; /* stk500 v2 xml file parameter */
|
||||
@@ -189,47 +142,30 @@ typedef struct avrmem {
|
||||
int pollindex; /* stk500 v2 xml file parameter */
|
||||
|
||||
unsigned char * buf; /* pointer to memory buffer */
|
||||
unsigned char * tags; /* allocation tags */
|
||||
OPCODE * op[AVR_OP_MAX]; /* opcodes */
|
||||
} AVRMEM;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Functions for OPCODE structures */
|
||||
OPCODE * avr_new_opcode(void);
|
||||
void avr_free_opcode(OPCODE * op);
|
||||
int avr_set_bits(OPCODE * op, unsigned char * cmd);
|
||||
int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr);
|
||||
int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data);
|
||||
int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data);
|
||||
int avr_get_output_index(OPCODE * op);
|
||||
|
||||
/* Functions for AVRMEM structures */
|
||||
AVRMEM * avr_new_memtype(void);
|
||||
int avr_initmem(AVRPART * p);
|
||||
AVRMEM * avr_dup_mem(AVRMEM * m);
|
||||
void avr_free_mem(AVRMEM * m);
|
||||
AVRMEM * avr_locate_mem(AVRPART * p, char * desc);
|
||||
void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, int type,
|
||||
void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
|
||||
int verbose);
|
||||
|
||||
/* Functions for AVRPART structures */
|
||||
AVRPART * avr_new_part(void);
|
||||
AVRPART * avr_dup_part(AVRPART * d);
|
||||
void avr_free_part(AVRPART * d);
|
||||
AVRPART * locate_part(LISTID parts, char * partdesc);
|
||||
AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode);
|
||||
void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose);
|
||||
void list_parts(FILE * f, char * prefix, LISTID parts);
|
||||
void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose);
|
||||
|
||||
typedef void (*walk_avrparts_cb)(const char *name, const char *desc,
|
||||
const char *cfgname, int cfglineno,
|
||||
void *cookie);
|
||||
void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie);
|
||||
void sort_avrparts(LISTID avrparts);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* avrpart_h */
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
* 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) 2011 Darell Tan <darell.tan@gmail.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
|
||||
@@ -15,7 +14,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/* $Id$ */
|
||||
|
||||
@@ -28,142 +28,17 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if !defined(WIN32NATIVE)
|
||||
# include <signal.h>
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "pindefs.h"
|
||||
#include "pgm.h"
|
||||
#include "par.h"
|
||||
#include "serbb.h"
|
||||
#include "tpi.h"
|
||||
|
||||
static int delay_decrement;
|
||||
#define SLOW_TOGGLE 0
|
||||
|
||||
#if defined(WIN32NATIVE)
|
||||
static int has_perfcount;
|
||||
static LARGE_INTEGER freq;
|
||||
#else
|
||||
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)
|
||||
{
|
||||
#if defined(WIN32NATIVE)
|
||||
/*
|
||||
* If the hardware supports a high-resolution performance counter,
|
||||
* we ultimately prefer that one, as it gives quite accurate delays
|
||||
* on modern high-speed CPUs.
|
||||
*/
|
||||
if (QueryPerformanceFrequency(&freq))
|
||||
{
|
||||
has_perfcount = 1;
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr,
|
||||
"%s: Using performance counter for bitbang delays\n",
|
||||
progname);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If a high-resolution performance counter is not available, we
|
||||
* don't have any Win32 implementation for setting up the
|
||||
* per-microsecond delay count, 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 (verbose >= 2)
|
||||
fprintf(stderr,
|
||||
"%s: Using guessed per-microsecond delay count for bitbang delays\n",
|
||||
progname);
|
||||
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 */
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 defined(WIN32NATIVE)
|
||||
LARGE_INTEGER countNow, countEnd;
|
||||
|
||||
if (has_perfcount)
|
||||
{
|
||||
QueryPerformanceCounter(&countNow);
|
||||
countEnd.QuadPart = countNow.QuadPart + freq.QuadPart * us / 1000000ll;
|
||||
|
||||
while (countNow.QuadPart < countEnd.QuadPart)
|
||||
QueryPerformanceCounter(&countNow);
|
||||
}
|
||||
else /* no performance counters -- run normal uncalibrated delay */
|
||||
{
|
||||
#endif /* WIN32NATIVE */
|
||||
volatile int del = us * delay_decrement;
|
||||
|
||||
while (del > 0)
|
||||
del--;
|
||||
#if defined(WIN32NATIVE)
|
||||
}
|
||||
#endif /* WIN32NATIVE */
|
||||
}
|
||||
extern char * progname;
|
||||
extern int do_cycles;
|
||||
extern int verbose;
|
||||
|
||||
/*
|
||||
* transmit and receive a byte of data to/from the AVR device
|
||||
@@ -213,93 +88,6 @@ static unsigned char bitbang_txrx(PROGRAMMER * pgm, unsigned char byte)
|
||||
return rbyte;
|
||||
}
|
||||
|
||||
static int bitbang_tpi_clk(PROGRAMMER * pgm)
|
||||
{
|
||||
unsigned char r = 0;
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_SCK], 1);
|
||||
|
||||
r = pgm->getpin(pgm, pgm->pinno[PIN_AVR_MISO]);
|
||||
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_SCK], 0);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void bitbang_tpi_tx(PROGRAMMER * pgm, unsigned char byte)
|
||||
{
|
||||
int i;
|
||||
unsigned char b, parity;
|
||||
|
||||
/* start bit */
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], 0);
|
||||
bitbang_tpi_clk(pgm);
|
||||
|
||||
parity = 0;
|
||||
for (i = 0; i <= 7; i++) {
|
||||
b = (byte >> i) & 0x01;
|
||||
parity ^= b;
|
||||
|
||||
/* set the data input line as desired */
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], b);
|
||||
bitbang_tpi_clk(pgm);
|
||||
}
|
||||
|
||||
/* parity bit */
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], parity);
|
||||
bitbang_tpi_clk(pgm);
|
||||
|
||||
/* 2 stop bits */
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], 1);
|
||||
bitbang_tpi_clk(pgm);
|
||||
bitbang_tpi_clk(pgm);
|
||||
}
|
||||
|
||||
int bitbang_tpi_rx(PROGRAMMER * pgm)
|
||||
{
|
||||
int i;
|
||||
unsigned char b, rbyte, parity;
|
||||
|
||||
/* make sure pin is on for "pullup" */
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], 1);
|
||||
|
||||
/* wait for start bit (up to 10 bits) */
|
||||
b = 1;
|
||||
for (i = 0; i < 10; i++) {
|
||||
b = bitbang_tpi_clk(pgm);
|
||||
if (b == 0)
|
||||
break;
|
||||
}
|
||||
if (b != 0) {
|
||||
fprintf(stderr, "bitbang_tpi_rx: start bit not received correctly\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rbyte = 0;
|
||||
parity = 0;
|
||||
for (i=0; i<=7; i++) {
|
||||
b = bitbang_tpi_clk(pgm);
|
||||
parity ^= b;
|
||||
|
||||
rbyte |= b << i;
|
||||
}
|
||||
|
||||
/* parity bit */
|
||||
if (bitbang_tpi_clk(pgm) != parity) {
|
||||
fprintf(stderr, "bitbang_tpi_rx: parity bit is wrong\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 2 stop bits */
|
||||
b = 1;
|
||||
b &= bitbang_tpi_clk(pgm);
|
||||
b &= bitbang_tpi_clk(pgm);
|
||||
if (b != 1) {
|
||||
fprintf(stderr, "bitbang_tpi_rx: stop bits not received correctly\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rbyte;
|
||||
}
|
||||
|
||||
int bitbang_rdy_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
@@ -330,8 +118,8 @@ int bitbang_vfy_led(PROGRAMMER * pgm, int value)
|
||||
* transmit an AVR device command and return the results; 'cmd' and
|
||||
* 'res' must point to at least a 4 byte data buffer
|
||||
*/
|
||||
int bitbang_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
unsigned char *res)
|
||||
int bitbang_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4])
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -355,77 +143,6 @@ int bitbang_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bitbang_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
int cmd_len, unsigned char *res, int res_len)
|
||||
{
|
||||
int i, r;
|
||||
|
||||
pgm->pgm_led(pgm, ON);
|
||||
|
||||
for (i=0; i<cmd_len; i++) {
|
||||
bitbang_tpi_tx(pgm, cmd[i]);
|
||||
}
|
||||
|
||||
r = 0;
|
||||
for (i=0; i<res_len; i++) {
|
||||
r = bitbang_tpi_rx(pgm);
|
||||
if (r == -1)
|
||||
break;
|
||||
res[i] = r;
|
||||
}
|
||||
|
||||
if(verbose >= 2)
|
||||
{
|
||||
fprintf(stderr, "bitbang_cmd_tpi(): [ ");
|
||||
for(i = 0; i < cmd_len; i++)
|
||||
fprintf(stderr, "%02X ", cmd[i]);
|
||||
fprintf(stderr, "] [ ");
|
||||
for(i = 0; i < res_len; i++)
|
||||
{
|
||||
fprintf(stderr, "%02X ", res[i]);
|
||||
}
|
||||
fprintf(stderr, "]\n");
|
||||
}
|
||||
|
||||
pgm->pgm_led(pgm, OFF);
|
||||
if (r == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* transmit bytes via SPI and return the results; 'cmd' and
|
||||
* 'res' must point to data buffers
|
||||
*/
|
||||
int bitbang_spi(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
unsigned char *res, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_LED_PGM], 0);
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
res[i] = bitbang_txrx(pgm, cmd[i]);
|
||||
}
|
||||
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_LED_PGM], 1);
|
||||
|
||||
if(verbose >= 2)
|
||||
{
|
||||
fprintf(stderr, "bitbang_cmd(): [ ");
|
||||
for(i = 0; i < count; i++)
|
||||
fprintf(stderr, "%02X ", cmd[i]);
|
||||
fprintf(stderr, "] [ ");
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
fprintf(stderr, "%02X ", res[i]);
|
||||
}
|
||||
fprintf(stderr, "]\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* issue the 'chip erase' command to the AVR device
|
||||
@@ -434,39 +151,6 @@ int bitbang_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
unsigned char cmd[4];
|
||||
unsigned char res[4];
|
||||
AVRMEM *mem;
|
||||
|
||||
if (p->flags & AVRPART_HAS_TPI) {
|
||||
pgm->pgm_led(pgm, ON);
|
||||
|
||||
while (avr_tpi_poll_nvmbsy(pgm));
|
||||
|
||||
/* NVMCMD <- CHIP_ERASE */
|
||||
bitbang_tpi_tx(pgm, TPI_CMD_SOUT | TPI_SIO_ADDR(TPI_IOREG_NVMCMD));
|
||||
bitbang_tpi_tx(pgm, TPI_NVMCMD_CHIP_ERASE); /* CHIP_ERASE */
|
||||
|
||||
/* Set Pointer Register */
|
||||
mem = avr_locate_mem(p, "flash");
|
||||
if (mem == NULL) {
|
||||
fprintf(stderr, "No flash memory to erase for part %s\n",
|
||||
p->desc);
|
||||
return -1;
|
||||
}
|
||||
bitbang_tpi_tx(pgm, TPI_CMD_SSTPR | 0);
|
||||
bitbang_tpi_tx(pgm, (mem->offset & 0xFF) | 1); /* high byte */
|
||||
bitbang_tpi_tx(pgm, TPI_CMD_SSTPR | 1);
|
||||
bitbang_tpi_tx(pgm, (mem->offset >> 8) & 0xFF);
|
||||
|
||||
/* write dummy value to start erase */
|
||||
bitbang_tpi_tx(pgm, TPI_CMD_SST);
|
||||
bitbang_tpi_tx(pgm, 0xFF);
|
||||
|
||||
while (avr_tpi_poll_nvmbsy(pgm));
|
||||
|
||||
pgm->pgm_led(pgm, OFF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
|
||||
fprintf(stderr, "chip erase instruction not defined for part \"%s\"\n",
|
||||
@@ -495,19 +179,6 @@ int bitbang_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
unsigned char cmd[4];
|
||||
unsigned char res[4];
|
||||
int i;
|
||||
|
||||
if (p->flags & AVRPART_HAS_TPI) {
|
||||
/* enable NVM programming */
|
||||
bitbang_tpi_tx(pgm, TPI_CMD_SKEY);
|
||||
for (i = sizeof(tpi_skey) - 1; i >= 0; i--)
|
||||
bitbang_tpi_tx(pgm, tpi_skey[i]);
|
||||
|
||||
/* check NVMEN bit */
|
||||
bitbang_tpi_tx(pgm, TPI_CMD_SLDCS | TPI_REG_TPISR);
|
||||
i = bitbang_tpi_rx(pgm);
|
||||
return (i != -1 && (i & TPI_REG_TPISR_NVMEN)) ? 0 : -2;
|
||||
}
|
||||
|
||||
if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
|
||||
fprintf(stderr, "program enable instruction not defined for part \"%s\"\n",
|
||||
@@ -532,68 +203,15 @@ int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
int rc;
|
||||
int tries;
|
||||
int i;
|
||||
|
||||
bitbang_calibrate_delay();
|
||||
|
||||
pgm->powerup(pgm);
|
||||
usleep(20000);
|
||||
|
||||
/* TPIDATA is a single line, so MISO & MOSI should be connected */
|
||||
if (p->flags & AVRPART_HAS_TPI) {
|
||||
/* make sure cmd_tpi() is defined */
|
||||
if (pgm->cmd_tpi == NULL) {
|
||||
fprintf(stderr, "%s: Error: %s programmer does not support TPI\n",
|
||||
progname, pgm->type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* bring RESET high first */
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1);
|
||||
usleep(1000);
|
||||
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "doing MOSI-MISO link check\n");
|
||||
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], 0);
|
||||
if (pgm->getpin(pgm, pgm->pinno[PIN_AVR_MISO]) != 0) {
|
||||
fprintf(stderr, "MOSI->MISO 0 failed\n");
|
||||
return -1;
|
||||
}
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], 1);
|
||||
if (pgm->getpin(pgm, pgm->pinno[PIN_AVR_MISO]) != 1) {
|
||||
fprintf(stderr, "MOSI->MISO 1 failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "MOSI-MISO link present\n");
|
||||
}
|
||||
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_SCK], 0);
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_RESET], 0);
|
||||
usleep(20000);
|
||||
|
||||
if (p->flags & AVRPART_HAS_TPI) {
|
||||
/* keep TPIDATA high for 16 clock cycles */
|
||||
pgm->setpin(pgm, pgm->pinno[PIN_AVR_MOSI], 1);
|
||||
for (i = 0; i < 16; i++)
|
||||
pgm->highpulsepin(pgm, pgm->pinno[PIN_AVR_SCK]);
|
||||
|
||||
/* remove extra guard timing bits */
|
||||
bitbang_tpi_tx(pgm, TPI_CMD_SSTCS | TPI_REG_TPIPCR);
|
||||
bitbang_tpi_tx(pgm, 0x7);
|
||||
|
||||
/* read TPI ident reg */
|
||||
bitbang_tpi_tx(pgm, TPI_CMD_SLDCS | TPI_REG_TPIIR);
|
||||
rc = bitbang_tpi_rx(pgm);
|
||||
if (rc != 0x80) {
|
||||
fprintf(stderr, "TPIIR not correct\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
pgm->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 */
|
||||
|
||||
@@ -605,7 +223,7 @@ int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
* order to possibly get back into sync with the chip if we are out
|
||||
* of sync.
|
||||
*/
|
||||
if (p->flags & AVRPART_IS_AT90S1200) {
|
||||
if (strcmp(p->desc, "AT90S1200")==0) {
|
||||
pgm->program_enable(pgm, p);
|
||||
}
|
||||
else {
|
||||
@@ -630,30 +248,4 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
* 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) 2011 Darell Tan <darell.tan@gmail.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
|
||||
@@ -15,34 +14,24 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* 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 bitbang_h
|
||||
#define bitbang_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int bitbang_setpin(int fd, int pin, int value);
|
||||
int bitbang_getpin(int fd, int pin);
|
||||
int bitbang_highpulsepin(int fd, int pin);
|
||||
void bitbang_delay(unsigned int us);
|
||||
|
||||
void bitbang_check_prerequisites(PROGRAMMER *pgm);
|
||||
|
||||
int bitbang_rdy_led (PROGRAMMER * pgm, int value);
|
||||
int bitbang_err_led (PROGRAMMER * pgm, int value);
|
||||
int bitbang_pgm_led (PROGRAMMER * pgm, int value);
|
||||
int bitbang_vfy_led (PROGRAMMER * pgm, int value);
|
||||
int bitbang_cmd (PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
unsigned char *res);
|
||||
int bitbang_cmd_tpi (PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
int cmd_len, unsigned char *res, int res_len);
|
||||
int bitbang_spi (PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
unsigned char *res, int count);
|
||||
int bitbang_cmd (PROGRAMMER * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4]);
|
||||
int bitbang_chip_erase (PROGRAMMER * pgm, AVRPART * p);
|
||||
int bitbang_program_enable (PROGRAMMER * pgm, AVRPART * p);
|
||||
void bitbang_powerup (PROGRAMMER * pgm);
|
||||
@@ -51,8 +40,4 @@ int bitbang_initialize (PROGRAMMER * pgm, AVRPART * p);
|
||||
void bitbang_disable (PROGRAMMER * pgm);
|
||||
void bitbang_enable (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,10 +1,37 @@
|
||||
#! /bin/sh
|
||||
|
||||
# autoconf-2.59 is required
|
||||
|
||||
: ${AUTOHEADER="autoheader${AC_VER}"}
|
||||
: ${AUTOCONF="autoconf${AC_VER}"}
|
||||
|
||||
# automake-1.9.x is required
|
||||
|
||||
: ${ACLOCAL="aclocal${AM_VER}"}
|
||||
: ${AUTOMAKE="automake${AM_VER}"}
|
||||
|
||||
# Verify autoconf version
|
||||
|
||||
AUTOCONF_VER=`(${AUTOCONF} --version 2>/dev/null | head -n 1 | \
|
||||
cut -d ' ' -f 4) 2>/dev/null`
|
||||
if [ "$AUTOCONF_VER" != "2.59" ]
|
||||
then
|
||||
echo "You need to use autoconf version 2.59."
|
||||
echo "You are using `${AUTOCONF} --version | head -n 1`."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify automake version
|
||||
|
||||
AUTOMAKE_VER=`(${AUTOMAKE} --version | head -n 1 | \
|
||||
cut -d ' ' -f 4 | cut -d '.' -f -2) 2>/dev/null`
|
||||
if [ "$AUTOMAKE_VER" != "1.9" ]
|
||||
then
|
||||
echo "You need to use automake version 1.9."
|
||||
echo "You are using `${AUTOMAKE} --version | head -n 1`."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export ACLOCAL AUTOHEADER AUTOCONF AUTOMAKE
|
||||
|
||||
# Bootstrap the build system.
|
||||
|
||||
1315
avrdude/buspirate.c
1315
avrdude/buspirate.c
File diff suppressed because it is too large
Load Diff
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
*
|
||||
* avrdude support for The Bus Pirate - universal serial interface
|
||||
*
|
||||
* Copyright (C) 2009 Michal Ludvig <mludvig@logix.net.nz>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef buspirate_h
|
||||
#define buspirate_h
|
||||
|
||||
extern const char buspirate_desc[];
|
||||
extern const char buspirate_bb_desc[];
|
||||
void buspirate_initpgm (struct programmer_t *pgm);
|
||||
void buspirate_bb_initpgm (struct programmer_t *pgm);
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
|
||||
* Copyright (C) 2005, 2007 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
* 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
|
||||
@@ -14,7 +14,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -42,44 +43,33 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "pgm.h"
|
||||
#include "butterfly.h"
|
||||
#include "serial.h"
|
||||
|
||||
/*
|
||||
* Private data for this programmer.
|
||||
*/
|
||||
struct pdata
|
||||
{
|
||||
char has_auto_incr_addr;
|
||||
unsigned int buffersize;
|
||||
};
|
||||
extern char * progname;
|
||||
extern int do_cycles;
|
||||
|
||||
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
||||
static char has_auto_incr_addr;
|
||||
static unsigned buffersize = 0;
|
||||
|
||||
static void butterfly_setup(PROGRAMMER * pgm)
|
||||
{
|
||||
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: butterfly_setup(): Out of memory allocating private data\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
memset(pgm->cookie, 0, sizeof(struct pdata));
|
||||
}
|
||||
/* These two defines are only for debugging. Will remove them once it starts
|
||||
working. */
|
||||
|
||||
#define show_func_info() \
|
||||
fprintf(stderr, "%s: line %d: called %s()\n", \
|
||||
__FILE__, __LINE__, __FUNCTION__)
|
||||
|
||||
#define no_show_func_info()
|
||||
|
||||
static void butterfly_teardown(PROGRAMMER * pgm)
|
||||
{
|
||||
free(pgm->cookie);
|
||||
}
|
||||
|
||||
static int butterfly_send(PROGRAMMER * pgm, char * buf, size_t len)
|
||||
{
|
||||
return serial_send(&pgm->fd, (unsigned char *)buf, len);
|
||||
no_show_func_info();
|
||||
|
||||
return serial_send(pgm->fd, (unsigned char *)buf, len);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +77,9 @@ static int butterfly_recv(PROGRAMMER * pgm, char * buf, size_t len)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = serial_recv(&pgm->fd, (unsigned char *)buf, len);
|
||||
no_show_func_info();
|
||||
|
||||
rv = serial_recv(pgm->fd, (unsigned char *)buf, len);
|
||||
if (rv < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: butterfly_recv(): programmer is not responding\n",
|
||||
@@ -100,7 +92,9 @@ static int butterfly_recv(PROGRAMMER * pgm, char * buf, size_t len)
|
||||
|
||||
static int butterfly_drain(PROGRAMMER * pgm, int display)
|
||||
{
|
||||
return serial_drain(&pgm->fd, display);
|
||||
no_show_func_info();
|
||||
|
||||
return serial_drain(pgm->fd, display);
|
||||
}
|
||||
|
||||
|
||||
@@ -119,6 +113,8 @@ static void butterfly_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
|
||||
|
||||
static int butterfly_rdy_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
/* Do nothing. */
|
||||
|
||||
return 0;
|
||||
@@ -127,6 +123,8 @@ static int butterfly_rdy_led(PROGRAMMER * pgm, int value)
|
||||
|
||||
static int butterfly_err_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
/* Do nothing. */
|
||||
|
||||
return 0;
|
||||
@@ -135,6 +133,8 @@ static int butterfly_err_led(PROGRAMMER * pgm, int value)
|
||||
|
||||
static int butterfly_pgm_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
/* Do nothing. */
|
||||
|
||||
return 0;
|
||||
@@ -143,6 +143,8 @@ static int butterfly_pgm_led(PROGRAMMER * pgm, int value)
|
||||
|
||||
static int butterfly_vfy_led(PROGRAMMER * pgm, int value)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
/* Do nothing. */
|
||||
|
||||
return 0;
|
||||
@@ -154,6 +156,8 @@ static int butterfly_vfy_led(PROGRAMMER * pgm, int value)
|
||||
*/
|
||||
static int butterfly_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
butterfly_send(pgm, "e", 1);
|
||||
butterfly_vfy_cmd_sent(pgm, "chip erase");
|
||||
|
||||
@@ -180,6 +184,8 @@ static void butterfly_leave_prog_mode(PROGRAMMER * pgm)
|
||||
*/
|
||||
static int butterfly_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -189,6 +195,8 @@ static int butterfly_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
||||
*/
|
||||
static void butterfly_powerup(PROGRAMMER * pgm)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
/* Do nothing. */
|
||||
|
||||
return;
|
||||
@@ -200,12 +208,13 @@ static void butterfly_powerup(PROGRAMMER * pgm)
|
||||
*/
|
||||
static void butterfly_powerdown(PROGRAMMER * pgm)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
/* Do nothing. */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#define IS_BUTTERFLY_MK 0x0001
|
||||
|
||||
/*
|
||||
* initialize the AVR device and prepare it to accept commands
|
||||
@@ -217,68 +226,36 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
char hw[2];
|
||||
char buf[10];
|
||||
char type;
|
||||
char c, devtype_1st;
|
||||
char c;
|
||||
int dev_supported = 0;
|
||||
|
||||
no_show_func_info();
|
||||
|
||||
/*
|
||||
* Send some ESC to activate butterfly bootloader. This is not needed
|
||||
* for plain avr109 bootloaders but does not harm there either.
|
||||
*/
|
||||
fprintf(stderr, "Connecting to programmer: ");
|
||||
if (pgm->flag & IS_BUTTERFLY_MK)
|
||||
{
|
||||
char mk_reset_cmd[6] = {"#aR@S\r"};
|
||||
unsigned char mk_timeout = 0;
|
||||
|
||||
putc('.', stderr);
|
||||
butterfly_send(pgm, mk_reset_cmd, sizeof(mk_reset_cmd));
|
||||
usleep(20000);
|
||||
|
||||
do
|
||||
{
|
||||
c = 27;
|
||||
butterfly_send(pgm, &c, 1);
|
||||
usleep(20000);
|
||||
c = 0xaa;
|
||||
usleep(80000);
|
||||
butterfly_send(pgm, &c, 1);
|
||||
if (mk_timeout % 10 == 0) putc('.', stderr);
|
||||
} while (mk_timeout++ < 10);
|
||||
|
||||
butterfly_recv(pgm, &c, 1);
|
||||
if ( c != 'M' && c != '?')
|
||||
{
|
||||
fprintf(stderr, "\nConnection FAILED.");
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
id[0] = 'M'; id[1] = 'K'; id[2] = '2'; id[3] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do {
|
||||
putc('.', stderr);
|
||||
butterfly_send(pgm, "\033", 1);
|
||||
butterfly_drain(pgm, 0);
|
||||
butterfly_send(pgm, "S", 1);
|
||||
butterfly_recv(pgm, &c, 1);
|
||||
if (c != '?') {
|
||||
putc('\n', stderr);
|
||||
/*
|
||||
* Got a useful response, continue getting the programmer
|
||||
* identifier. Programmer returns exactly 7 chars _without_
|
||||
* the null.
|
||||
*/
|
||||
id[0] = c;
|
||||
butterfly_recv(pgm, &id[1], sizeof(id)-2);
|
||||
id[sizeof(id)-1] = '\0';
|
||||
}
|
||||
} while (c == '?');
|
||||
do {
|
||||
putc('.', stderr);
|
||||
butterfly_send(pgm, "\033", 1);
|
||||
butterfly_drain(pgm, 0);
|
||||
butterfly_send(pgm, "S", 1);
|
||||
butterfly_recv(pgm, &c, 1);
|
||||
if (c != '?') {
|
||||
putc('\n', stderr);
|
||||
/*
|
||||
* Got a useful response, continue getting the programmer
|
||||
* identifier. Programmer returns exactly 7 chars _without_
|
||||
* the null.
|
||||
*/
|
||||
id[0] = c;
|
||||
butterfly_recv(pgm, &id[1], sizeof(id)-2);
|
||||
id[sizeof(id)-1] = '\0';
|
||||
}
|
||||
} while (c == '?');
|
||||
|
||||
/* Get the HW and SW versions to see if the programmer is present. */
|
||||
butterfly_drain(pgm, 0);
|
||||
|
||||
butterfly_send(pgm, "V", 1);
|
||||
butterfly_recv(pgm, sw, sizeof(sw));
|
||||
@@ -305,8 +282,8 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
/* See if programmer supports autoincrement of address. */
|
||||
|
||||
butterfly_send(pgm, "a", 1);
|
||||
butterfly_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1);
|
||||
if (PDATA(pgm)->has_auto_incr_addr == 'Y')
|
||||
butterfly_recv(pgm, &has_auto_incr_addr, 1);
|
||||
if (has_auto_incr_addr == 'Y')
|
||||
fprintf(stderr, "Programmer supports auto addr increment.\n");
|
||||
|
||||
/* Check support for buffered memory access, abort if not available */
|
||||
@@ -320,58 +297,58 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
exit(1);
|
||||
};
|
||||
butterfly_recv(pgm, &c, 1);
|
||||
PDATA(pgm)->buffersize = (unsigned int)(unsigned char)c<<8;
|
||||
buffersize = (unsigned int)(unsigned char)c<<8;
|
||||
butterfly_recv(pgm, &c, 1);
|
||||
PDATA(pgm)->buffersize += (unsigned int)(unsigned char)c;
|
||||
buffersize += (unsigned int)(unsigned char)c;
|
||||
fprintf(stderr,
|
||||
"Programmer supports buffered memory access with buffersize=%i bytes.\n",
|
||||
PDATA(pgm)->buffersize);
|
||||
buffersize);
|
||||
|
||||
/* Get list of devices that the programmer supports. */
|
||||
|
||||
butterfly_send(pgm, "t", 1);
|
||||
fprintf(stderr, "\nProgrammer supports the following devices:\n");
|
||||
devtype_1st = 0;
|
||||
while (1) {
|
||||
butterfly_recv(pgm, &c, 1);
|
||||
if (devtype_1st == 0)
|
||||
devtype_1st = c;
|
||||
|
||||
if (c == 0)
|
||||
break;
|
||||
fprintf(stderr, " Device code: 0x%02x\n", (unsigned int)(unsigned char)c);
|
||||
|
||||
/* FIXME: Need to lookup devcode and report the device. */
|
||||
|
||||
if (p->avr910_devcode == (int)(unsigned char)c)
|
||||
dev_supported = 1;
|
||||
};
|
||||
fprintf(stderr,"\n");
|
||||
|
||||
/* Tell the programmer which part we selected.
|
||||
According to the AVR109 code, this is ignored by the bootloader. As
|
||||
some early versions might not properly ignore it, rather pick up the
|
||||
first device type as reported above than anything out of avrdude.conf,
|
||||
so to avoid a potential conflict. There appears to be no general
|
||||
agreement on AVR910 device IDs beyond the ones from the original
|
||||
appnote 910. */
|
||||
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';
|
||||
buf[1] = devtype_1st;
|
||||
buf[1] = p->avr910_devcode;
|
||||
|
||||
butterfly_send(pgm, buf, 2);
|
||||
butterfly_vfy_cmd_sent(pgm, "select device");
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
"%s: devcode selected: 0x%02x\n",
|
||||
progname, (unsigned)buf[1]);
|
||||
if (dev_supported)
|
||||
butterfly_enter_prog_mode(pgm);
|
||||
|
||||
butterfly_enter_prog_mode(pgm);
|
||||
butterfly_drain(pgm, 0);
|
||||
|
||||
return 0;
|
||||
return dev_supported? 0: -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void butterfly_disable(PROGRAMMER * pgm)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
butterfly_leave_prog_mode(pgm);
|
||||
|
||||
return;
|
||||
@@ -380,12 +357,16 @@ static void butterfly_disable(PROGRAMMER * pgm)
|
||||
|
||||
static void butterfly_enable(PROGRAMMER * pgm)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int butterfly_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
strcpy(pgm->port, port);
|
||||
/*
|
||||
* If baudrate was not specified use 19200 Baud
|
||||
@@ -393,9 +374,7 @@ static int butterfly_open(PROGRAMMER * pgm, char * port)
|
||||
if(pgm->baudrate == 0) {
|
||||
pgm->baudrate = 19200;
|
||||
}
|
||||
if (serial_open(port, pgm->baudrate, &pgm->fd)==-1) {
|
||||
return -1;
|
||||
}
|
||||
pgm->fd = serial_open(port, pgm->baudrate);
|
||||
|
||||
/*
|
||||
* drain any extraneous input
|
||||
@@ -408,17 +387,20 @@ static int butterfly_open(PROGRAMMER * pgm, char * port)
|
||||
|
||||
static void butterfly_close(PROGRAMMER * pgm)
|
||||
{
|
||||
/* "exit programmer" */
|
||||
butterfly_send(pgm, "E", 1);
|
||||
butterfly_vfy_cmd_sent(pgm, "exit bootloader");
|
||||
no_show_func_info();
|
||||
|
||||
serial_close(&pgm->fd);
|
||||
pgm->fd.ifd = -1;
|
||||
/* "exit programmer" added by Martin Thomas 2/2004 */
|
||||
butterfly_send(pgm, "E", 1);
|
||||
|
||||
serial_close(pgm->fd);
|
||||
pgm->fd = -1;
|
||||
}
|
||||
|
||||
|
||||
static void butterfly_display(PROGRAMMER * pgm, const char * p)
|
||||
static void butterfly_display(PROGRAMMER * pgm, char * p)
|
||||
{
|
||||
no_show_func_info();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -436,33 +418,20 @@ static void butterfly_set_addr(PROGRAMMER * pgm, unsigned long addr)
|
||||
}
|
||||
|
||||
|
||||
static void butterfly_set_extaddr(PROGRAMMER * pgm, unsigned long addr)
|
||||
{
|
||||
char cmd[4];
|
||||
|
||||
cmd[0] = 'H';
|
||||
cmd[1] = (addr >> 16) & 0xff;
|
||||
cmd[2] = (addr >> 8) & 0xff;
|
||||
cmd[3] = addr & 0xff;
|
||||
|
||||
butterfly_send(pgm, cmd, sizeof(cmd));
|
||||
butterfly_vfy_cmd_sent(pgm, "set extaddr");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int butterfly_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char value)
|
||||
{
|
||||
char cmd[6];
|
||||
int size;
|
||||
int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
|
||||
|
||||
no_show_func_info();
|
||||
|
||||
if ((strcmp(m->desc, "flash") == 0) || (strcmp(m->desc, "eeprom") == 0))
|
||||
{
|
||||
cmd[0] = 'B';
|
||||
cmd[1] = 0;
|
||||
if ((cmd[3] = toupper((int)(m->desc[0]))) == 'E') { /* write to eeprom */
|
||||
if ((cmd[3] = toupper(m->desc[0])) == 'E') { /* write to eeprom */
|
||||
cmd[2] = 1;
|
||||
cmd[4] = value;
|
||||
size = 5;
|
||||
@@ -472,11 +441,7 @@ static int butterfly_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
size = 6;
|
||||
return -1;
|
||||
}
|
||||
if (use_ext_addr) {
|
||||
butterfly_set_extaddr(pgm, addr);
|
||||
} else {
|
||||
butterfly_set_addr(pgm, addr);
|
||||
}
|
||||
butterfly_set_addr(pgm, addr);
|
||||
}
|
||||
else if (strcmp(m->desc, "lock") == 0)
|
||||
{
|
||||
@@ -500,7 +465,6 @@ static int butterfly_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
static int cached = 0;
|
||||
static unsigned char cvalue;
|
||||
static unsigned long caddr;
|
||||
int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
|
||||
|
||||
if (cached && ((caddr + 1) == addr)) {
|
||||
*value = cvalue;
|
||||
@@ -509,11 +473,7 @@ static int butterfly_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
else {
|
||||
char buf[2];
|
||||
|
||||
if (use_ext_addr) {
|
||||
butterfly_set_extaddr(pgm, addr >> 1);
|
||||
} else {
|
||||
butterfly_set_addr(pgm, addr >> 1);
|
||||
}
|
||||
butterfly_set_addr(pgm, addr >> 1);
|
||||
|
||||
butterfly_send(pgm, "g\000\002F", 4);
|
||||
|
||||
@@ -521,13 +481,13 @@ static int butterfly_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
butterfly_recv(pgm, buf, sizeof(buf));
|
||||
|
||||
if ((addr & 0x01) == 0) {
|
||||
*value = buf[0];
|
||||
*value = buf[1];
|
||||
cached = 1;
|
||||
cvalue = buf[1];
|
||||
cvalue = buf[0];
|
||||
caddr = addr;
|
||||
}
|
||||
else {
|
||||
*value = buf[1];
|
||||
*value = buf[0];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,23 +504,14 @@ static int butterfly_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int butterfly_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned int addr)
|
||||
{
|
||||
if (strcmp(m->desc, "flash") == 0)
|
||||
return -1; /* not supported */
|
||||
if (strcmp(m->desc, "eeprom") == 0)
|
||||
return 0; /* nothing to do */
|
||||
fprintf(stderr,
|
||||
"%s: butterfly_page_erase() called on memory type \"%s\"\n",
|
||||
progname, m->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int butterfly_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char * value)
|
||||
{
|
||||
char cmd;
|
||||
|
||||
no_show_func_info();
|
||||
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
return butterfly_read_byte_flash(pgm, p, m, addr, value);
|
||||
}
|
||||
@@ -592,27 +543,21 @@ static int butterfly_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
|
||||
|
||||
|
||||
static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes)
|
||||
static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
unsigned int max_addr = addr + n_bytes;
|
||||
unsigned int addr = 0;
|
||||
unsigned int max_addr = n_bytes;
|
||||
char *cmd;
|
||||
unsigned int blocksize = PDATA(pgm)->buffersize;
|
||||
int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
|
||||
unsigned int wr_size = 2;
|
||||
unsigned int blocksize = buffersize;
|
||||
|
||||
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
|
||||
return -2;
|
||||
|
||||
if (m->desc[0] == 'e')
|
||||
wr_size = blocksize = 1; /* Write to eeprom single bytes only */
|
||||
blocksize = 1; /* Write to eeprom single bytes only */
|
||||
|
||||
if (use_ext_addr) {
|
||||
butterfly_set_extaddr(pgm, addr / wr_size);
|
||||
} else {
|
||||
butterfly_set_addr(pgm, addr / wr_size);
|
||||
}
|
||||
butterfly_set_addr(pgm, addr);
|
||||
|
||||
#if 0
|
||||
usleep(1000000);
|
||||
@@ -623,7 +568,7 @@ static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
cmd = malloc(4+blocksize);
|
||||
if (!cmd) return -1;
|
||||
cmd[0] = 'B';
|
||||
cmd[3] = toupper((int)(m->desc[0]));
|
||||
cmd[3] = toupper(m->desc[0]);
|
||||
|
||||
while (addr < max_addr) {
|
||||
if ((max_addr - addr) < blocksize) {
|
||||
@@ -637,6 +582,8 @@ static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
butterfly_vfy_cmd_sent(pgm, "write block");
|
||||
|
||||
addr += blocksize;
|
||||
|
||||
report_progress (addr, max_addr, NULL);
|
||||
} /* while */
|
||||
free(cmd);
|
||||
|
||||
@@ -645,33 +592,25 @@ static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
|
||||
|
||||
|
||||
static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes)
|
||||
static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
unsigned int max_addr = addr + n_bytes;
|
||||
int rd_size = 2;
|
||||
int blocksize = PDATA(pgm)->buffersize;
|
||||
int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
|
||||
unsigned int addr = 0;
|
||||
unsigned int max_addr = n_bytes;
|
||||
int rd_size = 1;
|
||||
|
||||
/* check parameter syntax: only "flash" or "eeprom" is allowed */
|
||||
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
|
||||
return -2;
|
||||
|
||||
if (m->desc[0] == 'e')
|
||||
rd_size = blocksize = 1; /* Read from eeprom single bytes only */
|
||||
|
||||
{ /* use buffered mode */
|
||||
char cmd[4];
|
||||
int blocksize = buffersize;
|
||||
|
||||
cmd[0] = 'g';
|
||||
cmd[3] = toupper((int)(m->desc[0]));
|
||||
cmd[3] = toupper(m->desc[0]);
|
||||
|
||||
if (use_ext_addr) {
|
||||
butterfly_set_extaddr(pgm, addr / rd_size);
|
||||
} else {
|
||||
butterfly_set_addr(pgm, addr / rd_size);
|
||||
}
|
||||
butterfly_set_addr(pgm, addr);
|
||||
while (addr < max_addr) {
|
||||
if ((max_addr - addr) < blocksize) {
|
||||
blocksize = max_addr - addr;
|
||||
@@ -683,6 +622,8 @@ static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
butterfly_recv(pgm, (char *)&m->buf[addr], blocksize);
|
||||
|
||||
addr += blocksize;
|
||||
|
||||
report_progress (addr, max_addr, NULL);
|
||||
} /* while */
|
||||
}
|
||||
|
||||
@@ -695,6 +636,8 @@ static int butterfly_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
|
||||
{
|
||||
unsigned char tmp;
|
||||
|
||||
no_show_func_info();
|
||||
|
||||
if (m->size < 3) {
|
||||
fprintf(stderr, "%s: memsize too small for sig byte read", progname);
|
||||
return -1;
|
||||
@@ -710,11 +653,12 @@ static int butterfly_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
|
||||
return 3;
|
||||
}
|
||||
|
||||
const char butterfly_desc[] = "Atmel Butterfly evaluation board; Atmel AppNotes AVR109, AVR911";
|
||||
|
||||
void butterfly_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
strcpy(pgm->type, "butterfly");
|
||||
no_show_func_info();
|
||||
|
||||
strcpy(pgm->type, "avr910");
|
||||
|
||||
/*
|
||||
* mandatory functions
|
||||
@@ -731,31 +675,19 @@ 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->page_erase = butterfly_page_erase;
|
||||
pgm->write_byte = butterfly_write_byte;
|
||||
pgm->read_byte = butterfly_read_byte;
|
||||
|
||||
pgm->paged_write = butterfly_paged_write;
|
||||
pgm->paged_load = butterfly_paged_load;
|
||||
|
||||
pgm->read_sig_bytes = butterfly_read_sig_bytes;
|
||||
|
||||
pgm->setup = butterfly_setup;
|
||||
pgm->teardown = butterfly_teardown;
|
||||
pgm->flag = 0;
|
||||
}
|
||||
|
||||
const char butterfly_mk_desc[] = "Mikrokopter.de Butterfly";
|
||||
|
||||
void butterfly_mk_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
butterfly_initpgm(pgm);
|
||||
strcpy(pgm->type, "butterfly_mk");
|
||||
pgm->flag = IS_BUTTERFLY_MK;
|
||||
}
|
||||
|
||||
@@ -13,25 +13,15 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef butterfly_h
|
||||
#define butterfly_h
|
||||
#ifndef __butterfly_h__
|
||||
#define __butterfly_h__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char butterfly_desc[];
|
||||
extern const char butterfly_mk_desc[];
|
||||
void butterfly_initpgm (PROGRAMMER * pgm);
|
||||
void butterfly_mk_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* butterfly_h */
|
||||
#endif /* __butterfly_h__ */
|
||||
|
||||
127
avrdude/config.c
127
avrdude/config.c
@@ -13,20 +13,19 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "config.h"
|
||||
#include "config_gram.h"
|
||||
@@ -34,8 +33,6 @@
|
||||
char default_programmer[MAX_STR_CONST];
|
||||
char default_parallel[PATH_MAX];
|
||||
char default_serial[PATH_MAX];
|
||||
double default_bitclock;
|
||||
int default_safemode;
|
||||
|
||||
char string_buf[MAX_STR_CONST];
|
||||
char *string_buf_ptr;
|
||||
@@ -48,20 +45,11 @@ AVRMEM * current_mem;
|
||||
LISTID part_list;
|
||||
LISTID programmers;
|
||||
|
||||
int lineno;
|
||||
const char * infile;
|
||||
|
||||
extern char * yytext;
|
||||
int lineno = 0;
|
||||
char * infile = NULL;
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
void cleanup_config(void)
|
||||
{
|
||||
ldestroy_cb(part_list, (void(*)(void*))avr_free_part);
|
||||
ldestroy_cb(programmers, (void(*)(void*))pgm_free);
|
||||
ldestroy_cb(string_list, (void(*)(void*))free_token);
|
||||
ldestroy_cb(number_list, (void(*)(void*))free_token);
|
||||
}
|
||||
|
||||
int init_config(void)
|
||||
{
|
||||
@@ -69,7 +57,7 @@ int init_config(void)
|
||||
number_list = lcreat(NULL, 0);
|
||||
current_prog = NULL;
|
||||
current_part = NULL;
|
||||
current_mem = NULL;
|
||||
current_mem = 0;
|
||||
part_list = lcreat(NULL, 0);
|
||||
programmers = lcreat(NULL, 0);
|
||||
|
||||
@@ -89,7 +77,7 @@ int yywrap()
|
||||
|
||||
int yyerror(char * errmsg)
|
||||
{
|
||||
fprintf(stderr, "%s: %s at %s:%d\n", progname, errmsg, infile, lineno);
|
||||
fprintf(stderr, "%s at %s:%d\n", errmsg, infile, lineno);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -115,14 +103,15 @@ TOKEN * new_token(int primary)
|
||||
void free_token(TOKEN * tkn)
|
||||
{
|
||||
if (tkn) {
|
||||
switch (tkn->value.type) {
|
||||
case V_STR:
|
||||
switch (tkn->primary) {
|
||||
case TKN_STRING:
|
||||
case TKN_ID:
|
||||
if (tkn->value.string)
|
||||
free(tkn->value.string);
|
||||
tkn->value.string = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
free(tkn);
|
||||
}
|
||||
}
|
||||
@@ -149,29 +138,15 @@ TOKEN * number(char * text)
|
||||
|
||||
tkn = new_token(TKN_NUMBER);
|
||||
tkn->value.type = V_NUM;
|
||||
tkn->value.number = atoi(text);
|
||||
tkn->value.number = atof(text);
|
||||
|
||||
#if DEBUG
|
||||
fprintf(stderr, "NUMBER(%d)\n", tkn->value.number);
|
||||
fprintf(stderr, "NUMBER(%g)\n", tkn->value.number);
|
||||
#endif
|
||||
|
||||
return tkn;
|
||||
}
|
||||
|
||||
TOKEN * number_real(char * text)
|
||||
{
|
||||
struct token_t * tkn;
|
||||
|
||||
tkn = new_token(TKN_NUMBER);
|
||||
tkn->value.type = V_NUM_REAL;
|
||||
tkn->value.number_real = atof(text);
|
||||
|
||||
#if DEBUG
|
||||
fprintf(stderr, "NUMBER(%g)\n", tkn->value.number_real);
|
||||
#endif
|
||||
|
||||
return tkn;
|
||||
}
|
||||
|
||||
TOKEN * hexnumber(char * text)
|
||||
{
|
||||
@@ -220,6 +195,31 @@ TOKEN * string(char * text)
|
||||
}
|
||||
|
||||
|
||||
TOKEN * id(char * text)
|
||||
{
|
||||
struct token_t * tkn;
|
||||
int len;
|
||||
|
||||
tkn = new_token(TKN_ID);
|
||||
|
||||
len = strlen(text);
|
||||
|
||||
tkn->value.type = V_STR;
|
||||
tkn->value.string = (char *) malloc(len+1);
|
||||
if (tkn->value.string == NULL) {
|
||||
fprintf(stderr, "id(): out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
strcpy(tkn->value.string, text);
|
||||
|
||||
#if DEBUG
|
||||
fprintf(stderr, "ID(%s)\n", tkn->value.string);
|
||||
#endif
|
||||
|
||||
return tkn;
|
||||
}
|
||||
|
||||
|
||||
TOKEN * keyword(int primary)
|
||||
{
|
||||
struct token_t * tkn;
|
||||
@@ -236,21 +236,21 @@ void print_token(TOKEN * tkn)
|
||||
return;
|
||||
|
||||
fprintf(stderr, "token = %d = ", tkn->primary);
|
||||
switch (tkn->value.type) {
|
||||
case V_NUM:
|
||||
fprintf(stderr, "NUMBER, value=%d", tkn->value.number);
|
||||
switch (tkn->primary) {
|
||||
case TKN_NUMBER:
|
||||
fprintf(stderr, "NUMBER, value=%g", tkn->value.number);
|
||||
break;
|
||||
|
||||
case V_NUM_REAL:
|
||||
fprintf(stderr, "NUMBER, value=%g", tkn->value.number_real);
|
||||
case TKN_STRING:
|
||||
fprintf(stderr, "STRING, value=%s", tkn->value.string);
|
||||
break;
|
||||
|
||||
case V_STR:
|
||||
fprintf(stderr, "STRING, value=%s", tkn->value.string);
|
||||
case TKN_ID:
|
||||
fprintf(stderr, "ID, value=%s", tkn->value.string);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "<other>");
|
||||
default:
|
||||
fprintf(stderr, "<other>");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -261,12 +261,14 @@ void print_token(TOKEN * tkn)
|
||||
void pyytext(void)
|
||||
{
|
||||
#if DEBUG
|
||||
extern char * yytext;
|
||||
|
||||
fprintf(stderr, "TOKEN: \"%s\"\n", yytext);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
char * dup_string(const char * str)
|
||||
char * dup_string(char * str)
|
||||
{
|
||||
char * s;
|
||||
|
||||
@@ -279,34 +281,3 @@ char * dup_string(const char * str)
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifdef HAVE_YYLEX_DESTROY
|
||||
/* reset lexer and free any allocated memory */
|
||||
extern int yylex_destroy(void);
|
||||
#endif
|
||||
|
||||
int read_config(const char * file)
|
||||
{
|
||||
FILE * f;
|
||||
|
||||
f = fopen(file, "r");
|
||||
if (f == NULL) {
|
||||
fprintf(stderr, "%s: can't open config file \"%s\": %s\n",
|
||||
progname, file, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
lineno = 1;
|
||||
infile = file;
|
||||
yyin = f;
|
||||
|
||||
yyparse();
|
||||
|
||||
#ifdef HAVE_YYLEX_DESTROY
|
||||
/* reset lexer and free any allocated memory */
|
||||
yylex_destroy();
|
||||
#endif
|
||||
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -13,13 +13,14 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* 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 config_h
|
||||
#define config_h
|
||||
#ifndef __config_h__
|
||||
#define __config_h__
|
||||
|
||||
#include "lists.h"
|
||||
#include "pindefs.h"
|
||||
@@ -28,14 +29,11 @@
|
||||
|
||||
#define MAX_STR_CONST 1024
|
||||
|
||||
enum { V_NONE, V_NUM, V_NUM_REAL, V_STR };
|
||||
enum { V_NONE, V_NUM, V_STR };
|
||||
typedef struct value_t {
|
||||
int type;
|
||||
/*union { TODO: use an anonymous union here ? */
|
||||
int number;
|
||||
double number_real;
|
||||
char * string;
|
||||
/*};*/
|
||||
double number;
|
||||
char * string;
|
||||
} VALUE;
|
||||
|
||||
|
||||
@@ -51,20 +49,13 @@ extern PROGRAMMER * current_prog;
|
||||
extern AVRPART * current_part;
|
||||
extern AVRMEM * current_mem;
|
||||
extern int lineno;
|
||||
extern const char * infile;
|
||||
extern char * infile;
|
||||
extern LISTID string_list;
|
||||
extern LISTID number_list;
|
||||
extern LISTID part_list;
|
||||
extern LISTID programmers;
|
||||
extern char default_programmer[];
|
||||
extern char default_parallel[];
|
||||
extern char default_serial[];
|
||||
extern double default_bitclock;
|
||||
extern int default_safemode;
|
||||
|
||||
/* This name is fixed, it's only here for symmetry with
|
||||
* default_parallel and default_serial. */
|
||||
#define DEFAULT_USB "usb"
|
||||
|
||||
|
||||
#if !defined(HAS_YYSTYPE)
|
||||
@@ -75,17 +66,11 @@ extern YYSTYPE yylval;
|
||||
extern char string_buf[MAX_STR_CONST];
|
||||
extern char *string_buf_ptr;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int yyparse(void);
|
||||
|
||||
|
||||
int init_config(void);
|
||||
|
||||
void cleanup_config(void);
|
||||
|
||||
TOKEN * new_token(int primary);
|
||||
|
||||
void free_token(TOKEN * tkn);
|
||||
@@ -94,24 +79,22 @@ void free_tokens(int n, ...);
|
||||
|
||||
TOKEN * number(char * text);
|
||||
|
||||
TOKEN * number_real(char * text);
|
||||
|
||||
TOKEN * hexnumber(char * text);
|
||||
|
||||
TOKEN * string(char * text);
|
||||
|
||||
TOKEN * id(char * text);
|
||||
|
||||
TOKEN * keyword(int primary);
|
||||
|
||||
void print_token(TOKEN * tkn);
|
||||
|
||||
void pyytext(void);
|
||||
PROGRAMMER * new_programmer(void);
|
||||
|
||||
char * dup_string(const char * str);
|
||||
AVRPART * new_part(void);
|
||||
|
||||
int read_config(const char * file);
|
||||
AVRPART * dup_part(AVRPART * d);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
char * dup_string(char * str);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,8 @@
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
#
|
||||
@@ -22,8 +23,8 @@
|
||||
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.60)
|
||||
AC_INIT(avrdude, 6.0, avrdude-dev@nongnu.org)
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT(avrdude, 5.1, avrdude-dev@nongnu.org)
|
||||
|
||||
AC_CANONICAL_BUILD
|
||||
AC_CANONICAL_HOST
|
||||
@@ -31,218 +32,34 @@ AC_CANONICAL_TARGET
|
||||
|
||||
AC_CONFIG_SRCDIR([main.c])
|
||||
AM_INIT_AUTOMAKE
|
||||
AC_CONFIG_HEADERS(ac_cfg.h)
|
||||
AM_CONFIG_HEADER([ac_cfg.h])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_SED
|
||||
AC_PROG_YACC
|
||||
AC_PROG_LEX
|
||||
AN_MAKEVAR([RANLIB], [AC_PROG_RANLIB])
|
||||
AN_PROGRAM([ranlib], [AC_PROG_RANLIB])
|
||||
AC_DEFUN([AC_PROG_RANLIB], [AC_CHECK_TARGET_TOOL(RANLIB, ranlib, :)])
|
||||
AC_PROG_RANLIB
|
||||
AN_MAKEVAR([AR], [AC_PROG_AR])
|
||||
AN_PROGRAM([ar], [AC_PROG_AR])
|
||||
AC_DEFUN([AC_PROG_AR], [AC_CHECK_TARGET_TOOL(AR, ar, :)])
|
||||
AC_PROG_AR
|
||||
AH_TEMPLATE([HAVE_YYLEX_DESTROY],
|
||||
[Define if lex/flex has yylex_destroy])
|
||||
# flex should have this
|
||||
if test "x$LEX" == xflex; then
|
||||
AC_MSG_CHECKING([whether yylex_destroy is generated by flex])
|
||||
flex_version=`$LEX -V -v --version 2>/dev/null | $SED -e 's/^.* //'`
|
||||
case $flex_version in
|
||||
[[0-1].*)]
|
||||
AC_MSG_RESULT([version $flex_version => no])
|
||||
;;
|
||||
[2.[0-4].*)]
|
||||
AC_MSG_RESULT([version $flex_version => no])
|
||||
;;
|
||||
[2.5.[0-8])]
|
||||
AC_MSG_RESULT([version $flex_version => no])
|
||||
;;
|
||||
[2.5.[0-8][A-Za-z]*)]
|
||||
AC_MSG_RESULT([version $flex_version => no])
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT([version $flex_version => yes])
|
||||
AC_DEFINE([HAVE_YYLEX_DESTROY])
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
dnl Makefile.am:77: compiling `config_gram.c' with per-target flags requires `AM_PROG_CC_C_O' in `configure.ac'
|
||||
AM_PROG_CC_C_O
|
||||
AM_PROG_LEX
|
||||
|
||||
# Checks for libraries.
|
||||
AC_CHECK_LIB([termcap], [tputs])
|
||||
AC_CHECK_LIB([ncurses], [tputs])
|
||||
AC_CHECK_LIB([readline], [readline])
|
||||
AH_TEMPLATE([HAVE_LIBELF],
|
||||
[Define if ELF support is enabled via libelf])
|
||||
AC_CHECK_LIB([elf], [elf_begin], [have_libelf=yes])
|
||||
if test x$have_libelf = xyes; then
|
||||
case $target in
|
||||
*)
|
||||
LIBELF="-lelf"
|
||||
;;
|
||||
esac
|
||||
AC_DEFINE([HAVE_LIBELF])
|
||||
AC_CHECK_HEADERS([libelf.h libelf/libelf.h])
|
||||
fi
|
||||
AC_SUBST(LIBELF, $LIBELF)
|
||||
# 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])
|
||||
|
||||
AC_SEARCH_LIBS([gethostent], [nsl])
|
||||
AC_SEARCH_LIBS([setsockopt], [socket])
|
||||
AH_TEMPLATE([HAVE_LIBUSB],
|
||||
[Define if USB support is enabled via libusb])
|
||||
AC_CHECK_LIB([usb], [usb_get_string_simple], [have_libusb=yes])
|
||||
if test x$have_libusb = xyes; then
|
||||
case $target in
|
||||
*-*-darwin*)
|
||||
LIBUSB="-lusb -framework CoreFoundation -framework IOKit"
|
||||
;;
|
||||
*)
|
||||
LIBUSB="-lusb"
|
||||
;;
|
||||
esac
|
||||
AC_DEFINE([HAVE_LIBUSB])
|
||||
AC_CHECK_HEADERS([usb.h])
|
||||
AC_CHECK_HEADERS([lusb0_usb.h])
|
||||
fi
|
||||
AC_SUBST(LIBUSB, $LIBUSB)
|
||||
|
||||
AH_TEMPLATE([HAVE_LIBUSB_1_0],
|
||||
[Define if USB support is enabled via libusb 1.0])
|
||||
AC_CHECK_LIB([usb-1.0], [libusb_init], [have_libusb_1_0=yes])
|
||||
if test x$have_libusb_1_0 = xyes; then
|
||||
case $target in
|
||||
*-*-darwin*)
|
||||
LIBUSB_1_0="-lusb-1.0 -framework CoreFoundation -framework IOKit"
|
||||
;;
|
||||
*)
|
||||
LIBUSB_1_0="-lusb-1.0"
|
||||
;;
|
||||
esac
|
||||
AC_DEFINE([HAVE_LIBUSB_1_0])
|
||||
AC_CHECK_HEADERS([libusb-1.0/libusb.h])
|
||||
AC_CHECK_HEADERS([libusb.h])
|
||||
fi
|
||||
AH_TEMPLATE([HAVE_LIBUSB_1_0],
|
||||
[Define if USB support is enabled via a libusb-1.0 compatible libusb])
|
||||
AC_CHECK_LIB([usb], [libusb_init], [have_libusb_1_0=yes])
|
||||
if test x$have_libusb_1_0 = xyes; then
|
||||
case $target in
|
||||
*-*-freebsd*)
|
||||
# FreeBSD 8+ has a native libusb-1.0 API compatible
|
||||
# library offered by -lusb (which is also libusb-0.1
|
||||
# compatible). FreeBSD <8 does not have a libusb-1.0
|
||||
# at all so probing will fail but we do not have to
|
||||
# special-case that.
|
||||
LIBUSB_1_0="-lusb"
|
||||
;;
|
||||
*)
|
||||
LIBUSB_1_0="-lusb-1.0"
|
||||
;;
|
||||
esac
|
||||
AC_DEFINE([HAVE_LIBUSB_1_0])
|
||||
AC_CHECK_HEADERS([libusb.h])
|
||||
fi
|
||||
AC_SUBST(LIBUSB_1_0, $LIBUSB_1_0)
|
||||
AH_TEMPLATE([HAVE_LIBFTDI1],
|
||||
[Define if FTDI support is enabled via libftdi1])
|
||||
AH_TEMPLATE([HAVE_LIBFTDI],
|
||||
[Define if FTDI support is enabled via libftdi])
|
||||
AH_TEMPLATE([HAVE_LIBFTDI_TYPE_232H],
|
||||
[Define if libftdi supports FT232H, libftdi version >= 0.20])
|
||||
AC_CHECK_LIB([ftdi1], [ftdi_new], [have_libftdi1=yes], [], [-lusb-1.0])
|
||||
AC_CHECK_LIB([ftdi], [ftdi_usb_get_strings], [have_libftdi=yes], [], [-lusb])
|
||||
if test x$have_libftdi1 = xyes; then
|
||||
LIBFTDI1="-lftdi1"
|
||||
AC_DEFINE([HAVE_LIBFTDI1])
|
||||
AC_SUBST(LIBFTDI1, $LIBFTDI1)
|
||||
else
|
||||
if test x$have_libftdi = xyes; then
|
||||
LIBFTDI="-lftdi -lusb"
|
||||
AC_DEFINE([HAVE_LIBFTDI])
|
||||
AC_SUBST(LIBFTDI, $LIBFTDI)
|
||||
AC_CHECK_DECL(TYPE_232H,[have_libftdi_FT232H=yes], [], [[#include <ftdi.h>]])
|
||||
if test x$have_libftdi_FT232H = xyes; then
|
||||
AC_DEFINE([HAVE_LIBFTDI_TYPE_232H])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AC_CHECK_HEADERS([pthread.h])
|
||||
# as there exits header file only pthread implementations for Windows, check if we have a library
|
||||
AC_CHECK_LIB([pthread], [pthread_create], [have_pthread=yes])
|
||||
if test x$have_pthread = xyes; then
|
||||
LIBPTHREAD="-lpthread"
|
||||
fi
|
||||
AC_SUBST(LIBPTHREAD, $LIBPTHREAD)
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([limits.h stdlib.h string.h])
|
||||
AC_CHECK_HEADERS([fcntl.h sys/ioctl.h sys/time.h termios.h unistd.h])
|
||||
AC_CHECK_HEADERS([ddk/hidsdi.h],,,[#include <windows.h>
|
||||
#include <setupapi.h>])
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([fcntl.h limits.h stdlib.h string.h sys/ioctl.h sys/time.h termios.h unistd.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_HEADER_TIME
|
||||
|
||||
# Checks for library functions.
|
||||
AC_CHECK_FUNCS([memset select strcasecmp strdup strerror strncasecmp strtol strtoul gettimeofday usleep])
|
||||
|
||||
AC_MSG_CHECKING([for a Win32 HID libray])
|
||||
SAVED_LIBS="${LIBS}"
|
||||
case $target in
|
||||
*-*-mingw32* | *-*-cygwin* | *-*-windows*)
|
||||
LIBHID="-lhid -lsetupapi"
|
||||
if test $ac_cv_header_ddk_hidsdi_h = yes
|
||||
then
|
||||
HIDINCLUDE="#include <ddk/hidsdi.h>"
|
||||
else
|
||||
HIDINCLUDE="#include \"my_ddk_hidsdi.h\""
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
LIBHID=""
|
||||
;;
|
||||
esac
|
||||
LIBS="${LIBS} ${LIBHID}"
|
||||
|
||||
AH_TEMPLATE([HAVE_LIBHID],
|
||||
[Define if HID support is enabled via the Win32 DDK])
|
||||
AC_TRY_RUN([#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
$HIDINCLUDE
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
GUID hidGuid;
|
||||
HidD_GetHidGuid(&hidGuid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
], [have_libhid=yes], [have_libhid=no], [have_libhid=no])
|
||||
AC_MSG_RESULT([$have_libhid])
|
||||
if test x$have_libhid = xyes; then
|
||||
AC_DEFINE([HAVE_LIBHID])
|
||||
else
|
||||
LIBHID=""
|
||||
fi
|
||||
LIBS="${SAVED_LIBS}"
|
||||
AC_SUBST(LIBHID, $LIBHID)
|
||||
|
||||
# Check for types
|
||||
|
||||
# Solaris has uint_t and ulong_t typedefs in <sys/types.h>, avoid
|
||||
# the redeclaration in usbtiny.c.
|
||||
AC_CHECK_TYPES([uint_t], [], [], [#include <sys/types.h>])
|
||||
AC_CHECK_TYPES([ulong_t], [], [], [#include <sys/types.h>])
|
||||
AC_PROG_GCC_TRADITIONAL
|
||||
AC_FUNC_MALLOC
|
||||
AC_CHECK_FUNCS([memset select strcasecmp strdup strerror strncasecmp strtol strtoul])
|
||||
|
||||
# Checks for misc stuff.
|
||||
|
||||
@@ -268,7 +85,7 @@ AC_ARG_ENABLE(
|
||||
[doc],
|
||||
AC_HELP_STRING(
|
||||
[--enable-doc],
|
||||
[Enable building documents]),
|
||||
[Enable building documents(default)]),
|
||||
[case "${enableval}" in
|
||||
yes) enabled_doc=yes ;;
|
||||
no) enabled_doc=no ;;
|
||||
@@ -287,25 +104,15 @@ AC_ARG_ENABLE(
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for enable-parport option) ;;
|
||||
esac],
|
||||
[enabled_parport=yes])
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[linuxgpio],
|
||||
AC_HELP_STRING(
|
||||
[--enable-linuxgpio],
|
||||
[Enable the Linux sysfs GPIO interface programmer type]),
|
||||
[case "${enableval}" in
|
||||
yes) enabled_linuxgpio=yes ;;
|
||||
no) enabled_linuxgpio=no ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for enable-linuxgpio option) ;;
|
||||
esac],
|
||||
[enabled_linuxgpio=no])
|
||||
|
||||
DIST_SUBDIRS_AC='doc windows'
|
||||
|
||||
if test "$enabled_doc" = "yes"; then
|
||||
SUBDIRS_AC='doc'
|
||||
|
||||
SUBDIRS_AC='doc @WINDOWS_DIRS@'
|
||||
DIST_SUBDIRS_AC='doc windows'
|
||||
else
|
||||
SUBDIRS_AC=''
|
||||
|
||||
SUBDIRS_AC='@WINDOWS_DIRS@'
|
||||
DIST_SUBDIRS_AC='windows'
|
||||
fi
|
||||
|
||||
AC_SUBST(DOC_INST_DIR, $DOC_INST_DIR)
|
||||
@@ -324,13 +131,13 @@ case $target in
|
||||
DEFAULT_PAR_PORT="unknown"
|
||||
DEFAULT_SER_PORT="/dev/ttyS0"
|
||||
;;
|
||||
i[[3456]]86-*-*freebsd*|amd64-*-*freebsd*)
|
||||
i[[3456]]86-*-freebsd*|amd64-*-freebsd*)
|
||||
DEFAULT_PAR_PORT="/dev/ppi0"
|
||||
DEFAULT_SER_PORT="/dev/cuad0"
|
||||
DEFAULT_SER_PORT="/dev/cuaa0"
|
||||
;;
|
||||
*-*-*freebsd*)
|
||||
*-*-freebsd*)
|
||||
DEFAULT_PAR_PORT="unknown"
|
||||
DEFAULT_SER_PORT="/dev/cuad0"
|
||||
DEFAULT_SER_PORT="/dev/cuaa0"
|
||||
;;
|
||||
*-*-solaris*)
|
||||
DEFAULT_PAR_PORT="/dev/printers/0"
|
||||
@@ -367,96 +174,29 @@ if test "$enabled_parport" = "yes"; then
|
||||
else
|
||||
confsubst="-e /^@HAVE_PARPORT_BEGIN@/,/^@HAVE_PARPORT_END@/d"
|
||||
fi
|
||||
|
||||
|
||||
if test "$enabled_linuxgpio" = "yes"; then
|
||||
AC_DEFINE(HAVE_LINUXGPIO, 1, [Linux sysfs GPIO support enabled])
|
||||
confsubst="$confsubst -e /^@HAVE_LINUXGPIO_/d"
|
||||
else
|
||||
confsubst="$confsubst -e /^@HAVE_LINUXGPIO_BEGIN@/,/^@HAVE_LINUXGPIO_END@/d"
|
||||
fi
|
||||
|
||||
|
||||
# If we are compiling with gcc, enable all warning and make warnings errors.
|
||||
if test "$GCC" = yes; then
|
||||
ENABLE_WARNINGS="-Wall"
|
||||
|
||||
# does this compiler support -Wno-pointer-sign ?
|
||||
AC_MSG_CHECKING([if gcc accepts -Wno-pointer-sign ])
|
||||
|
||||
safe_CFLAGS=$CFLAGS
|
||||
CFLAGS="$ENABLE_WARNINGS -Wno-pointer-sign"
|
||||
|
||||
AC_TRY_COMPILE(, [ int main () { return 0 ; } ], [
|
||||
no_pointer_sign=yes
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
no_pointer_sign=no
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
CFLAGS=$safe_CFLAGS
|
||||
|
||||
if test x$no_pointer_sign = xyes; then
|
||||
ENABLE_WARNINGS="$ENABLE_WARNINGS -Wno-pointer-sign"
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(ENABLE_WARNINGS,$ENABLE_WARNINGS)
|
||||
export confsubst
|
||||
|
||||
# See if we need to drop into the windows subdir.
|
||||
case $target in
|
||||
*-*-mingw32* | *-*-cygwin* | *-*-windows*)
|
||||
if test "$GCC" = yes -a \( "$CC" = "cc" -o "$CC" = "gcc" \); then
|
||||
# does this compiler support -mno-cygwin?
|
||||
AC_MSG_CHECKING([if $CC accepts -mno-cygwin])
|
||||
|
||||
safe_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$ENABLE_WARNINGS -mno-cygwin"
|
||||
|
||||
AC_TRY_COMPILE(, [ int main () { return 0 ; } ], [
|
||||
no_cygwin=yes
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
no_cygwin=no
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
CFLAGS="$safe_CFLAGS"
|
||||
|
||||
if test x$no_cygwin = xyes; then
|
||||
CFLAGS="${CFLAGS} -mno-cygwin"
|
||||
else
|
||||
AC_MSG_NOTICE([Your compiler does not understand the -mno-cygwin option.])
|
||||
AC_MSG_NOTICE([You might want to select an alternative compiler, like])
|
||||
AC_MSG_NOTICE([])
|
||||
AC_MSG_NOTICE([CC=mingw32-gcc ./configure])
|
||||
AC_MSG_NOTICE([])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([if linker accepts -static])
|
||||
|
||||
safe_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="${LDFLAGS} -static"
|
||||
AC_TRY_LINK(, [ int main () { return 0 ; } ], [
|
||||
can_link_static=yes
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
can_link_static_cygwin=no
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
LDFLAGS="$safe_LDFLAGS"
|
||||
|
||||
if test x$can_link_static = xyes; then
|
||||
LDFLAGS="${LDFLAGS} -static"
|
||||
fi
|
||||
|
||||
WINDOWS_DIRS="windows"
|
||||
CFLAGS="${CFLAGS} -DWIN32NATIVE"
|
||||
CFLAGS="-mno-cygwin -DWIN32NATIVE"
|
||||
LDFLAGS="-static"
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(WINDOWS_DIRS,$WINDOWS_DIRS)
|
||||
|
||||
# If we are compiling with gcc, enable all warning and make warnings errors.
|
||||
if test "$GCC" = yes; then
|
||||
ENABLE_WARNINGS="-Wall"
|
||||
fi
|
||||
AC_SUBST(ENABLE_WARNINGS,$ENABLE_WARNINGS)
|
||||
|
||||
if test "$enabled_doc" = "yes"; then
|
||||
AC_CONFIG_FILES([doc/Makefile])
|
||||
fi
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
doc/Makefile
|
||||
windows/Makefile
|
||||
avrdude.spec
|
||||
Makefile
|
||||
@@ -470,77 +210,6 @@ AC_CONFIG_FILES([
|
||||
# avrdude.conf file.
|
||||
|
||||
AC_CONFIG_FILES([avrdude.conf.tmp:avrdude.conf.in],
|
||||
[sed $confsubst avrdude.conf.tmp > avrdude.conf],
|
||||
[confsubst="$confsubst"])
|
||||
[sed $confsubst avrdude.conf.tmp > avrdude.conf])
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo "Configuration summary:"
|
||||
echo "----------------------"
|
||||
|
||||
if test x$have_libelf = xyes; then
|
||||
echo "DO HAVE libelf"
|
||||
else
|
||||
echo "DON'T HAVE libelf"
|
||||
fi
|
||||
|
||||
if test x$have_libusb = xyes; then
|
||||
echo "DO HAVE libusb"
|
||||
else
|
||||
echo "DON'T HAVE libusb"
|
||||
fi
|
||||
|
||||
if test x$have_libusb_1_0 = xyes; then
|
||||
echo "DO HAVE libusb_1_0"
|
||||
else
|
||||
echo "DON'T HAVE libusb_1_0"
|
||||
fi
|
||||
|
||||
if test x$have_libftdi1 = xyes; then
|
||||
echo "DO HAVE libftdi1"
|
||||
else
|
||||
echo "DON'T HAVE libftdi1"
|
||||
fi
|
||||
|
||||
if test x$have_libftdi = xyes; then
|
||||
if test x$have_libftdi1 = xyes; then
|
||||
echo "DO HAVE libftdi (but prefer to use libftdi1)"
|
||||
else
|
||||
echo "DO HAVE libftdi"
|
||||
fi
|
||||
else
|
||||
echo "DON'T HAVE libftdi"
|
||||
fi
|
||||
|
||||
if test x$have_libhid = xyes; then
|
||||
echo "DO HAVE libhid"
|
||||
else
|
||||
echo "DON'T HAVE libhid"
|
||||
fi
|
||||
|
||||
if test x$have_pthread = xyes; then
|
||||
echo "DO HAVE pthread"
|
||||
else
|
||||
echo "DON'T HAVE pthread"
|
||||
fi
|
||||
|
||||
if test x$enabled_doc = xyes; then
|
||||
echo "ENABLED doc"
|
||||
else
|
||||
echo "DISABLED doc"
|
||||
fi
|
||||
|
||||
if test x$enabled_parport = xyes; then
|
||||
echo "ENABLED parport"
|
||||
else
|
||||
echo "DISABLED parport"
|
||||
fi
|
||||
|
||||
if test x$enabled_linuxgpio = xyes; then
|
||||
echo "ENABLED linuxgpio"
|
||||
else
|
||||
echo "DISABLED linuxgpio"
|
||||
fi
|
||||
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include "avrdude.h"
|
||||
|
||||
#if defined(WIN32NATIVE)
|
||||
|
||||
|
||||
@@ -13,25 +13,21 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#if defined(WIN32NATIVE)
|
||||
#ifndef confwin_h
|
||||
#define confwin_h
|
||||
#ifndef __confwin_h__
|
||||
#define __confwin_h__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void win_sys_config_set(char sys_config[PATH_MAX]);
|
||||
void win_usr_config_set(char usr_config[PATH_MAX]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "crc16.h"
|
||||
|
||||
/* CRC16 Definitions */
|
||||
static const unsigned short crc_table[256] = {
|
||||
const unsigned short crc_table[256] = {
|
||||
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
|
||||
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
|
||||
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
#ifndef CRC16_H
|
||||
#define CRC16_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Derived from CRC algorithm for JTAG ICE mkII, published in Atmel
|
||||
* Appnote AVR067. Converted from C++ to C.
|
||||
@@ -27,8 +22,4 @@ extern int crcverify(const unsigned char* message,
|
||||
extern void crcappend(unsigned char* message,
|
||||
unsigned long length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
.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
|
||||
programmer_types.texi
|
||||
parts.texi
|
||||
programmers.texi
|
||||
@@ -13,33 +13,25 @@
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
|
||||
GENERATED_TEXINFOS = \
|
||||
$(builddir)/programmers.texi \
|
||||
$(builddir)/parts.texi \
|
||||
$(builddir)/programmer_types.texi \
|
||||
$(builddir)/version.texi
|
||||
|
||||
CLEANFILES = \
|
||||
$(GENERATED_TEXINFOS) \
|
||||
$(builddir)/stamp-vti
|
||||
version.texi \
|
||||
stamp-vti
|
||||
|
||||
info_TEXINFOS = avrdude.texi
|
||||
|
||||
EXTRA_DIST = \
|
||||
parts_comments.txt
|
||||
|
||||
all-local: info html ps pdf
|
||||
|
||||
html: avrdude-html/avrdude.html
|
||||
|
||||
avrdude-html/avrdude.html: $(srcdir)/$(info_TEXINFOS) $(GENERATED_TEXINFOS)
|
||||
avrdude-html/avrdude.html: $(srcdir)/$(info_TEXINFOS)
|
||||
texi2html -split_node $(srcdir)/$(info_TEXINFOS)
|
||||
if [ -e ./avrdude.html -o -e ./avrdude_1.html ]; then \
|
||||
mkdir -p avrdude-html ; \
|
||||
@@ -48,32 +40,6 @@ avrdude-html/avrdude.html: $(srcdir)/$(info_TEXINFOS) $(GENERATED_TEXINFOS)
|
||||
mv -f avrdude avrdude-html; \
|
||||
fi;
|
||||
|
||||
$(builddir)/avrdude.info: $(GENERATED_TEXINFOS)
|
||||
$(builddir)/avrdude.dvi: $(GENERATED_TEXINFOS)
|
||||
$(builddir)/avrdude.pdf: $(GENERATED_TEXINFOS)
|
||||
|
||||
# if it does not exist make this first
|
||||
../avrdude$(EXEEXT):
|
||||
$(MAKE) -C .. avrdude$(EXEEXT)
|
||||
|
||||
$(builddir)/programmers.texi: ../avrdude$(EXEEXT) ../avrdude.conf Makefile
|
||||
../avrdude$(EXEEXT) -C ../avrdude.conf -c \? 2>&1 \
|
||||
| $(AWK) '$$2 ~ /^=$$/ {printf("@item @code{%s} @tab %s\n",$$1,gensub("[^=]+=[ \t]*","",1))}' \
|
||||
| sed "s# *,\? *<\?\(http://[^ \t>]*\)>\?#,@*\n@url{\1}#g" \
|
||||
>programmers.texi
|
||||
|
||||
$(builddir)/programmer_types.texi: ../avrdude$(EXEEXT) ../avrdude.conf Makefile
|
||||
../avrdude$(EXEEXT) -C ../avrdude.conf -c \?type 2>&1 \
|
||||
| $(AWK) '$$2 ~ /^=$$/ {printf("@item @code{%s} @tab %s\n",$$1,gensub("[^=]+=[ \t]*","",1))}' \
|
||||
| sed "s#<\?\(http://[^ \t,>]*\)>\?#@url{\1}#g" \
|
||||
>programmer_types.texi
|
||||
|
||||
$(builddir)/parts.texi: ../avrdude$(EXEEXT) ../avrdude.conf parts_comments.txt Makefile
|
||||
../avrdude$(EXEEXT) -C ../avrdude.conf -p \? 2>&1 \
|
||||
| $(AWK) '$$2 ~ /^=$$/ {printf("@item @code{%s} @tab %s\n",$$1,$$3)}' \
|
||||
| sed -e "`sed 's:\([^ \t]*\)[ \t]*\(.*\):s/\1$$/\1 \2/g:g' <parts_comments.txt`" \
|
||||
>parts.texi
|
||||
|
||||
clean-local:
|
||||
rm -rf avrdude-html *.info
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +0,0 @@
|
||||
AT90S1200 (****)
|
||||
AT90S2343 (*)
|
||||
ATmega2560 (**)
|
||||
ATmega2561 (**)
|
||||
ATtiny11 (***)
|
||||
820
avrdude/fileio.c
820
avrdude/fileio.c
File diff suppressed because it is too large
Load Diff
@@ -13,25 +13,21 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* 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 fileio_h
|
||||
#define fileio_h
|
||||
#ifndef __fileio_h__
|
||||
#define __fileio_h__
|
||||
|
||||
typedef enum {
|
||||
FMT_AUTO,
|
||||
FMT_SREC,
|
||||
FMT_IHEX,
|
||||
FMT_RBIN,
|
||||
FMT_IMM,
|
||||
FMT_HEX,
|
||||
FMT_DEC,
|
||||
FMT_OCT,
|
||||
FMT_BIN,
|
||||
FMT_ELF
|
||||
FMT_IMM
|
||||
} FILEFMT;
|
||||
|
||||
struct fioparms {
|
||||
@@ -40,7 +36,6 @@ struct fioparms {
|
||||
char * iodesc;
|
||||
char * dir;
|
||||
char * rw;
|
||||
unsigned int fileoffset;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -48,17 +43,11 @@ enum {
|
||||
FIO_WRITE
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
char * fmtstr(FILEFMT format);
|
||||
|
||||
int fileio(int op, char * filename, FILEFMT format,
|
||||
int fileio_setparms(int op, struct fioparms * fp);
|
||||
|
||||
int fileio(int op, char * filename, FILEFMT format,
|
||||
struct avrpart * p, char * memtype, int size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
945
avrdude/ft245r.c
945
avrdude/ft245r.c
@@ -1,945 +0,0 @@
|
||||
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
|
||||
* some code:
|
||||
* Copyright (C) 2011-2012 Roger E. Wolff <R.E.Wolff@BitWizard.nl>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/* ft245r -- FT245R/FT232R Synchronous BitBangMode Programmer
|
||||
default pin assign
|
||||
FT232R / FT245R
|
||||
miso = 1; # RxD / D1
|
||||
sck = 0; # RTS / D0
|
||||
mosi = 2; # TxD / D2
|
||||
reset = 4; # DTR / D4
|
||||
*/
|
||||
|
||||
/*
|
||||
The ft232r is very similar, or even "identical" in the synchronous
|
||||
bitbang mode that we use here.
|
||||
|
||||
This allows boards that have an ft232r for communication and an avr
|
||||
as the processor to function as their own "ICSP". Boards that fit
|
||||
this description include the Arduino Duemilanove, Arduino Diecimila,
|
||||
Arduino NG (http://arduino.cc/it/main/boards) and the BitWizard
|
||||
ftdi_atmega board (http://www.bitwizard.nl/wiki/index.php/FTDI_ATmega)
|
||||
|
||||
The Arduinos have to be patched to bring some of the control lines
|
||||
to the ICSP header. The BitWizard board already has the neccessary
|
||||
wiring on the PCB.
|
||||
|
||||
How to add the wires to an arduino is documented here:
|
||||
http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html
|
||||
*/
|
||||
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "avrpart.h"
|
||||
#include "pindefs.h"
|
||||
#include "pgm.h"
|
||||
#include "config.h"
|
||||
#include "bitbang.h"
|
||||
#include "ft245r.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIBFTDI1) && defined(HAVE_LIBUSB_1_0)
|
||||
# if defined(HAVE_LIBUSB_1_0_LIBUSB_H)
|
||||
# include <libusb-1.0/libusb.h>
|
||||
# else
|
||||
# include <libusb.h>
|
||||
# endif
|
||||
# include <libftdi1/ftdi.h>
|
||||
#elif defined(HAVE_LIBFTDI) && defined(HAVE_USB_H)
|
||||
/* ftdi.h includes usb.h */
|
||||
#include <ftdi.h>
|
||||
#else
|
||||
#warning No libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.
|
||||
#define DO_NOT_BUILD_FT245R
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_PTHREAD_H
|
||||
|
||||
static int ft245r_nopthread_open (struct programmer_t *pgm, char * name) {
|
||||
fprintf(stderr,
|
||||
"%s: error: no pthread support. Please compile again with pthread installed."
|
||||
#if defined(_WIN32)
|
||||
" See http://sourceware.org/pthreads-win32/."
|
||||
#endif
|
||||
"\n",
|
||||
progname);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ft245r_initpgm(PROGRAMMER * pgm) {
|
||||
strcpy(pgm->type, "ftdi_syncbb");
|
||||
pgm->open = ft245r_nopthread_open;
|
||||
}
|
||||
|
||||
#elif defined(DO_NOT_BUILD_FT245R)
|
||||
|
||||
static int ft245r_noftdi_open (struct programmer_t *pgm, char * name) {
|
||||
fprintf(stderr,
|
||||
"%s: error: no libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.\n",
|
||||
progname);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ft245r_initpgm(PROGRAMMER * pgm) {
|
||||
strcpy(pgm->type, "ftdi_syncbb");
|
||||
pgm->open = ft245r_noftdi_open;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* Mac OS X defines sem_init but actually does not implement them */
|
||||
#include <dispatch/dispatch.h>
|
||||
|
||||
typedef dispatch_semaphore_t sem_t;
|
||||
|
||||
#define sem_init(psem,x,val) *psem = dispatch_semaphore_create(val)
|
||||
#define sem_post(psem) dispatch_semaphore_signal(*psem)
|
||||
#define sem_wait(psem) dispatch_semaphore_wait(*psem, DISPATCH_TIME_FOREVER)
|
||||
#else
|
||||
#include <semaphore.h>
|
||||
#endif
|
||||
|
||||
#define FT245R_CYCLES 2
|
||||
#define FT245R_FRAGMENT_SIZE 512
|
||||
#define REQ_OUTSTANDINGS 10
|
||||
//#define USE_INLINE_WRITE_PAGE
|
||||
|
||||
#define FT245R_DEBUG 0
|
||||
|
||||
static struct ftdi_context *handle;
|
||||
|
||||
static unsigned char ft245r_ddr;
|
||||
static unsigned char ft245r_out;
|
||||
static unsigned char ft245r_in;
|
||||
|
||||
#define BUFSIZE 0x2000
|
||||
|
||||
// libftdi / libftd2xx compatibility functions.
|
||||
|
||||
static pthread_t readerthread;
|
||||
static sem_t buf_data, buf_space;
|
||||
static unsigned char buffer[BUFSIZE];
|
||||
static int head, tail;
|
||||
|
||||
static void add_to_buf (unsigned char c) {
|
||||
int nh;
|
||||
|
||||
sem_wait (&buf_space);
|
||||
if (head == (BUFSIZE -1)) nh = 0;
|
||||
else nh = head + 1;
|
||||
|
||||
if (nh == tail) {
|
||||
fprintf (stderr, "buffer overflow. Cannot happen!\n");
|
||||
//exit (1);
|
||||
}
|
||||
buffer[head] = c;
|
||||
head = nh;
|
||||
sem_post (&buf_data);
|
||||
}
|
||||
|
||||
static void *reader (void *arg) {
|
||||
struct ftdi_context *handle = (struct ftdi_context *)(arg);
|
||||
unsigned char buf[0x1000];
|
||||
int br, i;
|
||||
|
||||
while (1) {
|
||||
pthread_testcancel();
|
||||
br = ftdi_read_data (handle, buf, sizeof(buf));
|
||||
for (i=0; i<br; i++)
|
||||
add_to_buf (buf[i]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ft245r_send(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
|
||||
int rv;
|
||||
|
||||
rv = ftdi_write_data(handle, buf, len);
|
||||
if (len != rv) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ft245r_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
|
||||
int i;
|
||||
|
||||
// Copy over data from the circular buffer..
|
||||
// XXX This should timeout, and return error if there isn't enough
|
||||
// data.
|
||||
for (i=0; i<len; i++) {
|
||||
sem_wait (&buf_data);
|
||||
buf[i] = buffer[tail];
|
||||
if (tail == (BUFSIZE -1)) tail = 0;
|
||||
else tail++;
|
||||
sem_post (&buf_space);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ft245r_drain(PROGRAMMER * pgm, int display) {
|
||||
int r;
|
||||
unsigned char t;
|
||||
|
||||
// flush the buffer in the chip by changing the mode.....
|
||||
r = ftdi_set_bitmode(handle, 0, BITMODE_RESET); // reset
|
||||
if (r) return -1;
|
||||
r = ftdi_set_bitmode(handle, ft245r_ddr, BITMODE_SYNCBB); // set Synchronuse BitBang
|
||||
if (r) return -1;
|
||||
|
||||
// drain our buffer.
|
||||
while (head != tail) {
|
||||
ft245r_recv (pgm, &t, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ft245r_chip_erase(PROGRAMMER * pgm, AVRPART * p) {
|
||||
unsigned char cmd[4] = {0,0,0,0};
|
||||
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;
|
||||
}
|
||||
|
||||
avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
|
||||
pgm->cmd(pgm, cmd, res);
|
||||
usleep(p->chip_erase_delay);
|
||||
return pgm->initialize(pgm, p);
|
||||
}
|
||||
|
||||
|
||||
static int ft245r_set_bitclock(PROGRAMMER * pgm) {
|
||||
int r;
|
||||
int rate = 0;
|
||||
|
||||
/* bitclock is second. 1us = 0.000001. Max rate for ft232r 750000 */
|
||||
if(pgm->bitclock) {
|
||||
rate = (uint32_t)(1.0/pgm->bitclock) * 2;
|
||||
} else if (pgm->baudrate) {
|
||||
rate = pgm->baudrate * 2;
|
||||
} else {
|
||||
rate = 150000; /* should work for all ftdi chips and the avr default internal clock of 1MHz */
|
||||
}
|
||||
|
||||
if ((verbose>1) || FT245R_DEBUG) {
|
||||
fprintf(stderr," ft245r: spi bitclk %d -> ft baudrate %d\n",
|
||||
rate / 2, rate);
|
||||
}
|
||||
r = ftdi_set_baudrate(handle, rate);
|
||||
if (r) {
|
||||
fprintf(stderr, "Set baudrate (%d) failed with error '%s'.\n",
|
||||
rate, ftdi_get_error_string (handle));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_pin(PROGRAMMER * pgm, int pinname, int val) {
|
||||
unsigned char buf[1];
|
||||
|
||||
if (pgm->pin[pinname].mask[0] == 0) {
|
||||
// ignore not defined pins (might be the led or vcc or buff if not needed)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,pinname,val);
|
||||
buf[0] = ft245r_out;
|
||||
|
||||
ft245r_send (pgm, buf, 1);
|
||||
ft245r_recv (pgm, buf, 1);
|
||||
|
||||
ft245r_in = buf[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_reset(PROGRAMMER * pgm, int value) {
|
||||
return set_pin(pgm, PIN_AVR_RESET, value);
|
||||
}
|
||||
|
||||
static int set_buff(PROGRAMMER * pgm, int value) {
|
||||
return set_pin(pgm, PPI_AVR_BUFF, value);
|
||||
}
|
||||
|
||||
static int set_vcc(PROGRAMMER * pgm, int value) {
|
||||
return set_pin(pgm, PPI_AVR_VCC, value);
|
||||
}
|
||||
|
||||
/* these functions are callbacks, which go into the
|
||||
* PROGRAMMER data structure ("optional functions")
|
||||
*/
|
||||
static int set_led_pgm(struct programmer_t * pgm, int value) {
|
||||
return set_pin(pgm, PIN_LED_PGM, value);
|
||||
}
|
||||
|
||||
static int set_led_rdy(struct programmer_t * pgm, int value) {
|
||||
return set_pin(pgm, PIN_LED_RDY, value);
|
||||
}
|
||||
|
||||
static int set_led_err(struct programmer_t * pgm, int value) {
|
||||
return set_pin(pgm, PIN_LED_ERR, value);
|
||||
}
|
||||
|
||||
static int set_led_vfy(struct programmer_t * pgm, int value) {
|
||||
return set_pin(pgm, PIN_LED_VFY, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* apply power to the AVR processor
|
||||
*/
|
||||
static void ft245r_powerup(PROGRAMMER * pgm)
|
||||
{
|
||||
set_vcc(pgm, ON); /* power up */
|
||||
usleep(100);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* remove power from the AVR processor
|
||||
*/
|
||||
static void ft245r_powerdown(PROGRAMMER * pgm)
|
||||
{
|
||||
set_vcc(pgm, OFF); /* power down */
|
||||
}
|
||||
|
||||
|
||||
static void ft245r_disable(PROGRAMMER * pgm) {
|
||||
set_buff(pgm, OFF);
|
||||
}
|
||||
|
||||
|
||||
static void ft245r_enable(PROGRAMMER * pgm) {
|
||||
/*
|
||||
* Prepare to start talking to the connected device - pull reset low
|
||||
* first, delay a few milliseconds, then enable the buffer. This
|
||||
* sequence allows the AVR to be reset before the buffer is enabled
|
||||
* to avoid a short period of time where the AVR may be driving the
|
||||
* programming lines at the same time the programmer tries to. Of
|
||||
* course, if a buffer is being used, then the /RESET line from the
|
||||
* programmer needs to be directly connected to the AVR /RESET line
|
||||
* and not via the buffer chip.
|
||||
*/
|
||||
set_reset(pgm, OFF);
|
||||
usleep(1);
|
||||
set_buff(pgm, ON);
|
||||
}
|
||||
|
||||
static int ft245r_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
unsigned char *res);
|
||||
/*
|
||||
* issue the 'program enable' command to the AVR device
|
||||
*/
|
||||
static int ft245r_program_enable(PROGRAMMER * pgm, AVRPART * p) {
|
||||
unsigned char cmd[4] = {0,0,0,0};
|
||||
unsigned char res[4];
|
||||
int i;
|
||||
|
||||
if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
|
||||
fprintf(stderr,
|
||||
"%s: AVR_OP_PGM_ENABLE command not defined for %s\n", progname, p->desc);
|
||||
fflush(stderr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd);
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
ft245r_cmd(pgm, cmd, res);
|
||||
|
||||
if (res[p->pollindex-1] == p->pollvalue) return 0;
|
||||
|
||||
if ((verbose>=1) || FT245R_DEBUG) {
|
||||
fprintf(stderr,
|
||||
"%s: Program enable command not successful. Retrying.\n", progname);
|
||||
fflush(stderr);
|
||||
}
|
||||
set_pin(pgm, PIN_AVR_RESET, ON);
|
||||
usleep(20);
|
||||
set_pin(pgm, PIN_AVR_RESET, OFF);
|
||||
|
||||
if (i == 3) {
|
||||
ft245r_drain(pgm, 0);
|
||||
tail = head;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"%s: Device is not responding to program enable. Check connection.\n", progname);
|
||||
fflush(stderr);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize the AVR device and prepare it to accept commands
|
||||
*/
|
||||
static int ft245r_initialize(PROGRAMMER * pgm, AVRPART * p) {
|
||||
|
||||
ft245r_powerup(pgm);
|
||||
|
||||
set_reset(pgm, OFF);
|
||||
usleep(5000); // 5ms
|
||||
set_reset(pgm, ON);
|
||||
usleep(5000); // 5ms
|
||||
set_reset(pgm, OFF);
|
||||
usleep(5000); // 5ms
|
||||
|
||||
return ft245r_program_enable(pgm, p);
|
||||
}
|
||||
|
||||
static inline int set_data(PROGRAMMER * pgm, unsigned char *buf, unsigned char data) {
|
||||
int j;
|
||||
int buf_pos = 0;
|
||||
unsigned char bit = 0x80;
|
||||
|
||||
for (j=0; j<8; j++) {
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_MOSI,data & bit);
|
||||
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0);
|
||||
buf[buf_pos] = ft245r_out;
|
||||
buf_pos++;
|
||||
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,1);
|
||||
buf[buf_pos] = ft245r_out;
|
||||
buf_pos++;
|
||||
|
||||
bit >>= 1;
|
||||
}
|
||||
return buf_pos;
|
||||
}
|
||||
|
||||
static inline unsigned char extract_data(PROGRAMMER * pgm, unsigned char *buf, int offset) {
|
||||
int j;
|
||||
int buf_pos = 1;
|
||||
unsigned char bit = 0x80;
|
||||
unsigned char r = 0;
|
||||
|
||||
buf += offset * (8 * FT245R_CYCLES);
|
||||
for (j=0; j<8; j++) {
|
||||
if (GET_BITS_0(buf[buf_pos],pgm,PIN_AVR_MISO)) {
|
||||
r |= bit;
|
||||
}
|
||||
buf_pos += FT245R_CYCLES;
|
||||
bit >>= 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* to check data */
|
||||
static inline unsigned char extract_data_out(PROGRAMMER * pgm, unsigned char *buf, int offset) {
|
||||
int j;
|
||||
int buf_pos = 1;
|
||||
unsigned char bit = 0x80;
|
||||
unsigned char r = 0;
|
||||
|
||||
buf += offset * (8 * FT245R_CYCLES);
|
||||
for (j=0; j<8; j++) {
|
||||
if (GET_BITS_0(buf[buf_pos],pgm,PIN_AVR_MOSI)) {
|
||||
r |= bit;
|
||||
}
|
||||
buf_pos += FT245R_CYCLES;
|
||||
bit >>= 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* transmit an AVR device command and return the results; 'cmd' and
|
||||
* 'res' must point to at least a 4 byte data buffer
|
||||
*/
|
||||
static int ft245r_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
unsigned char *res) {
|
||||
int i,buf_pos;
|
||||
unsigned char buf[128];
|
||||
|
||||
buf_pos = 0;
|
||||
for (i=0; i<4; i++) {
|
||||
buf_pos += set_data(pgm, buf+buf_pos, cmd[i]);
|
||||
}
|
||||
buf[buf_pos] = 0;
|
||||
buf_pos++;
|
||||
|
||||
ft245r_send (pgm, buf, buf_pos);
|
||||
ft245r_recv (pgm, buf, buf_pos);
|
||||
res[0] = extract_data(pgm, buf, 0);
|
||||
res[1] = extract_data(pgm, buf, 1);
|
||||
res[2] = extract_data(pgm, buf, 2);
|
||||
res[3] = extract_data(pgm, buf, 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* lower 8 pins are accepted, they might be also inverted */
|
||||
static const struct pindef_t valid_pins = {{0xff},{0xff}} ;
|
||||
|
||||
static const struct pin_checklist_t pin_checklist[] = {
|
||||
{ PIN_AVR_SCK, 1, &valid_pins},
|
||||
{ PIN_AVR_MOSI, 1, &valid_pins},
|
||||
{ PIN_AVR_MISO, 1, &valid_pins},
|
||||
{ PIN_AVR_RESET,1, &valid_pins},
|
||||
{ PPI_AVR_BUFF, 0, &valid_pins},
|
||||
};
|
||||
|
||||
static int ft245r_open(PROGRAMMER * pgm, char * port) {
|
||||
int rv;
|
||||
int devnum = -1;
|
||||
|
||||
rv = pins_check(pgm,pin_checklist,sizeof(pin_checklist)/sizeof(pin_checklist[0]), true);
|
||||
if(rv) {
|
||||
pgm->display(pgm, progbuf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
strcpy(pgm->port, port);
|
||||
|
||||
if (strcmp(port,DEFAULT_USB) != 0) {
|
||||
if (strncasecmp("ft", port, 2) == 0) {
|
||||
char *startptr = port + 2;
|
||||
char *endptr = NULL;
|
||||
devnum = strtol(startptr,&endptr,10);
|
||||
if ((startptr==endptr) || (*endptr != '\0')) {
|
||||
devnum = -1;
|
||||
}
|
||||
}
|
||||
if (devnum < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: invalid portname '%s': use 'ft[0-9]+'\n",
|
||||
progname,port);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
devnum = 0;
|
||||
}
|
||||
|
||||
handle = malloc (sizeof (struct ftdi_context));
|
||||
ftdi_init(handle);
|
||||
rv = ftdi_usb_open_desc_index(handle,
|
||||
pgm->usbvid?pgm->usbvid:0x0403,
|
||||
pgm->usbpid?pgm->usbpid:0x6001,
|
||||
pgm->usbproduct[0]?pgm->usbproduct:NULL,
|
||||
pgm->usbsn[0]?pgm->usbsn:NULL,
|
||||
devnum);
|
||||
if (rv) {
|
||||
fprintf (stderr, "can't open ftdi device %d. (%s)\n", devnum, ftdi_get_error_string(handle));
|
||||
goto cleanup_no_usb;
|
||||
}
|
||||
|
||||
ft245r_ddr =
|
||||
pgm->pin[PIN_AVR_SCK].mask[0]
|
||||
| pgm->pin[PIN_AVR_MOSI].mask[0]
|
||||
| pgm->pin[PIN_AVR_RESET].mask[0]
|
||||
| pgm->pin[PPI_AVR_BUFF].mask[0]
|
||||
| pgm->pin[PPI_AVR_VCC].mask[0]
|
||||
| pgm->pin[PIN_LED_ERR].mask[0]
|
||||
| pgm->pin[PIN_LED_RDY].mask[0]
|
||||
| pgm->pin[PIN_LED_PGM].mask[0]
|
||||
| pgm->pin[PIN_LED_VFY].mask[0];
|
||||
|
||||
/* set initial values for outputs, no reset everything else is off */
|
||||
ft245r_out = 0;
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_RESET,1);
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0);
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_MOSI,0);
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PPI_AVR_BUFF,0);
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PPI_AVR_VCC,0);
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_ERR,0);
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_RDY,0);
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_PGM,0);
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_VFY,0);
|
||||
|
||||
|
||||
rv = ftdi_set_bitmode(handle, ft245r_ddr, BITMODE_SYNCBB); // set Synchronous BitBang
|
||||
if (rv) {
|
||||
fprintf(stderr,
|
||||
"%s: Synchronous BitBangMode is not supported (%s)\n",
|
||||
progname, ftdi_get_error_string(handle));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rv = ft245r_set_bitclock(pgm);
|
||||
if (rv) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* We start a new thread to read the output from the FTDI. This is
|
||||
* necessary because otherwise we'll deadlock. We cannot finish
|
||||
* writing because the ftdi cannot send the results because we
|
||||
* haven't provided a read buffer yet. */
|
||||
|
||||
sem_init (&buf_data, 0, 0);
|
||||
sem_init (&buf_space, 0, BUFSIZE);
|
||||
pthread_create (&readerthread, NULL, reader, handle);
|
||||
|
||||
/*
|
||||
* drain any extraneous input
|
||||
*/
|
||||
ft245r_drain (pgm, 0);
|
||||
|
||||
ft245r_send (pgm, &ft245r_out, 1);
|
||||
ft245r_recv (pgm, &ft245r_in, 1);
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
ftdi_usb_close(handle);
|
||||
cleanup_no_usb:
|
||||
ftdi_deinit (handle);
|
||||
free(handle);
|
||||
handle = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void ft245r_close(PROGRAMMER * pgm) {
|
||||
if (handle) {
|
||||
// I think the switch to BB mode and back flushes the buffer.
|
||||
ftdi_set_bitmode(handle, 0, BITMODE_SYNCBB); // set Synchronous BitBang, all in puts
|
||||
ftdi_set_bitmode(handle, 0, BITMODE_RESET); // disable Synchronous BitBang
|
||||
pthread_cancel(readerthread);
|
||||
pthread_join(readerthread, NULL);
|
||||
ftdi_usb_close(handle);
|
||||
ftdi_deinit (handle); // TODO this works with libftdi 0.20, but hangs with 1.0
|
||||
free(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void ft245r_display(PROGRAMMER * pgm, const char * p) {
|
||||
fprintf(stderr, "%sPin assignment : 0..7 = DBUS0..7\n",p);/* , 8..11 = GPIO0..3\n",p);*/
|
||||
pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS);
|
||||
}
|
||||
|
||||
static int ft245r_paged_write_gen(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size, unsigned int addr,
|
||||
unsigned int n_bytes) {
|
||||
unsigned long i, pa;
|
||||
int rc;
|
||||
|
||||
for (i=0; i<n_bytes; i++, addr++) {
|
||||
rc = avr_write_byte_default(pgm, p, m, addr, m->buf[addr]);
|
||||
if (rc != 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (m->paged) {
|
||||
// Can this piece of code ever be activated?? Do AVRs exist that
|
||||
// have paged non-flash memories? -- REW
|
||||
// XXX Untested code below.
|
||||
/*
|
||||
* check to see if it is time to flush the page with a page
|
||||
* write
|
||||
*/
|
||||
|
||||
if (((addr % m->page_size) == m->page_size-1) || (i == n_bytes-1)) {
|
||||
pa = addr - (addr % m->page_size);
|
||||
|
||||
rc = avr_write_page(pgm, p, m, pa);
|
||||
if (rc != 0) {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static struct ft245r_request {
|
||||
int addr;
|
||||
int bytes;
|
||||
int n;
|
||||
struct ft245r_request *next;
|
||||
} *req_head,*req_tail,*req_pool;
|
||||
|
||||
static void put_request(int addr, int bytes, int n) {
|
||||
struct ft245r_request *p;
|
||||
if (req_pool) {
|
||||
p = req_pool;
|
||||
req_pool = p->next;
|
||||
} else {
|
||||
p = malloc(sizeof(struct ft245r_request));
|
||||
if (!p) {
|
||||
fprintf(stderr, "can't alloc memory\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
memset(p, 0, sizeof(struct ft245r_request));
|
||||
p->addr = addr;
|
||||
p->bytes = bytes;
|
||||
p->n = n;
|
||||
if (req_tail) {
|
||||
req_tail->next = p;
|
||||
req_tail = p;
|
||||
} else {
|
||||
req_head = req_tail = p;
|
||||
}
|
||||
}
|
||||
|
||||
static int do_request(PROGRAMMER * pgm, AVRMEM *m) {
|
||||
struct ft245r_request *p;
|
||||
int addr, bytes, j, n;
|
||||
unsigned char buf[FT245R_FRAGMENT_SIZE+1+128];
|
||||
|
||||
if (!req_head) return 0;
|
||||
p = req_head;
|
||||
req_head = p->next;
|
||||
if (!req_head) req_tail = req_head;
|
||||
|
||||
addr = p->addr;
|
||||
bytes = p->bytes;
|
||||
n = p->n;
|
||||
memset(p, 0, sizeof(struct ft245r_request));
|
||||
p->next = req_pool;
|
||||
req_pool = p;
|
||||
|
||||
ft245r_recv(pgm, buf, bytes);
|
||||
for (j=0; j<n; j++) {
|
||||
m->buf[addr++] = extract_data(pgm, buf , (j * 4 + 3));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ft245r_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int addr, int n_bytes) {
|
||||
unsigned int i,j;
|
||||
int addr_save,buf_pos,do_page_write,req_count;
|
||||
unsigned char buf[FT245R_FRAGMENT_SIZE+1+128];
|
||||
|
||||
req_count = 0;
|
||||
for (i=0; i<n_bytes; ) {
|
||||
addr_save = addr;
|
||||
buf_pos = 0;
|
||||
do_page_write = 0;
|
||||
for (j=0; j< FT245R_FRAGMENT_SIZE/8/FT245R_CYCLES/4; j++) {
|
||||
buf_pos += set_data(pgm, buf+buf_pos, (addr & 1)?0x48:0x40 );
|
||||
buf_pos += set_data(pgm, buf+buf_pos, (addr >> 9) & 0xff );
|
||||
buf_pos += set_data(pgm, buf+buf_pos, (addr >> 1) & 0xff );
|
||||
buf_pos += set_data(pgm, buf+buf_pos, m->buf[addr]);
|
||||
addr ++;
|
||||
i++;
|
||||
if ( (m->paged) &&
|
||||
(((i % m->page_size) == 0) || (i == n_bytes))) {
|
||||
do_page_write = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if defined(USE_INLINE_WRITE_PAGE)
|
||||
if (do_page_write) {
|
||||
int addr_wk = addr_save - (addr_save % m->page_size);
|
||||
/* If this device has a "load extended address" command, issue it. */
|
||||
if (m->op[AVR_OP_LOAD_EXT_ADDR]) {
|
||||
unsigned char cmd[4];
|
||||
OPCODE *lext = m->op[AVR_OP_LOAD_EXT_ADDR];
|
||||
|
||||
memset(cmd, 0, 4);
|
||||
avr_set_bits(lext, cmd);
|
||||
avr_set_addr(lext, cmd, addr_wk/2);
|
||||
buf_pos += set_data(pgm, buf+buf_pos, cmd[0]);
|
||||
buf_pos += set_data(pgm, buf+buf_pos, cmd[1]);
|
||||
buf_pos += set_data(pgm, buf+buf_pos, cmd[2]);
|
||||
buf_pos += set_data(pgm, buf+buf_pos, cmd[3]);
|
||||
}
|
||||
buf_pos += set_data(pgm, buf+buf_pos, 0x4C); /* Issue Page Write */
|
||||
buf_pos += set_data(pgm, buf+buf_pos,(addr_wk >> 9) & 0xff);
|
||||
buf_pos += set_data(pgm, buf+buf_pos,(addr_wk >> 1) & 0xff);
|
||||
buf_pos += set_data(pgm, buf+buf_pos, 0);
|
||||
}
|
||||
#endif
|
||||
if (i >= n_bytes) {
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0); // sck down
|
||||
buf[buf_pos++] = ft245r_out;
|
||||
}
|
||||
ft245r_send(pgm, buf, buf_pos);
|
||||
put_request(addr_save, buf_pos, 0);
|
||||
//ft245r_sync(pgm);
|
||||
#if 0
|
||||
fprintf(stderr, "send addr 0x%04x bufsize %d [%02x %02x] page_write %d\n",
|
||||
addr_save,buf_pos,
|
||||
extract_data_out(pgm, buf , (0*4 + 3) ),
|
||||
extract_data_out(pgm, buf , (1*4 + 3) ),
|
||||
do_page_write);
|
||||
#endif
|
||||
req_count++;
|
||||
if (req_count > REQ_OUTSTANDINGS)
|
||||
do_request(pgm, m);
|
||||
if (do_page_write) {
|
||||
#if defined(USE_INLINE_WRITE_PAGE)
|
||||
while (do_request(pgm, m))
|
||||
;
|
||||
usleep(m->max_write_delay);
|
||||
#else
|
||||
int addr_wk = addr_save - (addr_save % m->page_size);
|
||||
int rc;
|
||||
while (do_request(pgm, m))
|
||||
;
|
||||
rc = avr_write_page(pgm, p, m, addr_wk);
|
||||
if (rc != 0) {
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
req_count = 0;
|
||||
}
|
||||
}
|
||||
while (do_request(pgm, m))
|
||||
;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
static int ft245r_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size, unsigned int addr, unsigned int n_bytes) {
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
return ft245r_paged_write_flash(pgm, p, m, page_size, addr, n_bytes);
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
return ft245r_paged_write_gen(pgm, p, m, page_size, addr, n_bytes);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
static int ft245r_paged_load_gen(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size, unsigned int addr,
|
||||
int n_bytes) {
|
||||
unsigned char rbyte;
|
||||
unsigned long i;
|
||||
int rc;
|
||||
|
||||
for (i=0; i<n_bytes; i++) {
|
||||
rc = avr_read_byte_default(pgm, p, m, i+addr, &rbyte);
|
||||
if (rc != 0) {
|
||||
return -2;
|
||||
}
|
||||
m->buf[i+addr] = rbyte;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ft245r_paged_load_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size, unsigned int addr,
|
||||
unsigned int n_bytes) {
|
||||
unsigned long i,j,n;
|
||||
int addr_save,buf_pos;
|
||||
int req_count = 0;
|
||||
unsigned char buf[FT245R_FRAGMENT_SIZE+1];
|
||||
|
||||
for (i=0; i<n_bytes; ) {
|
||||
buf_pos = 0;
|
||||
addr_save = addr;
|
||||
for (j=0; j< FT245R_FRAGMENT_SIZE/8/FT245R_CYCLES/4; j++) {
|
||||
if (i >= n_bytes) break;
|
||||
buf_pos += set_data(pgm, buf+buf_pos, (addr & 1)?0x28:0x20 );
|
||||
buf_pos += set_data(pgm, buf+buf_pos, (addr >> 9) & 0xff );
|
||||
buf_pos += set_data(pgm, buf+buf_pos, (addr >> 1) & 0xff );
|
||||
buf_pos += set_data(pgm, buf+buf_pos, 0);
|
||||
addr ++;
|
||||
i++;
|
||||
}
|
||||
if (i >= n_bytes) {
|
||||
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0); // sck down
|
||||
buf[buf_pos++] = ft245r_out;
|
||||
}
|
||||
n = j;
|
||||
ft245r_send(pgm, buf, buf_pos);
|
||||
put_request(addr_save, buf_pos, n);
|
||||
req_count++;
|
||||
if (req_count > REQ_OUTSTANDINGS)
|
||||
do_request(pgm, m);
|
||||
|
||||
}
|
||||
while (do_request(pgm, m))
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ft245r_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size, unsigned int addr,
|
||||
unsigned int n_bytes) {
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
return ft245r_paged_load_flash(pgm, p, m, page_size, addr, n_bytes);
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
return ft245r_paged_load_gen(pgm, p, m, page_size, addr, n_bytes);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
void ft245r_initpgm(PROGRAMMER * pgm) {
|
||||
strcpy(pgm->type, "ftdi_syncbb");
|
||||
|
||||
/*
|
||||
* mandatory functions
|
||||
*/
|
||||
pgm->initialize = ft245r_initialize;
|
||||
pgm->display = ft245r_display;
|
||||
pgm->enable = ft245r_enable;
|
||||
pgm->disable = ft245r_disable;
|
||||
pgm->program_enable = ft245r_program_enable;
|
||||
pgm->chip_erase = ft245r_chip_erase;
|
||||
pgm->cmd = ft245r_cmd;
|
||||
pgm->open = ft245r_open;
|
||||
pgm->close = ft245r_close;
|
||||
pgm->read_byte = avr_read_byte_default;
|
||||
pgm->write_byte = avr_write_byte_default;
|
||||
|
||||
/*
|
||||
* optional functions
|
||||
*/
|
||||
pgm->paged_write = ft245r_paged_write;
|
||||
pgm->paged_load = ft245r_paged_load;
|
||||
|
||||
pgm->rdy_led = set_led_rdy;
|
||||
pgm->err_led = set_led_err;
|
||||
pgm->pgm_led = set_led_pgm;
|
||||
pgm->vfy_led = set_led_vfy;
|
||||
pgm->powerup = ft245r_powerup;
|
||||
pgm->powerdown = ft245r_powerdown;
|
||||
|
||||
handle = NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const char ft245r_desc[] = "FT245R/FT232R Synchronous BitBangMode Programmer";
|
||||
@@ -1,10 +0,0 @@
|
||||
#ifndef ft245r_h
|
||||
#define ft245r_h
|
||||
|
||||
#include "pgm.h"
|
||||
|
||||
extern const char ft245r_desc[];
|
||||
void ft245r_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
|
||||
#endif /* ft245r_h */
|
||||
1997
avrdude/jtag3.c
1997
avrdude/jtag3.c
File diff suppressed because it is too large
Load Diff
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2012 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef jtag3_h
|
||||
#define jtag3_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int jtag3_send(PROGRAMMER * pgm, unsigned char * data, size_t len);
|
||||
int jtag3_recv(PROGRAMMER * pgm, unsigned char **msg);
|
||||
void jtag3_close(PROGRAMMER * pgm);
|
||||
int jtag3_getsync(PROGRAMMER * pgm, int mode);
|
||||
int jtag3_getparm(PROGRAMMER * pgm, unsigned char scope,
|
||||
unsigned char section, unsigned char parm,
|
||||
unsigned char *value, unsigned char length);
|
||||
int jtag3_setparm(PROGRAMMER * pgm, unsigned char scope,
|
||||
unsigned char section, unsigned char parm,
|
||||
unsigned char *value, unsigned char length);
|
||||
int jtag3_command(PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
|
||||
unsigned char **resp, const char *descr);
|
||||
extern const char jtag3_desc[];
|
||||
extern const char jtag3_dw_desc[];
|
||||
extern const char jtag3_pdi_desc[];
|
||||
void jtag3_initpgm (PROGRAMMER * pgm);
|
||||
void jtag3_dw_initpgm (PROGRAMMER * pgm);
|
||||
void jtag3_pdi_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
/*
|
||||
* These functions are referenced from stk500v2.c for JTAGICE3 in
|
||||
* one of the STK500v2 modi.
|
||||
*/
|
||||
void jtag3_setup(PROGRAMMER * pgm);
|
||||
void jtag3_teardown(PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,278 +0,0 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2012 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
|
||||
/*
|
||||
* JTAGICE3 definitions
|
||||
* Reverse-engineered from various USB traces.
|
||||
*/
|
||||
|
||||
#if !defined(JTAG3_PRIVATE_EXPORTED)
|
||||
/*
|
||||
* Communication with the JTAGICE3 uses three data endpoints:
|
||||
*
|
||||
* Endpoint 0x01 (OUT) and 0x82 (IN) are the usual conversation
|
||||
* endpoints, with a maximal packet size of 512 octets. The
|
||||
* JTAGICE3 does *not* work on older USB 1.1 hubs that would only
|
||||
* allow for 64-octet max packet size.
|
||||
*
|
||||
* Endpoint 0x83 (IN) is also a bulk endpoint, with a max packetsize
|
||||
* of 64 octets. This endpoint is used by the ICE to deliver events
|
||||
* from the ICE.
|
||||
*
|
||||
* The request (host -> ICE, EP 0x01) format is:
|
||||
*
|
||||
* +---------------------------------------------
|
||||
* | 0 | 1 | 2 . 3 | 4 | 5 | 6 | ...
|
||||
* | | | | | | |
|
||||
* | token |dummy|serial# |scope| cmd |dummy| optional data
|
||||
* | 0x0e | 0 | NNNN | SS | CC | 0 | ...
|
||||
* +---------------------------------------------
|
||||
*
|
||||
* Both dummy bytes are always 0. The "scope" identifier appears
|
||||
* to distinguish commands (responses, events, parameters) roughly:
|
||||
*
|
||||
* 0x01 - general scope ("hello", "goodbye", firmware info, target
|
||||
* voltage readout)
|
||||
* 0x11 - scope for AVR in ISP mode (basically a wrapper around
|
||||
* the AVRISPmkII commands, as usual)
|
||||
* 0x12 - scope for AVR (JTAG, PDI, debugWIRE)
|
||||
*
|
||||
* The serial number is counted up.
|
||||
*
|
||||
*
|
||||
* The response (ICE -> host, EP 0x82) format is:
|
||||
*
|
||||
* +--------------------------------------------------+
|
||||
* | 0 | 1 . 2 | 3 | 4 | ... | N |
|
||||
* | | | | | | |
|
||||
* | token |serial# |scope| rsp | optional data |dummy|
|
||||
* | 0x0e | NNNN | SS | RR | ... | 0 |
|
||||
* +--------------------------------------------------+
|
||||
*
|
||||
* The response's serial number is mirrored from the request, but the
|
||||
* dummy byte before the serial number is left out. However, another
|
||||
* zero dummy byte is always attached to the end of the response data.
|
||||
* Response codes are similar to the JTAGICEmkII, 0x80 is a generic
|
||||
* "OK" response, other responses above 0x80 indicate various data
|
||||
* responses (parameter read, memory read, PC value), and 0xa0 is a
|
||||
* generic "failure" response. It appears the failure response gets
|
||||
* another byte appended (probably indicating the reason) after the
|
||||
* 0 dummy byte, but there's not enough analysis material so far.
|
||||
*
|
||||
*
|
||||
* The event format (EP 0x83) is:
|
||||
*
|
||||
* +----------------------------------------
|
||||
* | 0 | 1 | 2 . 3 | 4 | 5 | ...
|
||||
* | | | | | |
|
||||
* | token |dummy|serial# |scope| evt | data
|
||||
* | 0x0e | 0 | NNNN | SS | EV | ...
|
||||
* +----------------------------------------
|
||||
*/
|
||||
#define TOKEN 0x0e
|
||||
|
||||
#endif /* JTAG3_PRIVATE_EXPORTED */
|
||||
|
||||
#define SCOPE_INFO 0x00
|
||||
#define SCOPE_GENERAL 0x01
|
||||
#define SCOPE_AVR_ISP 0x11
|
||||
#define SCOPE_AVR 0x12
|
||||
|
||||
/* Info scope */
|
||||
#define CMD3_GET_INFO 0x00
|
||||
|
||||
/* byte after GET_INFO is always 0, next is: */
|
||||
# define CMD3_INFO_NAME 0x80 /* JTAGICE3 */
|
||||
# define CMD3_INFO_SERIAL 0x81 /* J3xxxxxxxxxx */
|
||||
|
||||
/* Generic scope */
|
||||
#define CMD3_SET_PARAMETER 0x01
|
||||
#define CMD3_GET_PARAMETER 0x02
|
||||
#define CMD3_SIGN_ON 0x10
|
||||
#define CMD3_SIGN_OFF 0x11 /* takes one parameter? */
|
||||
#define CMD3_START_DW_DEBUG 0x13
|
||||
#define CMD3_MONCON_DISABLE 0x17
|
||||
|
||||
/* AVR ISP scope: no commands of its own */
|
||||
|
||||
/* AVR scope */
|
||||
//#define CMD3_SET_PARAMETER 0x01
|
||||
//#define CMD3_GET_PARAMETER 0x02
|
||||
//#define CMD3_SIGN_ON 0x10 /* an additional signon/-off pair */
|
||||
//#define CMD3_SIGN_OFF 0x11
|
||||
#define CMD3_ENTER_PROGMODE 0x15
|
||||
#define CMD3_LEAVE_PROGMODE 0x16
|
||||
#define CMD3_ERASE_MEMORY 0x20
|
||||
#define CMD3_READ_MEMORY 0x21
|
||||
#define CMD3_WRITE_MEMORY 0x23
|
||||
#define CMD3_READ_PC 0x35
|
||||
|
||||
/* ICE responses */
|
||||
#define RSP3_OK 0x80
|
||||
#define RSP3_INFO 0x81
|
||||
#define RSP3_PC 0x83
|
||||
#define RSP3_DATA 0x84
|
||||
#define RSP3_FAILED 0xA0
|
||||
|
||||
#define RSP3_STATUS_MASK 0xE0
|
||||
|
||||
/* possible failure codes that could be appended to RSP3_FAILED: */
|
||||
# define RSP3_FAIL_DEBUGWIRE 0x10
|
||||
# define RSP3_FAIL_PDI 0x1B
|
||||
# define RSP3_FAIL_NO_ANSWER 0x20
|
||||
# define RSP3_FAIL_NO_TARGET_POWER 0x22
|
||||
# define RSP3_FAIL_WRONG_MODE 0x32 /* progmode vs. non-prog */
|
||||
# define RSP3_FAIL_UNSUPP_MEMORY 0x34 /* unsupported memory type */
|
||||
# define RSP3_FAIL_WRONG_LENGTH 0x35 /* wrong lenth for mem access */
|
||||
# define RSP3_FAIL_NOT_UNDERSTOOD 0x91
|
||||
|
||||
/* ICE events */
|
||||
#define EVT3_BREAK 0x40 /* AVR scope */
|
||||
#define EVT3_SLEEP 0x11 /* General scope, also wakeup */
|
||||
#define EVT3_POWER 0x10 /* General scope */
|
||||
|
||||
/* memory types */
|
||||
#define MTYPE_SRAM 0x20 /* target's SRAM or [ext.] IO registers */
|
||||
#define MTYPE_EEPROM 0x22 /* EEPROM, what way? */
|
||||
#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 */
|
||||
#define MTYPE_FLASH 0xc0 /* xmega (app.) flash - undocumented in AVR067 */
|
||||
#define MTYPE_BOOT_FLASH 0xc1 /* xmega boot flash - undocumented in AVR067 */
|
||||
#define MTYPE_EEPROM_XMEGA 0xc4 /* xmega EEPROM in debug mode - undocumented in AVR067 */
|
||||
#define MTYPE_USERSIG 0xc5 /* xmega user signature - undocumented in AVR067 */
|
||||
#define MTYPE_PRODSIG 0xc6 /* xmega production signature - undocumented in AVR067 */
|
||||
|
||||
/*
|
||||
* Parameters are divided into sections, where the section number
|
||||
* precedes each parameter address. There are distinct parameter
|
||||
* sets for generic and AVR scope.
|
||||
*/
|
||||
#define PARM3_HW_VER 0x00 /* section 0, generic scope, 1 byte */
|
||||
#define PARM3_FW_MAJOR 0x01 /* section 0, generic scope, 1 byte */
|
||||
#define PARM3_FW_MINOR 0x02 /* section 0, generic scope, 1 byte */
|
||||
#define PARM3_FW_RELEASE 0x03 /* section 0, generic scope, 1 byte;
|
||||
* always asked for by Atmel Studio,
|
||||
* but never displayed there */
|
||||
#define PARM3_VTARGET 0x00 /* section 1, generic scope, 2 bytes,
|
||||
* in millivolts */
|
||||
#define PARM3_DEVICEDESC 0x00 /* section 2, memory etc. configuration,
|
||||
* 31 bytes for tiny/mega AVR, 47 bytes
|
||||
* for Xmega; is also used in command
|
||||
* 0x36 in JTAGICEmkII, starting with
|
||||
* firmware 7.x */
|
||||
|
||||
#define PARM3_ARCH 0x00 /* section 0, AVR scope, 1 byte */
|
||||
# define PARM3_ARCH_TINY 1 /* also small megaAVR with ISP/DW only */
|
||||
# define PARM3_ARCH_MEGA 2
|
||||
# define PARM3_ARCH_XMEGA 3
|
||||
|
||||
#define PARM3_SESS_PURPOSE 0x01 /* section 0, AVR scope, 1 byte */
|
||||
# define PARM3_SESS_PROGRAMMING 1
|
||||
# define PARM3_SESS_DEBUGGING 2
|
||||
|
||||
#define PARM3_CONNECTION 0x00 /* section 1, AVR scope, 1 byte */
|
||||
# define PARM3_CONN_ISP 1
|
||||
# define PARM3_CONN_JTAG 4
|
||||
# define PARM3_CONN_DW 5
|
||||
# define PARM3_CONN_PDI 6
|
||||
|
||||
|
||||
#define PARM3_JTAGCHAIN 0x01 /* JTAG chain info, AVR scope (units
|
||||
* before/after, bits before/after), 4
|
||||
* bytes */
|
||||
|
||||
#define PARM3_CLK_MEGA_PROG 0x20 /* section 1, AVR scope, 2 bytes (kHz) */
|
||||
#define PARM3_CLK_MEGA_DEBUG 0x21 /* section 1, AVR scope, 2 bytes (kHz) */
|
||||
#define PARM3_CLK_XMEGA_JTAG 0x30 /* section 1, AVR scope, 2 bytes (kHz) */
|
||||
#define PARM3_CLK_XMEGA_PDI 0x31 /* section 1, AVR scope, 2 bytes (kHz) */
|
||||
|
||||
|
||||
|
||||
/* Xmega erase memory types, for CMND_XMEGA_ERASE */
|
||||
#define XMEGA_ERASE_CHIP 0x00
|
||||
#define XMEGA_ERASE_APP 0x01
|
||||
#define XMEGA_ERASE_BOOT 0x02
|
||||
#define XMEGA_ERASE_EEPROM 0x03
|
||||
#define XMEGA_ERASE_APP_PAGE 0x04
|
||||
#define XMEGA_ERASE_BOOT_PAGE 0x05
|
||||
#define XMEGA_ERASE_EEPROM_PAGE 0x06
|
||||
#define XMEGA_ERASE_USERSIG 0x07
|
||||
|
||||
#if !defined(JTAG3_PRIVATE_EXPORTED)
|
||||
|
||||
struct mega_device_desc {
|
||||
unsigned char flash_page_size[2]; // in bytes
|
||||
unsigned char flash_size[4]; // in bytes
|
||||
unsigned char dummy1[4]; // always 0
|
||||
unsigned char boot_address[4]; // maximal (BOOTSZ = 3) bootloader
|
||||
// address, in 16-bit words (!)
|
||||
unsigned char sram_offset[2]; // pointing behind IO registers
|
||||
unsigned char eeprom_size[2];
|
||||
unsigned char eeprom_page_size;
|
||||
unsigned char ocd_revision; // see XML; basically:
|
||||
// t13*, t2313*, t4313: 0
|
||||
// all other DW devices: 1
|
||||
// ATmega128(A): 1 (!)
|
||||
// ATmega16*,162,169*,32*,64*: 2
|
||||
// ATmega2560/2561: 4
|
||||
// all other megaAVR devices: 3
|
||||
unsigned char always_one; // always = 1
|
||||
unsigned char allow_full_page_bitstream; // old AVRs, see XML
|
||||
unsigned char dummy2[2]; // always 0
|
||||
// all IO addresses below are given
|
||||
// in IO number space (without
|
||||
// offset 0x20), even though e.g.
|
||||
// OSCCAL always resides outside
|
||||
unsigned char idr_address; // IDR, aka. OCDR
|
||||
unsigned char eearh_address; // EEPROM access
|
||||
unsigned char eearl_address;
|
||||
unsigned char eecr_address;
|
||||
unsigned char eedr_address;
|
||||
unsigned char spmcr_address;
|
||||
unsigned char osccal_address;
|
||||
};
|
||||
|
||||
|
||||
/* Xmega device descriptor */
|
||||
struct xmega_device_desc {
|
||||
unsigned char nvm_app_offset[4]; // NVM offset for application flash
|
||||
unsigned char nvm_boot_offset[4]; // NVM offset for boot flash
|
||||
unsigned char nvm_eeprom_offset[4]; // NVM offset for EEPROM
|
||||
unsigned char nvm_fuse_offset[4]; // NVM offset for fuses
|
||||
unsigned char nvm_lock_offset[4]; // NVM offset for lock bits
|
||||
unsigned char nvm_user_sig_offset[4]; // NVM offset for user signature row
|
||||
unsigned char nvm_prod_sig_offset[4]; // NVM offset for production sign. row
|
||||
unsigned char nvm_data_offset[4]; // NVM offset for data memory (SRAM + IO)
|
||||
unsigned char app_size[4]; // size of application flash
|
||||
unsigned char boot_size[2]; // size of boot flash
|
||||
unsigned char flash_page_size[2]; // flash page size
|
||||
unsigned char eeprom_size[2]; // size of EEPROM
|
||||
unsigned char eeprom_page_size; // EEPROM page size
|
||||
unsigned char nvm_base_addr[2]; // IO space base address of NVM controller
|
||||
unsigned char mcu_base_addr[2]; // IO space base address of MCU control
|
||||
};
|
||||
#endif /* JTAG3_PRIVATE_EXPORTED */
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2005, 2007 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
* 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
|
||||
@@ -13,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -32,38 +33,34 @@
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "crc16.h"
|
||||
#include "pgm.h"
|
||||
#include "jtagmkI.h"
|
||||
#include "jtagmkI_private.h"
|
||||
#include "serial.h"
|
||||
extern int verbose;
|
||||
extern char * progname;
|
||||
extern int do_cycles;
|
||||
|
||||
/*
|
||||
* Private data for this programmer.
|
||||
* XXX There should really be a programmer-specific private data
|
||||
* pointer in struct PROGRAMMER.
|
||||
*/
|
||||
struct pdata
|
||||
{
|
||||
int initial_baudrate;
|
||||
static long initial_baudrate;
|
||||
|
||||
/*
|
||||
* See jtagmkI_read_byte() for an explanation of the flash and
|
||||
* EEPROM page caches.
|
||||
*/
|
||||
unsigned char *flash_pagecache;
|
||||
unsigned long flash_pageaddr;
|
||||
unsigned int flash_pagesize;
|
||||
/*
|
||||
* See jtagmkI_read_byte() for an explanation of the flash and
|
||||
* EEPROM page caches.
|
||||
*/
|
||||
static unsigned char *flash_pagecache;
|
||||
static unsigned long flash_pageaddr;
|
||||
static unsigned int flash_pagesize;
|
||||
|
||||
unsigned char *eeprom_pagecache;
|
||||
unsigned long eeprom_pageaddr;
|
||||
unsigned int eeprom_pagesize;
|
||||
|
||||
int prog_enabled; /* Cached value of PROGRAMMING status. */
|
||||
};
|
||||
|
||||
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
||||
static unsigned char *eeprom_pagecache;
|
||||
static unsigned long eeprom_pageaddr;
|
||||
static unsigned int eeprom_pagesize;
|
||||
|
||||
static int prog_enabled; /* Cached value of PROGRAMMING status. */
|
||||
/*
|
||||
* The OCDEN fuse is bit 7 of the high fuse (hfuse). In order to
|
||||
* perform memory operations on MTYPE_SPM and MTYPE_EEPROM, OCDEN
|
||||
@@ -105,27 +102,10 @@ static int jtagmkI_getparm(PROGRAMMER * pgm, unsigned char parm,
|
||||
unsigned char * value);
|
||||
static int jtagmkI_setparm(PROGRAMMER * pgm, unsigned char parm,
|
||||
unsigned char value);
|
||||
static void jtagmkI_print_parms1(PROGRAMMER * pgm, const char * p);
|
||||
static void jtagmkI_print_parms1(PROGRAMMER * pgm, char * p);
|
||||
|
||||
static int jtagmkI_resync(PROGRAMMER *pgm, int maxtries, int signon);
|
||||
|
||||
static void jtagmkI_setup(PROGRAMMER * pgm)
|
||||
{
|
||||
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: jtagmkI_setup(): Out of memory allocating private data\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
memset(pgm->cookie, 0, sizeof(struct pdata));
|
||||
}
|
||||
|
||||
static void jtagmkI_teardown(PROGRAMMER * pgm)
|
||||
{
|
||||
free(pgm->cookie);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
u32_to_b3(unsigned char *b, unsigned long l)
|
||||
{
|
||||
@@ -153,7 +133,7 @@ static void jtagmkI_prmsg(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
||||
if (i % 16 == 15)
|
||||
putc('\n', stderr);
|
||||
else
|
||||
putc(' ', stderr);
|
||||
putchar(' ');
|
||||
}
|
||||
if (i % 16 != 0)
|
||||
putc('\n', stderr);
|
||||
@@ -200,8 +180,8 @@ static int jtagmkI_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
||||
unsigned char *buf;
|
||||
|
||||
if (verbose >= 3)
|
||||
fprintf(stderr, "\n%s: jtagmkI_send(): sending %u bytes\n",
|
||||
progname, (unsigned int)len);
|
||||
fprintf(stderr, "\n%s: jtagmkI_send(): sending %zd bytes\n",
|
||||
progname, len);
|
||||
|
||||
if ((buf = malloc(len + 2)) == NULL)
|
||||
{
|
||||
@@ -214,7 +194,7 @@ static int jtagmkI_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
||||
buf[len] = ' '; /* "CRC" */
|
||||
buf[len + 1] = ' '; /* EOP */
|
||||
|
||||
if (serial_send(&pgm->fd, buf, len + 2) != 0) {
|
||||
if (serial_send(pgm->fd, buf, len + 2) != 0) {
|
||||
fprintf(stderr,
|
||||
"%s: jtagmkI_send(): failed to send command to serial port\n",
|
||||
progname);
|
||||
@@ -228,7 +208,7 @@ static int jtagmkI_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
||||
|
||||
static void jtagmkI_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
|
||||
{
|
||||
if (serial_recv(&pgm->fd, buf, len) != 0) {
|
||||
if (serial_recv(pgm->fd, buf, len) != 0) {
|
||||
fprintf(stderr,
|
||||
"\n%s: jtagmkI_recv(): failed to send command to serial port\n",
|
||||
progname);
|
||||
@@ -243,7 +223,7 @@ static void jtagmkI_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
|
||||
|
||||
static int jtagmkI_drain(PROGRAMMER * pgm, int display)
|
||||
{
|
||||
return serial_drain(&pgm->fd, display);
|
||||
return serial_drain(pgm->fd, display);
|
||||
}
|
||||
|
||||
|
||||
@@ -268,14 +248,14 @@ static int jtagmkI_resync(PROGRAMMER * pgm, int maxtries, int signon)
|
||||
fprintf(stderr, "%s: jtagmkI_resync(): Sending sync command: ",
|
||||
progname);
|
||||
|
||||
if (serial_send(&pgm->fd, buf, 1) != 0) {
|
||||
if (serial_send(pgm->fd, buf, 1) != 0) {
|
||||
fprintf(stderr,
|
||||
"\n%s: jtagmkI_resync(): failed to send command to serial port\n",
|
||||
progname);
|
||||
serial_recv_timeout = otimeout;
|
||||
return -1;
|
||||
}
|
||||
if (serial_recv(&pgm->fd, resp, 1) == 0 && resp[0] == RESP_OK) {
|
||||
if (serial_recv(pgm->fd, resp, 1) == 0 && resp[0] == RESP_OK) {
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "got RESP_OK\n");
|
||||
break;
|
||||
@@ -300,14 +280,14 @@ static int jtagmkI_resync(PROGRAMMER * pgm, int maxtries, int signon)
|
||||
fprintf(stderr, "%s: jtagmkI_resync(): Sending sign-on command: ",
|
||||
progname);
|
||||
|
||||
if (serial_send(&pgm->fd, buf, 4) != 0) {
|
||||
if (serial_send(pgm->fd, buf, 4) != 0) {
|
||||
fprintf(stderr,
|
||||
"\n%s: jtagmkI_resync(): failed to send command to serial port\n",
|
||||
progname);
|
||||
serial_recv_timeout = otimeout;
|
||||
return -1;
|
||||
}
|
||||
if (serial_recv(&pgm->fd, resp, 9) == 0 && resp[0] == RESP_OK) {
|
||||
if (serial_recv(pgm->fd, resp, 9) == 0 && resp[0] == RESP_OK) {
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "got RESP_OK\n");
|
||||
break;
|
||||
@@ -354,6 +334,16 @@ static int jtagmkI_getsync(PROGRAMMER * pgm)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jtagmkI_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4])
|
||||
{
|
||||
|
||||
fprintf(stderr, "%s: jtagmkI_command(): no direct SPI supported for JTAG\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* issue the 'chip erase' command to the AVR device
|
||||
*/
|
||||
@@ -403,10 +393,10 @@ static void jtagmkI_set_devdescr(PROGRAMMER * pgm, AVRPART * p)
|
||||
for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
|
||||
m = ldata(ln);
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
PDATA(pgm)->flash_pagesize = m->page_size;
|
||||
u16_to_b2(sendbuf.dd.uiFlashPageSize, PDATA(pgm)->flash_pagesize);
|
||||
flash_pagesize = m->page_size;
|
||||
u16_to_b2(sendbuf.dd.uiFlashPageSize, flash_pagesize);
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
sendbuf.dd.ucEepromPageSize = PDATA(pgm)->eeprom_pagesize = m->page_size;
|
||||
sendbuf.dd.ucEepromPageSize = eeprom_pagesize = m->page_size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,7 +460,7 @@ static int jtagmkI_program_enable(PROGRAMMER * pgm)
|
||||
{
|
||||
unsigned char buf[1], resp[2];
|
||||
|
||||
if (PDATA(pgm)->prog_enabled)
|
||||
if (prog_enabled)
|
||||
return 0;
|
||||
|
||||
buf[0] = CMD_ENTER_PROGMODE;
|
||||
@@ -494,7 +484,7 @@ static int jtagmkI_program_enable(PROGRAMMER * pgm)
|
||||
fprintf(stderr, "OK\n");
|
||||
}
|
||||
|
||||
PDATA(pgm)->prog_enabled = 1;
|
||||
prog_enabled = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -503,10 +493,10 @@ static int jtagmkI_program_disable(PROGRAMMER * pgm)
|
||||
{
|
||||
unsigned char buf[1], resp[2];
|
||||
|
||||
if (!PDATA(pgm)->prog_enabled)
|
||||
if (!prog_enabled)
|
||||
return 0;
|
||||
|
||||
if (pgm->fd.ifd != -1) {
|
||||
if (pgm->fd != -1) {
|
||||
buf[0] = CMD_LEAVE_PROGMODE;
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: jtagmkI_program_disable(): "
|
||||
@@ -527,8 +517,10 @@ static int jtagmkI_program_disable(PROGRAMMER * pgm)
|
||||
if (verbose == 2)
|
||||
fprintf(stderr, "OK\n");
|
||||
}
|
||||
|
||||
(void)jtagmkI_reset(pgm);
|
||||
}
|
||||
PDATA(pgm)->prog_enabled = 0;
|
||||
prog_enabled = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -550,7 +542,7 @@ static unsigned char jtagmkI_get_baud(long baud)
|
||||
static int jtagmkI_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
AVRMEM hfuse;
|
||||
unsigned char cmd[1], resp[5];
|
||||
char cmd[1], resp[5];
|
||||
unsigned char b;
|
||||
|
||||
if (!(p->flags & AVRPART_HAS_JTAG)) {
|
||||
@@ -561,7 +553,7 @@ static int jtagmkI_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
|
||||
jtagmkI_drain(pgm, 0);
|
||||
|
||||
if ((serdev->flags & SERDEV_FL_CANSETSPEED) && PDATA(pgm)->initial_baudrate != pgm->baudrate) {
|
||||
if (initial_baudrate != pgm->baudrate) {
|
||||
if ((b = jtagmkI_get_baud(pgm->baudrate)) == 0) {
|
||||
fprintf(stderr, "%s: jtagmkI_initialize(): unsupported baudrate %d\n",
|
||||
progname, pgm->baudrate);
|
||||
@@ -571,8 +563,8 @@ static int jtagmkI_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
"trying to set baudrate to %d\n",
|
||||
progname, pgm->baudrate);
|
||||
if (jtagmkI_setparm(pgm, PARM_BITRATE, b) == 0) {
|
||||
PDATA(pgm)->initial_baudrate = pgm->baudrate; /* don't adjust again later */
|
||||
serial_setspeed(&pgm->fd, pgm->baudrate);
|
||||
initial_baudrate = pgm->baudrate; /* don't adjust again later */
|
||||
serial_setspeed(pgm->fd, pgm->baudrate);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -606,24 +598,24 @@ static int jtagmkI_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
*/
|
||||
jtagmkI_set_devdescr(pgm, p);
|
||||
|
||||
jtagmkI_setparm(pgm, PARM_FLASH_PAGESIZE_LOW, PDATA(pgm)->flash_pagesize & 0xff);
|
||||
jtagmkI_setparm(pgm, PARM_FLASH_PAGESIZE_HIGH, PDATA(pgm)->flash_pagesize >> 8);
|
||||
jtagmkI_setparm(pgm, PARM_EEPROM_PAGESIZE, PDATA(pgm)->eeprom_pagesize & 0xff);
|
||||
jtagmkI_setparm(pgm, PARM_FLASH_PAGESIZE_LOW, flash_pagesize & 0xff);
|
||||
jtagmkI_setparm(pgm, PARM_FLASH_PAGESIZE_HIGH, flash_pagesize >> 8);
|
||||
jtagmkI_setparm(pgm, PARM_EEPROM_PAGESIZE, eeprom_pagesize & 0xff);
|
||||
|
||||
free(PDATA(pgm)->flash_pagecache);
|
||||
free(PDATA(pgm)->eeprom_pagecache);
|
||||
if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) {
|
||||
free(flash_pagecache);
|
||||
free(eeprom_pagecache);
|
||||
if ((flash_pagecache = malloc(flash_pagesize)) == NULL) {
|
||||
fprintf(stderr, "%s: jtagmkI_initialize(): Out of memory\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
|
||||
if ((eeprom_pagecache = malloc(eeprom_pagesize)) == NULL) {
|
||||
fprintf(stderr, "%s: jtagmkI_initialize(): Out of memory\n",
|
||||
progname);
|
||||
free(PDATA(pgm)->flash_pagecache);
|
||||
free(flash_pagecache);
|
||||
return -1;
|
||||
}
|
||||
PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
|
||||
flash_pageaddr = eeprom_pageaddr = (unsigned long)-1L;
|
||||
|
||||
if (jtagmkI_reset(pgm) < 0)
|
||||
return -1;
|
||||
@@ -644,10 +636,10 @@ static int jtagmkI_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
static void jtagmkI_disable(PROGRAMMER * pgm)
|
||||
{
|
||||
|
||||
free(PDATA(pgm)->flash_pagecache);
|
||||
PDATA(pgm)->flash_pagecache = NULL;
|
||||
free(PDATA(pgm)->eeprom_pagecache);
|
||||
PDATA(pgm)->eeprom_pagecache = NULL;
|
||||
free(flash_pagecache);
|
||||
flash_pagecache = NULL;
|
||||
free(eeprom_pagecache);
|
||||
eeprom_pagecache = NULL;
|
||||
|
||||
(void)jtagmkI_program_disable(pgm);
|
||||
}
|
||||
@@ -666,16 +658,14 @@ static int jtagmkI_open(PROGRAMMER * pgm, char * port)
|
||||
fprintf(stderr, "%s: jtagmkI_open()\n", progname);
|
||||
|
||||
strcpy(pgm->port, port);
|
||||
PDATA(pgm)->initial_baudrate = -1L;
|
||||
initial_baudrate = -1L;
|
||||
|
||||
for (i = 0; i < sizeof(baudtab) / sizeof(baudtab[0]); i++) {
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr,
|
||||
"%s: jtagmkI_open(): trying to sync at baud rate %ld:\n",
|
||||
progname, baudtab[i].baud);
|
||||
if (serial_open(port, baudtab[i].baud, &pgm->fd)==-1) {
|
||||
return -1;
|
||||
}
|
||||
pgm->fd = serial_open(port, baudtab[i].baud);
|
||||
|
||||
/*
|
||||
* drain any extraneous input
|
||||
@@ -683,19 +673,19 @@ static int jtagmkI_open(PROGRAMMER * pgm, char * port)
|
||||
jtagmkI_drain(pgm, 0);
|
||||
|
||||
if (jtagmkI_getsync(pgm) == 0) {
|
||||
PDATA(pgm)->initial_baudrate = baudtab[i].baud;
|
||||
initial_baudrate = baudtab[i].baud;
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: jtagmkI_open(): succeeded\n", progname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
serial_close(&pgm->fd);
|
||||
serial_close(pgm->fd);
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"%s: jtagmkI_open(): failed to synchronize to ICE\n",
|
||||
progname);
|
||||
pgm->fd.ifd = -1;
|
||||
pgm->fd = -1;
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -703,45 +693,42 @@ static int jtagmkI_open(PROGRAMMER * pgm, char * port)
|
||||
|
||||
static void jtagmkI_close(PROGRAMMER * pgm)
|
||||
{
|
||||
unsigned char b;
|
||||
unsigned char buf[1], resp[2];
|
||||
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: jtagmkI_close()\n", progname);
|
||||
|
||||
/*
|
||||
* Revert baud rate to what it used to be when we started. This
|
||||
* appears to make AVR Studio happier when it is about to access the
|
||||
* ICE later on.
|
||||
*/
|
||||
if ((serdev->flags & SERDEV_FL_CANSETSPEED) && PDATA(pgm)->initial_baudrate != pgm->baudrate) {
|
||||
if ((b = jtagmkI_get_baud(PDATA(pgm)->initial_baudrate)) == 0) {
|
||||
fprintf(stderr, "%s: jtagmkI_close(): unsupported baudrate %d\n",
|
||||
progname, PDATA(pgm)->initial_baudrate);
|
||||
} else {
|
||||
if (pgm->fd != -1) {
|
||||
buf[0] = CMD_GO;
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: jtagmkI_close(): Sending GO command: ",
|
||||
progname);
|
||||
jtagmkI_send(pgm, buf, 1);
|
||||
jtagmkI_recv(pgm, resp, 1);
|
||||
if (resp[0] != RESP_OK) {
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: jtagmkI_close(): "
|
||||
"trying to set baudrate to %d\n",
|
||||
progname, PDATA(pgm)->initial_baudrate);
|
||||
if (jtagmkI_setparm(pgm, PARM_BITRATE, b) == 0) {
|
||||
serial_setspeed(&pgm->fd, pgm->baudrate);
|
||||
}
|
||||
putc('\n', stderr);
|
||||
fprintf(stderr,
|
||||
"%s: jtagmkI_close(): "
|
||||
"timeout/error communicating with programmer (resp %c)\n",
|
||||
progname, resp[0]);
|
||||
exit(1);
|
||||
} else {
|
||||
if (verbose == 2)
|
||||
fprintf(stderr, "OK\n");
|
||||
}
|
||||
|
||||
serial_close(pgm->fd);
|
||||
}
|
||||
|
||||
if (pgm->fd.ifd != -1) {
|
||||
serial_close(&pgm->fd);
|
||||
}
|
||||
|
||||
pgm->fd.ifd = -1;
|
||||
pgm->fd = -1;
|
||||
}
|
||||
|
||||
|
||||
static int jtagmkI_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes)
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
int block_size, send_size, tries;
|
||||
unsigned int maxaddr = addr + n_bytes;
|
||||
int addr, block_size, send_size, tries;
|
||||
unsigned char cmd[6], *datacmd;
|
||||
unsigned char resp[2];
|
||||
int is_flash = 0;
|
||||
@@ -772,18 +759,20 @@ static int jtagmkI_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
cmd[0] = CMD_WRITE_MEM;
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
cmd[1] = MTYPE_FLASH_PAGE;
|
||||
PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
|
||||
page_size = PDATA(pgm)->flash_pagesize;
|
||||
flash_pageaddr = (unsigned long)-1L;
|
||||
page_size = flash_pagesize;
|
||||
is_flash = 1;
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
cmd[1] = MTYPE_EEPROM_PAGE;
|
||||
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
|
||||
page_size = PDATA(pgm)->eeprom_pagesize;
|
||||
eeprom_pageaddr = (unsigned long)-1L;
|
||||
page_size = eeprom_pagesize;
|
||||
}
|
||||
datacmd[0] = CMD_DATA;
|
||||
|
||||
serial_recv_timeout = 1000;
|
||||
for (; addr < maxaddr; addr += page_size) {
|
||||
for (addr = 0; addr < n_bytes; addr += page_size) {
|
||||
report_progress(addr, n_bytes,NULL);
|
||||
|
||||
tries = 0;
|
||||
again:
|
||||
|
||||
@@ -875,11 +864,9 @@ static int jtagmkI_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
}
|
||||
|
||||
static int jtagmkI_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes)
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
int block_size, read_size, is_flash = 0, tries;
|
||||
unsigned int maxaddr = addr + n_bytes;
|
||||
int addr, block_size, read_size, is_flash = 0, tries;
|
||||
unsigned char cmd[6], resp[256 * 2 + 3];
|
||||
long otimeout = serial_recv_timeout;
|
||||
#define MAXTRIES 3
|
||||
@@ -908,7 +895,9 @@ static int jtagmkI_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
}
|
||||
|
||||
serial_recv_timeout = 1000;
|
||||
for (; addr < maxaddr; addr += page_size) {
|
||||
for (addr = 0; addr < n_bytes; addr += page_size) {
|
||||
report_progress(addr, n_bytes,NULL);
|
||||
|
||||
tries = 0;
|
||||
again:
|
||||
if (tries != 0 && jtagmkI_resync(pgm, 2000, 0) < 0) {
|
||||
@@ -992,15 +981,15 @@ static int jtagmkI_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
cmd[1] = MTYPE_FLASH_PAGE;
|
||||
pagesize = mem->page_size;
|
||||
paddr = addr & ~(pagesize - 1);
|
||||
paddr_ptr = &PDATA(pgm)->flash_pageaddr;
|
||||
cache_ptr = PDATA(pgm)->flash_pagecache;
|
||||
paddr_ptr = &flash_pageaddr;
|
||||
cache_ptr = flash_pagecache;
|
||||
is_flash = 1;
|
||||
} else if (strcmp(mem->desc, "eeprom") == 0) {
|
||||
cmd[1] = MTYPE_EEPROM_PAGE;
|
||||
pagesize = mem->page_size;
|
||||
paddr = addr & ~(pagesize - 1);
|
||||
paddr_ptr = &PDATA(pgm)->eeprom_pageaddr;
|
||||
cache_ptr = PDATA(pgm)->eeprom_pagecache;
|
||||
paddr_ptr = &eeprom_pageaddr;
|
||||
cache_ptr = eeprom_pagecache;
|
||||
} else if (strcmp(mem->desc, "lfuse") == 0) {
|
||||
cmd[1] = MTYPE_FUSE_BITS;
|
||||
addr = 0;
|
||||
@@ -1102,11 +1091,11 @@ static int jtagmkI_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
if (strcmp(mem->desc, "flash") == 0) {
|
||||
cmd[1] = MTYPE_SPM;
|
||||
need_progmode = 0;
|
||||
PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
|
||||
flash_pageaddr = (unsigned long)-1L;
|
||||
} else if (strcmp(mem->desc, "eeprom") == 0) {
|
||||
cmd[1] = MTYPE_EEPROM;
|
||||
need_progmode = 0;
|
||||
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
|
||||
eeprom_pageaddr = (unsigned long)-1L;
|
||||
} else if (strcmp(mem->desc, "lfuse") == 0) {
|
||||
cmd[1] = MTYPE_FUSE_BITS;
|
||||
addr = 0;
|
||||
@@ -1132,7 +1121,7 @@ static int jtagmkI_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd[2] = 1 - 1;
|
||||
cmd[2] = 1;
|
||||
if (cmd[1] == MTYPE_SPM) {
|
||||
/*
|
||||
* Flash is word-addressed, but we cannot handle flash anyway
|
||||
@@ -1304,7 +1293,7 @@ static int jtagmkI_setparm(PROGRAMMER * pgm, unsigned char parm,
|
||||
}
|
||||
|
||||
|
||||
static void jtagmkI_display(PROGRAMMER * pgm, const char * p)
|
||||
static void jtagmkI_display(PROGRAMMER * pgm, char * p)
|
||||
{
|
||||
|
||||
unsigned char hw, fw;
|
||||
@@ -1322,7 +1311,7 @@ static void jtagmkI_display(PROGRAMMER * pgm, const char * p)
|
||||
}
|
||||
|
||||
|
||||
static void jtagmkI_print_parms1(PROGRAMMER * pgm, const char * p)
|
||||
static void jtagmkI_print_parms1(PROGRAMMER * pgm, char * p)
|
||||
{
|
||||
unsigned char vtarget, jtag_clock;
|
||||
const char *clkstr;
|
||||
@@ -1372,7 +1361,6 @@ static void jtagmkI_print_parms(PROGRAMMER * pgm)
|
||||
jtagmkI_print_parms1(pgm, "");
|
||||
}
|
||||
|
||||
const char jtagmkI_desc[] = "Atmel JTAG ICE mkI";
|
||||
|
||||
void jtagmkI_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
@@ -1387,19 +1375,18 @@ void jtagmkI_initpgm(PROGRAMMER * pgm)
|
||||
pgm->disable = jtagmkI_disable;
|
||||
pgm->program_enable = jtagmkI_program_enable_dummy;
|
||||
pgm->chip_erase = jtagmkI_chip_erase;
|
||||
pgm->cmd = jtagmkI_cmd;
|
||||
pgm->open = jtagmkI_open;
|
||||
pgm->close = jtagmkI_close;
|
||||
pgm->read_byte = jtagmkI_read_byte;
|
||||
pgm->write_byte = jtagmkI_write_byte;
|
||||
|
||||
/*
|
||||
* optional functions
|
||||
*/
|
||||
pgm->paged_write = jtagmkI_paged_write;
|
||||
pgm->paged_load = jtagmkI_paged_load;
|
||||
pgm->read_byte = jtagmkI_read_byte;
|
||||
pgm->write_byte = jtagmkI_write_byte;
|
||||
pgm->print_parms = jtagmkI_print_parms;
|
||||
pgm->set_sck_period = jtagmkI_set_sck_period;
|
||||
pgm->setup = jtagmkI_setup;
|
||||
pgm->teardown = jtagmkI_teardown;
|
||||
pgm->page_size = 256;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -21,16 +22,7 @@
|
||||
#ifndef jtagmkI_h
|
||||
#define jtagmkI_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char jtagmkI_desc[];
|
||||
void jtagmkI_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
2953
avrdude/jtagmkII.c
2953
avrdude/jtagmkII.c
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2002-2004, 2006 Brian S. Dean <bsd@bsdhome.com>
|
||||
* 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
|
||||
@@ -13,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -21,43 +22,7 @@
|
||||
#ifndef jtagmkII_h
|
||||
#define jtagmkII_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len);
|
||||
int jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg);
|
||||
void jtagmkII_close(PROGRAMMER * pgm);
|
||||
int jtagmkII_getsync(PROGRAMMER * pgm, int mode);
|
||||
int jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm,
|
||||
unsigned char * value);
|
||||
|
||||
extern const char jtagmkII_desc[];
|
||||
extern const char jtagmkII_avr32_desc[];
|
||||
extern const char jtagmkII_dw_desc[];
|
||||
extern const char jtagmkII_pdi_desc[];
|
||||
extern const char jtagmkII_dragon_desc[];
|
||||
extern const char jtagmkII_dragon_dw_desc[];
|
||||
extern const char jtagmkII_dragon_pdi_desc[];
|
||||
void jtagmkII_initpgm (PROGRAMMER * pgm);
|
||||
void jtagmkII_avr32_initpgm (PROGRAMMER * pgm);
|
||||
void jtagmkII_dw_initpgm (PROGRAMMER * pgm);
|
||||
void jtagmkII_pdi_initpgm (PROGRAMMER * pgm);
|
||||
void jtagmkII_dragon_initpgm (PROGRAMMER * pgm);
|
||||
void jtagmkII_dragon_dw_initpgm (PROGRAMMER * pgm);
|
||||
void jtagmkII_dragon_pdi_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
/*
|
||||
* These functions are referenced from stk500v2.c for JTAG ICE mkII
|
||||
* and AVR Dragon programmers running in one of the STK500v2
|
||||
* modi.
|
||||
*/
|
||||
void jtagmkII_setup(PROGRAMMER * pgm);
|
||||
void jtagmkII_teardown(PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2005, 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
* Copyright (C) 2005 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -14,7 +14,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -25,7 +26,6 @@
|
||||
* 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,235 +71,167 @@
|
||||
*/
|
||||
#define MAX_MESSAGE 100000
|
||||
|
||||
#endif /* JTAGMKII_PRIVATE_EXPORTED */
|
||||
|
||||
/* ICE command codes */
|
||||
#define CMND_SIGN_OFF 0x00
|
||||
#define CMND_GET_SIGN_ON 0x01
|
||||
#define CMND_SET_PARAMETER 0x02
|
||||
#define CMND_GET_PARAMETER 0x03
|
||||
#define CMND_WRITE_MEMORY 0x04
|
||||
#define CMND_READ_MEMORY 0x05
|
||||
#define CMND_WRITE_PC 0x06
|
||||
#define CMND_READ_PC 0x07
|
||||
#define CMND_GO 0x08
|
||||
#define CMND_SINGLE_STEP 0x09
|
||||
#define CMND_FORCED_STOP 0x0A
|
||||
#define CMND_RESET 0x0B
|
||||
#define CMND_CHIP_ERASE 0x13
|
||||
#define CMND_CLEAR_EVENTS 0x22
|
||||
#define CMND_CLR_BREAK 0x1A
|
||||
#define CMND_ENTER_PROGMODE 0x14
|
||||
#define CMND_ERASEPAGE_SPM 0x0D
|
||||
#define CMND_FORCED_STOP 0x0A
|
||||
#define CMND_GET_BREAK 0x12
|
||||
#define CMND_GET_PARAMETER 0x03
|
||||
#define CMND_GET_SIGN_ON 0x01
|
||||
#define CMND_GET_SYNC 0x0f
|
||||
#define CMND_GO 0x08
|
||||
#define CMND_LEAVE_PROGMODE 0x15
|
||||
#define CMND_READ_MEMORY 0x05
|
||||
#define CMND_READ_PC 0x07
|
||||
#define CMND_RESET 0x0B
|
||||
#define CMND_RESTORE_TARGET 0x23
|
||||
#define CMND_RUN_TO_ADDR 0x1C
|
||||
#define CMND_SELFTEST 0x10
|
||||
#define CMND_SET_BREAK 0x11
|
||||
#define CMND_SET_DEVICE_DESCRIPTOR 0x0C
|
||||
#define CMND_ERASEPAGE_SPM 0x0D
|
||||
#define CMND_GET_SYNC 0x0f
|
||||
#define CMND_SELFTEST 0x10
|
||||
#define CMND_SET_BREAK 0x11
|
||||
#define CMND_GET_BREAK 0x12
|
||||
#define CMND_CHIP_ERASE 0x13
|
||||
#define CMND_ENTER_PROGMODE 0x14
|
||||
#define CMND_LEAVE_PROGMODE 0x15
|
||||
#define CMND_SET_N_PARAMETERS 0x16
|
||||
#define CMND_CLR_BREAK 0x1A
|
||||
#define CMND_RUN_TO_ADDR 0x1C
|
||||
#define CMND_SPI_CMD 0x1D
|
||||
#define CMND_CLEAR_EVENTS 0x22
|
||||
#define CMND_RESTORE_TARGET 0x23
|
||||
#define CMND_GET_IR 0x24
|
||||
#define CMND_GET_xxx 0x25
|
||||
#define CMND_WRITE_SAB 0x28
|
||||
#define CMND_READ_SAB 0x29
|
||||
#define CMND_RESET_AVR 0x2B
|
||||
#define CMND_READ_MEMORY32 0x2C
|
||||
#define CMND_WRITE_MEMORY32 0x2D
|
||||
#define CMND_ISP_PACKET 0x2F
|
||||
#define CMND_XMEGA_ERASE 0x34
|
||||
#define CMND_SET_XMEGA_PARAMS 0x36 // undocumented in AVR067
|
||||
|
||||
#define CMND_SET_N_PARAMETERS 0x16
|
||||
#define CMND_SET_PARAMETER 0x02
|
||||
#define CMND_SIGN_OFF 0x00
|
||||
#define CMND_SINGLE_STEP 0x09
|
||||
#define CMND_SPI_CMD 0x1D
|
||||
#define CMND_WRITE_MEMORY 0x04
|
||||
#define CMND_WRITE_PC 0x06
|
||||
|
||||
/* ICE responses */
|
||||
#define RSP_OK 0x80
|
||||
#define RSP_PARAMETER 0x81
|
||||
#define RSP_MEMORY 0x82
|
||||
#define RSP_GET_BREAK 0x83
|
||||
#define RSP_PC 0x84
|
||||
#define RSP_SELFTEST 0x85
|
||||
#define RSP_SIGN_ON 0x86
|
||||
#define RSP_SPI_DATA 0x88
|
||||
#define RSP_FAILED 0xA0
|
||||
#define RSP_ILLEGAL_PARAMETER 0xA1
|
||||
#define RSP_ILLEGAL_MEMORY_TYPE 0xA2
|
||||
#define RSP_ILLEGAL_MEMORY_RANGE 0xA3
|
||||
#define RSP_ILLEGAL_EMULATOR_MODE 0xA4
|
||||
#define RSP_ILLEGAL_MCU_STATE 0xA5
|
||||
#define RSP_ILLEGAL_VALUE 0xA6
|
||||
#define RSP_SET_N_PARAMETERS 0xA7
|
||||
#define RSP_ILLEGAL_BREAKPOINT 0xA8
|
||||
#define RSP_ILLEGAL_JTAG_ID 0xA9
|
||||
#define RSP_ILLEGAL_COMMAND 0xAA
|
||||
#define RSP_NO_TARGET_POWER 0xAB
|
||||
#define RSP_DEBUGWIRE_SYNC_FAILED 0xAC
|
||||
#define RSP_ILLEGAL_POWER_STATE 0xAD
|
||||
#define RSP_DEBUGWIRE_SYNC_FAILED 0xAC
|
||||
#define RSP_FAILED 0xA0
|
||||
#define RSP_GET_BREAK 0x83
|
||||
#define RSP_ILLEGAL_BREAKPOINT 0xA8
|
||||
#define RSP_ILLEGAL_COMMAND 0xAA
|
||||
#define RSP_ILLEGAL_EMULATOR_MODE 0xA4
|
||||
#define RSP_ILLEGAL_JTAG_ID 0xA9
|
||||
#define RSP_ILLEGAL_MCU_STATE 0xA5
|
||||
#define RSP_ILLEGAL_MEMORY_TYPE 0xA2
|
||||
#define RSP_ILLEGAL_MEMORY_RANGE 0xA3
|
||||
#define RSP_ILLEGAL_PARAMETER 0xA1
|
||||
#define RSP_ILLEGAL_POWER_STATE 0xAD
|
||||
#define RSP_ILLEGAL_VALUE 0xA6
|
||||
#define RSP_MEMORY 0x82
|
||||
#define RSP_NO_TARGET_POWER 0xAB
|
||||
#define RSP_OK 0x80
|
||||
#define RSP_PARAMETER 0x81
|
||||
#define RSP_PC 0x84
|
||||
#define RSP_SELFTEST 0x85
|
||||
#define RSP_SET_N_PARAMETERS 0xA7
|
||||
#define RSP_SIGN_ON 0x86
|
||||
#define RSP_SPI_DATA 0x88
|
||||
|
||||
/* ICE events */
|
||||
#define EVT_BREAK 0xE0
|
||||
#define EVT_RUN 0xE1
|
||||
#define EVT_ERROR_PHY_FORCE_BREAK_TIMEOUT 0xE2
|
||||
#define EVT_BREAK 0xE0
|
||||
#define EVT_DEBUG 0xE6
|
||||
#define EVT_ERROR_PHY_FORCE_BREAK_TIMEOUT 0xE2
|
||||
#define EVT_ERROR_PHY_MAX_BIT_LENGTH_DIFF 0xED
|
||||
#define EVT_ERROR_PHY_OPT_RECEIVE_TIMEOUT 0xF9
|
||||
#define EVT_ERROR_PHY_OPT_RECEIVED_BREAK 0xFA
|
||||
#define EVT_ERROR_PHY_RECEIVED_BREAK 0xF8
|
||||
#define EVT_ERROR_PHY_RECEIVE_TIMEOUT 0xF7
|
||||
#define EVT_ERROR_PHY_RELEASE_BREAK_TIMEOUT 0xE3
|
||||
#define EVT_TARGET_POWER_ON 0xE4
|
||||
#define EVT_TARGET_POWER_OFF 0xE5
|
||||
#define EVT_DEBUG 0xE6
|
||||
#define EVT_EXT_RESET 0xE7
|
||||
#define EVT_TARGET_SLEEP 0xE8
|
||||
#define EVT_TARGET_WAKEUP 0xE9
|
||||
#define EVT_ICE_POWER_ERROR_STATE 0xEA
|
||||
#define EVT_ICE_POWER_OK 0xEB
|
||||
#define EVT_IDR_DIRTY 0xEC
|
||||
#define EVT_ERROR_PHY_MAX_BIT_LENGTH_DIFF 0xED
|
||||
#define EVT_NONE 0xEF
|
||||
#define EVT_ERROR_PHY_SYNC_TIMEOUT 0xF0
|
||||
#define EVT_PROGRAM_BREAK 0xF1
|
||||
#define EVT_PDSB_BREAK 0xF2
|
||||
#define EVT_PDSMB_BREAK 0xF3
|
||||
#define EVT_ERROR_PHY_SYNC_TIMEOUT_BAUD 0xF4
|
||||
#define EVT_ERROR_PHY_SYNC_OUT_OF_RANGE 0xF5
|
||||
#define EVT_ERROR_PHY_SYNC_WAIT_TIMEOUT 0xF6
|
||||
#define EVT_ERROR_PHY_RECEIVE_TIMEOUT 0xF7
|
||||
#define EVT_ERROR_PHY_RECEIVED_BREAK 0xF8
|
||||
#define EVT_ERROR_PHY_OPT_RECEIVE_TIMEOUT 0xF9
|
||||
#define EVT_ERROR_PHY_OPT_RECEIVED_BREAK 0xFA
|
||||
#define EVT_RESULT_PHY_NO_ACTIVITY 0xFB
|
||||
#define EVT_ERROR_PHY_SYNC_OUT_OF_RANGE 0xF5
|
||||
#define EVT_ERROR_PHY_SYNC_TIMEOUT 0xF0
|
||||
#define EVT_ERROR_PHY_SYNC_TIMEOUT_BAUD 0xF4
|
||||
#define EVT_ERROR_PHY_SYNC_WAIT_TIMEOUT 0xF6
|
||||
#define EVT_RESULT_PHY_NO_ACTIVITY 0xFB
|
||||
#define EVT_EXT_RESET 0xE7
|
||||
#define EVT_ICE_POWER_ERROR_STATE 0xEA
|
||||
#define EVT_ICE_POWER_OK 0xEB
|
||||
#define EVT_IDR_DIRTY 0xEC
|
||||
#define EVT_NONE 0xEF
|
||||
#define EVT_PDSB_BREAK 0xF2
|
||||
#define EVT_PDSMB_BREAK 0xF3
|
||||
#define EVT_PROGRAM_BREAK 0xF1
|
||||
#define EVT_RUN 0xE1
|
||||
#define EVT_TARGET_POWER_OFF 0xE5
|
||||
#define EVT_TARGET_POWER_ON 0xE4
|
||||
#define EVT_TARGET_SLEEP 0xE8
|
||||
#define EVT_TARGET_WAKEUP 0xE9
|
||||
|
||||
/* 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_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_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 */
|
||||
#define MTYPE_CAN 0xB6 /* CAN mailbox */
|
||||
#define MTYPE_FLASH 0xc0 /* xmega (app.) flash - undocumented in AVR067 */
|
||||
#define MTYPE_BOOT_FLASH 0xc1 /* xmega boot flash - undocumented in AVR067 */
|
||||
#define MTYPE_EEPROM_XMEGA 0xc4 /* xmega EEPROM in debug mode - undocumented in AVR067 */
|
||||
#define MTYPE_USERSIG 0xc5 /* xmega user signature - undocumented in AVR067 */
|
||||
#define MTYPE_PRODSIG 0xc6 /* xmega production signature - undocumented in AVR067 */
|
||||
#define MTYPE_CAN 0xB6 /* CAN mailbox */
|
||||
|
||||
/* (some) ICE parameters, for CMND_{GET,SET}_PARAMETER */
|
||||
#define PAR_HW_VERSION 0x01
|
||||
#define PAR_FW_VERSION 0x02
|
||||
#define PAR_EMULATOR_MODE 0x03
|
||||
# define EMULATOR_MODE_DEBUGWIRE 0x00
|
||||
# define EMULATOR_MODE_JTAG 0x01
|
||||
# define EMULATOR_MODE_HV 0x02 /* HVSP or PP mode of AVR Dragon */
|
||||
# define EMULATOR_MODE_SPI 0x03
|
||||
# define EMULATOR_MODE_JTAG_AVR32 0x04
|
||||
# define EMULATOR_MODE_JTAG_XMEGA 0x05
|
||||
# define EMULATOR_MODE_PDI 0x06
|
||||
#define PAR_IREG 0x04
|
||||
#define PAR_BAUD_RATE 0x05
|
||||
# define PAR_BAUD_2400 0x01
|
||||
# define PAR_BAUD_4800 0x02
|
||||
# define PAR_BAUD_9600 0x03
|
||||
# define PAR_BAUD_19200 0x04 /* default */
|
||||
# define PAR_BAUD_38400 0x05
|
||||
# define PAR_BAUD_57600 0x06
|
||||
# define PAR_BAUD_115200 0x07
|
||||
# define PAR_BAUD_14400 0x08
|
||||
#define PAR_OCD_VTARGET 0x06
|
||||
#define PAR_OCD_JTAG_CLK 0x07
|
||||
#define PAR_OCD_BREAK_CAUSE 0x08
|
||||
#define PAR_TIMERS_RUNNING 0x09
|
||||
#define PAR_BREAK_ON_CHANGE_FLOW 0x0A
|
||||
#define PAR_BREAK_ADDR1 0x0B
|
||||
#define PAR_BREAK_ADDR2 0x0C
|
||||
#define PAR_COMBBREAKCTRL 0x0D
|
||||
#define PAR_JTAGID 0x0E
|
||||
#define PAR_UNITS_BEFORE 0x0F
|
||||
#define PAR_UNITS_AFTER 0x10
|
||||
#define PAR_BIT_BEFORE 0x11
|
||||
#define PAR_BIT_ATER 0x12
|
||||
#define PAR_EXTERNAL_RESET 0x13
|
||||
#define PAR_FLASH_PAGE_SIZE 0x14
|
||||
#define PAR_EEPROM_PAGE_SIZE 0x15
|
||||
#define PAR_UNUSED1 0x16
|
||||
#define PAR_PSB0 0x17
|
||||
#define PAR_PSB1 0x18
|
||||
#define PAR_PROTOCOL_DEBUG_EVENT 0x19
|
||||
#define PAR_MCU_STATE 0x1A
|
||||
# define STOPPED 0x00
|
||||
# define RUNNING 0x01
|
||||
# define PROGRAMMING 0x02
|
||||
#define PAR_DAISY_CHAIN_INFO 0x1B
|
||||
#define PAR_BOOT_ADDRESS 0x1C
|
||||
#define PAR_TARGET_SIGNATURE 0x1D
|
||||
#define PAR_DEBUGWIRE_BAUDRATE 0x1E
|
||||
#define PAR_PROGRAM_ENTRY_POINT 0x1F
|
||||
#define PAR_PDI_OFFSET_START 0x32
|
||||
#define PAR_PDI_OFFSET_END 0x33
|
||||
#define PAR_PACKET_PARSING_ERRORS 0x40
|
||||
#define PAR_VALID_PACKETS_RECEIVED 0x41
|
||||
#define PAR_INTERCOMMUNICATION_TX_FAILURES 0x42
|
||||
#define PAR_INTERCOMMUNICATION_RX_FAILURES 0x43
|
||||
#define PAR_CRC_ERRORS 0x44
|
||||
#define PAR_POWER_SOURCE 0x45
|
||||
# define POWER_EXTERNAL 0x00
|
||||
# define POWER_USB 0x01
|
||||
#define PAR_CAN_FLAG 0x22
|
||||
# define DONT_READ_CAN_MAILBOX 0x00
|
||||
# define READ_CAN_MAILBOX 0x01
|
||||
#define PAR_ENABLE_IDR_IN_RUN_MODE 0x23
|
||||
# define ACCESS_OSCCAL 0x00
|
||||
# define ACCESS_IDR 0x01
|
||||
#define PAR_HW_VERSION 0x01
|
||||
#define PAR_FW_VERSION 0x02
|
||||
#define PAR_EMULATOR_MODE 0x03
|
||||
# define EMULATOR_MODE_DEBUGWIRE 0x00
|
||||
# define EMULATOR_MODE_JTAG 0x01
|
||||
# define EMULATOR_MODE_UNKNOWN 0x02
|
||||
# define EMULATOR_MODE_SPI 0x03
|
||||
#define PAR_IREG 0x04
|
||||
#define PAR_BAUD_RATE 0x05
|
||||
# define PAR_BAUD_2400 0x01
|
||||
# define PAR_BAUD_4800 0x02
|
||||
# define PAR_BAUD_9600 0x03
|
||||
# define PAR_BAUD_19200 0x04 /* default */
|
||||
# define PAR_BAUD_38400 0x05
|
||||
# define PAR_BAUD_57600 0x06
|
||||
# define PAR_BAUD_115200 0x07
|
||||
# define PAR_BAUD_14400 0x08
|
||||
#define PAR_OCD_VTARGET 0x06
|
||||
#define PAR_OCD_JTAG_CLK 0x07
|
||||
#define PAR_OCD_BREAK_CAUSE 0x08
|
||||
#define PAR_TIMERS_RUNNING 0x09
|
||||
#define PAR_BREAK_ON_CHANGE_FLOW 0x0A
|
||||
#define PAR_BREAK_ADDR1 0x0B
|
||||
#define PAR_BREAK_ADDR2 0x0C
|
||||
#define PAR_COMBBREAKCTRL 0x0D
|
||||
#define PAR_JTAGID 0x0E
|
||||
#define PAR_UNITS_BEFORE 0x0F
|
||||
#define PAR_UNITS_AFTER 0x10
|
||||
#define PAR_BIT_BEFORE 0x11
|
||||
#define PAR_BIT_ATER 0x12
|
||||
#define PAR_EXTERNAL_RESET 0x13
|
||||
#define PAR_FLASH_PAGE_SIZE 0x14
|
||||
#define PAR_EEPROM_PAGE_SIZE 0x15
|
||||
#define PAR_UNUSED1 0x16
|
||||
#define PAR_PSB0 0x17
|
||||
#define PAR_PSB1 0x18
|
||||
#define PAR_PROTOCOL_DEBUG_EVENT 0x19
|
||||
#define PAR_MCU_STATE 0x1A
|
||||
# define STOPPED 0x00
|
||||
# define RUNNING 0x01
|
||||
# define PROGRAMMING 0x02
|
||||
#define PAR_DAISY_CHAIN_INFO 0x1B
|
||||
#define PAR_BOOT_ADDRESS 0x1C
|
||||
#define PAR_TARGET_SIGNATURE 0x1D
|
||||
#define PAR_DEBUGWIRE_BAUDRATE 0x1E
|
||||
#define PAR_PROGRAM_ENTRY_POINT 0x1F
|
||||
#define PAR_PACKET_PARSING_ERRORS 0x40
|
||||
#define PAR_VALID_PACKETS_RECEIVED 0x41
|
||||
#define PAR_INTERCOMMUNICATION_TX_FAILURES 0x42
|
||||
#define PAR_INTERCOMMUNICATION_RX_FAILURES 0x43
|
||||
#define PAR_CRC_ERRORS 0x44
|
||||
#define PAR_POWER_SOURCE 0x45
|
||||
# define POWER_EXTERNAL 0x00
|
||||
# define POWER_USB 0x01
|
||||
#define PAR_CAN_FLAG 0x22
|
||||
# define DONT_READ_CAN_MAILBOX 0x00
|
||||
# define READ_CAN_MAILBOX 0x01
|
||||
#define PAR_ENABLE_IDR_IN_RUN_MODE 0x23
|
||||
# define ACCESS_OSCCAL 0x00
|
||||
# define ACCESS_IDR 0x01
|
||||
#define PAR_ALLOW_PAGEPROGRAMMING_IN_SCANCHAIN 0x24
|
||||
# define PAGEPROG_NOT_ALLOWED 0x00
|
||||
# define PAGEPROG_ALLOWED 0x01
|
||||
# define PAGEPROG_NOT_ALLOWED 0x00
|
||||
# define PAGEPROG_ALLOWED 0x01
|
||||
|
||||
/* Xmega erase memory types, for CMND_XMEGA_ERASE */
|
||||
#define XMEGA_ERASE_CHIP 0x00
|
||||
#define XMEGA_ERASE_APP 0x01
|
||||
#define XMEGA_ERASE_BOOT 0x02
|
||||
#define XMEGA_ERASE_EEPROM 0x03
|
||||
#define XMEGA_ERASE_APP_PAGE 0x04
|
||||
#define XMEGA_ERASE_BOOT_PAGE 0x05
|
||||
#define XMEGA_ERASE_EEPROM_PAGE 0x06
|
||||
#define XMEGA_ERASE_USERSIG 0x07
|
||||
|
||||
/* AVR32 related definitions */
|
||||
#define AVR32_FLASHC_FCR 0xFFFE1400
|
||||
#define AVR32_FLASHC_FCMD 0xFFFE1404
|
||||
#define AVR32_FLASHC_FCMD_KEY 0xA5000000
|
||||
#define AVR32_FLASHC_FCMD_WRITE_PAGE 1
|
||||
#define AVR32_FLASHC_FCMD_ERASE_PAGE 2
|
||||
#define AVR32_FLASHC_FCMD_CLEAR_PAGE_BUFFER 3
|
||||
#define AVR32_FLASHC_FCMD_LOCK 4
|
||||
#define AVR32_FLASHC_FCMD_UNLOCK 5
|
||||
#define AVR32_FLASHC_FSR 0xFFFE1408
|
||||
#define AVR32_FLASHC_FSR_RDY 0x00000001
|
||||
#define AVR32_FLASHC_FSR_ERR 0x00000008
|
||||
#define AVR32_FLASHC_FGPFRHI 0xFFFE140C
|
||||
#define AVR32_FLASHC_FGPFRLO 0xFFFE1410
|
||||
|
||||
#define AVR32_DC 0x00000008
|
||||
#define AVR32_DS 0x00000010
|
||||
#define AVR32_DINST 0x00000104
|
||||
#define AVR32_DCCPU 0x00000110
|
||||
#define AVR32_DCEMU 0x00000114
|
||||
#define AVR32_DCSR 0x00000118
|
||||
|
||||
#define AVR32_DC_ABORT 0x80000000
|
||||
#define AVR32_DC_RESET 0x40000000
|
||||
#define AVR32_DC_DBE 0x00002000
|
||||
#define AVR32_DC_DBR 0x00001000
|
||||
|
||||
#define AVR32_RESET_READ 0x0001
|
||||
#define AVR32_RESET_WRITE 0x0002
|
||||
#define AVR32_RESET_CHIP_ERASE 0x0004
|
||||
#define AVR32_SET4RUNNING 0x0008
|
||||
//#define AVR32_RESET_COMMON (AVR32_RESET_READ | AVR32_RESET_WRITE | AVR32_RESET_CHIP_ERASE )
|
||||
|
||||
|
||||
#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
|
||||
@@ -356,30 +288,3 @@ struct device_descriptor
|
||||
/* new as of early 2005, firmware 4.x */
|
||||
unsigned char EECRAddress[2]; /* EECR memory-mapped IO address */
|
||||
};
|
||||
|
||||
/* New Xmega device descriptor, for firmware version 7 and above */
|
||||
struct xmega_device_desc {
|
||||
unsigned char whatever[2]; // cannot guess; must be 0x0002
|
||||
unsigned char datalen; // length of the following data, = 47
|
||||
unsigned char nvm_app_offset[4]; // NVM offset for application flash
|
||||
unsigned char nvm_boot_offset[4]; // NVM offset for boot flash
|
||||
unsigned char nvm_eeprom_offset[4]; // NVM offset for EEPROM
|
||||
unsigned char nvm_fuse_offset[4]; // NVM offset for fuses
|
||||
unsigned char nvm_lock_offset[4]; // NVM offset for lock bits
|
||||
unsigned char nvm_user_sig_offset[4]; // NVM offset for user signature row
|
||||
unsigned char nvm_prod_sig_offset[4]; // NVM offset for production sign. row
|
||||
unsigned char nvm_data_offset[4]; // NVM offset for data memory (SRAM + IO)
|
||||
unsigned char app_size[4]; // size of application flash
|
||||
unsigned char boot_size[2]; // size of boot flash
|
||||
unsigned char flash_page_size[2]; // flash page size
|
||||
unsigned char eeprom_size[2]; // size of EEPROM
|
||||
unsigned char eeprom_page_size; // EEPROM page size
|
||||
unsigned char nvm_base_addr[2]; // IO space base address of NVM controller
|
||||
unsigned char mcu_base_addr[2]; // IO space base address of MCU control
|
||||
};
|
||||
#endif /* JTAGMKII_PRIVATE_EXPORTED */
|
||||
|
||||
/* return code from jtagmkII_getsync() to indicate a "graceful"
|
||||
* failure, i.e. an attempt to enable ISP failed and should be
|
||||
* eventually retried */
|
||||
#define JTAGII_GETSYNC_FAIL_GRACEFUL (-2)
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
152
avrdude/lexer.l
152
avrdude/lexer.l
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
@@ -14,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -28,40 +28,38 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "config_gram.h"
|
||||
#include "lists.h"
|
||||
|
||||
#ifndef YYERRCODE
|
||||
#define YYERRCODE 256
|
||||
#endif
|
||||
extern int lineno;
|
||||
extern char * infile;
|
||||
|
||||
void pyytext(void);
|
||||
|
||||
#define YY_NO_UNPUT
|
||||
|
||||
%}
|
||||
|
||||
DIGIT [0-9]
|
||||
HEXDIGIT [0-9a-fA-F]
|
||||
ID [_a-zA-Z][_a-zA-Z0-9]*
|
||||
SIGN [+-]
|
||||
|
||||
%x strng
|
||||
%x incl
|
||||
%x comment
|
||||
%option nounput
|
||||
|
||||
/* Bump resources for classic lex. */
|
||||
%e2000
|
||||
%p10000
|
||||
%p5000
|
||||
%n1000
|
||||
|
||||
%%
|
||||
|
||||
#{SIGN}*{DIGIT}+ { yylval = number(yytext); return TKN_NUMBER; }
|
||||
#{SIGN}*{DIGIT}+"."{DIGIT}* { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
|
||||
#{SIGN}*"."{DIGIT}* { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
|
||||
{DIGIT}+ { yylval = number(yytext); return TKN_NUMBER; }
|
||||
{DIGIT}+"."{DIGIT}* { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
|
||||
"."{DIGIT}+ { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
|
||||
{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(strng); }
|
||||
|
||||
@@ -121,136 +119,105 @@ SIGN [+-]
|
||||
exit(1); }
|
||||
|
||||
allowfullpagebitstream { yylval=NULL; return K_ALLOWFULLPAGEBITSTREAM; }
|
||||
avr910 { yylval=NULL; return K_AVR910; }
|
||||
avr910_devcode { yylval=NULL; return K_AVR910_DEVCODE; }
|
||||
bank_size { yylval=NULL; return K_PAGE_SIZE; }
|
||||
banked { yylval=NULL; return K_PAGED; }
|
||||
baudrate { yylval=NULL; return K_BAUDRATE; }
|
||||
blocksize { yylval=NULL; return K_BLOCKSIZE; }
|
||||
bs2 { yylval=NULL; return K_BS2; }
|
||||
buff { yylval=NULL; return K_BUFF; }
|
||||
bytedelay { yylval=NULL; return K_BYTEDELAY; }
|
||||
chip_erase { yylval=new_token(K_CHIP_ERASE); return K_CHIP_ERASE; }
|
||||
butterfly { yylval=NULL; return K_BUTTERFLY; }
|
||||
chip_erase_delay { yylval=NULL; return K_CHIP_ERASE_DELAY; }
|
||||
chiperasepolltimeout { yylval=NULL; return K_CHIPERASEPOLLTIMEOUT; }
|
||||
chiperasepulsewidth { yylval=NULL; return K_CHIPERASEPULSEWIDTH; }
|
||||
chiperasetime { yylval=NULL; return K_CHIPERASETIME; }
|
||||
cmdexedelay { yylval=NULL; return K_CMDEXEDELAY; }
|
||||
connection_type { yylval=NULL; return K_CONNTYPE; }
|
||||
dedicated { yylval=new_token(K_DEDICATED); return K_DEDICATED; }
|
||||
default_bitclock { yylval=NULL; return K_DEFAULT_BITCLOCK; }
|
||||
desc { yylval=NULL; return K_DESC; }
|
||||
default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
|
||||
default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
|
||||
default_safemode { yylval=NULL; return K_DEFAULT_SAFEMODE; }
|
||||
default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
|
||||
delay { yylval=NULL; return K_DELAY; }
|
||||
desc { yylval=NULL; return K_DESC; }
|
||||
devicecode { yylval=NULL; return K_DEVICECODE; }
|
||||
eecr { yylval=NULL; return K_EECR; }
|
||||
eeprom { yylval=NULL; return K_EEPROM; }
|
||||
eeprom_instr { yylval=NULL; return K_EEPROM_INSTR; }
|
||||
enablepageprogramming { yylval=NULL; return K_ENABLEPAGEPROGRAMMING; }
|
||||
errled { yylval=NULL; return K_ERRLED; }
|
||||
flash { yylval=NULL; return K_FLASH; }
|
||||
flash_instr { yylval=NULL; return K_FLASH_INSTR; }
|
||||
has_debugwire { yylval=NULL; return K_HAS_DW; }
|
||||
has_jtag { yylval=NULL; return K_HAS_JTAG; }
|
||||
has_pdi { yylval=NULL; return K_HAS_PDI; }
|
||||
has_tpi { yylval=NULL; return K_HAS_TPI; }
|
||||
hventerstabdelay { yylval=NULL; return K_HVENTERSTABDELAY; }
|
||||
hvleavestabdelay { yylval=NULL; return K_HVLEAVESTABDELAY; }
|
||||
hvsp_controlstack { yylval=NULL; return K_HVSP_CONTROLSTACK; }
|
||||
hvspcmdexedelay { yylval=NULL; return K_HVSPCMDEXEDELAY; }
|
||||
id { yylval=NULL; return K_ID; }
|
||||
idr { yylval=NULL; return K_IDR; }
|
||||
io { yylval=new_token(K_IO); return K_IO; }
|
||||
is_at90s1200 { yylval=NULL; return K_IS_AT90S1200; }
|
||||
is_avr32 { yylval=NULL; return K_IS_AVR32; }
|
||||
latchcycles { yylval=NULL; return K_LATCHCYCLES; }
|
||||
load_ext_addr { yylval=new_token(K_LOAD_EXT_ADDR); return K_LOAD_EXT_ADDR; }
|
||||
loadpage_hi { yylval=new_token(K_LOADPAGE_HI); return K_LOADPAGE_HI; }
|
||||
loadpage_lo { yylval=new_token(K_LOADPAGE_LO); return K_LOADPAGE_LO; }
|
||||
jtagmki { yylval=NULL; return K_JTAG_MKI; }
|
||||
jtagmkii { yylval=NULL; return K_JTAG_MKII; }
|
||||
max_write_delay { yylval=NULL; return K_MAX_WRITE_DELAY; }
|
||||
mcu_base { yylval=NULL; return K_MCU_BASE; }
|
||||
memory { yylval=NULL; return K_MEMORY; }
|
||||
min_write_delay { yylval=NULL; return K_MIN_WRITE_DELAY; }
|
||||
miso { yylval=NULL; return K_MISO; }
|
||||
mode { yylval=NULL; return K_MODE; }
|
||||
mosi { yylval=NULL; return K_MOSI; }
|
||||
no { yylval=new_token(K_NO); return K_NO; }
|
||||
num_banks { yylval=NULL; return K_NUM_PAGES; }
|
||||
num_pages { yylval=NULL; return K_NUM_PAGES; }
|
||||
nvm_base { yylval=NULL; return K_NVM_BASE; }
|
||||
ocdrev { yylval=NULL; return K_OCDREV; }
|
||||
offset { yylval=NULL; return K_OFFSET; }
|
||||
page_size { yylval=NULL; return K_PAGE_SIZE; }
|
||||
paged { yylval=NULL; return K_PAGED; }
|
||||
pagel { yylval=NULL; return K_PAGEL; }
|
||||
par { yylval=NULL; return K_PAR; }
|
||||
parallel { yylval=NULL; return K_PARALLEL; }
|
||||
parent { yylval=NULL; return K_PARENT; }
|
||||
part { yylval=NULL; return K_PART; }
|
||||
pgm_enable { yylval=new_token(K_PGM_ENABLE); return K_PGM_ENABLE; }
|
||||
pgmled { yylval=NULL; return K_PGMLED; }
|
||||
pollindex { yylval=NULL; return K_POLLINDEX; }
|
||||
pollmethod { yylval=NULL; return K_POLLMETHOD; }
|
||||
pollvalue { yylval=NULL; return K_POLLVALUE; }
|
||||
postdelay { yylval=NULL; return K_POSTDELAY; }
|
||||
poweroffdelay { yylval=NULL; return K_POWEROFFDELAY; }
|
||||
pp_controlstack { yylval=NULL; return K_PP_CONTROLSTACK; }
|
||||
predelay { yylval=NULL; return K_PREDELAY; }
|
||||
progmodedelay { yylval=NULL; return K_PROGMODEDELAY; }
|
||||
programfusepolltimeout { yylval=NULL; return K_PROGRAMFUSEPOLLTIMEOUT; }
|
||||
programfusepulsewidth { yylval=NULL; return K_PROGRAMFUSEPULSEWIDTH; }
|
||||
programlockpolltimeout { yylval=NULL; return K_PROGRAMLOCKPOLLTIMEOUT; }
|
||||
programlockpulsewidth { yylval=NULL; return K_PROGRAMLOCKPULSEWIDTH; }
|
||||
programmer { yylval=NULL; return K_PROGRAMMER; }
|
||||
pseudo { yylval=new_token(K_PSEUDO); return K_PSEUDO; }
|
||||
pwroff_after_write { yylval=NULL; return K_PWROFF_AFTER_WRITE; }
|
||||
rampz { yylval=NULL; return K_RAMPZ; }
|
||||
rdyled { yylval=NULL; return K_RDYLED; }
|
||||
read { yylval=new_token(K_READ); return K_READ; }
|
||||
read_hi { yylval=new_token(K_READ_HI); return K_READ_HI; }
|
||||
read_lo { yylval=new_token(K_READ_LO); return K_READ_LO; }
|
||||
readback_p1 { yylval=NULL; return K_READBACK_P1; }
|
||||
readback_p2 { yylval=NULL; return K_READBACK_P2; }
|
||||
readsize { yylval=NULL; return K_READSIZE; }
|
||||
reset { yylval=new_token(K_RESET); return K_RESET; }
|
||||
resetdelay { yylval=NULL; return K_RESETDELAY; }
|
||||
resetdelayms { yylval=NULL; return K_RESETDELAYMS; }
|
||||
resetdelayus { yylval=NULL; return K_RESETDELAYUS; }
|
||||
retry_pulse { yylval=NULL; return K_RETRY_PULSE; }
|
||||
sck { yylval=new_token(K_SCK); return K_SCK; }
|
||||
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; }
|
||||
stabdelay { yylval=NULL; return K_STABDELAY; }
|
||||
stk500 { yylval=NULL; return K_STK500; }
|
||||
stk500v2 { yylval=NULL; return K_STK500V2; }
|
||||
stk500_devcode { yylval=NULL; return K_STK500_DEVCODE; }
|
||||
synchcycles { yylval=NULL; return K_SYNCHCYCLES; }
|
||||
synchloops { yylval=NULL; return K_SYNCHLOOPS; }
|
||||
timeout { yylval=NULL; return K_TIMEOUT; }
|
||||
togglevtg { yylval=NULL; return K_TOGGLEVTG; }
|
||||
type { yylval=NULL; return K_TYPE; }
|
||||
usb { yylval=NULL; return K_USB; }
|
||||
usbdev { yylval=NULL; return K_USBDEV; }
|
||||
usbpid { yylval=NULL; return K_USBPID; }
|
||||
usbproduct { yylval=NULL; return K_USBPRODUCT; }
|
||||
usbsn { yylval=NULL; return K_USBSN; }
|
||||
usbvendor { yylval=NULL; return K_USBVENDOR; }
|
||||
usbvid { yylval=NULL; return K_USBVID; }
|
||||
vcc { yylval=NULL; return K_VCC; }
|
||||
vfyled { yylval=NULL; return K_VFYLED; }
|
||||
|
||||
timeout { yylval=NULL; return K_TIMEOUT; }
|
||||
stabdelay { yylval=NULL; return K_STABDELAY; }
|
||||
cmdexedelay { yylval=NULL; return K_CMDEXEDELAY; }
|
||||
synchloops { yylval=NULL; return K_SYNCHLOOPS; }
|
||||
bytedelay { yylval=NULL; return K_BYTEDELAY; }
|
||||
pollvalue { yylval=NULL; return K_POLLVALUE; }
|
||||
pollindex { yylval=NULL; return K_POLLINDEX; }
|
||||
predelay { yylval=NULL; return K_PREDELAY; }
|
||||
postdelay { yylval=NULL; return K_POSTDELAY; }
|
||||
pollmethod { yylval=NULL; return K_POLLMETHOD; }
|
||||
mode { yylval=NULL; return K_MODE; }
|
||||
delay { yylval=NULL; return K_DELAY; }
|
||||
blocksize { yylval=NULL; return K_BLOCKSIZE; }
|
||||
readsize { yylval=NULL; return K_READSIZE; }
|
||||
|
||||
|
||||
|
||||
dedicated { yylval=new_token(K_DEDICATED); return K_DEDICATED; }
|
||||
io { yylval=new_token(K_IO); return K_IO; }
|
||||
pseudo { yylval=new_token(K_PSEUDO); return K_PSEUDO; }
|
||||
|
||||
reset { yylval=new_token(K_RESET); return K_RESET; }
|
||||
sck { yylval=new_token(K_SCK); return K_SCK; }
|
||||
|
||||
read { yylval=new_token(K_READ); return K_READ; }
|
||||
write { yylval=new_token(K_WRITE); return K_WRITE; }
|
||||
write_hi { yylval=new_token(K_WRITE_HI); return K_WRITE_HI; }
|
||||
read_lo { yylval=new_token(K_READ_LO); return K_READ_LO; }
|
||||
read_hi { yylval=new_token(K_READ_HI); return K_READ_HI; }
|
||||
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; }
|
||||
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; }
|
||||
|
||||
no { yylval=new_token(K_NO); return K_NO; }
|
||||
yes { yylval=new_token(K_YES); return K_YES; }
|
||||
|
||||
"," { yylval = NULL; pyytext(); return TKN_COMMA; }
|
||||
"=" { yylval = NULL; pyytext(); return TKN_EQUAL; }
|
||||
";" { yylval = NULL; pyytext(); return TKN_SEMI; }
|
||||
"~" { yylval = NULL; pyytext(); return TKN_TILDE; }
|
||||
"(" { yylval = NULL; pyytext(); return TKN_LEFT_PAREN; }
|
||||
")" { yylval = NULL; pyytext(); return TKN_RIGHT_PAREN; }
|
||||
|
||||
"\n" { lineno++; }
|
||||
[ \r\t]+ { /* ignore whitespace */ }
|
||||
@@ -259,9 +226,10 @@ c: { fprintf(stderr, "error at %s:%d: possible old-style config file entry\n",
|
||||
infile, lineno);
|
||||
fprintf(stderr, " Update your config file (see %s%s for a sample)\n",
|
||||
CONFIG_DIR, "/avrdude.conf.sample");
|
||||
return YYERRCODE; }
|
||||
exit(1); }
|
||||
|
||||
. { return YYERRCODE; }
|
||||
. { fprintf(stderr, "error at %s:%d unrecognized character: \"%s\"\n",
|
||||
infile, lineno, yytext); exit(1); }
|
||||
|
||||
%%
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -24,10 +25,8 @@
|
||||
#define OBSOLETE__IOW _IOW
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#ifdef HAVE_PARPORT
|
||||
#include <linux/parport.h>
|
||||
#include <linux/ppdev.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
@@ -1,352 +0,0 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Support for bitbanging GPIO pins using the /sys/class/gpio interface
|
||||
*
|
||||
* Copyright (C) 2013 Radoslav Kolev <radoslav@kolev.info>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "pindefs.h"
|
||||
#include "pgm.h"
|
||||
#include "bitbang.h"
|
||||
|
||||
#if HAVE_LINUXGPIO
|
||||
|
||||
/*
|
||||
* GPIO user space helpers
|
||||
*
|
||||
* Copyright 2009 Analog Devices Inc.
|
||||
* Michael Hennerich (hennerich@blackfin.uclinux.org)
|
||||
*
|
||||
* Licensed under the GPL-2 or later
|
||||
*/
|
||||
|
||||
/*
|
||||
* GPIO user space helpers
|
||||
* The following functions are acting on an "unsigned gpio" argument, which corresponds to the
|
||||
* gpio numbering scheme in the kernel (starting from 0).
|
||||
* The higher level functions use "int pin" to specify the pins with an offset of 1:
|
||||
* gpio = pin - 1;
|
||||
*/
|
||||
|
||||
#define GPIO_DIR_IN 0
|
||||
#define GPIO_DIR_OUT 1
|
||||
|
||||
static int linuxgpio_export(unsigned int gpio)
|
||||
{
|
||||
int fd, len, r;
|
||||
char buf[11];
|
||||
|
||||
fd = open("/sys/class/gpio/export", O_WRONLY);
|
||||
if (fd < 0) {
|
||||
perror("Can't open /sys/class/gpio/export");
|
||||
return fd;
|
||||
}
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%d", gpio);
|
||||
r = write(fd, buf, len);
|
||||
close(fd);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int linuxgpio_unexport(unsigned int gpio)
|
||||
{
|
||||
int fd, len, r;
|
||||
char buf[11];
|
||||
|
||||
fd = open("/sys/class/gpio/unexport", O_WRONLY);
|
||||
if (fd < 0) {
|
||||
perror("Can't open /sys/class/gpio/unexport");
|
||||
return fd;
|
||||
}
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%d", gpio);
|
||||
r = write(fd, buf, len);
|
||||
close(fd);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int linuxgpio_openfd(unsigned int gpio)
|
||||
{
|
||||
char filepath[60];
|
||||
|
||||
snprintf(filepath, sizeof(filepath), "/sys/class/gpio/gpio%d/value", gpio);
|
||||
return (open(filepath, O_RDWR));
|
||||
}
|
||||
|
||||
static int linuxgpio_dir(unsigned int gpio, unsigned int dir)
|
||||
{
|
||||
int fd, r;
|
||||
char buf[60];
|
||||
|
||||
snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio);
|
||||
|
||||
fd = open(buf, O_WRONLY);
|
||||
if (fd < 0) {
|
||||
perror("Can't open gpioX/direction");
|
||||
return fd;
|
||||
}
|
||||
|
||||
if (dir == GPIO_DIR_OUT)
|
||||
r = write(fd, "out", 4);
|
||||
else
|
||||
r = write(fd, "in", 3);
|
||||
|
||||
close(fd);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int linuxgpio_dir_out(unsigned int gpio)
|
||||
{
|
||||
return linuxgpio_dir(gpio, GPIO_DIR_OUT);
|
||||
}
|
||||
|
||||
static int linuxgpio_dir_in(unsigned int gpio)
|
||||
{
|
||||
return linuxgpio_dir(gpio, GPIO_DIR_IN);
|
||||
}
|
||||
|
||||
/*
|
||||
* End of GPIO user space helpers
|
||||
*/
|
||||
|
||||
#define N_GPIO (PIN_MAX + 1)
|
||||
|
||||
/*
|
||||
* an array which holds open FDs to /sys/class/gpio/gpioXX/value for all needed pins
|
||||
*/
|
||||
static int linuxgpio_fds[N_GPIO] ;
|
||||
|
||||
|
||||
static int linuxgpio_setpin(PROGRAMMER * pgm, int pin, int value)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (pin & PIN_INVERSE)
|
||||
{
|
||||
value = !value;
|
||||
pin &= PIN_MASK;
|
||||
}
|
||||
|
||||
if ( linuxgpio_fds[pin] < 0 )
|
||||
return -1;
|
||||
|
||||
if (value)
|
||||
r = write(linuxgpio_fds[pin], "1", 1);
|
||||
else
|
||||
r = write(linuxgpio_fds[pin], "0", 1);
|
||||
|
||||
if (r!=1) return -1;
|
||||
|
||||
if (pgm->ispdelay > 1)
|
||||
bitbang_delay(pgm->ispdelay);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int linuxgpio_getpin(PROGRAMMER * pgm, int pin)
|
||||
{
|
||||
unsigned char invert=0;
|
||||
char c;
|
||||
|
||||
if (pin & PIN_INVERSE)
|
||||
{
|
||||
invert = 1;
|
||||
pin &= PIN_MASK;
|
||||
}
|
||||
|
||||
if ( linuxgpio_fds[pin] < 0 )
|
||||
return -1;
|
||||
|
||||
if (lseek(linuxgpio_fds[pin], 0, SEEK_SET)<0)
|
||||
return -1;
|
||||
|
||||
if (read(linuxgpio_fds[pin], &c, 1)!=1)
|
||||
return -1;
|
||||
|
||||
if (c=='0')
|
||||
return 0+invert;
|
||||
else if (c=='1')
|
||||
return 1-invert;
|
||||
else
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
static int linuxgpio_highpulsepin(PROGRAMMER * pgm, int pin)
|
||||
{
|
||||
|
||||
if ( linuxgpio_fds[pin & PIN_MASK] < 0 )
|
||||
return -1;
|
||||
|
||||
linuxgpio_setpin(pgm, pin, 1);
|
||||
linuxgpio_setpin(pgm, pin, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void linuxgpio_display(PROGRAMMER *pgm, const char *p)
|
||||
{
|
||||
fprintf(stderr, "%sPin assignment : /sys/class/gpio/gpio{n}\n",p);
|
||||
pgm_display_generic_mask(pgm, p, SHOW_AVR_PINS);
|
||||
}
|
||||
|
||||
static void linuxgpio_enable(PROGRAMMER *pgm)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static void linuxgpio_disable(PROGRAMMER *pgm)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static void linuxgpio_powerup(PROGRAMMER *pgm)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static void linuxgpio_powerdown(PROGRAMMER *pgm)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static int linuxgpio_open(PROGRAMMER *pgm, char *port)
|
||||
{
|
||||
int r, i, pin;
|
||||
|
||||
bitbang_check_prerequisites(pgm);
|
||||
|
||||
|
||||
for (i=0; i<N_GPIO; i++)
|
||||
linuxgpio_fds[i] = -1;
|
||||
//Avrdude assumes that if a pin number is 0 it means not used/available
|
||||
//this causes a problem because 0 is a valid GPIO number in Linux sysfs.
|
||||
//To avoid annoying off by one pin numbering we assume SCK, MOSI, MISO
|
||||
//and RESET pins are always defined in avrdude.conf, even as 0. If they're
|
||||
//not programming will not work anyway. The drawbacks of this approach are
|
||||
//that unwanted toggling of GPIO0 can occur and that other optional pins
|
||||
//mostry LED status, can't be set to GPIO0. It can be fixed when a better
|
||||
//solution exists.
|
||||
for (i=0; i<N_PINS; i++) {
|
||||
if ( pgm->pinno[i] != 0 ||
|
||||
i == PIN_AVR_RESET ||
|
||||
i == PIN_AVR_SCK ||
|
||||
i == PIN_AVR_MOSI ||
|
||||
i == PIN_AVR_MISO ) {
|
||||
pin = pgm->pinno[i] & PIN_MASK;
|
||||
if ((r=linuxgpio_export(pin)) < 0) {
|
||||
fprintf(stderr, "Can't export GPIO %d, already exported/busy?: %s",
|
||||
pin, strerror(errno));
|
||||
return r;
|
||||
}
|
||||
if (i == PIN_AVR_MISO)
|
||||
r=linuxgpio_dir_in(pin);
|
||||
else
|
||||
r=linuxgpio_dir_out(pin);
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if ((linuxgpio_fds[pin]=linuxgpio_openfd(pin)) < 0)
|
||||
return linuxgpio_fds[pin];
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void linuxgpio_close(PROGRAMMER *pgm)
|
||||
{
|
||||
int i, reset_pin;
|
||||
|
||||
reset_pin = pgm->pinno[PIN_AVR_RESET] & PIN_MASK;
|
||||
|
||||
//first configure all pins as input, except RESET
|
||||
//this should avoid possible conflicts when AVR firmware starts
|
||||
for (i=0; i<N_GPIO; i++) {
|
||||
if (linuxgpio_fds[i] >= 0 && i != reset_pin) {
|
||||
close(linuxgpio_fds[i]);
|
||||
linuxgpio_dir_in(i);
|
||||
linuxgpio_unexport(i);
|
||||
}
|
||||
}
|
||||
//configure RESET as input, if there's external pull up it will go high
|
||||
if (linuxgpio_fds[reset_pin] >= 0) {
|
||||
close(linuxgpio_fds[reset_pin]);
|
||||
linuxgpio_dir_in(reset_pin);
|
||||
linuxgpio_unexport(reset_pin);
|
||||
}
|
||||
}
|
||||
|
||||
void linuxgpio_initpgm(PROGRAMMER *pgm)
|
||||
{
|
||||
strcpy(pgm->type, "linuxgpio");
|
||||
|
||||
pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
|
||||
|
||||
pgm->rdy_led = bitbang_rdy_led;
|
||||
pgm->err_led = bitbang_err_led;
|
||||
pgm->pgm_led = bitbang_pgm_led;
|
||||
pgm->vfy_led = bitbang_vfy_led;
|
||||
pgm->initialize = bitbang_initialize;
|
||||
pgm->display = linuxgpio_display;
|
||||
pgm->enable = linuxgpio_enable;
|
||||
pgm->disable = linuxgpio_disable;
|
||||
pgm->powerup = linuxgpio_powerup;
|
||||
pgm->powerdown = linuxgpio_powerdown;
|
||||
pgm->program_enable = bitbang_program_enable;
|
||||
pgm->chip_erase = bitbang_chip_erase;
|
||||
pgm->cmd = bitbang_cmd;
|
||||
pgm->open = linuxgpio_open;
|
||||
pgm->close = linuxgpio_close;
|
||||
pgm->setpin = linuxgpio_setpin;
|
||||
pgm->getpin = linuxgpio_getpin;
|
||||
pgm->highpulsepin = linuxgpio_highpulsepin;
|
||||
pgm->read_byte = avr_read_byte_default;
|
||||
pgm->write_byte = avr_write_byte_default;
|
||||
}
|
||||
|
||||
const char linuxgpio_desc[] = "GPIO bitbanging using the Linux sysfs interface";
|
||||
|
||||
#else /* !HAVE_LINUXGPIO */
|
||||
|
||||
void linuxgpio_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: Linux sysfs GPIO support not available in this configuration\n",
|
||||
progname);
|
||||
}
|
||||
|
||||
const char linuxgpio_desc[] = "GPIO bitbanging using the Linux sysfs interface (not available)";
|
||||
|
||||
#endif /* HAVE_LINUXGPIO */
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2013 Radoslav Kolev <radoslav@kolev.info>
|
||||
*
|
||||
* 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: par.h 722 2007-01-24 22:43:46Z joerg_wunsch $ */
|
||||
|
||||
#ifndef linuxgpio_h
|
||||
#define linuxgpio_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char linuxgpio_desc[];
|
||||
void linuxgpio_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -13,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -477,7 +478,7 @@ lcreat ( void * liststruct, int elements )
|
||||
| at the same time.
|
||||
--------------------------------------------------*/
|
||||
void
|
||||
ldestroy_cb ( LISTID lid, void (*ucleanup)(void * data_ptr) )
|
||||
ldestroy_cb ( LISTID lid, void (*ucleanup)() )
|
||||
{
|
||||
LIST * l;
|
||||
LISTNODE * ln;
|
||||
@@ -1279,43 +1280,6 @@ lsrch ( LISTID lid, void * p, int (* compare)(void * p1, void * p2) )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
| lsort
|
||||
|
|
||||
| sort list - sorts list inplace (using bubble sort)
|
||||
|
|
||||
----------------------------------------------------------------------*/
|
||||
void
|
||||
lsort ( LISTID lid, int (* compare)(void * p1, void * p2) )
|
||||
{
|
||||
LIST * l;
|
||||
LISTNODE * lt; /* this */
|
||||
LISTNODE * ln; /* next */
|
||||
int unsorted = 1;
|
||||
|
||||
l = (LIST *)lid;
|
||||
|
||||
CKLMAGIC(l);
|
||||
|
||||
while(unsorted){
|
||||
lt = l->top;
|
||||
unsorted = 0;
|
||||
while (lt!=NULL) {
|
||||
CKMAGIC(lt);
|
||||
ln = lt->next;
|
||||
if (ln!= NULL && compare(lt->data,ln->data) > 0) {
|
||||
void * p = ln->data;
|
||||
ln->data = lt->data;
|
||||
lt->data = p;
|
||||
unsorted = 1;
|
||||
}
|
||||
lt = ln;
|
||||
}
|
||||
}
|
||||
|
||||
CKLMAGIC(l);
|
||||
}
|
||||
|
||||
|
||||
int lprint ( FILE * f, LISTID lid )
|
||||
{
|
||||
@@ -1326,8 +1290,8 @@ int lprint ( FILE * f, LISTID lid )
|
||||
|
||||
l = (LIST *)lid;
|
||||
|
||||
fprintf ( f, "list id %p internal data structures:\n",
|
||||
lid );
|
||||
fprintf ( f, "list id 0x%08x internal data structures:\n",
|
||||
(unsigned int)lid );
|
||||
#if CHECK_MAGIC
|
||||
if ((l->magic1 != MAGIC) || (l->magic2 != MAGIC)) {
|
||||
fprintf ( f, " *** WARNING: LIST MAGIC IS CORRUPT ***\n" );
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -27,8 +28,8 @@
|
||||
Author : Brian Dean
|
||||
Date : 10 January, 1990
|
||||
----------------------------------------------------------------------*/
|
||||
#ifndef lists_h
|
||||
#define lists_h
|
||||
#ifndef __lists_h__
|
||||
#define __lists_h__
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -66,15 +67,11 @@ typedef void * LNODEID;
|
||||
#define LISTRMV(l,d) lrmv_d(l,d) /* remove from end of the list */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* .................... Function Prototypes .................... */
|
||||
|
||||
LISTID lcreat ( void * liststruct, int poolsize );
|
||||
void ldestroy ( LISTID lid );
|
||||
void ldestroy_cb ( LISTID lid, void (*ucleanup)(void * data_ptr) );
|
||||
void ldestroy_cb ( LISTID lid, void (*ucleanup)() );
|
||||
|
||||
LNODEID lfirst ( LISTID ); /* head of the list */
|
||||
LNODEID llast ( LISTID ); /* tail of the list */
|
||||
@@ -103,14 +100,8 @@ void * lrmv_d ( LISTID lid, void * data_ptr );
|
||||
|
||||
LISTID lcat ( LISTID lid1, LISTID lid2 );
|
||||
|
||||
void lsort ( LISTID lid, int (*compare)(void * p1, void * p2));
|
||||
|
||||
void * lsrch ( LISTID lid, void * p, int (*compare)(void *p1,void *p2));
|
||||
|
||||
int lprint ( FILE * f, LISTID lid );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
1214
avrdude/main.c
1214
avrdude/main.c
File diff suppressed because it is too large
Load Diff
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $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 */
|
||||
259
avrdude/par.c
259
avrdude/par.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000-2006 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2000-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
|
||||
@@ -13,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -27,24 +28,28 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
#if defined(__FreeBSD__)
|
||||
# include "freebsd_ppi.h"
|
||||
#elif defined(__linux__)
|
||||
# include "linux_ppdev.h"
|
||||
#elif defined(__sun__) || defined(__sun) /* Solaris */
|
||||
#elif defined(__sun__) && defined(__svr4__) /* Solaris */
|
||||
# include "solaris_ecpp.h"
|
||||
#endif
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "pindefs.h"
|
||||
#include "pgm.h"
|
||||
#include "ppi.h"
|
||||
#include "bitbang.h"
|
||||
#include "par.h"
|
||||
|
||||
extern char * progname;
|
||||
extern int do_cycles;
|
||||
extern int verbose;
|
||||
|
||||
#if HAVE_PARPORT
|
||||
|
||||
#define SLOW_TOGGLE 0
|
||||
|
||||
struct ppipins_t {
|
||||
int pin;
|
||||
int reg;
|
||||
@@ -52,7 +57,7 @@ struct ppipins_t {
|
||||
int inverted;
|
||||
};
|
||||
|
||||
static struct ppipins_t ppipins[] = {
|
||||
struct ppipins_t ppipins[] = {
|
||||
{ 1, PPICTRL, 0x01, 1 },
|
||||
{ 2, PPIDATA, 0x01, 0 },
|
||||
{ 3, PPIDATA, 0x02, 0 },
|
||||
@@ -76,9 +81,7 @@ static struct ppipins_t ppipins[] = {
|
||||
|
||||
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,41 +90,25 @@ static int par_setpin(PROGRAMMER * pgm, int pin, int value)
|
||||
pin--;
|
||||
|
||||
if (ppipins[pin].inverted)
|
||||
inverted = !inverted;
|
||||
|
||||
if (inverted)
|
||||
value = !value;
|
||||
|
||||
if (value)
|
||||
ppi_set(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||
ppi_set(pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||
else
|
||||
ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||
ppi_clr(pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||
|
||||
if (pgm->ispdelay > 1)
|
||||
bitbang_delay(pgm->ispdelay);
|
||||
#if SLOW_TOGGLE
|
||||
usleep(1000);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void par_setmany(PROGRAMMER * pgm, unsigned int pinset, int value)
|
||||
{
|
||||
int pin, mask;
|
||||
|
||||
/* mask is anything non-pin - needs to be applied to each par_setpin to preserve inversion */
|
||||
mask = pinset & (~PIN_MASK);
|
||||
|
||||
for (pin = 1; pin <= 17; pin++) {
|
||||
if (pinset & (1 << pin))
|
||||
par_setpin(pgm, pin | mask, 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)
|
||||
@@ -129,15 +116,12 @@ static int par_getpin(PROGRAMMER * pgm, int pin)
|
||||
|
||||
pin--;
|
||||
|
||||
value = ppi_get(&pgm->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;
|
||||
@@ -146,46 +130,65 @@ static int par_getpin(PROGRAMMER * pgm, 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--;
|
||||
|
||||
if (ppipins[pin].inverted)
|
||||
inverted = !inverted;
|
||||
ppi_set(pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||
#if SLOW_TOGGLE
|
||||
usleep(1000);
|
||||
#endif
|
||||
ppi_clr(pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
|
||||
|
||||
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);
|
||||
}
|
||||
#if SLOW_TOGGLE
|
||||
usleep(1000);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int par_getpinmask(int pin)
|
||||
{
|
||||
pin &= PIN_MASK;
|
||||
|
||||
if (pin < 1 || pin > 17)
|
||||
return -1;
|
||||
|
||||
return ppipins[pin-1].bit;
|
||||
}
|
||||
|
||||
|
||||
char vccpins_buf[64];
|
||||
static char * vccpins_str(unsigned int pmask)
|
||||
{
|
||||
unsigned int mask;
|
||||
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) {
|
||||
sprintf(b2, "%d", pin);
|
||||
if (b[0] != 0)
|
||||
strcat(b, ",");
|
||||
strcat(b, b2);
|
||||
}
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/*
|
||||
* apply power to the AVR processor
|
||||
*/
|
||||
static void par_powerup(PROGRAMMER * pgm)
|
||||
{
|
||||
par_setmany(pgm, pgm->pinno[PPI_AVR_VCC], 1); /* power up */
|
||||
ppi_set(pgm->fd, PPIDATA, pgm->pinno[PPI_AVR_VCC]); /* power up */
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
@@ -195,12 +198,12 @@ static void par_powerup(PROGRAMMER * pgm)
|
||||
*/
|
||||
static void par_powerdown(PROGRAMMER * pgm)
|
||||
{
|
||||
par_setmany(pgm, pgm->pinno[PPI_AVR_VCC], 0); /* power down */
|
||||
ppi_clr(pgm->fd, PPIDATA, pgm->pinno[PPI_AVR_VCC]); /* power down */
|
||||
}
|
||||
|
||||
static void par_disable(PROGRAMMER * pgm)
|
||||
{
|
||||
par_setmany(pgm, pgm->pinno[PPI_AVR_BUFF], 1); /* turn off */
|
||||
ppi_set(pgm->fd, PPIDATA, pgm->pinno[PPI_AVR_BUFF]);
|
||||
}
|
||||
|
||||
static void par_enable(PROGRAMMER * pgm)
|
||||
@@ -222,17 +225,15 @@ static void par_enable(PROGRAMMER * pgm)
|
||||
/*
|
||||
* enable the 74367 buffer, if connected; this signal is active low
|
||||
*/
|
||||
par_setmany(pgm, pgm->pinno[PPI_AVR_BUFF], 0);
|
||||
ppi_clr(pgm->fd, PPIDATA, pgm->pinno[PPI_AVR_BUFF]);
|
||||
}
|
||||
|
||||
static int par_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
int rc;
|
||||
|
||||
bitbang_check_prerequisites(pgm);
|
||||
|
||||
ppi_open(port, &pgm->fd);
|
||||
if (pgm->fd.ifd < 0) {
|
||||
pgm->fd = ppi_open(port);
|
||||
if (pgm->fd < 0) {
|
||||
fprintf(stderr, "%s: failed to open parallel port \"%s\"\n\n",
|
||||
progname, port);
|
||||
exit(1);
|
||||
@@ -241,14 +242,14 @@ static int par_open(PROGRAMMER * pgm, char * port)
|
||||
/*
|
||||
* 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;
|
||||
@@ -261,90 +262,84 @@ static int par_open(PROGRAMMER * pgm, char * port)
|
||||
|
||||
static void par_close(PROGRAMMER * pgm)
|
||||
{
|
||||
|
||||
/*
|
||||
* Restore pin values before closing,
|
||||
* but ensure that buffers are turned off.
|
||||
*/
|
||||
ppi_setall(&pgm->fd, PPIDATA, pgm->ppidata);
|
||||
ppi_setall(&pgm->fd, PPICTRL, pgm->ppictrl);
|
||||
pgm->ppidata |= pgm->pinno[PPI_AVR_BUFF];
|
||||
ppi_setall(pgm->fd, PPIDATA, pgm->ppidata);
|
||||
ppi_setall(pgm->fd, PPICTRL, pgm->ppictrl);
|
||||
|
||||
par_setmany(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;
|
||||
static void par_display(PROGRAMMER * pgm, char * p)
|
||||
{
|
||||
char vccpins[64];
|
||||
char buffpins[64];
|
||||
|
||||
case EXIT_RESET_DISABLED:
|
||||
par_setpin(pgm, pgm->pinno[PIN_AVR_RESET], 1);
|
||||
break;
|
||||
|
||||
case EXIT_RESET_UNSPEC:
|
||||
/* Leave it alone. */
|
||||
break;
|
||||
if (pgm->pinno[PPI_AVR_VCC]) {
|
||||
snprintf(vccpins, sizeof(vccpins), " = pins %s",
|
||||
vccpins_str(pgm->pinno[PPI_AVR_VCC]));
|
||||
}
|
||||
else {
|
||||
strcpy(vccpins, " (not used)");
|
||||
}
|
||||
|
||||
switch (pgm->exit_datahigh) {
|
||||
case EXIT_DATAHIGH_ENABLED:
|
||||
ppi_setall(&pgm->fd, PPIDATA, 0xff);
|
||||
break;
|
||||
|
||||
case EXIT_DATAHIGH_DISABLED:
|
||||
ppi_setall(&pgm->fd, PPIDATA, 0x00);
|
||||
break;
|
||||
|
||||
case EXIT_DATAHIGH_UNSPEC:
|
||||
/* Leave it alone. */
|
||||
break;
|
||||
if (pgm->pinno[PPI_AVR_BUFF]) {
|
||||
snprintf(buffpins, sizeof(buffpins), " = pins %s",
|
||||
vccpins_str(pgm->pinno[PPI_AVR_BUFF]));
|
||||
}
|
||||
else {
|
||||
strcpy(buffpins, " (not used)");
|
||||
}
|
||||
|
||||
switch (pgm->exit_vcc) {
|
||||
case EXIT_VCC_ENABLED:
|
||||
par_setmany(pgm, pgm->pinno[PPI_AVR_VCC], 1);
|
||||
break;
|
||||
fprintf(stderr,
|
||||
"%s VCC = 0x%02x%s\n"
|
||||
"%s BUFF = 0x%02x%s\n"
|
||||
"%s RESET = %d\n"
|
||||
"%s SCK = %d\n"
|
||||
"%s MOSI = %d\n"
|
||||
"%s MISO = %d\n"
|
||||
"%s ERR LED = %d\n"
|
||||
"%s RDY LED = %d\n"
|
||||
"%s PGM LED = %d\n"
|
||||
"%s VFY LED = %d\n",
|
||||
|
||||
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;
|
||||
p, pgm->pinno[PPI_AVR_VCC], vccpins,
|
||||
p, pgm->pinno[PPI_AVR_BUFF], buffpins,
|
||||
p, pgm->pinno[PIN_AVR_RESET],
|
||||
p, pgm->pinno[PIN_AVR_SCK],
|
||||
p, pgm->pinno[PIN_AVR_MOSI],
|
||||
p, pgm->pinno[PIN_AVR_MISO],
|
||||
p, pgm->pinno[PIN_LED_ERR],
|
||||
p, pgm->pinno[PIN_LED_RDY],
|
||||
p, pgm->pinno[PIN_LED_PGM],
|
||||
p, pgm->pinno[PIN_LED_VFY]);
|
||||
}
|
||||
|
||||
/*
|
||||
* parse the -E string
|
||||
*/
|
||||
static int par_parseexitspecs(PROGRAMMER * pgm, char *s)
|
||||
static int par_getexitspecs(PROGRAMMER * pgm, char *s, int *set, int *clr)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
while ((cp = strtok(s, ","))) {
|
||||
if (strcmp(cp, "reset") == 0) {
|
||||
pgm->exit_reset = EXIT_RESET_ENABLED;
|
||||
*clr |= par_getpinmask(pgm->pinno[PIN_AVR_RESET]);
|
||||
}
|
||||
else if (strcmp(cp, "noreset") == 0) {
|
||||
pgm->exit_reset = EXIT_RESET_DISABLED;
|
||||
*set |= par_getpinmask(pgm->pinno[PIN_AVR_RESET]);
|
||||
}
|
||||
else if (strcmp(cp, "vcc") == 0) {
|
||||
pgm->exit_vcc = EXIT_VCC_ENABLED;
|
||||
if (pgm->pinno[PPI_AVR_VCC])
|
||||
*set |= pgm->pinno[PPI_AVR_VCC];
|
||||
}
|
||||
else if (strcmp(cp, "novcc") == 0) {
|
||||
pgm->exit_vcc = EXIT_VCC_DISABLED;
|
||||
}
|
||||
else if (strcmp(cp, "d_high") == 0) {
|
||||
pgm->exit_datahigh = EXIT_DATAHIGH_ENABLED;
|
||||
}
|
||||
else if (strcmp(cp, "d_low") == 0) {
|
||||
pgm->exit_datahigh = EXIT_DATAHIGH_DISABLED;
|
||||
if (pgm->pinno[PPI_AVR_VCC])
|
||||
*clr |= pgm->pinno[PPI_AVR_VCC];
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
@@ -355,22 +350,18 @@ static int par_parseexitspecs(PROGRAMMER * pgm, char *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void par_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
strcpy(pgm->type, "PPI");
|
||||
|
||||
pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
|
||||
|
||||
pgm->exit_vcc = EXIT_VCC_UNSPEC;
|
||||
pgm->exit_reset = EXIT_RESET_UNSPEC;
|
||||
pgm->exit_datahigh = EXIT_DATAHIGH_UNSPEC;
|
||||
|
||||
pgm->rdy_led = bitbang_rdy_led;
|
||||
pgm->err_led = bitbang_err_led;
|
||||
pgm->pgm_led = bitbang_pgm_led;
|
||||
pgm->vfy_led = bitbang_vfy_led;
|
||||
pgm->initialize = bitbang_initialize;
|
||||
pgm->display = pgm_display_generic;
|
||||
pgm->display = par_display;
|
||||
pgm->enable = par_enable;
|
||||
pgm->disable = par_disable;
|
||||
pgm->powerup = par_powerup;
|
||||
@@ -378,16 +369,12 @@ void par_initpgm(PROGRAMMER * pgm)
|
||||
pgm->program_enable = bitbang_program_enable;
|
||||
pgm->chip_erase = bitbang_chip_erase;
|
||||
pgm->cmd = bitbang_cmd;
|
||||
pgm->cmd_tpi = bitbang_cmd_tpi;
|
||||
pgm->spi = bitbang_spi;
|
||||
pgm->open = par_open;
|
||||
pgm->close = par_close;
|
||||
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;
|
||||
pgm->getexitspecs = par_getexitspecs;
|
||||
}
|
||||
|
||||
#else /* !HAVE_PARPORT */
|
||||
@@ -400,5 +387,3 @@ void par_initpgm(PROGRAMMER * pgm)
|
||||
}
|
||||
|
||||
#endif /* HAVE_PARPORT */
|
||||
|
||||
const char par_desc[] = "Parallel port bitbanging";
|
||||
|
||||
@@ -13,23 +13,17 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* 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 par_h
|
||||
#define par_h
|
||||
#ifndef __par_h__
|
||||
#define __par_h__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char par_desc[];
|
||||
void par_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
184
avrdude/pgm.c
184
avrdude/pgm.c
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -25,16 +25,15 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "pgm.h"
|
||||
|
||||
extern char * progname;
|
||||
|
||||
static int pgm_default_2 (struct programmer_t *, AVRPART *);
|
||||
static int pgm_default_3 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char * value);
|
||||
static void pgm_default_4 (struct programmer_t *);
|
||||
static int pgm_default_5 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char data);
|
||||
static void pgm_default_6 (struct programmer_t *, const char *);
|
||||
static int pgm_default_5 (struct programmer_t *, unsigned char cmd[4],
|
||||
unsigned char res[4]);
|
||||
static void pgm_default_6 (struct programmer_t *, char *);
|
||||
|
||||
|
||||
static int pgm_default_open (struct programmer_t *pgm, char * name)
|
||||
@@ -81,12 +80,9 @@ PROGRAMMER * pgm_new(void)
|
||||
pgm->config_file[0] = 0;
|
||||
pgm->lineno = 0;
|
||||
pgm->baudrate = 0;
|
||||
pgm->initpgm = NULL;
|
||||
|
||||
for (i=0; i<N_PINS; i++) {
|
||||
for (i=0; i<N_PINS; i++)
|
||||
pgm->pinno[i] = 0;
|
||||
pin_clear_all(&(pgm->pin[i]));
|
||||
}
|
||||
|
||||
/*
|
||||
* mandatory functions - these are called without checking to see
|
||||
@@ -100,10 +96,9 @@ 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
|
||||
@@ -119,50 +114,15 @@ PROGRAMMER * pgm_new(void)
|
||||
* optional functions - these are checked to make sure they are
|
||||
* assigned before they are called
|
||||
*/
|
||||
pgm->cmd = NULL;
|
||||
pgm->cmd_tpi = NULL;
|
||||
pgm->spi = 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;
|
||||
pgm->parseextparams = NULL;
|
||||
pgm->setup = NULL;
|
||||
pgm->teardown = NULL;
|
||||
|
||||
return pgm;
|
||||
}
|
||||
|
||||
void pgm_free(PROGRAMMER * const p)
|
||||
{
|
||||
ldestroy_cb(p->id,free);
|
||||
p->id = NULL;
|
||||
/* this is done by pgm_teardown, but usually cookie is not set to NULL */
|
||||
/* if (p->cookie !=NULL) {
|
||||
free(p->cookie);
|
||||
p->cookie = NULL;
|
||||
}*/
|
||||
free(p);
|
||||
}
|
||||
|
||||
PROGRAMMER * pgm_dup(const PROGRAMMER const * src)
|
||||
{
|
||||
PROGRAMMER * pgm;
|
||||
|
||||
pgm = (PROGRAMMER *)malloc(sizeof(*pgm));
|
||||
if (pgm == NULL) {
|
||||
fprintf(stderr, "%s: out of memory allocating programmer structure\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memcpy(pgm, src, sizeof(*pgm));
|
||||
|
||||
pgm->id = lcreat(NULL, 0);
|
||||
|
||||
return pgm;
|
||||
}
|
||||
@@ -180,137 +140,21 @@ 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, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char data)
|
||||
static int pgm_default_5 (struct programmer_t * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4])
|
||||
{
|
||||
pgm_default();
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void pgm_default_6 (struct programmer_t * pgm, const char * p)
|
||||
static void pgm_default_6 (struct programmer_t * pgm, char * p)
|
||||
{
|
||||
pgm_default();
|
||||
}
|
||||
|
||||
|
||||
void programmer_display(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
fprintf(stderr, "%sProgrammer Type : %s\n", p, pgm->type);
|
||||
fprintf(stderr, "%sDescription : %s\n", p, pgm->desc);
|
||||
|
||||
pgm->display(pgm, p);
|
||||
}
|
||||
|
||||
|
||||
void pgm_display_generic_mask(PROGRAMMER * pgm, const char * p, unsigned int show)
|
||||
{
|
||||
if(show & (1<<PPI_AVR_VCC))
|
||||
fprintf(stderr, "%s VCC = %s\n", p, pins_to_str(&pgm->pin[PPI_AVR_VCC]));
|
||||
if(show & (1<<PPI_AVR_BUFF))
|
||||
fprintf(stderr, "%s BUFF = %s\n", p, pins_to_str(&pgm->pin[PPI_AVR_BUFF]));
|
||||
if(show & (1<<PIN_AVR_RESET))
|
||||
fprintf(stderr, "%s RESET = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_RESET]));
|
||||
if(show & (1<<PIN_AVR_SCK))
|
||||
fprintf(stderr, "%s SCK = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_SCK]));
|
||||
if(show & (1<<PIN_AVR_MOSI))
|
||||
fprintf(stderr, "%s MOSI = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_MOSI]));
|
||||
if(show & (1<<PIN_AVR_MISO))
|
||||
fprintf(stderr, "%s MISO = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_MISO]));
|
||||
if(show & (1<<PIN_LED_ERR))
|
||||
fprintf(stderr, "%s ERR LED = %s\n", p, pins_to_str(&pgm->pin[PIN_LED_ERR]));
|
||||
if(show & (1<<PIN_LED_RDY))
|
||||
fprintf(stderr, "%s RDY LED = %s\n", p, pins_to_str(&pgm->pin[PIN_LED_RDY]));
|
||||
if(show & (1<<PIN_LED_PGM))
|
||||
fprintf(stderr, "%s PGM LED = %s\n", p, pins_to_str(&pgm->pin[PIN_LED_PGM]));
|
||||
if(show & (1<<PIN_LED_VFY))
|
||||
fprintf(stderr, "%s VFY LED = %s\n", p, pins_to_str(&pgm->pin[PIN_LED_VFY]));
|
||||
}
|
||||
|
||||
void pgm_display_generic(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS);
|
||||
}
|
||||
|
||||
PROGRAMMER * locate_programmer(LISTID programmers, const char * configid)
|
||||
{
|
||||
LNODEID ln1, ln2;
|
||||
PROGRAMMER * p = NULL;
|
||||
const char * id;
|
||||
int found;
|
||||
|
||||
found = 0;
|
||||
|
||||
for (ln1=lfirst(programmers); ln1 && !found; ln1=lnext(ln1)) {
|
||||
p = ldata(ln1);
|
||||
for (ln2=lfirst(p->id); ln2 && !found; ln2=lnext(ln2)) {
|
||||
id = ldata(ln2);
|
||||
if (strcasecmp(configid, id) == 0)
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
return p;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over the list of programmers given as "programmers", and
|
||||
* call the callback function cb for each entry found. cb is being
|
||||
* passed the following arguments:
|
||||
* . the name of the programmer (for -c)
|
||||
* . the descriptive text given in the config file
|
||||
* . the name of the config file this programmer has been defined in
|
||||
* . the line number of the config file this programmer has been defined at
|
||||
* . the "cookie" passed into walk_programmers() (opaque client data)
|
||||
*/
|
||||
void walk_programmers(LISTID programmers, walk_programmers_cb cb, void *cookie)
|
||||
{
|
||||
LNODEID ln1;
|
||||
LNODEID ln2;
|
||||
PROGRAMMER * p;
|
||||
|
||||
for (ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) {
|
||||
p = ldata(ln1);
|
||||
for (ln2=lfirst(p->id); ln2; ln2=lnext(ln2)) {
|
||||
cb(ldata(ln2), p->desc, p->config_file, p->lineno, cookie);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare function to sort the list of programmers
|
||||
*/
|
||||
static int sort_programmer_compare(PROGRAMMER * p1,PROGRAMMER * p2)
|
||||
{
|
||||
char* id1;
|
||||
char* id2;
|
||||
if(p1 == NULL || p2 == NULL) {
|
||||
return 0;
|
||||
}
|
||||
id1 = ldata(lfirst(p1->id));
|
||||
id2 = ldata(lfirst(p2->id));
|
||||
return strncasecmp(id1,id2,AVR_IDLEN);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sort the list of programmers given as "programmers"
|
||||
*/
|
||||
void sort_programmers(LISTID programmers)
|
||||
{
|
||||
lsort(programmers,(int (*)(void*, void*)) sort_programmer_compare);
|
||||
}
|
||||
|
||||
|
||||
108
avrdude/pgm.h
108
avrdude/pgm.h
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,20 +13,21 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* 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 pgm_h
|
||||
#define pgm_h
|
||||
#ifndef __pgm_h__
|
||||
#define __pgm_h__
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "avrpart.h"
|
||||
#include "lists.h"
|
||||
#include "pindefs.h"
|
||||
#include "serial.h"
|
||||
|
||||
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
@@ -35,82 +35,41 @@
|
||||
#define PGM_DESCLEN 80
|
||||
#define PGM_PORTLEN PATH_MAX
|
||||
#define PGM_TYPELEN 32
|
||||
#define PGM_USBSTRINGLEN 256
|
||||
|
||||
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 enum {
|
||||
EXIT_DATAHIGH_UNSPEC,
|
||||
EXIT_DATAHIGH_ENABLED,
|
||||
EXIT_DATAHIGH_DISABLED
|
||||
} exit_datahigh_t;
|
||||
|
||||
typedef enum {
|
||||
CONNTYPE_PARALLEL,
|
||||
CONNTYPE_SERIAL,
|
||||
CONNTYPE_USB
|
||||
} conntype_t;
|
||||
extern LISTID programmers;
|
||||
|
||||
typedef struct programmer_t {
|
||||
LISTID id;
|
||||
char desc[PGM_DESCLEN];
|
||||
char type[PGM_TYPELEN];
|
||||
char port[PGM_PORTLEN];
|
||||
void (*initpgm)(struct programmer_t * pgm);
|
||||
unsigned int pinno[N_PINS];
|
||||
struct pindef_t pin[N_PINS];
|
||||
exit_vcc_t exit_vcc;
|
||||
exit_reset_t exit_reset;
|
||||
exit_datahigh_t exit_datahigh;
|
||||
conntype_t conntype;
|
||||
int ppidata;
|
||||
int ppictrl;
|
||||
int baudrate;
|
||||
int usbvid, usbpid;
|
||||
char usbdev[PGM_USBSTRINGLEN], usbsn[PGM_USBSTRINGLEN];
|
||||
char usbvendor[PGM_USBSTRINGLEN], usbproduct[PGM_USBSTRINGLEN];
|
||||
double bitclock; /* JTAG ICE clock period in microseconds */
|
||||
int ispdelay; /* ISP clock delay */
|
||||
union filedescriptor fd;
|
||||
int fd;
|
||||
int page_size; /* page size if the programmer supports paged write/load */
|
||||
int (*rdy_led) (struct programmer_t * pgm, int value);
|
||||
int (*err_led) (struct programmer_t * pgm, int value);
|
||||
int (*pgm_led) (struct programmer_t * pgm, int value);
|
||||
int (*vfy_led) (struct programmer_t * pgm, int value);
|
||||
int (*initialize) (struct programmer_t * pgm, AVRPART * p);
|
||||
void (*display) (struct programmer_t * pgm, const char * p);
|
||||
void (*display) (struct programmer_t * pgm, char * p);
|
||||
void (*enable) (struct programmer_t * pgm);
|
||||
void (*disable) (struct programmer_t * pgm);
|
||||
void (*powerup) (struct programmer_t * pgm);
|
||||
void (*powerdown) (struct programmer_t * pgm);
|
||||
int (*program_enable) (struct programmer_t * pgm, AVRPART * p);
|
||||
int (*chip_erase) (struct programmer_t * pgm, AVRPART * p);
|
||||
int (*cmd) (struct programmer_t * pgm, const unsigned char *cmd,
|
||||
unsigned char *res);
|
||||
int (*cmd_tpi) (struct programmer_t * pgm, const unsigned char *cmd,
|
||||
int cmd_len, unsigned char res[], int res_len);
|
||||
int (*spi) (struct programmer_t * pgm, const unsigned char *cmd,
|
||||
unsigned char *res, int count);
|
||||
int (*cmd) (struct programmer_t * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4]);
|
||||
int (*open) (struct programmer_t * pgm, char * port);
|
||||
void (*close) (struct programmer_t * pgm);
|
||||
int (*paged_write) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size, unsigned int baseaddr,
|
||||
unsigned int n_bytes);
|
||||
int page_size, int n_bytes);
|
||||
int (*paged_load) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size, unsigned int baseaddr,
|
||||
unsigned int n_bytes);
|
||||
int (*page_erase) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int baseaddr);
|
||||
int page_size, int n_bytes);
|
||||
void (*write_setup) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
|
||||
int (*write_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned long addr, unsigned char value);
|
||||
@@ -119,52 +78,37 @@ typedef struct programmer_t {
|
||||
int (*read_sig_bytes) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
|
||||
void (*print_parms) (struct programmer_t * pgm);
|
||||
int (*set_vtarget) (struct programmer_t * pgm, double v);
|
||||
int (*set_varef) (struct programmer_t * pgm, unsigned int chan, double v);
|
||||
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);
|
||||
int (*parseextparams) (struct programmer_t * pgm, LISTID xparams);
|
||||
void (*setup) (struct programmer_t * pgm);
|
||||
void (*teardown) (struct programmer_t * pgm);
|
||||
int (*getexitspecs) (struct programmer_t * pgm, char *s, int *set, int *clr);
|
||||
char config_file[PATH_MAX]; /* config file where defined */
|
||||
int lineno; /* config file line number */
|
||||
void *cookie; /* for private use by the programmer */
|
||||
char flag; /* for private use of the programmer */
|
||||
} PROGRAMMER;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
PROGRAMMER * pgm_new(void);
|
||||
PROGRAMMER * pgm_dup(const PROGRAMMER const * src);
|
||||
void pgm_free(PROGRAMMER * const p);
|
||||
|
||||
void programmer_display(PROGRAMMER * pgm, const char * p);
|
||||
#if defined(WIN32NATIVE)
|
||||
|
||||
/* show is a mask like this (1<<PIN_AVR_SCK)|(1<<PIN_AVR_MOSI)| ... */
|
||||
#define SHOW_ALL_PINS (~0u)
|
||||
#define SHOW_PPI_PINS ((1<<PPI_AVR_VCC)|(1<<PPI_AVR_BUFF))
|
||||
#define SHOW_AVR_PINS ((1<<PIN_AVR_RESET)|(1<<PIN_AVR_SCK)|(1<<PIN_AVR_MOSI)|(1<<PIN_AVR_MISO))
|
||||
#define SHOW_LED_PINS ((1<<PIN_LED_ERR)|(1<<PIN_LED_RDY)|(1<<PIN_LED_PGM)|(1<<PIN_LED_VFY))
|
||||
void pgm_display_generic_mask(PROGRAMMER * pgm, const char * p, unsigned int show);
|
||||
void pgm_display_generic(PROGRAMMER * pgm, const char * p);
|
||||
#include <windows.h>
|
||||
|
||||
PROGRAMMER * locate_programmer(LISTID programmers, const char * configid);
|
||||
/* usleep replacements */
|
||||
/* sleep Windows in ms, Unix usleep in us
|
||||
#define usleep(us) Sleep((us)<20000?20:us/1000)
|
||||
#define usleep(us) Sleep(us/1000)
|
||||
#define ANTIWARP 3
|
||||
#define usleep(us) Sleep(us/1000*ANTIWARP)
|
||||
*/
|
||||
void usleep(unsigned long us);
|
||||
|
||||
typedef void (*walk_programmers_cb)(const char *name, const char *desc,
|
||||
const char *cfgname, int cfglineno,
|
||||
void *cookie);
|
||||
void walk_programmers(LISTID programmers, walk_programmers_cb cb, void *cookie);
|
||||
void gettimeofday(struct timeval*, void*z);
|
||||
|
||||
void sort_programmers(LISTID programmers);
|
||||
#endif /* __win32native_h */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id: pgm.c 976 2011-08-23 21:03:36Z joerg_wunsch $ */
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "pgm_type.h"
|
||||
|
||||
#include "arduino.h"
|
||||
#include "avr.h"
|
||||
#include "avr910.h"
|
||||
#include "avrftdi.h"
|
||||
#include "buspirate.h"
|
||||
#include "butterfly.h"
|
||||
#include "ft245r.h"
|
||||
#include "jtagmkI.h"
|
||||
#include "jtagmkII.h"
|
||||
#include "jtag3.h"
|
||||
#include "linuxgpio.h"
|
||||
#include "par.h"
|
||||
#include "pickit2.h"
|
||||
#include "ppi.h"
|
||||
#include "serbb.h"
|
||||
#include "stk500.h"
|
||||
#include "stk500generic.h"
|
||||
#include "stk500v2.h"
|
||||
#include "usbasp.h"
|
||||
#include "usbtiny.h"
|
||||
#include "wiring.h"
|
||||
|
||||
|
||||
const PROGRAMMER_TYPE const programmers_types[] = {
|
||||
{"arduino", arduino_initpgm, arduino_desc},
|
||||
{"avr910", avr910_initpgm, avr910_desc},
|
||||
{"avrftdi", avrftdi_initpgm, avrftdi_desc},
|
||||
{"buspirate", buspirate_initpgm, buspirate_desc},
|
||||
{"buspirate_bb", buspirate_bb_initpgm, buspirate_bb_desc},
|
||||
{"butterfly", butterfly_initpgm, butterfly_desc},
|
||||
{"butterfly_mk", butterfly_mk_initpgm, butterfly_mk_desc},
|
||||
{"dragon_dw", jtagmkII_dragon_dw_initpgm, jtagmkII_dragon_dw_desc},
|
||||
{"dragon_hvsp", stk500v2_dragon_hvsp_initpgm, stk500v2_dragon_hvsp_desc},
|
||||
{"dragon_isp", stk500v2_dragon_isp_initpgm, stk500v2_dragon_isp_desc},
|
||||
{"dragon_jtag", jtagmkII_dragon_initpgm, jtagmkII_dragon_desc},
|
||||
{"dragon_pdi", jtagmkII_dragon_pdi_initpgm, jtagmkII_dragon_pdi_desc},
|
||||
{"dragon_pp", stk500v2_dragon_pp_initpgm, stk500v2_dragon_pp_desc},
|
||||
{"ftdi_syncbb", ft245r_initpgm, ft245r_desc},
|
||||
{"jtagmki", jtagmkI_initpgm, jtagmkI_desc},
|
||||
{"jtagmkii", jtagmkII_initpgm, jtagmkII_desc},
|
||||
{"jtagmkii_avr32", jtagmkII_avr32_initpgm, jtagmkII_avr32_desc},
|
||||
{"jtagmkii_dw", jtagmkII_dw_initpgm, jtagmkII_dw_desc},
|
||||
{"jtagmkii_isp", stk500v2_jtagmkII_initpgm, stk500v2_jtagmkII_desc},
|
||||
{"jtagmkii_pdi", jtagmkII_pdi_initpgm, jtagmkII_pdi_desc},
|
||||
{"jtagice3", jtag3_initpgm, jtag3_desc},
|
||||
{"jtagice3_pdi", jtag3_pdi_initpgm, jtag3_pdi_desc},
|
||||
{"jtagice3_dw", jtag3_dw_initpgm, jtag3_dw_desc},
|
||||
{"jtagice3_isp", stk500v2_jtag3_initpgm, stk500v2_jtag3_desc},
|
||||
{"linuxgpio", linuxgpio_initpgm, linuxgpio_desc},
|
||||
{"par", par_initpgm, par_desc},
|
||||
{"pickit2", pickit2_initpgm, pickit2_desc},
|
||||
{"serbb", serbb_initpgm, serbb_desc},
|
||||
{"stk500", stk500_initpgm, stk500_desc},
|
||||
{"stk500generic", stk500generic_initpgm, stk500generic_desc},
|
||||
{"stk500v2", stk500v2_initpgm, stk500v2_desc},
|
||||
{"stk500hvsp", stk500hvsp_initpgm, stk500hvsp_desc},
|
||||
{"stk500pp", stk500pp_initpgm, stk500pp_desc},
|
||||
{"stk600", stk600_initpgm, stk600_desc},
|
||||
{"stk600hvsp", stk600hvsp_initpgm, stk600hvsp_desc},
|
||||
{"stk600pp", stk600pp_initpgm, stk600pp_desc},
|
||||
{"usbasp", usbasp_initpgm, usbasp_desc},
|
||||
{"usbtiny", usbtiny_initpgm, usbtiny_desc},
|
||||
{"wiring", wiring_initpgm, wiring_desc},
|
||||
};
|
||||
|
||||
const PROGRAMMER_TYPE * locate_programmer_type(const char * id)
|
||||
{
|
||||
const PROGRAMMER_TYPE * p = NULL;
|
||||
int i;
|
||||
int found;
|
||||
|
||||
found = 0;
|
||||
|
||||
for (i = 0; i < sizeof(programmers_types)/sizeof(programmers_types[0]) && !found; i++) {
|
||||
p = &(programmers_types[i]);
|
||||
if (strcasecmp(id, p->id) == 0)
|
||||
found = 1;
|
||||
}
|
||||
|
||||
if (found)
|
||||
return p;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over the list of programmers given as "programmers", and
|
||||
* call the callback function cb for each entry found. cb is being
|
||||
* passed the following arguments:
|
||||
* . the name of the programmer (for -c)
|
||||
* . the descriptive text given in the config file
|
||||
* . the name of the config file this programmer has been defined in
|
||||
* . the line number of the config file this programmer has been defined at
|
||||
* . the "cookie" passed into walk_programmers() (opaque client data)
|
||||
*/
|
||||
/*
|
||||
void walk_programmer_types(LISTID programmer_types, walk_programmer_types_cb cb, void *cookie)
|
||||
{
|
||||
LNODEID ln1;
|
||||
PROGRAMMER * p;
|
||||
|
||||
for (ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) {
|
||||
p = ldata(ln1);
|
||||
cb(p->id, p->desc, cookie);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
void walk_programmer_types(walk_programmer_types_cb cb, void *cookie)
|
||||
{
|
||||
const PROGRAMMER_TYPE * p;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(programmers_types)/sizeof(programmers_types[0]); i++) {
|
||||
p = &(programmers_types[i]);
|
||||
cb(p->id, p->desc, cookie);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id: pgm.h 1007 2011-09-14 21:49:42Z joerg_wunsch $ */
|
||||
|
||||
#ifndef pgm_type_h
|
||||
#define pgm_type_h
|
||||
|
||||
#include "lists.h"
|
||||
#include "pgm.h"
|
||||
|
||||
/*LISTID programmer_types;*/
|
||||
|
||||
typedef struct programmer_type_t {
|
||||
const char * const id;
|
||||
void (*initpgm)(struct programmer_t * pgm);
|
||||
const char * const desc;
|
||||
} PROGRAMMER_TYPE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const PROGRAMMER_TYPE * locate_programmer_type(/*LISTID programmer_types, */const char * id);
|
||||
|
||||
typedef void (*walk_programmer_types_cb)(const char *id, const char *desc,
|
||||
void *cookie);
|
||||
void walk_programmer_types(/*LISTID programmer_types,*/ walk_programmer_types_cb cb, void *cookie);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1362
avrdude/pickit2.c
1362
avrdude/pickit2.c
File diff suppressed because it is too large
Load Diff
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id: pickit2.h 2010-05-03 dbrown $ */
|
||||
|
||||
#ifndef pickit2_h
|
||||
#define pickit2_h
|
||||
|
||||
#include "avrpart.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char pickit2_desc[];
|
||||
void pickit2_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // pickit2_h
|
||||
@@ -1,365 +0,0 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2000-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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id: pindefs.h 1132 2013-01-09 19:23:30Z rliebscher $ */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "avrdude.h"
|
||||
#include "pindefs.h"
|
||||
#include "pgm.h"
|
||||
|
||||
/**
|
||||
* Adds a pin in the pin definition as normal or inverse pin.
|
||||
*
|
||||
* @param[out] pindef pin definition to update
|
||||
* @param[in] pin number of pin [0..PIN_MAX]
|
||||
* @param[in] inverse inverse (true) or normal (false) pin
|
||||
*/
|
||||
void pin_set_value(struct pindef_t * const pindef, const int pin, const bool inverse) {
|
||||
|
||||
pindef->mask[pin / PIN_FIELD_ELEMENT_SIZE] |= 1 << (pin % PIN_FIELD_ELEMENT_SIZE);
|
||||
if(inverse) {
|
||||
pindef->inverse[pin / PIN_FIELD_ELEMENT_SIZE] |= (1 << (pin % PIN_FIELD_ELEMENT_SIZE));
|
||||
} else {
|
||||
pindef->inverse[pin / PIN_FIELD_ELEMENT_SIZE] &= ~(1 << (pin % PIN_FIELD_ELEMENT_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all defined pins in pindef.
|
||||
*
|
||||
* @param[out] pindef pin definition to clear
|
||||
*/
|
||||
void pin_clear_all(struct pindef_t * const pindef) {
|
||||
memset(pindef, 0, sizeof(struct pindef_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert new pin definition to old pin number
|
||||
*
|
||||
* @param[in] pindef new pin definition structure
|
||||
* @param[out] pinno old pin definition integer
|
||||
*/
|
||||
static void pin_fill_old_pinno(const struct pindef_t * const pindef, unsigned int * const pinno) {
|
||||
bool found = false;
|
||||
int i;
|
||||
for(i = 0; i < PIN_MAX; i++) {
|
||||
if(pindef->mask[i / PIN_FIELD_ELEMENT_SIZE] & (1 << (i % PIN_FIELD_ELEMENT_SIZE))) {
|
||||
if(found) {
|
||||
fprintf(stderr, "Multiple pins found\n"); //TODO
|
||||
exit(1);
|
||||
}
|
||||
found = true;
|
||||
*pinno = i;
|
||||
if(pindef->inverse[i / PIN_FIELD_ELEMENT_SIZE] & (1 << (i % PIN_FIELD_ELEMENT_SIZE))) {
|
||||
*pinno |= PIN_INVERSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert new pin definition to old pinlist, does not support mixed inverted/non-inverted pin
|
||||
*
|
||||
* @param[in] pindef new pin definition structure
|
||||
* @param[out] pinno old pin definition integer
|
||||
*/
|
||||
static void pin_fill_old_pinlist(const struct pindef_t * const pindef, unsigned int * const pinno) {
|
||||
int i;
|
||||
|
||||
for(i = 0; i < PIN_FIELD_SIZE; i++) {
|
||||
if(i == 0) {
|
||||
if((pindef->mask[i] & ~PIN_MASK) != 0) {
|
||||
fprintf(stderr, "Pins of higher index than max field size for old pinno found\n");
|
||||
exit(1);
|
||||
}
|
||||
if(pindef->mask[i] == pindef->inverse[i]) { /* all set bits in mask are set in inverse */
|
||||
*pinno = pindef->mask[i];
|
||||
*pinno |= PIN_INVERSE;
|
||||
} else if(pindef->mask[i] == ((~pindef->inverse[i]) & pindef->mask[i])) { /* all set bits in mask are cleared in inverse */
|
||||
*pinno = pindef->mask[i];
|
||||
} else {
|
||||
fprintf(stderr, "pins have different polarity set\n");
|
||||
exit(1);
|
||||
}
|
||||
} else if(pindef->mask[i] != 0) {
|
||||
fprintf(stderr, "Pins have higher number than fit in old format\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert for given programmer new pin definitions to old pin definitions.
|
||||
*
|
||||
* @param[inout] pgm programmer whose pins shall be converted.
|
||||
*/
|
||||
void pgm_fill_old_pins(struct programmer_t * const pgm) {
|
||||
|
||||
pin_fill_old_pinlist(&(pgm->pin[PPI_AVR_VCC]), &(pgm->pinno[PPI_AVR_VCC]));
|
||||
pin_fill_old_pinlist(&(pgm->pin[PPI_AVR_BUFF]), &(pgm->pinno[PPI_AVR_BUFF]));
|
||||
pin_fill_old_pinno(&(pgm->pin[PIN_AVR_RESET]), &(pgm->pinno[PIN_AVR_RESET]));
|
||||
pin_fill_old_pinno(&(pgm->pin[PIN_AVR_SCK]), &(pgm->pinno[PIN_AVR_SCK]));
|
||||
pin_fill_old_pinno(&(pgm->pin[PIN_AVR_MOSI]), &(pgm->pinno[PIN_AVR_MOSI]));
|
||||
pin_fill_old_pinno(&(pgm->pin[PIN_AVR_MISO]), &(pgm->pinno[PIN_AVR_MISO]));
|
||||
pin_fill_old_pinno(&(pgm->pin[PIN_LED_ERR]), &(pgm->pinno[PIN_LED_ERR]));
|
||||
pin_fill_old_pinno(&(pgm->pin[PIN_LED_RDY]), &(pgm->pinno[PIN_LED_RDY]));
|
||||
pin_fill_old_pinno(&(pgm->pin[PIN_LED_PGM]), &(pgm->pinno[PIN_LED_PGM]));
|
||||
pin_fill_old_pinno(&(pgm->pin[PIN_LED_VFY]), &(pgm->pinno[PIN_LED_VFY]));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns a string representation of pins in the mask eg. 1,3,5-7,9,12
|
||||
* Another execution of this function will overwrite the previous result in the static buffer.
|
||||
* Consecutive pin number are representated as start-end.
|
||||
*
|
||||
* @param[in] pinmask the pin mask for which we want the string representation
|
||||
* @returns pointer to a static string.
|
||||
*/
|
||||
const char * pinmask_to_str(const pinmask_t * const pinmask) {
|
||||
static char buf[(PIN_MAX + 1) * 5]; // should be enough for PIN_MAX=255
|
||||
char *p = buf;
|
||||
int n;
|
||||
int pin;
|
||||
const char * fmt;
|
||||
int start = -1;
|
||||
int end = -1;
|
||||
|
||||
buf[0] = 0;
|
||||
for(pin = PIN_MIN; pin <= PIN_MAX; pin++) {
|
||||
int index = pin / PIN_FIELD_ELEMENT_SIZE;
|
||||
int bit = pin % PIN_FIELD_ELEMENT_SIZE;
|
||||
if(pinmask[index] & (1 << bit)) {
|
||||
bool output = false;
|
||||
if(start == -1) {
|
||||
output = true;
|
||||
start = pin;
|
||||
end = start;
|
||||
} else if(pin == end + 1) {
|
||||
end = pin;
|
||||
} else {
|
||||
if(start != end) {
|
||||
n = sprintf(p, "-%d", end);
|
||||
p += n;
|
||||
}
|
||||
output = true;
|
||||
start = pin;
|
||||
end = start;
|
||||
}
|
||||
if(output) {
|
||||
fmt = (buf[0] == 0) ? "%d" : ",%d";
|
||||
n = sprintf(p, fmt, pin);
|
||||
p += n;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(start != end) {
|
||||
n = sprintf(p, "-%d", end);
|
||||
p += n;
|
||||
}
|
||||
|
||||
if(buf[0] == 0)
|
||||
return "(no pins)";
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function checks all pin of pgm against the constraints given in the checklist.
|
||||
* It checks if
|
||||
* @li any invalid pins are used
|
||||
* @li valid pins are used inverted when not allowed
|
||||
* @li any pins are used by more than one function
|
||||
* @li any mandatory pin is not set all.
|
||||
*
|
||||
* In case of any error it report the wrong function and the pin numbers.
|
||||
* For verbose >= 2 it also reports the possible correct values.
|
||||
* For verbose >=3 it shows also which pins were ok.
|
||||
*
|
||||
* @param[in] pgm the programmer to check
|
||||
* @param[in] checklist the constraint for the pins
|
||||
* @param[in] size the number of entries in checklist
|
||||
* @returns 0 if all pin definitions are valid, -1 otherwise
|
||||
*/
|
||||
int pins_check(const struct programmer_t * const pgm, const struct pin_checklist_t * const checklist, const int size, bool output) {
|
||||
static const struct pindef_t no_valid_pins = {{0}, {0}}; // default value if check list does not contain anything else
|
||||
int rv = 0; // return value
|
||||
int pinname; // loop counter through pinnames
|
||||
pinmask_t already_used_all[PIN_FIELD_SIZE] = {0}; // collect pin definitions of all pin names for check of double use
|
||||
// loop over all possible pinnames
|
||||
for(pinname = 0; pinname < N_PINS; pinname++) {
|
||||
bool used = false;
|
||||
bool invalid = false;
|
||||
bool inverse = false;
|
||||
int index;
|
||||
int segment;
|
||||
bool mandatory_used = false;
|
||||
pinmask_t invalid_used[PIN_FIELD_SIZE] = {0};
|
||||
pinmask_t inverse_used[PIN_FIELD_SIZE] = {0};
|
||||
pinmask_t already_used[PIN_FIELD_SIZE] = {0};
|
||||
const struct pindef_t * valid_pins = &no_valid_pins;
|
||||
bool is_mandatory = false;
|
||||
bool is_ok = true;
|
||||
//find corresponding check pattern
|
||||
for(index = 0; index < size; index++) {
|
||||
if(checklist[index].pinname == pinname) {
|
||||
valid_pins = checklist[index].valid_pins;
|
||||
is_mandatory = checklist[index].mandatory;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(segment = 0; segment < PIN_FIELD_SIZE; segment++) {
|
||||
// check if for mandatory any pin is defined
|
||||
invalid_used[segment] = pgm->pin[pinname].mask[segment] & ~valid_pins->mask[segment];
|
||||
if(is_mandatory && (0 != (pgm->pin[pinname].mask[segment] & valid_pins->mask[segment]))) {
|
||||
mandatory_used = true;
|
||||
}
|
||||
// check if it does not use any non valid pins
|
||||
invalid_used[segment] = pgm->pin[pinname].mask[segment] & ~valid_pins->mask[segment];
|
||||
if(invalid_used[segment]) {
|
||||
invalid = true;
|
||||
}
|
||||
// check if it does not use any valid pins as inverse if not allowed
|
||||
inverse_used[segment] = pgm->pin[pinname].inverse[segment] & valid_pins->mask[segment] & ~valid_pins->inverse[segment];
|
||||
if(inverse_used[segment]) {
|
||||
inverse = true;
|
||||
}
|
||||
// check if it does not use same pins as other function
|
||||
already_used[segment] = pgm->pin[pinname].mask[segment] & already_used_all[segment];
|
||||
if(already_used[segment]) {
|
||||
used = true;
|
||||
}
|
||||
already_used_all[segment] |= pgm->pin[pinname].mask[segment];
|
||||
}
|
||||
if(invalid) {
|
||||
if(output) {
|
||||
fprintf(stderr,
|
||||
"%s: %s: Following pins are not valid pins for this function: %s\n",
|
||||
progname, avr_pin_name(pinname), pinmask_to_str(invalid_used));
|
||||
if(verbose >= 2) {
|
||||
fprintf(stderr,
|
||||
"%s: %s: Valid pins for this function are: %s\n",
|
||||
progname, avr_pin_name(pinname), pinmask_to_str(valid_pins->mask));
|
||||
}
|
||||
}
|
||||
is_ok = false;
|
||||
}
|
||||
if(inverse) {
|
||||
if(output) {
|
||||
fprintf(stderr,
|
||||
"%s: %s: Following pins are not usable as inverse pins for this function: %s\n",
|
||||
progname, avr_pin_name(pinname), pinmask_to_str(inverse_used));
|
||||
if(verbose >= 2) {
|
||||
fprintf(stderr,
|
||||
"%s: %s: Valid inverse pins for this function are: %s\n",
|
||||
progname, avr_pin_name(pinname), pinmask_to_str(valid_pins->inverse));
|
||||
}
|
||||
}
|
||||
is_ok = false;
|
||||
}
|
||||
if(used) {
|
||||
if(output) {
|
||||
fprintf(stderr,
|
||||
"%s: %s: Following pins are set for other functions too: %s\n",
|
||||
progname, avr_pin_name(pinname), pinmask_to_str(already_used));
|
||||
is_ok = false;
|
||||
}
|
||||
}
|
||||
if(!mandatory_used && is_mandatory && !invalid) {
|
||||
if(output) {
|
||||
fprintf(stderr,
|
||||
"%s: %s: Mandatory pin is not defined.\n",
|
||||
progname, avr_pin_name(pinname));
|
||||
}
|
||||
is_ok = false;
|
||||
}
|
||||
if(!is_ok) {
|
||||
rv = -1;
|
||||
} else if(output && verbose >= 3) {
|
||||
fprintf(stderr,
|
||||
"%s: %s: Pin is ok.\n",
|
||||
progname, avr_pin_name(pinname));
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns a string representation of defined pins eg. ~1,2,~4,~5,7
|
||||
* Another execution of this function will overwrite the previous result in the static buffer.
|
||||
*
|
||||
* @param[in] pindef the pin definition for which we want the string representation
|
||||
* @returns pointer to a static string.
|
||||
*/
|
||||
const char * pins_to_str(const struct pindef_t * const pindef) {
|
||||
static char buf[(PIN_MAX + 1) * 5]; // should be enough for PIN_MAX=255
|
||||
char *p = buf;
|
||||
int n;
|
||||
int pin;
|
||||
const char * fmt;
|
||||
|
||||
buf[0] = 0;
|
||||
for(pin = PIN_MIN; pin <= PIN_MAX; pin++) {
|
||||
int index = pin / PIN_FIELD_ELEMENT_SIZE;
|
||||
int bit = pin % PIN_FIELD_ELEMENT_SIZE;
|
||||
if(pindef->mask[index] & (1 << bit)) {
|
||||
if(pindef->inverse[index] & (1 << bit)) {
|
||||
fmt = (buf[0] == 0) ? "~%d" : ",~%d";
|
||||
} else {
|
||||
fmt = (buf[0] == 0) ? " %d" : ",%d";
|
||||
}
|
||||
n = sprintf(p, fmt, pin);
|
||||
p += n;
|
||||
}
|
||||
}
|
||||
|
||||
if(buf[0] == 0)
|
||||
return " (not used)";
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the pin as string.
|
||||
*
|
||||
* @param pinname the pinname which we want as string.
|
||||
* @returns a string with the pinname, or <unknown> if pinname is invalid.
|
||||
*/
|
||||
const char * avr_pin_name(int pinname) {
|
||||
switch(pinname) {
|
||||
case PPI_AVR_VCC : return "VCC";
|
||||
case PPI_AVR_BUFF : return "BUFF";
|
||||
case PIN_AVR_RESET : return "RESET";
|
||||
case PIN_AVR_SCK : return "SCK";
|
||||
case PIN_AVR_MOSI : return "MOSI";
|
||||
case PIN_AVR_MISO : return "MISO";
|
||||
case PIN_LED_ERR : return "ERRLED";
|
||||
case PIN_LED_RDY : return "RDYLED";
|
||||
case PIN_LED_PGM : return "PGMLED";
|
||||
case PIN_LED_VFY : return "VFYLED";
|
||||
default : return "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -21,27 +22,8 @@
|
||||
#ifndef __pindefs_h__
|
||||
#define __pindefs_h__
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
/* lets try to select at least 32 bits */
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
typedef uint32_t pinmask_t;
|
||||
#else
|
||||
#if UINT_MAX >= 0xFFFFFFFF
|
||||
typedef unsigned int pinmask_t;
|
||||
#else
|
||||
typedef unsigned long pinmask_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
enum {
|
||||
PPI_AVR_VCC = 1,
|
||||
PPI_AVR_VCC=1,
|
||||
PPI_AVR_BUFF,
|
||||
PIN_AVR_RESET,
|
||||
PIN_AVR_SCK,
|
||||
@@ -53,150 +35,10 @@ enum {
|
||||
PIN_LED_VFY,
|
||||
N_PINS
|
||||
};
|
||||
#define PIN_INVERSE 0x80 /* flag for inverted pin in serbb */
|
||||
#define PIN_MASK 0x7f
|
||||
|
||||
#define PIN_MASK (UINT_MAX>>1)
|
||||
#define PIN_INVERSE (~(PIN_MASK)) /* flag for inverted pin in serbb */
|
||||
#define PIN_MIN 0 /* smallest allowed pin number */
|
||||
#define PIN_MAX 31 /* largest allowed pin number */
|
||||
|
||||
#ifdef HAVE_LINUX_GPIO
|
||||
/* Embedded systems might have a lot more gpio than only 0-31 */
|
||||
#undef PIN_MAX
|
||||
#define PIN_MAX 255 /* largest allowed pin number */
|
||||
#endif
|
||||
|
||||
/** Number of pins in each element of the bitfield */
|
||||
#define PIN_FIELD_ELEMENT_SIZE (sizeof(pinmask_t) * 8)
|
||||
/** Numer of elements to store the complete bitfield of all pins */
|
||||
#define PIN_FIELD_SIZE ((PIN_MAX + PIN_FIELD_ELEMENT_SIZE)/PIN_FIELD_ELEMENT_SIZE)
|
||||
|
||||
/**
|
||||
* This sets the corresponding bits to 1 or 0, the inverse mask is used to invert the value in necessary.
|
||||
* It uses only the lowest element (index=0) of the bitfield, which should be enough for most
|
||||
* programmers.
|
||||
*
|
||||
* @param[in] x input value
|
||||
* @param[in] pgm the programmer whose pin definitions to use
|
||||
* @param[in] pinname the logical name of the pin (PIN_AVR_*, ...)
|
||||
* @param[in] level the logical level (level != 0 => 1, level == 0 => 0),
|
||||
* if the pin is defined as inverted the resulting bit is also inverted
|
||||
* @returns the input value with the relevant bits modified
|
||||
*/
|
||||
#define SET_BITS_0(x,pgm,pinname,level) (((x) & ~(pgm)->pin[pinname].mask[0]) \
|
||||
| (\
|
||||
(pgm)->pin[pinname].mask[0] & ( \
|
||||
(level) \
|
||||
?~((pgm)->pin[pinname].inverse[0]) \
|
||||
: ((pgm)->pin[pinname].inverse[0]) \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Check if the corresponding bit is set (returns != 0) or cleared.
|
||||
* The inverse mask is used, to invert the relevant bits.
|
||||
* If the pin definition contains multiple pins, then a single set pin leads to return value != 0.
|
||||
* Then you have to check the relevant bits of the returned value, if you need more information.
|
||||
* It uses only the lowest element (index=0) of the bitfield, which should be enough for most
|
||||
* programmers.
|
||||
*
|
||||
* @param[in] x input value
|
||||
* @param[in] pgm the programmer whose pin definitions to use
|
||||
* @param[in] pinname the logical name of the pin (PIN_AVR_*, ...)
|
||||
* @returns the input value with only the relevant bits (which are already inverted,
|
||||
* so you get always the logical level)
|
||||
*/
|
||||
#define GET_BITS_0(x,pgm,pinname) (((x) ^ (pgm)->pin[pinname].inverse[0]) & (pgm)->pin[pinname].mask[0])
|
||||
|
||||
/**
|
||||
* Data structure to hold used pins by logical function (PIN_AVR_*, ...)
|
||||
*/
|
||||
struct pindef_t {
|
||||
pinmask_t mask[PIN_FIELD_SIZE]; ///< bitfield of used pins
|
||||
pinmask_t inverse[PIN_FIELD_SIZE]; ///< bitfield of inverse/normal usage of used pins
|
||||
};
|
||||
|
||||
/**
|
||||
* Data structure to define a checklist of valid pins for each function.
|
||||
*/
|
||||
struct pin_checklist_t {
|
||||
int pinname; ///< logical pinname eg. PIN_AVR_SCK
|
||||
int mandatory; ///< is this a mandatory pin
|
||||
const struct pindef_t* valid_pins; ///< mask defines allowed pins, inverse define is they might be used inverted
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a pin in the pin definition as normal or inverse pin.
|
||||
*
|
||||
* @param[out] pindef pin definition to update
|
||||
* @param[in] pin number of pin [0..PIN_MAX]
|
||||
* @param[in] inverse inverse (true) or normal (false) pin
|
||||
*/
|
||||
void pin_set_value(struct pindef_t * const pindef, const int pin, const bool inverse);
|
||||
|
||||
/**
|
||||
* Clear all defined pins in pindef.
|
||||
*
|
||||
* @param[out] pindef pin definition to clear
|
||||
*/
|
||||
void pin_clear_all(struct pindef_t * const pindef);
|
||||
|
||||
struct programmer_t; /* forward declaration */
|
||||
|
||||
/**
|
||||
* Convert for given programmer new pin definitions to old pin definitions.
|
||||
*
|
||||
* @param[inout] pgm programmer whose pins shall be converted.
|
||||
*/
|
||||
void pgm_fill_old_pins(struct programmer_t * const pgm);
|
||||
|
||||
/**
|
||||
* This function checks all pin of pgm against the constraints given in the checklist.
|
||||
* It checks if
|
||||
* @li any invalid pins are used
|
||||
* @li valid pins are used inverted when not allowed
|
||||
* @li any pins are used by more than one function
|
||||
* @li any mandatory pin is not set all.
|
||||
*
|
||||
* In case of any error it report the wrong function and the pin numbers.
|
||||
* For verbose >= 2 it also reports the possible correct values.
|
||||
* For verbose >=3 it shows also which pins were ok.
|
||||
*
|
||||
* @param[in] pgm the programmer to check
|
||||
* @param[in] checklist the constraint for the pins
|
||||
* @param[in] size the number of entries in checklist
|
||||
* @param[in] output false suppresses error messages to the user
|
||||
* @returns 0 if all pin definitions are valid, -1 otherwise
|
||||
*/
|
||||
int pins_check(const struct programmer_t * const pgm, const struct pin_checklist_t * const checklist, const int size, const bool output);
|
||||
|
||||
/**
|
||||
* Returns the name of the pin as string.
|
||||
*
|
||||
* @param pinname the pinname which we want as string.
|
||||
* @returns a string with the pinname, or <unknown> if pinname is invalid.
|
||||
*/
|
||||
const char * avr_pin_name(int pinname);
|
||||
|
||||
/**
|
||||
* This function returns a string representation of defined pins eg. ~1,2,~4,~5,7
|
||||
* Another execution of this function will overwrite the previous result in the static buffer.
|
||||
*
|
||||
* @param[in] pindef the pin definition for which we want the string representation
|
||||
* @returns pointer to a static string.
|
||||
*/
|
||||
const char * pins_to_str(const struct pindef_t * const pindef);
|
||||
|
||||
/**
|
||||
* This function returns a string representation of pins in the mask eg. 1,3,5-7,9,12
|
||||
* Another execution of this function will overwrite the previous result in the static buffer.
|
||||
* Consecutive pin number are representated as start-end.
|
||||
*
|
||||
* @param[in] pinmask the pin mask for which we want the string representation
|
||||
* @returns pointer to a static string.
|
||||
*/
|
||||
const char * pinmask_to_str(const pinmask_t * const pinmask);
|
||||
|
||||
#define LED_ON(fd,pin) ppi_setpin(fd,pin,0)
|
||||
#define LED_OFF(fd,pin) ppi_setpin(fd,pin,1)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -32,28 +33,28 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
#if defined(__FreeBSD__)
|
||||
# include "freebsd_ppi.h"
|
||||
#elif defined(__linux__)
|
||||
# include "linux_ppdev.h"
|
||||
#elif defined(__sun__) || defined(__sun) /* Solaris */
|
||||
#elif defined(__sun__) && defined(__svr4__) /* Solaris */
|
||||
# include "solaris_ecpp.h"
|
||||
#endif
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "pindefs.h"
|
||||
#include "pgm.h"
|
||||
#include "ppi.h"
|
||||
|
||||
extern char * progname;
|
||||
|
||||
enum {
|
||||
PPI_READ,
|
||||
PPI_WRITE,
|
||||
PPI_SHADOWREAD
|
||||
};
|
||||
|
||||
static int ppi_shadow_access(union filedescriptor *fdp, int reg,
|
||||
unsigned char *v, unsigned char action)
|
||||
int ppi_shadow_access(int fd, int reg, unsigned char *v, unsigned char action)
|
||||
{
|
||||
static unsigned char shadow[3];
|
||||
int shadow_num;
|
||||
@@ -80,12 +81,12 @@ static int ppi_shadow_access(union filedescriptor *fdp, int reg,
|
||||
*v = shadow[shadow_num];
|
||||
break;
|
||||
case PPI_READ:
|
||||
DO_PPI_READ(fdp->ifd, reg, v);
|
||||
DO_PPI_READ(fd, reg, v);
|
||||
shadow[shadow_num]=*v;
|
||||
break;
|
||||
case PPI_WRITE:
|
||||
shadow[shadow_num]=*v;
|
||||
DO_PPI_WRITE(fdp->ifd, reg, v);
|
||||
DO_PPI_WRITE(fd, reg, v);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@@ -94,14 +95,14 @@ static int ppi_shadow_access(union filedescriptor *fdp, int reg,
|
||||
/*
|
||||
* set the indicated bit of the specified register.
|
||||
*/
|
||||
int ppi_set(union filedescriptor *fdp, int reg, int bit)
|
||||
int ppi_set(int fd, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
int rc;
|
||||
|
||||
rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
|
||||
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
|
||||
v |= bit;
|
||||
rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
|
||||
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
|
||||
|
||||
if (rc)
|
||||
return -1;
|
||||
@@ -113,14 +114,14 @@ int ppi_set(union filedescriptor *fdp, int reg, int bit)
|
||||
/*
|
||||
* clear the indicated bit of the specified register.
|
||||
*/
|
||||
int ppi_clr(union filedescriptor *fdp, int reg, int bit)
|
||||
int ppi_clr(int fd, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
int rc;
|
||||
|
||||
rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
|
||||
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
|
||||
v &= ~bit;
|
||||
rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
|
||||
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
|
||||
|
||||
if (rc)
|
||||
return -1;
|
||||
@@ -132,12 +133,12 @@ int ppi_clr(union filedescriptor *fdp, int reg, int bit)
|
||||
/*
|
||||
* get the indicated bit of the specified register.
|
||||
*/
|
||||
int ppi_get(union filedescriptor *fdp, int reg, int bit)
|
||||
int ppi_get(int fd, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
int rc;
|
||||
|
||||
rc = ppi_shadow_access(fdp, reg, &v, PPI_READ);
|
||||
rc = ppi_shadow_access(fd, reg, &v, PPI_READ);
|
||||
v &= bit;
|
||||
|
||||
if (rc)
|
||||
@@ -149,14 +150,14 @@ int ppi_get(union filedescriptor *fdp, int reg, int bit)
|
||||
/*
|
||||
* toggle the indicated bit of the specified register.
|
||||
*/
|
||||
int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
|
||||
int ppi_toggle(int fd, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
int rc;
|
||||
|
||||
rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
|
||||
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
|
||||
v ^= bit;
|
||||
rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
|
||||
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
|
||||
|
||||
if (rc)
|
||||
return -1;
|
||||
@@ -168,12 +169,12 @@ int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
|
||||
/*
|
||||
* get all bits of the specified register.
|
||||
*/
|
||||
int ppi_getall(union filedescriptor *fdp, int reg)
|
||||
int ppi_getall(int fd, int reg)
|
||||
{
|
||||
unsigned char v;
|
||||
int rc;
|
||||
|
||||
rc = ppi_shadow_access(fdp, reg, &v, PPI_READ);
|
||||
rc = ppi_shadow_access(fd, reg, &v, PPI_READ);
|
||||
|
||||
if (rc)
|
||||
return -1;
|
||||
@@ -184,13 +185,13 @@ int ppi_getall(union filedescriptor *fdp, int reg)
|
||||
/*
|
||||
* set all bits of the specified register to val.
|
||||
*/
|
||||
int ppi_setall(union filedescriptor *fdp, int reg, int val)
|
||||
int ppi_setall(int fd, int reg, int val)
|
||||
{
|
||||
unsigned char v;
|
||||
int rc;
|
||||
|
||||
v = val;
|
||||
rc = ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
|
||||
rc = ppi_shadow_access(fd, reg, &v, PPI_WRITE);
|
||||
|
||||
if (rc)
|
||||
return -1;
|
||||
@@ -199,7 +200,7 @@ int ppi_setall(union filedescriptor *fdp, int reg, int val)
|
||||
}
|
||||
|
||||
|
||||
void ppi_open(char * port, union filedescriptor *fdp)
|
||||
int ppi_open(char * port)
|
||||
{
|
||||
int fd;
|
||||
unsigned char v;
|
||||
@@ -208,8 +209,7 @@ void ppi_open(char * port, union filedescriptor *fdp)
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "%s: can't open device \"%s\": %s\n",
|
||||
progname, port, strerror(errno));
|
||||
fdp->ifd = -1;
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ppi_claim (fd);
|
||||
@@ -218,18 +218,18 @@ void ppi_open(char * port, union filedescriptor *fdp)
|
||||
* Initialize shadow registers
|
||||
*/
|
||||
|
||||
ppi_shadow_access (fdp, PPIDATA, &v, PPI_READ);
|
||||
ppi_shadow_access (fdp, PPICTRL, &v, PPI_READ);
|
||||
ppi_shadow_access (fdp, PPISTATUS, &v, PPI_READ);
|
||||
ppi_shadow_access (fd, PPIDATA, &v, PPI_READ);
|
||||
ppi_shadow_access (fd, PPICTRL, &v, PPI_READ);
|
||||
ppi_shadow_access (fd, PPISTATUS, &v, PPI_READ);
|
||||
|
||||
fdp->ifd = fd;
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
void ppi_close(union filedescriptor *fdp)
|
||||
void ppi_close(int fd)
|
||||
{
|
||||
ppi_release (fdp->ifd);
|
||||
close(fdp->ifd);
|
||||
ppi_release (fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
#endif /* HAVE_PARPORT */
|
||||
|
||||
@@ -13,13 +13,14 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* 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 ppi_h
|
||||
#define ppi_h
|
||||
#ifndef __ppi_h__
|
||||
#define __ppi_h__
|
||||
|
||||
/*
|
||||
* PPI registers
|
||||
@@ -30,29 +31,23 @@ enum {
|
||||
PPISTATUS
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int ppi_get (union filedescriptor *fdp, int reg, int bit);
|
||||
|
||||
int ppi_set (union filedescriptor *fdp, int reg, int bit);
|
||||
int ppi_get (int fd, int reg, int bit);
|
||||
|
||||
int ppi_clr (union filedescriptor *fdp, int reg, int bit);
|
||||
int ppi_set (int fd, int reg, int bit);
|
||||
|
||||
int ppi_getall (union filedescriptor *fdp, int reg);
|
||||
int ppi_clr (int fd, int reg, int bit);
|
||||
|
||||
int ppi_setall (union filedescriptor *fdp, int reg, int val);
|
||||
int ppi_getall (int fd, int reg);
|
||||
|
||||
int ppi_toggle (union filedescriptor *fdp, int reg, int bit);
|
||||
int ppi_setall (int fd, int reg, int val);
|
||||
|
||||
void ppi_open (char * port, union filedescriptor *fdp);
|
||||
int ppi_toggle (int fd, int reg, int bit);
|
||||
|
||||
void ppi_close (union filedescriptor *fdp);
|
||||
int ppi_open (char * port);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
void ppi_close (int fd);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003, 2004, 2006
|
||||
* Eric B. Weddington <eweddington@cso.atmel.com>
|
||||
* Copyright 2008, Joerg Wunsch
|
||||
* Copyright (C) 2003, 2004 Eric B. Weddington <ericw@evcohs.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
|
||||
@@ -15,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -30,8 +29,7 @@ reg = register as defined in an enum in ppi.h. This must be converted
|
||||
*/
|
||||
|
||||
|
||||
#include "ac_cfg.h"
|
||||
#include "avrdude.h"
|
||||
|
||||
|
||||
#if defined (WIN32NATIVE)
|
||||
|
||||
@@ -44,10 +42,12 @@ reg = register as defined in an enum in ppi.h. This must be converted
|
||||
#include <windows.h>
|
||||
#include <sys/time.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "serial.h"
|
||||
#include "ppi.h"
|
||||
|
||||
extern char *progname;
|
||||
|
||||
|
||||
|
||||
#define DEVICE_LPT1 "lpt1"
|
||||
#define DEVICE_LPT2 "lpt2"
|
||||
#define DEVICE_LPT3 "lpt3"
|
||||
@@ -73,7 +73,7 @@ static const winpp winports[DEVICE_MAX] =
|
||||
|
||||
/* FUNCTION PROTOTYPES */
|
||||
static int winnt_pp_open(void);
|
||||
static unsigned short port_get(union filedescriptor *fdp, int reg);
|
||||
static unsigned short port_get(int fd, int reg);
|
||||
static unsigned char reg2offset(int reg);
|
||||
static unsigned char inb(unsigned short port);
|
||||
static void outb(unsigned char value, unsigned short port);
|
||||
@@ -82,7 +82,7 @@ static void outb(unsigned char value, unsigned short port);
|
||||
|
||||
/* FUNCTION DEFINITIONS */
|
||||
|
||||
void ppi_open(char *port, union filedescriptor *fdp)
|
||||
int ppi_open(char *port)
|
||||
{
|
||||
unsigned char i;
|
||||
int fd;
|
||||
@@ -92,8 +92,7 @@ void ppi_open(char *port, union filedescriptor *fdp)
|
||||
if(fd < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: can't open device \"giveio\"\n\n", progname);
|
||||
fdp->ifd = -1;
|
||||
return;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Search the windows port names for a match */
|
||||
@@ -107,32 +106,13 @@ void ppi_open(char *port, union filedescriptor *fdp)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(fd == -1)
|
||||
{
|
||||
/*
|
||||
* Supplied port name did not match any of the pre-defined
|
||||
* names. Try interpreting it as a numeric
|
||||
* (hexadecimal/decimal/octal) address.
|
||||
*/
|
||||
char *cp;
|
||||
|
||||
fd = strtol(port, &cp, 0);
|
||||
if(*port == '\0' || *cp != '\0')
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: port name \"%s\" is neither lpt1/2/3 nor valid number\n",
|
||||
progname, port);
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
if(fd < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: can't open device \"%s\"\n\n", progname, port);
|
||||
fdp->ifd = -1;
|
||||
return;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
fdp->ifd = fd;
|
||||
return(fd);
|
||||
}
|
||||
|
||||
|
||||
@@ -177,7 +157,7 @@ static int winnt_pp_open(void)
|
||||
|
||||
|
||||
|
||||
void ppi_close(union filedescriptor *fdp)
|
||||
void ppi_close(int fd)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -187,12 +167,12 @@ void ppi_close(union filedescriptor *fdp)
|
||||
/*
|
||||
* set the indicated bit of the specified register.
|
||||
*/
|
||||
int ppi_set(union filedescriptor *fdp, int reg, int bit)
|
||||
int ppi_set(int fd, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned short port;
|
||||
|
||||
port = port_get(fdp, reg);
|
||||
port = port_get(fd, reg);
|
||||
v = inb(port);
|
||||
v |= bit;
|
||||
outb(v, port);
|
||||
@@ -203,12 +183,12 @@ int ppi_set(union filedescriptor *fdp, int reg, int bit)
|
||||
/*
|
||||
* clear the indicated bit of the specified register.
|
||||
*/
|
||||
int ppi_clr(union filedescriptor *fdp, int reg, int bit)
|
||||
int ppi_clr(int fd, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned short port;
|
||||
|
||||
port = port_get(fdp, reg);
|
||||
port = port_get(fd, reg);
|
||||
v = inb(port);
|
||||
v &= ~bit;
|
||||
outb(v, port);
|
||||
@@ -220,11 +200,11 @@ int ppi_clr(union filedescriptor *fdp, int reg, int bit)
|
||||
/*
|
||||
* get the indicated bit of the specified register.
|
||||
*/
|
||||
int ppi_get(union filedescriptor *fdp, int reg, int bit)
|
||||
int ppi_get(int fd, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
|
||||
v = inb(port_get(fdp, reg));
|
||||
v = inb(port_get(fd, reg));
|
||||
v &= bit;
|
||||
|
||||
return(v);
|
||||
@@ -236,12 +216,12 @@ int ppi_get(union filedescriptor *fdp, int reg, int bit)
|
||||
/*
|
||||
* toggle the indicated bit of the specified register.
|
||||
*/
|
||||
int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
|
||||
int ppi_toggle(int fd, int reg, int bit)
|
||||
{
|
||||
unsigned char v;
|
||||
unsigned short port;
|
||||
|
||||
port = port_get(fdp, reg);
|
||||
port = port_get(fd, reg);
|
||||
|
||||
v = inb(port);
|
||||
v ^= bit;
|
||||
@@ -254,11 +234,11 @@ int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
|
||||
/*
|
||||
* get all bits of the specified register.
|
||||
*/
|
||||
int ppi_getall(union filedescriptor *fdp, int reg)
|
||||
int ppi_getall(int fd, int reg)
|
||||
{
|
||||
unsigned char v;
|
||||
|
||||
v = inb(port_get(fdp, reg));
|
||||
v = inb(port_get(fd, reg));
|
||||
|
||||
return((int)v);
|
||||
}
|
||||
@@ -269,9 +249,9 @@ int ppi_getall(union filedescriptor *fdp, int reg)
|
||||
/*
|
||||
* set all bits of the specified register to val.
|
||||
*/
|
||||
int ppi_setall(union filedescriptor *fdp, int reg, int val)
|
||||
int ppi_setall(int fd, int reg, int val)
|
||||
{
|
||||
outb((unsigned char)val, port_get(fdp, reg));
|
||||
outb((unsigned char)val, port_get(fd, reg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -279,9 +259,9 @@ int ppi_setall(union filedescriptor *fdp, int reg, int val)
|
||||
|
||||
|
||||
/* Calculate port address to access. */
|
||||
static unsigned short port_get(union filedescriptor *fdp, int reg)
|
||||
static unsigned short port_get(int fd, int reg)
|
||||
{
|
||||
return((unsigned short)(fdp->ifd + reg2offset(reg)));
|
||||
return((unsigned short)(fd + reg2offset(reg)));
|
||||
}
|
||||
|
||||
|
||||
@@ -336,9 +316,7 @@ static void outb(unsigned char value, unsigned short port)
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(HAVE_GETTIMEOFDAY)
|
||||
struct timezone;
|
||||
int gettimeofday(struct timeval *tv, struct timezone *unused){
|
||||
void gettimeofday(struct timeval*tv, void*z){
|
||||
// i've found only ms resolution, avrdude expects us
|
||||
|
||||
SYSTEMTIME st;
|
||||
@@ -346,10 +324,7 @@ int gettimeofday(struct timeval *tv, struct timezone *unused){
|
||||
|
||||
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
|
||||
|
||||
@@ -373,8 +348,7 @@ int gettimeofday(struct timeval *tv, struct timezone *unused){
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_USLEEP)
|
||||
int usleep(unsigned int us)
|
||||
void usleep(unsigned long us)
|
||||
{
|
||||
int has_highperf;
|
||||
LARGE_INTEGER freq,start,stop,loopend;
|
||||
@@ -384,7 +358,7 @@ int usleep(unsigned int us)
|
||||
// verify - increasing the delay helps sometimes but not
|
||||
// realiably. There must be some other problem. Maybe just
|
||||
// with my test-hardware maybe in the code-base.
|
||||
//// us=(unsigned long) (us*1.5);
|
||||
//// us=(unsigned long) (us*1.5);
|
||||
|
||||
has_highperf=QueryPerformanceFrequency(&freq);
|
||||
|
||||
@@ -393,7 +367,7 @@ int usleep(unsigned int us)
|
||||
if (has_highperf) {
|
||||
QueryPerformanceCounter(&start);
|
||||
loopend.QuadPart=start.QuadPart+freq.QuadPart*us/(1000*1000);
|
||||
do {
|
||||
do {
|
||||
QueryPerformanceCounter(&stop);
|
||||
} while (stop.QuadPart<=loopend.QuadPart);
|
||||
}
|
||||
@@ -405,12 +379,9 @@ int usleep(unsigned int us)
|
||||
|
||||
DEBUG_QueryPerformanceCounter(&stop);
|
||||
}
|
||||
|
||||
|
||||
DEBUG_DisplayTimingInfo(start, stop, freq, us, has_highperf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* !HAVE_USLEEP */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* avrdude is Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||
*
|
||||
* This file: Copyright (C) 2005-2007 Colin O'Flynn <coflynn@newae.com>
|
||||
* This file: Copyright (C) 2005 Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -15,19 +15,21 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ac_cfg.h"
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "pgm.h"
|
||||
#include "safemode.h"
|
||||
|
||||
/* This value from ac_cfg.h */
|
||||
char * progname = PACKAGE_NAME;
|
||||
|
||||
/*
|
||||
* Writes the specified fuse in fusename (can be "lfuse", "hfuse", or
|
||||
* "efuse") and verifies it. Will try up to tries amount of times
|
||||
@@ -47,14 +49,8 @@ int safemode_writefuse (unsigned char fuse, char * fusename, PROGRAMMER * pgm,
|
||||
|
||||
/* Keep trying to write then read back the fuse values */
|
||||
while (tries > 0) {
|
||||
if (avr_write_byte(pgm, p, m, 0, fuse) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (pgm->read_byte(pgm, p, m, 0, &fuseread) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
avr_write_byte(pgm, p, m, 0, fuse);
|
||||
avr_read_byte(pgm, p, m, 0, &fuseread);
|
||||
|
||||
/* Report information to user if needed */
|
||||
if (verbose > 0) {
|
||||
@@ -85,7 +81,6 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
|
||||
|
||||
unsigned char value;
|
||||
unsigned char fusegood = 0;
|
||||
unsigned char allowfuseread = 1;
|
||||
unsigned char safemode_lfuse;
|
||||
unsigned char safemode_hfuse;
|
||||
unsigned char safemode_efuse;
|
||||
@@ -104,43 +99,15 @@ 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 */
|
||||
if(pgm->read_byte(pgm, p, m, 0, &safemode_fuse) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%s: safemode read 1, fuse value: %x\n",progname, safemode_fuse);
|
||||
}
|
||||
if(pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%s: safemode read 2, fuse value: %x\n",progname, value);
|
||||
}
|
||||
avr_read_byte(pgm, p, m, 0, &safemode_fuse);
|
||||
avr_read_byte(pgm, p, m, 0, &value);
|
||||
if (value == safemode_fuse) {
|
||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%s: safemode read 3, fuse value: %x\n",progname, value);
|
||||
}
|
||||
if (value == safemode_fuse)
|
||||
{
|
||||
fusegood = 1; /* Fuse read OK three times */
|
||||
}
|
||||
avr_read_byte(pgm, p, m, 0, &value);
|
||||
if (value == safemode_fuse){
|
||||
fusegood = 1; /* Fuse read OK three times */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Programmer does not allow fuse reading.... no point trying anymore
|
||||
if (allowfuseread == 0)
|
||||
{
|
||||
return -5;
|
||||
}
|
||||
}
|
||||
|
||||
if (fusegood == 0) {
|
||||
fprintf(stderr,
|
||||
@@ -149,7 +116,7 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
|
||||
return -1;
|
||||
}
|
||||
else if ((fusegood == 1) && (verbose > 0)) {
|
||||
fprintf(stderr, "%s: safemode: fuse reads as %X\n", progname, safemode_fuse);
|
||||
printf("%s: safemode: fuse reads as %X\n", progname, safemode_fuse);
|
||||
}
|
||||
|
||||
|
||||
@@ -159,44 +126,16 @@ 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 */
|
||||
if (pgm->read_byte(pgm, p, m, 0, &safemode_lfuse) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%s: safemode read 1, lfuse value: %x\n",progname, safemode_lfuse);
|
||||
}
|
||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%s: safemode read 2, lfuse value: %x\n",progname, value);
|
||||
}
|
||||
avr_read_byte(pgm, p, m, 0, &safemode_lfuse);
|
||||
avr_read_byte(pgm, p, m, 0, &value);
|
||||
if (value == safemode_lfuse) {
|
||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%s: safemode read 3, lfuse value: %x\n",progname, value);
|
||||
}
|
||||
avr_read_byte(pgm, p, m, 0, &value);
|
||||
if (value == safemode_lfuse){
|
||||
fusegood = 1; /* Fuse read OK three times */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Programmer does not allow fuse reading.... no point trying anymore
|
||||
if (allowfuseread == 0)
|
||||
{
|
||||
return -5;
|
||||
}
|
||||
|
||||
|
||||
if (fusegood == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: safemode: Verify error - unable to read lfuse properly. "
|
||||
@@ -204,7 +143,7 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
|
||||
return -1;
|
||||
}
|
||||
else if ((fusegood == 1) && (verbose > 0)) {
|
||||
fprintf(stderr, "%s: safemode: lfuse reads as %X\n", progname, safemode_lfuse);
|
||||
printf("%s: safemode: lfuse reads as %X\n", progname, safemode_lfuse);
|
||||
}
|
||||
|
||||
/* Read hfuse three times */
|
||||
@@ -213,43 +152,16 @@ 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 */
|
||||
if (pgm->read_byte(pgm, p, m, 0, &safemode_hfuse) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%s: safemode read 1, hfuse value: %x\n",progname, safemode_hfuse);
|
||||
}
|
||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%s: safemode read 2, hfuse value: %x\n",progname, value);
|
||||
}
|
||||
avr_read_byte(pgm, p, m, 0, &safemode_hfuse);
|
||||
avr_read_byte(pgm, p, m, 0, &value);
|
||||
if (value == safemode_hfuse) {
|
||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%s: safemode read 3, hfuse value: %x\n",progname, value);
|
||||
}
|
||||
avr_read_byte(pgm, p, m, 0, &value);
|
||||
if (value == safemode_hfuse){
|
||||
fusegood = 1; /* Fuse read OK three times */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Programmer does not allow fuse reading.... no point trying anymore
|
||||
if (allowfuseread == 0)
|
||||
{
|
||||
return -5;
|
||||
}
|
||||
|
||||
if (fusegood == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: safemode: Verify error - unable to read hfuse properly. "
|
||||
@@ -257,7 +169,7 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
|
||||
return -2;
|
||||
}
|
||||
else if ((fusegood == 1) && (verbose > 0)){
|
||||
fprintf(stderr, "%s: safemode: hfuse reads as %X\n", progname, safemode_hfuse);
|
||||
printf("%s: safemode: hfuse reads as %X\n", progname, safemode_hfuse);
|
||||
}
|
||||
|
||||
/* Read efuse three times */
|
||||
@@ -266,43 +178,16 @@ 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 */
|
||||
if (pgm->read_byte(pgm, p, m, 0, &safemode_efuse) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%s: safemode read 1, efuse value: %x\n",progname, safemode_efuse);
|
||||
}
|
||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%s: safemode read 2, efuse value: %x\n",progname, value);
|
||||
}
|
||||
avr_read_byte(pgm, p, m, 0, &safemode_efuse);
|
||||
avr_read_byte(pgm, p, m, 0, &value);
|
||||
if (value == safemode_efuse) {
|
||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
if (verbose > 2)
|
||||
{
|
||||
fprintf(stderr, "%s: safemode read 3, efuse value: %x\n",progname, value);
|
||||
}
|
||||
avr_read_byte(pgm, p, m, 0, &value);
|
||||
if (value == safemode_efuse){
|
||||
fusegood = 1; /* Fuse read OK three times */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Programmer does not allow fuse reading.... no point trying anymore
|
||||
if (allowfuseread == 0)
|
||||
{
|
||||
return -5;
|
||||
}
|
||||
|
||||
|
||||
if (fusegood == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: safemode: Verify error - unable to read efuse properly. "
|
||||
@@ -310,7 +195,7 @@ int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
|
||||
return -3;
|
||||
}
|
||||
else if ((fusegood == 1) && (verbose > 0)) {
|
||||
fprintf(stderr, "%s: safemode: efuse reads as %X\n", progname, safemode_efuse);
|
||||
printf("%s: safemode: efuse reads as %X\n", progname, safemode_efuse);
|
||||
}
|
||||
|
||||
*lfuse = safemode_lfuse;
|
||||
|
||||
@@ -15,17 +15,14 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef safemode_h
|
||||
#define safemode_h
|
||||
#ifndef __safemode_h__
|
||||
#define __safemode_h__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Writes the specified fuse in fusename (can be "lfuse", "hfuse", or "efuse") and verifies it. Will try up to tries
|
||||
amount of times before giving up */
|
||||
int safemode_writefuse (unsigned char fuse, char * fusename, PROGRAMMER * pgm, AVRPART * p, int tries, int verbose);
|
||||
@@ -39,8 +36,4 @@ pointed to be lfuse, hfuse, and efuse. This allows you to change the fuse bits i
|
||||
if user requests fuse bits are changed, the requested value is now verified */
|
||||
int safemode_memfuses (int save, unsigned char * lfuse, unsigned char * hfuse, unsigned char * efuse, unsigned char * fuse);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* safemode_h */
|
||||
#endif //__safemode_h
|
||||
|
||||
@@ -1,664 +0,0 @@
|
||||
/*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $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 <stdlib.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "serial.h"
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/* Numeric constants for 'reportType' parameters */
|
||||
#define USB_HID_REPORT_TYPE_INPUT 1
|
||||
#define USB_HID_REPORT_TYPE_OUTPUT 2
|
||||
#define USB_HID_REPORT_TYPE_FEATURE 3
|
||||
|
||||
/* These are the error codes which can be returned by functions of this
|
||||
* module.
|
||||
*/
|
||||
#define USB_ERROR_NONE 0
|
||||
#define USB_ERROR_ACCESS 1
|
||||
#define USB_ERROR_NOTFOUND 2
|
||||
#define USB_ERROR_BUSY 16
|
||||
#define USB_ERROR_IO 5
|
||||
|
||||
#define USB_VENDOR_ID 0x16c0
|
||||
#define USB_PRODUCT_ID 0x05df
|
||||
|
||||
static int reportDataSizes[4] = {13, 29, 61, 125};
|
||||
|
||||
static unsigned char avrdoperRxBuffer[280]; /* buffer for receive data */
|
||||
static int avrdoperRxLength = 0; /* amount of valid bytes in rx buffer */
|
||||
static int avrdoperRxPosition = 0; /* amount of bytes already consumed in rx buffer */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#if defined(WIN32NATIVE) && defined(HAVE_LIBHID)
|
||||
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
|
||||
#if defined(HAVE_DDK_HIDSDI_H)
|
||||
# include <ddk/hidsdi.h>
|
||||
#else
|
||||
# include "my_ddk_hidsdi.h"
|
||||
#endif
|
||||
#include <ddk/hidpi.h>
|
||||
|
||||
#ifdef USB_DEBUG
|
||||
#define DEBUG_PRINT(arg) printf arg
|
||||
#else
|
||||
#define DEBUG_PRINT(arg)
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static void convertUniToAscii(char *buffer)
|
||||
{
|
||||
unsigned short *uni = (void *)buffer;
|
||||
char *ascii = buffer;
|
||||
|
||||
while(*uni != 0){
|
||||
if(*uni >= 256){
|
||||
*ascii++ = '?';
|
||||
uni++;
|
||||
}else{
|
||||
*ascii++ = *uni++;
|
||||
}
|
||||
}
|
||||
*ascii++ = 0;
|
||||
}
|
||||
|
||||
static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
|
||||
int product, char *productName, int usesReportIDs)
|
||||
{
|
||||
GUID hidGuid; /* GUID for HID driver */
|
||||
HDEVINFO deviceInfoList;
|
||||
SP_DEVICE_INTERFACE_DATA deviceInfo;
|
||||
SP_DEVICE_INTERFACE_DETAIL_DATA *deviceDetails = NULL;
|
||||
DWORD size;
|
||||
int i, openFlag = 0; /* may be FILE_FLAG_OVERLAPPED */
|
||||
int errorCode = USB_ERROR_NOTFOUND;
|
||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||
HIDD_ATTRIBUTES deviceAttributes;
|
||||
|
||||
HidD_GetHidGuid(&hidGuid);
|
||||
deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL,
|
||||
DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
|
||||
deviceInfo.cbSize = sizeof(deviceInfo);
|
||||
for(i=0;;i++){
|
||||
if(handle != INVALID_HANDLE_VALUE){
|
||||
CloseHandle(handle);
|
||||
handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
if(!SetupDiEnumDeviceInterfaces(deviceInfoList, 0, &hidGuid, i, &deviceInfo))
|
||||
break; /* no more entries */
|
||||
/* first do a dummy call just to determine the actual size required */
|
||||
SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL);
|
||||
if(deviceDetails != NULL)
|
||||
free(deviceDetails);
|
||||
deviceDetails = malloc(size);
|
||||
deviceDetails->cbSize = sizeof(*deviceDetails);
|
||||
/* this call is for real: */
|
||||
SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails,
|
||||
size, &size, NULL);
|
||||
DEBUG_PRINT(("checking HID path \"%s\"\n", deviceDetails->DevicePath));
|
||||
/* attempt opening for R/W -- we don't care about devices which can't be accessed */
|
||||
handle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
|
||||
openFlag, NULL);
|
||||
if(handle == INVALID_HANDLE_VALUE){
|
||||
DEBUG_PRINT(("opening failed: %d\n", (int)GetLastError()));
|
||||
/* errorCode = USB_ERROR_ACCESS; opening will always fail for mouse -- ignore */
|
||||
continue;
|
||||
}
|
||||
deviceAttributes.Size = sizeof(deviceAttributes);
|
||||
HidD_GetAttributes(handle, &deviceAttributes);
|
||||
DEBUG_PRINT(("device attributes: vid=%d pid=%d\n",
|
||||
deviceAttributes.VendorID, deviceAttributes.ProductID));
|
||||
if(deviceAttributes.VendorID != vendor || deviceAttributes.ProductID != product)
|
||||
continue; /* ignore this device */
|
||||
errorCode = USB_ERROR_NOTFOUND;
|
||||
if(vendorName != NULL && productName != NULL){
|
||||
char buffer[512];
|
||||
if(!HidD_GetManufacturerString(handle, buffer, sizeof(buffer))){
|
||||
DEBUG_PRINT(("error obtaining vendor name\n"));
|
||||
errorCode = USB_ERROR_IO;
|
||||
continue;
|
||||
}
|
||||
convertUniToAscii(buffer);
|
||||
DEBUG_PRINT(("vendorName = \"%s\"\n", buffer));
|
||||
if(strcmp(vendorName, buffer) != 0)
|
||||
continue;
|
||||
if(!HidD_GetProductString(handle, buffer, sizeof(buffer))){
|
||||
DEBUG_PRINT(("error obtaining product name\n"));
|
||||
errorCode = USB_ERROR_IO;
|
||||
continue;
|
||||
}
|
||||
convertUniToAscii(buffer);
|
||||
DEBUG_PRINT(("productName = \"%s\"\n", buffer));
|
||||
if(strcmp(productName, buffer) != 0)
|
||||
continue;
|
||||
}
|
||||
break; /* we have found the device we are looking for! */
|
||||
}
|
||||
SetupDiDestroyDeviceInfoList(deviceInfoList);
|
||||
if(deviceDetails != NULL)
|
||||
free(deviceDetails);
|
||||
if(handle != INVALID_HANDLE_VALUE){
|
||||
fdp->pfd = (void *)handle;
|
||||
errorCode = 0;
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static void usbCloseDevice(union filedescriptor *fdp)
|
||||
{
|
||||
CloseHandle((HANDLE)fdp->pfd);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static int usbSetReport(union filedescriptor *fdp, int reportType, char *buffer, int len)
|
||||
{
|
||||
HANDLE handle = (HANDLE)fdp->pfd;
|
||||
BOOLEAN rval = 0;
|
||||
DWORD bytesWritten;
|
||||
|
||||
switch(reportType){
|
||||
case USB_HID_REPORT_TYPE_INPUT:
|
||||
break;
|
||||
case USB_HID_REPORT_TYPE_OUTPUT:
|
||||
rval = WriteFile(handle, buffer, len, &bytesWritten, NULL);
|
||||
break;
|
||||
case USB_HID_REPORT_TYPE_FEATURE:
|
||||
rval = HidD_SetFeature(handle, buffer, len);
|
||||
break;
|
||||
}
|
||||
return rval == 0 ? USB_ERROR_IO : 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNumber,
|
||||
char *buffer, int *len)
|
||||
{
|
||||
HANDLE handle = (HANDLE)fdp->pfd;
|
||||
BOOLEAN rval = 0;
|
||||
DWORD bytesRead;
|
||||
|
||||
switch(reportType){
|
||||
case USB_HID_REPORT_TYPE_INPUT:
|
||||
buffer[0] = reportNumber;
|
||||
rval = ReadFile(handle, buffer, *len, &bytesRead, NULL);
|
||||
if(rval)
|
||||
*len = bytesRead;
|
||||
break;
|
||||
case USB_HID_REPORT_TYPE_OUTPUT:
|
||||
break;
|
||||
case USB_HID_REPORT_TYPE_FEATURE:
|
||||
buffer[0] = reportNumber;
|
||||
rval = HidD_GetFeature(handle, buffer, *len);
|
||||
break;
|
||||
}
|
||||
return rval == 0 ? USB_ERROR_IO : 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#else /* !(WIN32NATIVE && HAVE_LIBHID) */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#if defined(HAVE_USB_H)
|
||||
# include <usb.h>
|
||||
#elif defined(HAVE_LUSB0_USB_H)
|
||||
# include <lusb0_usb.h>
|
||||
#else
|
||||
# error "libusb needs either <usb.h> or <lusb0_usb.h>"
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#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 int 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);
|
||||
//return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int avrdoper_set_dtr_rts(union filedescriptor *fdp, int is_on)
|
||||
{
|
||||
fprintf(stderr, "%s: AVR-Doper doesn't support DTR/RTS setting\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
struct serial_device avrdoper_serdev =
|
||||
{
|
||||
.open = avrdoper_open,
|
||||
.close = avrdoper_close,
|
||||
.send = avrdoper_send,
|
||||
.recv = avrdoper_recv,
|
||||
.drain = avrdoper_drain,
|
||||
.set_dtr_rts = avrdoper_set_dtr_rts,
|
||||
.flags = SERDEV_FL_NONE,
|
||||
};
|
||||
|
||||
#endif /* defined(HAVE_LIBUSB) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID)) */
|
||||
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
@@ -14,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -31,20 +31,18 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "serial.h"
|
||||
|
||||
extern char *progname;
|
||||
extern int verbose;
|
||||
|
||||
long serial_recv_timeout = 5000; /* ms */
|
||||
|
||||
struct baud_mapping {
|
||||
@@ -61,21 +59,12 @@ static struct baud_mapping baud_lookup_table [] = {
|
||||
{ 9600, B9600 },
|
||||
{ 19200, B19200 },
|
||||
{ 38400, B38400 },
|
||||
#ifdef B57600
|
||||
{ 57600, B57600 },
|
||||
#endif
|
||||
#ifdef B115200
|
||||
{ 115200, B115200 },
|
||||
#endif
|
||||
#ifdef B230400
|
||||
{ 230400, B230400 },
|
||||
#endif
|
||||
{ 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;
|
||||
@@ -86,234 +75,103 @@ static speed_t serial_baud_lookup(long baud)
|
||||
map++;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a non-standard BAUD rate is used, issue
|
||||
* a warning (if we are verbose) and return the raw rate
|
||||
*/
|
||||
if (verbose > 0)
|
||||
fprintf(stderr, "%s: serial_baud_lookup(): Using non-standard baud rate: %ld",
|
||||
progname, baud);
|
||||
|
||||
return baud;
|
||||
fprintf(stderr, "%s: serial_baud_lookup(): unknown baud rate: %ld",
|
||||
progname, baud);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int ser_setspeed(union filedescriptor *fd, long baud)
|
||||
static int ser_setspeed(int fd, long baud)
|
||||
{
|
||||
int rc;
|
||||
struct termios termios;
|
||||
speed_t speed = serial_baud_lookup (baud);
|
||||
|
||||
if (!isatty(fd->ifd))
|
||||
return -ENOTTY;
|
||||
if (!isatty(fd))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* initialize terminal modes
|
||||
*/
|
||||
rc = tcgetattr(fd->ifd, &termios);
|
||||
rc = tcgetattr(fd, &termios);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: ser_setspeed(): tcgetattr() failed",
|
||||
progname);
|
||||
fprintf(stderr, "%s: ser_setspeed(): tcgetattr() failed, %s",
|
||||
progname, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy termios for ser_close if we haven't already
|
||||
*/
|
||||
if (! saved_original_termios++) {
|
||||
original_termios = termios;
|
||||
}
|
||||
|
||||
termios.c_iflag = IGNBRK;
|
||||
termios.c_iflag = 0;
|
||||
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->ifd, TCSANOW, &termios);
|
||||
|
||||
rc = tcsetattr(fd, TCSANOW, &termios);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: ser_setspeed(): tcsetattr() failed\n",
|
||||
progname);
|
||||
fprintf(stderr, "%s: ser_setspeed(): tcsetattr() failed, %s",
|
||||
progname, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Everything is now set up for a local line without modem control
|
||||
* or flow control, so clear O_NONBLOCK again.
|
||||
* set non blocking mode
|
||||
*/
|
||||
rc = fcntl(fd->ifd, F_GETFL, 0);
|
||||
if (rc != -1)
|
||||
fcntl(fd->ifd, F_SETFL, rc & ~O_NONBLOCK);
|
||||
rc = fcntl(fd, F_GETFL, 0);
|
||||
fcntl(fd, F_SETFL, rc | O_NONBLOCK);
|
||||
#endif
|
||||
|
||||
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 int
|
||||
net_open(const char *port, union filedescriptor *fdp)
|
||||
{
|
||||
char *hstr, *pstr, *end;
|
||||
unsigned int pnum;
|
||||
int fd;
|
||||
struct sockaddr_in sockaddr;
|
||||
struct hostent *hp;
|
||||
|
||||
if ((hstr = strdup(port)) == NULL) {
|
||||
fprintf(stderr, "%s: net_open(): Out of memory!\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (((pstr = strchr(hstr, ':')) == NULL) || (pstr == hstr)) {
|
||||
fprintf(stderr, "%s: net_open(): Mangled host:port string \"%s\"\n",
|
||||
progname, hstr);
|
||||
free(hstr);
|
||||
return -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);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((hp = gethostbyname(hstr)) == NULL) {
|
||||
fprintf(stderr, "%s: net_open(): unknown host \"%s\"\n",
|
||||
progname, hstr);
|
||||
free(hstr);
|
||||
return -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));
|
||||
return -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));
|
||||
return -1;
|
||||
}
|
||||
|
||||
fdp->ifd = fd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ser_set_dtr_rts(union filedescriptor *fdp, int is_on)
|
||||
{
|
||||
unsigned int ctl;
|
||||
int r;
|
||||
|
||||
r = ioctl(fdp->ifd, TIOCMGET, &ctl);
|
||||
if (r < 0) {
|
||||
perror("ioctl(\"TIOCMGET\")");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (is_on) {
|
||||
/* Set DTR and RTS */
|
||||
ctl |= (TIOCM_DTR | TIOCM_RTS);
|
||||
}
|
||||
else {
|
||||
/* Clear DTR and RTS */
|
||||
ctl &= ~(TIOCM_DTR | TIOCM_RTS);
|
||||
}
|
||||
|
||||
r = ioctl(fdp->ifd, TIOCMSET, &ctl);
|
||||
if (r < 0) {
|
||||
perror("ioctl(\"TIOCMSET\")");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ser_open(char * port, long baud, union filedescriptor *fdp)
|
||||
static int ser_open(char * port, long baud)
|
||||
{
|
||||
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) {
|
||||
return net_open(port + strlen("net:"), fdp);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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));
|
||||
return -1;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fdp->ifd = fd;
|
||||
|
||||
/*
|
||||
* set serial line attributes
|
||||
*/
|
||||
rc = ser_setspeed(fdp, baud);
|
||||
rc = ser_setspeed(fd, baud);
|
||||
if (rc) {
|
||||
fprintf(stderr,
|
||||
"%s: ser_open(): can't set attributes for device \"%s\": %s\n",
|
||||
progname, port, strerror(-rc));
|
||||
close(fd);
|
||||
return -1;
|
||||
"%s: ser_open(): can't set attributes for device \"%s\"\n",
|
||||
progname, port);
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
static void ser_close(union filedescriptor *fd)
|
||||
static void ser_close(int fd)
|
||||
{
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
/* FIXME: Should really restore the terminal to original state here. */
|
||||
|
||||
close(fd->ifd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
static int ser_send(union filedescriptor *fd, unsigned char * buf, size_t buflen)
|
||||
static int ser_send(int fd, unsigned char * buf, size_t buflen)
|
||||
{
|
||||
struct timeval timeout, to2;
|
||||
fd_set wfds;
|
||||
int nfds;
|
||||
int rc;
|
||||
unsigned char * p = buf;
|
||||
size_t len = buflen;
|
||||
@@ -342,8 +200,35 @@ static int ser_send(union filedescriptor *fd, unsigned char * buf, size_t buflen
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 500000;
|
||||
to2 = timeout;
|
||||
|
||||
while (len) {
|
||||
rc = write(fd->ifd, p, (len > 1024) ? 1024 : len);
|
||||
reselect:
|
||||
FD_ZERO(&wfds);
|
||||
FD_SET(fd, &wfds);
|
||||
|
||||
nfds = select(fd+1, NULL, &wfds, NULL, &to2);
|
||||
if (nfds == 0) {
|
||||
if (verbose >= 1)
|
||||
fprintf(stderr,
|
||||
"%s: ser_send(): programmer is not responding\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
else if (nfds == -1) {
|
||||
if (errno == EINTR || errno == EAGAIN) {
|
||||
goto reselect;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "%s: ser_send(): select(): %s\n",
|
||||
progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
rc = write(fd, p, (len > 1024) ? 1024 : len);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: ser_send(): write error: %s\n",
|
||||
progname, strerror(errno));
|
||||
@@ -357,7 +242,7 @@ static int ser_send(union filedescriptor *fd, unsigned char * buf, size_t buflen
|
||||
}
|
||||
|
||||
|
||||
static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
|
||||
static int ser_recv(int fd, unsigned char * buf, size_t buflen)
|
||||
{
|
||||
struct timeval timeout, to2;
|
||||
fd_set rfds;
|
||||
@@ -373,9 +258,9 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
|
||||
while (len < buflen) {
|
||||
reselect:
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd->ifd, &rfds);
|
||||
FD_SET(fd, &rfds);
|
||||
|
||||
nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &to2);
|
||||
nfds = select(fd+1, &rfds, NULL, NULL, &to2);
|
||||
if (nfds == 0) {
|
||||
if (verbose > 1)
|
||||
fprintf(stderr,
|
||||
@@ -397,7 +282,7 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
|
||||
}
|
||||
}
|
||||
|
||||
rc = read(fd->ifd, p, (buflen - len > 1024) ? 1024 : buflen - len);
|
||||
rc = read(fd, p, (buflen - len > 1024) ? 1024 : buflen - len);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: ser_recv(): read error: %s\n",
|
||||
progname, strerror(errno));
|
||||
@@ -433,7 +318,7 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
|
||||
}
|
||||
|
||||
|
||||
static int ser_drain(union filedescriptor *fd, int display)
|
||||
static int ser_drain(int fd, int display)
|
||||
{
|
||||
struct timeval timeout;
|
||||
fd_set rfds;
|
||||
@@ -450,10 +335,10 @@ static int ser_drain(union filedescriptor *fd, int display)
|
||||
|
||||
while (1) {
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd->ifd, &rfds);
|
||||
FD_SET(fd, &rfds);
|
||||
|
||||
reselect:
|
||||
nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &timeout);
|
||||
nfds = select(fd+1, &rfds, NULL, NULL, &timeout);
|
||||
if (nfds == 0) {
|
||||
if (display) {
|
||||
fprintf(stderr, "<drain\n");
|
||||
@@ -472,7 +357,7 @@ static int ser_drain(union filedescriptor *fd, int display)
|
||||
}
|
||||
}
|
||||
|
||||
rc = read(fd->ifd, &buf, 1);
|
||||
rc = read(fd, &buf, 1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: ser_drain(): read error: %s\n",
|
||||
progname, strerror(errno));
|
||||
@@ -494,8 +379,6 @@ struct serial_device serial_serdev =
|
||||
.send = ser_send,
|
||||
.recv = ser_recv,
|
||||
.drain = ser_drain,
|
||||
.set_dtr_rts = ser_set_dtr_rts,
|
||||
.flags = SERDEV_FL_CANSETSPEED,
|
||||
};
|
||||
|
||||
struct serial_device *serdev = &serial_serdev;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
@@ -14,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -23,16 +23,16 @@
|
||||
* Native Win32 serial interface for avrdude.
|
||||
*/
|
||||
|
||||
#include "avrdude.h"
|
||||
|
||||
#if defined(WIN32NATIVE)
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h> /* for isprint */
|
||||
|
||||
#include "serial.h"
|
||||
|
||||
extern char *progname;
|
||||
extern int verbose;
|
||||
|
||||
long serial_recv_timeout = 5000; /* ms */
|
||||
|
||||
#define W32SERBUFSIZE 1024
|
||||
@@ -66,15 +66,9 @@ static DWORD serial_baud_lookup(long baud)
|
||||
map++;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a non-standard BAUD rate is used, issue
|
||||
* a warning (if we are verbose) and return the raw rate
|
||||
*/
|
||||
if (verbose > 0)
|
||||
fprintf(stderr, "%s: serial_baud_lookup(): Using non-standard baud rate: %ld",
|
||||
progname, baud);
|
||||
|
||||
return baud;
|
||||
fprintf(stderr, "%s: serial_baud_lookup(): unknown baud rate: %ld",
|
||||
progname, baud);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -89,10 +83,10 @@ static BOOL serial_w32SetTimeOut(HANDLE hComPort, DWORD timeout) // in ms
|
||||
return SetCommTimeouts(hComPort, &ctmo);
|
||||
}
|
||||
|
||||
static int ser_setspeed(union filedescriptor *fd, long baud)
|
||||
static int ser_setspeed(int fd, long baud)
|
||||
{
|
||||
DCB dcb;
|
||||
HANDLE hComPort = (HANDLE)fd->pfd;
|
||||
HANDLE hComPort = (HANDLE)fd;
|
||||
|
||||
ZeroMemory (&dcb, sizeof(DCB));
|
||||
dcb.DCBlength = sizeof(DCB);
|
||||
@@ -111,42 +105,15 @@ static int ser_setspeed(union filedescriptor *fd, long baud)
|
||||
}
|
||||
|
||||
|
||||
static int ser_open(char * port, long baud, union filedescriptor *fdp)
|
||||
static int ser_open(char * port, long baud)
|
||||
{
|
||||
LPVOID lpMsgBuf;
|
||||
HANDLE hComPort=INVALID_HANDLE_VALUE;
|
||||
char *newname = 0;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strncasecmp(port, "com", strlen("com")) == 0) {
|
||||
|
||||
// prepend "\\\\.\\" to name, required for port # >= 10
|
||||
newname = malloc(strlen("\\\\.\\") + strlen(port) + 1);
|
||||
|
||||
if (newname == 0) {
|
||||
fprintf(stderr,
|
||||
"%s: ser_open(): out of memory\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
strcpy(newname, "\\\\.\\");
|
||||
strcat(newname, port);
|
||||
|
||||
port = newname;
|
||||
}
|
||||
/* if (hComPort!=INVALID_HANDLE_VALUE)
|
||||
fprintf(stderr, "%s: ser_open(): \"%s\" is already open\n",
|
||||
progname, port);
|
||||
*/
|
||||
|
||||
hComPort = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
@@ -165,7 +132,7 @@ static int ser_open(char * port, long baud, union filedescriptor *fdp)
|
||||
fprintf(stderr, "%s: ser_open(): can't open device \"%s\": %s\n",
|
||||
progname, port, (char*)lpMsgBuf);
|
||||
LocalFree( lpMsgBuf );
|
||||
return -1;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!SetupComm(hComPort, W32SERBUFSIZE, W32SERBUFSIZE))
|
||||
@@ -173,16 +140,16 @@ static int ser_open(char * port, long baud, union filedescriptor *fdp)
|
||||
CloseHandle(hComPort);
|
||||
fprintf(stderr, "%s: ser_open(): can't set buffers for \"%s\"\n",
|
||||
progname, port);
|
||||
return -1;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fdp->pfd = (void *)hComPort;
|
||||
if (ser_setspeed(fdp, baud) != 0)
|
||||
|
||||
if (ser_setspeed((int)hComPort, baud) != 0)
|
||||
{
|
||||
CloseHandle(hComPort);
|
||||
fprintf(stderr, "%s: ser_open(): can't set com-state for \"%s\"\n",
|
||||
progname, port);
|
||||
return -1;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!serial_w32SetTimeOut(hComPort,0))
|
||||
@@ -190,48 +157,31 @@ static int ser_open(char * port, long baud, union filedescriptor *fdp)
|
||||
CloseHandle(hComPort);
|
||||
fprintf(stderr, "%s: ser_open(): can't set initial timeout for \"%s\"\n",
|
||||
progname, port);
|
||||
return -1;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (newname != 0) {
|
||||
free(newname);
|
||||
}
|
||||
return 0;
|
||||
return (int)hComPort;
|
||||
}
|
||||
|
||||
|
||||
static void ser_close(union filedescriptor *fd)
|
||||
static void ser_close(int fd)
|
||||
{
|
||||
HANDLE hComPort=(HANDLE)fd->pfd;
|
||||
HANDLE hComPort=(HANDLE)fd;
|
||||
if (hComPort != INVALID_HANDLE_VALUE)
|
||||
CloseHandle (hComPort);
|
||||
|
||||
hComPort = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
static int ser_set_dtr_rts(union filedescriptor *fd, int is_on)
|
||||
{
|
||||
HANDLE hComPort=(HANDLE)fd->pfd;
|
||||
|
||||
if (is_on) {
|
||||
EscapeCommFunction(hComPort, SETDTR);
|
||||
EscapeCommFunction(hComPort, SETRTS);
|
||||
} else {
|
||||
EscapeCommFunction(hComPort, CLRDTR);
|
||||
EscapeCommFunction(hComPort, CLRRTS);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ser_send(union filedescriptor *fd, unsigned char * buf, size_t buflen)
|
||||
static int ser_send(int fd, char * buf, size_t buflen)
|
||||
{
|
||||
size_t len = buflen;
|
||||
unsigned char c='\0';
|
||||
DWORD written;
|
||||
unsigned char * b = buf;
|
||||
char * b = buf;
|
||||
|
||||
HANDLE hComPort=(HANDLE)fd->pfd;
|
||||
HANDLE hComPort=(HANDLE)fd;
|
||||
|
||||
if (hComPort == INVALID_HANDLE_VALUE) {
|
||||
fprintf(stderr, "%s: ser_send(): port not open\n",
|
||||
@@ -279,13 +229,14 @@ static int ser_send(union filedescriptor *fd, unsigned char * buf, size_t buflen
|
||||
}
|
||||
|
||||
|
||||
static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
|
||||
static int ser_recv(int fd, char * buf, size_t buflen)
|
||||
{
|
||||
unsigned char c;
|
||||
unsigned char * p = buf;
|
||||
char * p = buf;
|
||||
size_t len = 0;
|
||||
DWORD read;
|
||||
|
||||
HANDLE hComPort=(HANDLE)fd->pfd;
|
||||
HANDLE hComPort=(HANDLE)fd;
|
||||
|
||||
if (hComPort == INVALID_HANDLE_VALUE) {
|
||||
fprintf(stderr, "%s: ser_read(): port not open\n",
|
||||
@@ -313,22 +264,13 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* time out detected */
|
||||
if (read == 0) {
|
||||
if (verbose > 1)
|
||||
fprintf(stderr,
|
||||
"%s: ser_recv(): programmer is not responding\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = buf;
|
||||
|
||||
if (verbose > 3)
|
||||
{
|
||||
fprintf(stderr, "%s: Recv: ", progname);
|
||||
|
||||
while (read) {
|
||||
while (len) {
|
||||
c = *p;
|
||||
if (isprint(c)) {
|
||||
fprintf(stderr, "%c ", c);
|
||||
@@ -339,7 +281,7 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
|
||||
fprintf(stderr, "[%02x] ", c);
|
||||
|
||||
p++;
|
||||
read--;
|
||||
len--;
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
@@ -347,14 +289,14 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
|
||||
}
|
||||
|
||||
|
||||
static int ser_drain(union filedescriptor *fd, int display)
|
||||
static int ser_drain(int fd, int display)
|
||||
{
|
||||
// int rc;
|
||||
unsigned char buf[10];
|
||||
BOOL readres;
|
||||
DWORD read;
|
||||
|
||||
HANDLE hComPort=(HANDLE)fd->pfd;
|
||||
HANDLE hComPort=(HANDLE)fd;
|
||||
|
||||
if (hComPort == INVALID_HANDLE_VALUE) {
|
||||
fprintf(stderr, "%s: ser_drain(): port not open\n",
|
||||
@@ -407,8 +349,6 @@ struct serial_device serial_serdev =
|
||||
.send = ser_send,
|
||||
.recv = ser_recv,
|
||||
.drain = ser_drain,
|
||||
.set_dtr_rts = ser_set_dtr_rts,
|
||||
.flags = SERDEV_FL_CANSETSPEED,
|
||||
};
|
||||
|
||||
struct serial_device *serdev = &serial_serdev;
|
||||
|
||||
@@ -14,23 +14,19 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* 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 serbb_h
|
||||
#define serbb_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char serbb_desc[];
|
||||
void serbb_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
int serbb_setpin(int fd, int pin, int value);
|
||||
int serbb_getpin(int fd, int pin);
|
||||
int serbb_highpulsepin(int fd, int pin);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
* 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
|
||||
@@ -15,7 +14,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/* $Id$ */
|
||||
|
||||
@@ -36,45 +36,39 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "pindefs.h"
|
||||
#include "pgm.h"
|
||||
#include "bitbang.h"
|
||||
#include "serbb.h"
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
static struct termios oldmode;
|
||||
extern char *progname;
|
||||
struct termios oldmode;
|
||||
|
||||
/*
|
||||
serial port/pin mapping
|
||||
|
||||
1 cd <-
|
||||
2 (rxd) <-
|
||||
2 rxd <-
|
||||
3 txd ->
|
||||
4 dtr ->
|
||||
5 GND
|
||||
6 dsr <-
|
||||
7 rts ->
|
||||
8 cts <-
|
||||
9 ri <-
|
||||
5 dsr <-
|
||||
6 rts ->
|
||||
7 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 };
|
||||
static int serregbits[] =
|
||||
{ TIOCM_CD, 0, 0, TIOCM_DTR, TIOCM_DSR, TIOCM_RTS, TIOCM_CTS };
|
||||
|
||||
#ifdef DEBUG
|
||||
static char *serpins[DB9PINS + 1] =
|
||||
{ "NONE", "CD", "RXD", "TXD", "DTR", "GND", "DSR", "RTS", "CTS", "RI" };
|
||||
static char *serpins[7] =
|
||||
{ "CD", "RXD", "TXD ~RESET", "DTR MOSI", "DSR", "RTS SCK", "CTS MISO" };
|
||||
#endif
|
||||
|
||||
static int serbb_setpin(PROGRAMMER * pgm, int pin, int value)
|
||||
{
|
||||
unsigned int ctl;
|
||||
int r;
|
||||
|
||||
if (pin & PIN_INVERSE)
|
||||
{
|
||||
@@ -82,56 +76,39 @@ static int serbb_setpin(PROGRAMMER * pgm, int pin, int value)
|
||||
pin &= PIN_MASK;
|
||||
}
|
||||
|
||||
if ( pin < 1 || pin > DB9PINS )
|
||||
if ( pin < 1 || pin > 7 )
|
||||
return -1;
|
||||
|
||||
pin--;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("%s to %d\n",serpins[pin],value);
|
||||
#endif
|
||||
|
||||
switch ( pin )
|
||||
{
|
||||
case 3: /* txd */
|
||||
r = ioctl(pgm->fd.ifd, value ? TIOCSBRK : TIOCCBRK, 0);
|
||||
if (r < 0) {
|
||||
perror("ioctl(\"TIOCxBRK\")");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 2: /* txd */
|
||||
ioctl(pgm->fd, value ? TIOCSBRK : TIOCCBRK, 0);
|
||||
return 0;
|
||||
|
||||
case 4: /* dtr */
|
||||
case 7: /* rts */
|
||||
r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl);
|
||||
if (r < 0) {
|
||||
perror("ioctl(\"TIOCMGET\")");
|
||||
return -1;
|
||||
}
|
||||
case 3: /* dtr, rts */
|
||||
case 5: ioctl(pgm->fd, TIOCMGET, &ctl);
|
||||
if ( value )
|
||||
ctl |= serregbits[pin];
|
||||
else
|
||||
ctl &= ~(serregbits[pin]);
|
||||
r = ioctl(pgm->fd.ifd, TIOCMSET, &ctl);
|
||||
if (r < 0) {
|
||||
perror("ioctl(\"TIOCMSET\")");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
ioctl(pgm->fd, TIOCMSET, &ctl);
|
||||
return 0;
|
||||
|
||||
default: /* impossible */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pgm->ispdelay > 1)
|
||||
bitbang_delay(pgm->ispdelay);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int serbb_getpin(PROGRAMMER * pgm, int pin)
|
||||
{
|
||||
unsigned int ctl;
|
||||
unsigned char invert;
|
||||
int r;
|
||||
|
||||
if (pin & PIN_INVERSE)
|
||||
{
|
||||
@@ -140,23 +117,21 @@ static int serbb_getpin(PROGRAMMER * pgm, int pin)
|
||||
} else
|
||||
invert = 0;
|
||||
|
||||
if ( pin < 1 || pin > DB9PINS )
|
||||
if ( pin < 1 || pin > 7 )
|
||||
return(-1);
|
||||
|
||||
pin --;
|
||||
|
||||
switch ( pin )
|
||||
{
|
||||
case 2: /* rxd, currently not implemented, FIXME */
|
||||
case 1: /* rxd, currently not implemented, FIXME */
|
||||
return(-1);
|
||||
|
||||
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;
|
||||
}
|
||||
case 0: /* cd, dsr, dtr, rts, cts */
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6: ioctl(pgm->fd, TIOCMGET, &ctl);
|
||||
if ( !invert )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
@@ -179,18 +154,25 @@ static int serbb_getpin(PROGRAMMER * pgm, int pin)
|
||||
|
||||
static int serbb_highpulsepin(PROGRAMMER * pgm, int pin)
|
||||
{
|
||||
if ( (pin & PIN_MASK) < 1 || (pin & PIN_MASK) > DB9PINS )
|
||||
if (pin < 1 || pin > 7)
|
||||
return -1;
|
||||
|
||||
serbb_setpin(pgm, pin, 1);
|
||||
#if SLOW_TOGGLE
|
||||
usleep(1000);
|
||||
#endif
|
||||
serbb_setpin(pgm, pin, 0);
|
||||
|
||||
#if SLOW_TOGGLE
|
||||
usleep(1000);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void serbb_display(PROGRAMMER *pgm, const char *p)
|
||||
static void serbb_display(PROGRAMMER *pgm, char *p)
|
||||
{
|
||||
/* MAYBE */
|
||||
}
|
||||
@@ -219,25 +201,15 @@ 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.ifd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
pgm->fd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
|
||||
if (pgm->fd.ifd < 0) {
|
||||
perror(port);
|
||||
if (pgm->fd < 0)
|
||||
return(-1);
|
||||
}
|
||||
|
||||
r = tcgetattr(pgm->fd.ifd, &mode);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "%s: ", port);
|
||||
perror("tcgetattr");
|
||||
return(-1);
|
||||
}
|
||||
tcgetattr(pgm->fd, &mode);
|
||||
oldmode = mode;
|
||||
|
||||
mode.c_iflag = IGNBRK | IGNPAR;
|
||||
@@ -246,26 +218,19 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
|
||||
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);
|
||||
}
|
||||
tcsetattr(pgm->fd, TCSANOW, &mode);
|
||||
|
||||
/* Clear O_NONBLOCK flag. */
|
||||
flags = fcntl(pgm->fd.ifd, F_GETFL, 0);
|
||||
flags = fcntl(pgm->fd, F_GETFL, 0);
|
||||
if (flags == -1)
|
||||
{
|
||||
fprintf(stderr, "%s: Can not get flags: %s\n",
|
||||
progname, strerror(errno));
|
||||
fprintf(stderr, "%s: Can not get flags\n", progname);
|
||||
return(-1);
|
||||
}
|
||||
flags &= ~O_NONBLOCK;
|
||||
if (fcntl(pgm->fd.ifd, F_SETFL, flags) == -1)
|
||||
if (fcntl(pgm->fd, F_SETFL, flags) == -1)
|
||||
{
|
||||
fprintf(stderr, "%s: Can not clear nonblock flag: %s\n",
|
||||
progname, strerror(errno));
|
||||
fprintf(stderr, "%s: Can not clear nonblock flag\n", progname);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
@@ -274,23 +239,14 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
|
||||
|
||||
static void serbb_close(PROGRAMMER *pgm)
|
||||
{
|
||||
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);
|
||||
}
|
||||
tcsetattr(pgm->fd, TCSANOW, &oldmode);
|
||||
return;
|
||||
}
|
||||
|
||||
const char serbb_desc[] = "Serial port bitbanging";
|
||||
|
||||
void serbb_initpgm(PROGRAMMER *pgm)
|
||||
{
|
||||
strcpy(pgm->type, "SERBB");
|
||||
|
||||
pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
|
||||
|
||||
pgm->rdy_led = bitbang_rdy_led;
|
||||
pgm->err_led = bitbang_err_led;
|
||||
pgm->pgm_led = bitbang_pgm_led;
|
||||
@@ -304,14 +260,11 @@ void serbb_initpgm(PROGRAMMER *pgm)
|
||||
pgm->program_enable = bitbang_program_enable;
|
||||
pgm->chip_erase = bitbang_chip_erase;
|
||||
pgm->cmd = bitbang_cmd;
|
||||
pgm->cmd_tpi = bitbang_cmd_tpi;
|
||||
pgm->open = serbb_open;
|
||||
pgm->close = serbb_close;
|
||||
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 */
|
||||
|
||||
@@ -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, 2006 Joerg Wunsch <j@uriah.heep.sax.de>
|
||||
* 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
|
||||
@@ -15,7 +15,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/* $Id$ */
|
||||
|
||||
@@ -23,8 +24,6 @@
|
||||
* Win32 serial bitbanging interface for avrdude.
|
||||
*/
|
||||
|
||||
#include "avrdude.h"
|
||||
|
||||
#if defined(WIN32NATIVE)
|
||||
|
||||
|
||||
@@ -37,7 +36,9 @@
|
||||
#include "pindefs.h"
|
||||
#include "pgm.h"
|
||||
#include "bitbang.h"
|
||||
#include "serbb.h"
|
||||
|
||||
extern char *progname;
|
||||
extern int verbose;
|
||||
|
||||
/* cached status lines */
|
||||
static int dtr, rts, txd;
|
||||
@@ -48,21 +49,19 @@ static int dtr, rts, txd;
|
||||
serial port/pin mapping
|
||||
|
||||
1 cd <-
|
||||
2 (rxd) <-
|
||||
2 rxd <-
|
||||
3 txd ->
|
||||
4 dtr ->
|
||||
5 GND
|
||||
6 dsr <-
|
||||
7 rts ->
|
||||
8 cts <-
|
||||
9 ri <-
|
||||
*/
|
||||
5 dsr <-
|
||||
6 rts ->
|
||||
7 cts <-
|
||||
|
||||
#define DB9PINS 9
|
||||
Negative pin # means negated value.
|
||||
*/
|
||||
|
||||
static int serbb_setpin(PROGRAMMER * pgm, int pin, int value)
|
||||
{
|
||||
HANDLE hComPort = (HANDLE)pgm->fd.pfd;
|
||||
HANDLE hComPort = (HANDLE)pgm->fd;
|
||||
LPVOID lpMsgBuf;
|
||||
DWORD dwFunc;
|
||||
const char *name;
|
||||
@@ -73,24 +72,26 @@ static int serbb_setpin(PROGRAMMER * pgm, int pin, int value)
|
||||
pin &= PIN_MASK;
|
||||
}
|
||||
|
||||
if (pin < 1 || pin > DB9PINS)
|
||||
if (pin < 1 || pin > 7)
|
||||
return -1;
|
||||
|
||||
pin--;
|
||||
|
||||
switch (pin)
|
||||
{
|
||||
case 3: /* txd */
|
||||
case 2: /* txd */
|
||||
dwFunc = value? SETBREAK: CLRBREAK;
|
||||
name = value? "SETBREAK": "CLRBREAK";
|
||||
txd = value;
|
||||
break;
|
||||
|
||||
case 4: /* dtr */
|
||||
case 3: /* dtr */
|
||||
dwFunc = value? SETDTR: CLRDTR;
|
||||
name = value? "SETDTR": "CLRDTR";
|
||||
dtr = value;
|
||||
break;
|
||||
|
||||
case 7: /* rts */
|
||||
case 5: /* rts */
|
||||
dwFunc = value? SETRTS: CLRRTS;
|
||||
name = value? "SETRTS": "CLRRTS";
|
||||
break;
|
||||
@@ -125,16 +126,12 @@ static int serbb_setpin(PROGRAMMER * pgm, int pin, int value)
|
||||
LocalFree(lpMsgBuf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (pgm->ispdelay > 1)
|
||||
bitbang_delay(pgm->ispdelay);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int serbb_getpin(PROGRAMMER * pgm, int pin)
|
||||
{
|
||||
HANDLE hComPort = (HANDLE)pgm->fd.pfd;
|
||||
HANDLE hComPort = (HANDLE)pgm->fd;
|
||||
LPVOID lpMsgBuf;
|
||||
int invert, rv;
|
||||
const char *name;
|
||||
@@ -147,10 +144,12 @@ static int serbb_getpin(PROGRAMMER * pgm, int pin)
|
||||
} else
|
||||
invert = 0;
|
||||
|
||||
if (pin < 1 || pin > DB9PINS)
|
||||
if (pin < 1 || pin > 7)
|
||||
return -1;
|
||||
|
||||
if (pin == 1 /* cd */ || pin == 6 /* dsr */ || pin == 8 /* cts */)
|
||||
pin --;
|
||||
|
||||
if (pin == 0 /* cd */ || pin == 4 /* dsr */ || pin == 6 /* cts */)
|
||||
{
|
||||
if (!GetCommModemStatus(hComPort, &modemstate))
|
||||
{
|
||||
@@ -177,13 +176,13 @@ static int serbb_getpin(PROGRAMMER * pgm, int pin)
|
||||
progname, modemstate);
|
||||
switch (pin)
|
||||
{
|
||||
case 1:
|
||||
case 0:
|
||||
modemstate &= MS_RLSD_ON;
|
||||
break;
|
||||
case 6:
|
||||
case 4:
|
||||
modemstate &= MS_DSR_ON;
|
||||
break;
|
||||
case 8:
|
||||
case 6:
|
||||
modemstate &= MS_CTS_ON;
|
||||
break;
|
||||
}
|
||||
@@ -196,15 +195,15 @@ static int serbb_getpin(PROGRAMMER * pgm, int pin)
|
||||
|
||||
switch (pin)
|
||||
{
|
||||
case 3: /* txd */
|
||||
case 2: /* txd */
|
||||
rv = txd;
|
||||
name = "TXD";
|
||||
break;
|
||||
case 4: /* dtr */
|
||||
case 3: /* dtr */
|
||||
rv = dtr;
|
||||
name = "DTR";
|
||||
break;
|
||||
case 7: /* rts */
|
||||
case 5: /* rts */
|
||||
rv = rts;
|
||||
name = "RTS";
|
||||
break;
|
||||
@@ -227,17 +226,24 @@ static int serbb_getpin(PROGRAMMER * pgm, int pin)
|
||||
|
||||
static int serbb_highpulsepin(PROGRAMMER * pgm, int pin)
|
||||
{
|
||||
if ( (pin & PIN_MASK) < 1 || (pin & PIN_MASK) > DB9PINS )
|
||||
return -1;
|
||||
if (pin < 1 || pin > 7)
|
||||
return -1;
|
||||
|
||||
serbb_setpin(pgm, pin, 1);
|
||||
#if SLOW_TOGGLE
|
||||
usleep(1000);
|
||||
#endif
|
||||
serbb_setpin(pgm, pin, 0);
|
||||
|
||||
#if SLOW_TOGGLE
|
||||
usleep(1000);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void serbb_display(PROGRAMMER *pgm, const char *p)
|
||||
static void serbb_display(PROGRAMMER *pgm, char *p)
|
||||
{
|
||||
/* MAYBE */
|
||||
}
|
||||
@@ -268,8 +274,6 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
|
||||
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);
|
||||
|
||||
@@ -321,7 +325,7 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
|
||||
"%s: ser_open(): opened comm port \"%s\", handle 0x%x\n",
|
||||
progname, port, (int)hComPort);
|
||||
|
||||
pgm->fd.pfd = (void *)hComPort;
|
||||
pgm->fd = (int)hComPort;
|
||||
|
||||
dtr = rts = txd = 0;
|
||||
|
||||
@@ -330,12 +334,9 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
|
||||
|
||||
static void serbb_close(PROGRAMMER *pgm)
|
||||
{
|
||||
HANDLE hComPort=(HANDLE)pgm->fd.pfd;
|
||||
HANDLE hComPort=(HANDLE)pgm->fd;
|
||||
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",
|
||||
@@ -344,14 +345,10 @@ static void serbb_close(PROGRAMMER *pgm)
|
||||
hComPort = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
const char serbb_desc[] = "Serial port bitbanging";
|
||||
|
||||
void serbb_initpgm(PROGRAMMER *pgm)
|
||||
{
|
||||
strcpy(pgm->type, "SERBB");
|
||||
|
||||
pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
|
||||
|
||||
pgm->rdy_led = bitbang_rdy_led;
|
||||
pgm->err_led = bitbang_err_led;
|
||||
pgm->pgm_led = bitbang_pgm_led;
|
||||
@@ -365,14 +362,11 @@ void serbb_initpgm(PROGRAMMER *pgm)
|
||||
pgm->program_enable = bitbang_program_enable;
|
||||
pgm->chip_erase = bitbang_chip_erase;
|
||||
pgm->cmd = bitbang_cmd;
|
||||
pgm->cmd_tpi = bitbang_cmd_tpi;
|
||||
pgm->open = serbb_open;
|
||||
pgm->close = serbb_close;
|
||||
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 */
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -26,47 +27,24 @@
|
||||
|
||||
The target file will be selected at configure time. */
|
||||
|
||||
#ifndef serial_h
|
||||
#define serial_h
|
||||
#ifndef __serial_h__
|
||||
#define __serial_h__
|
||||
|
||||
extern long serial_recv_timeout;
|
||||
union filedescriptor
|
||||
{
|
||||
int ifd;
|
||||
void *pfd;
|
||||
struct
|
||||
{
|
||||
void *handle;
|
||||
int rep; /* bulk read endpoint */
|
||||
int wep; /* bulk write endpoint */
|
||||
int eep; /* event read endpoint */
|
||||
int max_xfer; /* max transfer size */
|
||||
} usb;
|
||||
};
|
||||
|
||||
struct serial_device
|
||||
{
|
||||
// open should return -1 on error, other values on success
|
||||
int (*open)(char * port, long baud, union filedescriptor *fd);
|
||||
int (*setspeed)(union filedescriptor *fd, long baud);
|
||||
void (*close)(union filedescriptor *fd);
|
||||
int (*open)(char * port, long baud);
|
||||
int (*setspeed)(int fd, long baud);
|
||||
void (*close)(int fd);
|
||||
|
||||
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 (*set_dtr_rts)(union filedescriptor *fd, int is_on);
|
||||
|
||||
int flags;
|
||||
#define SERDEV_FL_NONE 0x0000 /* no flags */
|
||||
#define SERDEV_FL_CANSETSPEED 0x0001 /* device can change speed */
|
||||
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);
|
||||
};
|
||||
|
||||
extern struct serial_device *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;
|
||||
extern struct serial_device serial_serdev, usb_serdev, usb_serdev_frame;
|
||||
|
||||
#define serial_open (serdev->open)
|
||||
#define serial_setspeed (serdev->setspeed)
|
||||
@@ -74,6 +52,5 @@ extern struct serial_device avrdoper_serdev;
|
||||
#define serial_send (serdev->send)
|
||||
#define serial_recv (serdev->recv)
|
||||
#define serial_drain (serdev->drain)
|
||||
#define serial_set_dtr_rts (serdev->set_dtr_rts)
|
||||
|
||||
#endif /* serial_h */
|
||||
#endif /* __serial_h__ */
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
483
avrdude/stk500.c
483
avrdude/stk500.c
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||
* Copyright (C) 2008 Joerg Wunsch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -14,7 +13,8 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
@@ -36,24 +36,28 @@
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "pgm.h"
|
||||
#include "stk500.h"
|
||||
#include "stk500_private.h"
|
||||
#include "serial.h"
|
||||
|
||||
#define STK500_XTAL 7372800U
|
||||
#define MAX_SYNC_ATTEMPTS 10
|
||||
|
||||
extern int verbose;
|
||||
extern char * progname;
|
||||
extern int do_cycles;
|
||||
|
||||
|
||||
static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value);
|
||||
static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value);
|
||||
static void stk500_print_parms1(PROGRAMMER * pgm, const char * p);
|
||||
static void stk500_print_parms1(PROGRAMMER * pgm, char * p);
|
||||
static int stk500_is_page_empty(unsigned int address, int page_size,
|
||||
const unsigned char *buf);
|
||||
|
||||
|
||||
static int stk500_send(PROGRAMMER * pgm, unsigned char * buf, size_t len)
|
||||
{
|
||||
return serial_send(&pgm->fd, buf, len);
|
||||
return serial_send(pgm->fd, buf, len);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,65 +65,48 @@ 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);
|
||||
return -1;
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int stk500_drain(PROGRAMMER * pgm, int display)
|
||||
static int stk500_drain(PROGRAMMER * pgm, int display)
|
||||
{
|
||||
return serial_drain(&pgm->fd, display);
|
||||
return serial_drain(pgm->fd, display);
|
||||
}
|
||||
|
||||
|
||||
int stk500_getsync(PROGRAMMER * pgm)
|
||||
static int stk500_getsync(PROGRAMMER * pgm)
|
||||
{
|
||||
unsigned char buf[32], resp[32];
|
||||
int attempt;
|
||||
|
||||
/*
|
||||
* 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_drain(pgm, 0);
|
||||
stk500_send(pgm, buf, 2);
|
||||
stk500_drain(pgm, 0);
|
||||
|
||||
for (attempt = 0; attempt < MAX_SYNC_ATTEMPTS; attempt++) {
|
||||
stk500_send(pgm, buf, 2);
|
||||
stk500_recv(pgm, resp, 1);
|
||||
if (resp[0] == Resp_STK_INSYNC){
|
||||
break;
|
||||
}
|
||||
fprintf(stderr,
|
||||
"%s: stk500_getsync() attempt %d of %d: not in sync: resp=0x%02x\n",
|
||||
progname, attempt + 1, MAX_SYNC_ATTEMPTS, resp[0]);
|
||||
}
|
||||
if (attempt == MAX_SYNC_ATTEMPTS) {
|
||||
stk500_recv(pgm, resp, 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);
|
||||
return -1;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (stk500_recv(pgm, resp, 1) < 0)
|
||||
return -1;
|
||||
stk500_recv(pgm, resp, 1);
|
||||
if (resp[0] != Resp_STK_OK) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500_getsync(): can't communicate with device: "
|
||||
"resp=0x%02x\n",
|
||||
progname, resp[0]);
|
||||
return -1;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -130,8 +117,8 @@ int stk500_getsync(PROGRAMMER * pgm)
|
||||
* transmit an AVR device command and return the results; 'cmd' and
|
||||
* 'res' must point to at least a 4 byte data buffer
|
||||
*/
|
||||
static int stk500_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
unsigned char *res)
|
||||
static int stk500_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4])
|
||||
{
|
||||
unsigned char buf[32];
|
||||
|
||||
@@ -144,8 +131,7 @@ static int stk500_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
|
||||
stk500_send(pgm, buf, 6);
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] != Resp_STK_INSYNC) {
|
||||
fprintf(stderr, "%s: stk500_cmd(): programmer is out of sync\n", progname);
|
||||
exit(1);
|
||||
@@ -154,11 +140,9 @@ static int stk500_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||
res[0] = cmd[1];
|
||||
res[1] = cmd[2];
|
||||
res[2] = cmd[3];
|
||||
if (stk500_recv(pgm, &res[3], 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, &res[3], 1);
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] != Resp_STK_OK) {
|
||||
fprintf(stderr, "%s: stk500_cmd(): protocol error\n", progname);
|
||||
exit(1);
|
||||
@@ -177,14 +161,6 @@ 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);
|
||||
@@ -221,16 +197,14 @@ static int stk500_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
||||
buf[1] = Sync_CRC_EOP;
|
||||
|
||||
stk500_send(pgm, buf, 2);
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 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;
|
||||
}
|
||||
if (stk500_getsync(pgm) < 0)
|
||||
return -1;
|
||||
stk500_getsync(pgm);
|
||||
goto retry;
|
||||
}
|
||||
else if (buf[0] != Resp_STK_INSYNC) {
|
||||
@@ -241,8 +215,7 @@ static int stk500_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] == Resp_STK_OK) {
|
||||
return 0;
|
||||
}
|
||||
@@ -288,16 +261,14 @@ static int stk500_set_extended_parms(PROGRAMMER * pgm, int n,
|
||||
buf[i] = Sync_CRC_EOP;
|
||||
|
||||
stk500_send(pgm, buf, i+1);
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 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;
|
||||
}
|
||||
if (stk500_getsync(pgm) < 0)
|
||||
return -1;
|
||||
stk500_getsync(pgm);
|
||||
goto retry;
|
||||
}
|
||||
else if (buf[0] != Resp_STK_INSYNC) {
|
||||
@@ -308,8 +279,7 @@ static int stk500_set_extended_parms(PROGRAMMER * pgm, int n,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] == Resp_STK_OK) {
|
||||
return 0;
|
||||
}
|
||||
@@ -335,77 +305,6 @@ static int stk500_set_extended_parms(PROGRAMMER * pgm, int n,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Crossbow MIB510 initialization and shutdown. Use cmd = 1 to
|
||||
* initialize, cmd = 0 to close.
|
||||
*/
|
||||
static int mib510_isp(PROGRAMMER * pgm, unsigned char cmd)
|
||||
{
|
||||
unsigned char buf[9];
|
||||
int tries = 0;
|
||||
|
||||
buf[0] = 0xaa;
|
||||
buf[1] = 0x55;
|
||||
buf[2] = 0x55;
|
||||
buf[3] = 0xaa;
|
||||
buf[4] = 0x17;
|
||||
buf[5] = 0x51;
|
||||
buf[6] = 0x31;
|
||||
buf[7] = 0x13;
|
||||
buf[8] = cmd;
|
||||
|
||||
|
||||
retry:
|
||||
|
||||
tries++;
|
||||
|
||||
stk500_send(pgm, buf, 9);
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
if (buf[0] == Resp_STK_NOSYNC) {
|
||||
if (tries > 33) {
|
||||
fprintf(stderr, "%s: mib510_isp(): can't get into sync\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
if (stk500_getsync(pgm) < 0)
|
||||
return -1;
|
||||
goto retry;
|
||||
}
|
||||
else if (buf[0] != Resp_STK_INSYNC) {
|
||||
fprintf(stderr,
|
||||
"%s: mib510_isp(): protocol error, "
|
||||
"expect=0x%02x, resp=0x%02x\n",
|
||||
progname, Resp_STK_INSYNC, buf[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
if (buf[0] == Resp_STK_OK) {
|
||||
return 0;
|
||||
}
|
||||
else if (buf[0] == Resp_STK_NODEVICE) {
|
||||
fprintf(stderr, "%s: mib510_isp(): no device\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buf[0] == Resp_STK_FAILED)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: mib510_isp(): command %d failed\n",
|
||||
progname, cmd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
fprintf(stderr, "%s: mib510_isp(): unknown response=0x%02x\n",
|
||||
progname, buf[0]);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* initialize the AVR device and prepare it to accept commands
|
||||
@@ -417,18 +316,13 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
int tries;
|
||||
unsigned maj, min;
|
||||
int rc;
|
||||
int n_extparms;
|
||||
int n_extparms = 3;
|
||||
|
||||
stk500_getparm(pgm, Parm_STK_SW_MAJOR, &maj);
|
||||
stk500_getparm(pgm, Parm_STK_SW_MINOR, &min);
|
||||
|
||||
// MIB510 does not need extparams
|
||||
if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0)
|
||||
n_extparms = 0;
|
||||
else if ((maj > 1) || ((maj == 1) && (min > 10)))
|
||||
if ((maj > 1) || ((maj == 1) && (min > 10)))
|
||||
n_extparms = 4;
|
||||
else
|
||||
n_extparms = 3;
|
||||
|
||||
tries = 0;
|
||||
|
||||
@@ -532,17 +426,16 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
buf[21] = Sync_CRC_EOP;
|
||||
|
||||
stk500_send(pgm, buf, 22);
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 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;
|
||||
if (stk500_getsync(pgm) < 0)
|
||||
return -1;
|
||||
stk500_getsync(pgm);
|
||||
goto retry;
|
||||
return -1;
|
||||
}
|
||||
else if (buf[0] != Resp_STK_INSYNC) {
|
||||
fprintf(stderr,
|
||||
@@ -552,8 +445,7 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] != Resp_STK_OK) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500_initialize(): (b) protocol error, "
|
||||
@@ -564,40 +456,37 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
|
||||
|
||||
if (n_extparms) {
|
||||
if ((p->pagel == 0) || (p->bs2 == 0)) {
|
||||
if (verbose > 1)
|
||||
fprintf(stderr,
|
||||
"%s: PAGEL and BS2 signals not defined in the configuration "
|
||||
"file for part %s, using dummy values\n",
|
||||
progname, p->desc);
|
||||
buf[2] = 0xD7; /* they look somehow possible, */
|
||||
buf[3] = 0xA0; /* don't they? ;) */
|
||||
fprintf(stderr,
|
||||
"%s: please define PAGEL and BS2 signals in the configuration "
|
||||
"file for part %s\n",
|
||||
progname, p->desc);
|
||||
}
|
||||
else {
|
||||
buf[0] = n_extparms+1;
|
||||
|
||||
/*
|
||||
* m is currently pointing to eeprom memory if the part has it
|
||||
*/
|
||||
if (m)
|
||||
buf[1] = m->page_size;
|
||||
else
|
||||
buf[1] = 0;
|
||||
|
||||
buf[2] = p->pagel;
|
||||
buf[3] = p->bs2;
|
||||
}
|
||||
buf[0] = n_extparms+1;
|
||||
|
||||
/*
|
||||
* m is currently pointing to eeprom memory if the part has it
|
||||
*/
|
||||
if (m)
|
||||
buf[1] = m->page_size;
|
||||
else
|
||||
buf[1] = 0;
|
||||
|
||||
|
||||
if (n_extparms == 4) {
|
||||
if (p->reset_disposition == RESET_DEDICATED)
|
||||
buf[4] = 0;
|
||||
else
|
||||
buf[4] = 1;
|
||||
}
|
||||
|
||||
rc = stk500_set_extended_parms(pgm, n_extparms+1, buf);
|
||||
if (rc) {
|
||||
fprintf(stderr, "%s: stk500_initialize(): failed\n", progname);
|
||||
exit(1);
|
||||
|
||||
if (n_extparms == 4) {
|
||||
if (p->reset_disposition == RESET_DEDICATED)
|
||||
buf[4] = 0;
|
||||
else
|
||||
buf[4] = 1;
|
||||
}
|
||||
|
||||
rc = stk500_set_extended_parms(pgm, n_extparms+1, buf);
|
||||
if (rc) {
|
||||
fprintf(stderr, "%s: stk500_initialize(): failed\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,16 +507,14 @@ static void stk500_disable(PROGRAMMER * pgm)
|
||||
buf[1] = Sync_CRC_EOP;
|
||||
|
||||
stk500_send(pgm, buf, 2);
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] == Resp_STK_NOSYNC) {
|
||||
if (tries > 33) {
|
||||
fprintf(stderr, "%s: stk500_disable(): can't get into sync\n",
|
||||
progname);
|
||||
return;
|
||||
}
|
||||
if (stk500_getsync(pgm) < 0)
|
||||
return;
|
||||
stk500_getsync(pgm);
|
||||
goto retry;
|
||||
}
|
||||
else if (buf[0] != Resp_STK_INSYNC) {
|
||||
@@ -638,8 +525,7 @@ static void stk500_disable(PROGRAMMER * pgm)
|
||||
return;
|
||||
}
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] == Resp_STK_OK) {
|
||||
return;
|
||||
}
|
||||
@@ -664,22 +550,19 @@ static void stk500_enable(PROGRAMMER * pgm)
|
||||
static int stk500_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
strcpy(pgm->port, port);
|
||||
if (serial_open(port, pgm->baudrate? pgm->baudrate: 115200, &pgm->fd)==-1) {
|
||||
return -1;
|
||||
}
|
||||
if (pgm->baudrate)
|
||||
pgm->fd = serial_open(port, pgm->baudrate);
|
||||
else
|
||||
pgm->fd = serial_open(port, 115200);
|
||||
|
||||
/*
|
||||
* drain any extraneous input
|
||||
*/
|
||||
stk500_drain(pgm, 0);
|
||||
|
||||
// MIB510 init
|
||||
if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0 &&
|
||||
mib510_isp(pgm, 1) != 0)
|
||||
return -1;
|
||||
stk500_getsync(pgm);
|
||||
|
||||
if (stk500_getsync(pgm) < 0)
|
||||
return -1;
|
||||
stk500_drain(pgm, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -687,12 +570,8 @@ static int stk500_open(PROGRAMMER * pgm, char * port)
|
||||
|
||||
static void stk500_close(PROGRAMMER * pgm)
|
||||
{
|
||||
// MIB510 close
|
||||
if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0)
|
||||
(void)mib510_isp(pgm, 0);
|
||||
|
||||
serial_close(&pgm->fd);
|
||||
pgm->fd.ifd = -1;
|
||||
serial_close(pgm->fd);
|
||||
pgm->fd = -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -711,16 +590,14 @@ static int stk500_loadaddr(PROGRAMMER * pgm, unsigned int addr)
|
||||
|
||||
stk500_send(pgm, buf, 4);
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] == Resp_STK_NOSYNC) {
|
||||
if (tries > 33) {
|
||||
fprintf(stderr, "%s: stk500_loadaddr(): can't get into sync\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
if (stk500_getsync(pgm) < 0)
|
||||
return -1;
|
||||
stk500_getsync(pgm);
|
||||
goto retry;
|
||||
}
|
||||
else if (buf[0] != Resp_STK_INSYNC) {
|
||||
@@ -731,8 +608,7 @@ static int stk500_loadaddr(PROGRAMMER * pgm, unsigned int addr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] == Resp_STK_OK) {
|
||||
return 0;
|
||||
}
|
||||
@@ -746,23 +622,29 @@ static int stk500_loadaddr(PROGRAMMER * pgm, unsigned int addr)
|
||||
}
|
||||
|
||||
|
||||
static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes)
|
||||
static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
unsigned char buf[page_size + 16];
|
||||
unsigned char buf[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) {
|
||||
page_size = 128;
|
||||
}
|
||||
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
memtype = 'F';
|
||||
flash = 1;
|
||||
}
|
||||
else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
memtype = 'E';
|
||||
flash = 0;
|
||||
}
|
||||
else {
|
||||
return -2;
|
||||
@@ -773,7 +655,19 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
else
|
||||
a_div = 1;
|
||||
|
||||
n = addr + n_bytes;
|
||||
if (n_bytes > m->size) {
|
||||
n_bytes = m->size;
|
||||
n = m->size;
|
||||
}
|
||||
else {
|
||||
if ((n_bytes % page_size) != 0) {
|
||||
n = n_bytes + page_size - (n_bytes % page_size);
|
||||
}
|
||||
else {
|
||||
n = n_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
fprintf(stderr,
|
||||
"n_bytes = %d\n"
|
||||
@@ -783,43 +677,45 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
n_bytes, n, a_div, page_size);
|
||||
#endif
|
||||
|
||||
for (; addr < n; addr += block_size) {
|
||||
// MIB510 uses fixed blocks size of 256 bytes
|
||||
if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0) {
|
||||
block_size = 256;
|
||||
} else {
|
||||
if (n - addr < page_size)
|
||||
block_size = n - addr;
|
||||
else
|
||||
block_size = page_size;
|
||||
for (addr = 0; addr < n; addr += page_size) {
|
||||
report_progress (addr, n_bytes, NULL);
|
||||
|
||||
if (addr + page_size > n_bytes) {
|
||||
block_size = n_bytes % page_size;
|
||||
}
|
||||
else {
|
||||
block_size = page_size;
|
||||
}
|
||||
|
||||
/* Only skip on empty page if programming flash. */
|
||||
if (flash) {
|
||||
if (stk500_is_page_empty(addr, block_size, m->buf)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
tries = 0;
|
||||
retry:
|
||||
tries++;
|
||||
stk500_loadaddr(pgm, addr/a_div);
|
||||
buf[0] = Cmnd_STK_PROG_PAGE;
|
||||
buf[1] = (block_size >> 8) & 0xff;
|
||||
buf[2] = block_size & 0xff;
|
||||
buf[3] = memtype;
|
||||
stk500_send(pgm, buf, 4);
|
||||
|
||||
/* 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);
|
||||
stk500_send(pgm, &m->buf[addr], block_size);
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
buf[0] = Sync_CRC_EOP;
|
||||
stk500_send(pgm, buf, 1);
|
||||
|
||||
stk500_recv(pgm, buf, 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;
|
||||
}
|
||||
if (stk500_getsync(pgm) < 0)
|
||||
return -1;
|
||||
stk500_getsync(pgm);
|
||||
goto retry;
|
||||
}
|
||||
else if (buf[0] != Resp_STK_INSYNC) {
|
||||
@@ -830,8 +726,7 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
return -4;
|
||||
}
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] != Resp_STK_OK) {
|
||||
fprintf(stderr,
|
||||
"\n%s: stk500_paged_write(): (a) protocol error, "
|
||||
@@ -844,12 +739,27 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
return n_bytes;
|
||||
}
|
||||
|
||||
static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes)
|
||||
static int stk500_is_page_empty(unsigned int address, int page_size,
|
||||
const unsigned char *buf)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < page_size; i++) {
|
||||
if(buf[address + i] != 0xFF) {
|
||||
/* Page is not empty. */
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Page is empty. */
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int n_bytes)
|
||||
{
|
||||
unsigned char buf[16];
|
||||
int memtype;
|
||||
unsigned int addr;
|
||||
int a_div;
|
||||
int tries;
|
||||
unsigned int n;
|
||||
@@ -870,18 +780,29 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
else
|
||||
a_div = 1;
|
||||
|
||||
n = addr + n_bytes;
|
||||
for (; addr < n; addr += block_size) {
|
||||
// MIB510 uses fixed blocks size of 256 bytes
|
||||
if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0) {
|
||||
block_size = 256;
|
||||
} else {
|
||||
if (n - addr < page_size)
|
||||
block_size = n - addr;
|
||||
else
|
||||
block_size = page_size;
|
||||
if (n_bytes > m->size) {
|
||||
n_bytes = m->size;
|
||||
n = m->size;
|
||||
}
|
||||
else {
|
||||
if ((n_bytes % page_size) != 0) {
|
||||
n = n_bytes + page_size - (n_bytes % page_size);
|
||||
}
|
||||
else {
|
||||
n = n_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
for (addr = 0; addr < n; addr += page_size) {
|
||||
report_progress (addr, n_bytes, NULL);
|
||||
|
||||
if (addr + page_size > n_bytes) {
|
||||
block_size = n_bytes % page_size;
|
||||
}
|
||||
else {
|
||||
block_size = page_size;
|
||||
}
|
||||
|
||||
tries = 0;
|
||||
retry:
|
||||
tries++;
|
||||
@@ -893,16 +814,14 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
buf[4] = Sync_CRC_EOP;
|
||||
stk500_send(pgm, buf, 5);
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 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;
|
||||
}
|
||||
if (stk500_getsync(pgm) < 0)
|
||||
return -1;
|
||||
stk500_getsync(pgm);
|
||||
goto retry;
|
||||
}
|
||||
else if (buf[0] != Resp_STK_INSYNC) {
|
||||
@@ -913,14 +832,10 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
return -4;
|
||||
}
|
||||
|
||||
if (stk500_recv(pgm, &m->buf[addr], block_size) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, &m->buf[addr], block_size);
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
|
||||
if(strcmp(ldata(lfirst(pgm->id)), "mib510") == 0) {
|
||||
if (buf[0] != Resp_STK_INSYNC) {
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] != Resp_STK_OK) {
|
||||
fprintf(stderr,
|
||||
"\n%s: stk500_paged_load(): (a) protocol error, "
|
||||
"expect=0x%02x, resp=0x%02x\n",
|
||||
@@ -928,16 +843,6 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
return -5;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (buf[0] != Resp_STK_OK) {
|
||||
fprintf(stderr,
|
||||
"\n%s: stk500_paged_load(): (a) protocol error, "
|
||||
"expect=0x%02x, resp=0x%02x\n",
|
||||
progname, Resp_STK_OK, buf[0]);
|
||||
return -5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return n_bytes;
|
||||
}
|
||||
@@ -968,8 +873,7 @@ static int stk500_set_vtarget(PROGRAMMER * pgm, double v)
|
||||
}
|
||||
|
||||
|
||||
static int stk500_set_varef(PROGRAMMER * pgm, unsigned int chan /* unused */,
|
||||
double v)
|
||||
static int stk500_set_varef(PROGRAMMER * pgm, double v)
|
||||
{
|
||||
unsigned uaref, utarg;
|
||||
|
||||
@@ -1089,16 +993,14 @@ static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
|
||||
|
||||
stk500_send(pgm, buf, 3);
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 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;
|
||||
}
|
||||
if (stk500_getsync(pgm) < 0)
|
||||
return -1;
|
||||
stk500_getsync(pgm);
|
||||
goto retry;
|
||||
}
|
||||
else if (buf[0] != Resp_STK_INSYNC) {
|
||||
@@ -1109,12 +1011,10 @@ static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 1);
|
||||
v = buf[0];
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] == Resp_STK_FAILED) {
|
||||
fprintf(stderr,
|
||||
"\n%s: stk500_getparm(): parameter 0x%02x failed\n",
|
||||
@@ -1149,16 +1049,14 @@ static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value)
|
||||
|
||||
stk500_send(pgm, buf, 4);
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] == Resp_STK_NOSYNC) {
|
||||
if (tries > 33) {
|
||||
fprintf(stderr, "\n%s: stk500_setparm(): can't get into sync\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
if (stk500_getsync(pgm) < 0)
|
||||
return -1;
|
||||
stk500_getsync(pgm);
|
||||
goto retry;
|
||||
}
|
||||
else if (buf[0] != Resp_STK_INSYNC) {
|
||||
@@ -1169,14 +1067,12 @@ static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value)
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] == Resp_STK_OK)
|
||||
return 0;
|
||||
|
||||
parm = buf[0]; /* if not STK_OK, we've been echoed parm here */
|
||||
if (stk500_recv(pgm, buf, 1) < 0)
|
||||
exit(1);
|
||||
stk500_recv(pgm, buf, 1);
|
||||
if (buf[0] == Resp_STK_FAILED) {
|
||||
fprintf(stderr,
|
||||
"\n%s: stk500_setparm(): parameter 0x%02x failed\n",
|
||||
@@ -1193,7 +1089,7 @@ static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value)
|
||||
}
|
||||
|
||||
|
||||
static void stk500_display(PROGRAMMER * pgm, const char * p)
|
||||
static void stk500_display(PROGRAMMER * pgm, char * p)
|
||||
{
|
||||
unsigned maj, min, hdw, topcard;
|
||||
|
||||
@@ -1224,7 +1120,7 @@ static void stk500_display(PROGRAMMER * pgm, const char * p)
|
||||
}
|
||||
|
||||
|
||||
static void stk500_print_parms1(PROGRAMMER * pgm, const char * p)
|
||||
static void stk500_print_parms1(PROGRAMMER * pgm, char * p)
|
||||
{
|
||||
unsigned vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration;
|
||||
|
||||
@@ -1276,7 +1172,6 @@ static void stk500_print_parms(PROGRAMMER * pgm)
|
||||
stk500_print_parms1(pgm, "");
|
||||
}
|
||||
|
||||
const char stk500_desc[] = "Atmel STK500 Version 1.x firmware";
|
||||
|
||||
void stk500_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
@@ -1294,8 +1189,6 @@ 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
|
||||
|
||||
@@ -13,29 +13,17 @@
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
* 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 stk500_h
|
||||
#define stk500_h
|
||||
#ifndef __stk500_h__
|
||||
#define __stk500_h__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char stk500_desc[];
|
||||
void stk500_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
/* used by arduino.c to avoid duplicate code */
|
||||
int stk500_getsync(PROGRAMMER * pgm);
|
||||
int stk500_drain(PROGRAMMER * pgm, int display);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* avrdude interface for Atmel STK500 programmer
|
||||
*
|
||||
* This is a wrapper around the STK500[v1] and STK500v2 programmers.
|
||||
* Try to select the programmer type that actually responds, and
|
||||
* divert to the actual programmer implementation if successful.
|
||||
*/
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "pgm.h"
|
||||
#include "stk500generic.h"
|
||||
#include "stk500.h"
|
||||
#include "stk500v2.h"
|
||||
|
||||
static int stk500generic_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
stk500_initpgm(pgm);
|
||||
if (pgm->open(pgm, port) >= 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: successfully opened stk500v1 device -- please use -c stk500v1\n",
|
||||
progname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pgm->close(pgm);
|
||||
|
||||
stk500v2_initpgm(pgm);
|
||||
if (pgm->open(pgm, port) >= 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: successfully opened stk500v2 device -- please use -c stk500v2\n",
|
||||
progname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"%s: cannot open either stk500v1 or stk500v2 programmer\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void stk500generic_setup(PROGRAMMER * pgm)
|
||||
{
|
||||
/*
|
||||
* Only STK500v2 needs setup/teardown.
|
||||
*/
|
||||
stk500v2_initpgm(pgm);
|
||||
pgm->setup(pgm);
|
||||
}
|
||||
|
||||
static void stk500generic_teardown(PROGRAMMER * pgm)
|
||||
{
|
||||
stk500v2_initpgm(pgm);
|
||||
pgm->teardown(pgm);
|
||||
}
|
||||
|
||||
const char stk500generic_desc[] = "Atmel STK500, autodetect firmware version";
|
||||
|
||||
void stk500generic_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
strcpy(pgm->type, "STK500GENERIC");
|
||||
|
||||
pgm->open = stk500generic_open;
|
||||
pgm->setup = stk500generic_setup;
|
||||
pgm->teardown = stk500generic_teardown;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef stk500generic_h__
|
||||
#define stk500generic_h__
|
||||
|
||||
extern const char stk500generic_desc[];
|
||||
void stk500generic_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
4069
avrdude/stk500v2.c
4069
avrdude/stk500v2.c
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user