avrdude-6.2/ 000755 000153 000000 00000000000 12622456146 012401 5 ustar 00j wheel 000000 000000 avrdude-6.2/config.guess 000755 000153 000000 00000127737 12622456107 014737 0 ustar 00j wheel 000000 000000 #! /bin/sh
# Attempt to guess a canonical system name.
# Copyright 1992-2013 Free Software Foundation, Inc.
timestamp='2013-05-16'
# This file 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 3 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 .
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
#
# Originally written by Per Bothner.
#
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
#
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION]
Output the configuration name of the system \`$me' is run on.
Operation modes:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to ."
version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright 1992-2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit ;;
--version | -v )
echo "$version" ; exit ;;
--help | --h* | -h )
echo "$usage"; exit ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help" >&2
exit 1 ;;
* )
break ;;
esac
done
if test $# != 0; then
echo "$me: too many arguments$help" >&2
exit 1
fi
trap 'exit 1' 1 2 15
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.
# Portable tmp directory creation inspired by the Autoconf team.
set_cc_for_build='
trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
: ${TMPDIR=/tmp} ;
{ tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
dummy=$tmp/dummy ;
tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
case $CC_FOR_BUILD,$HOST_CC,$CC in
,,) echo "int x;" > $dummy.c ;
for c in cc gcc c89 c99 ; do
if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
CC_FOR_BUILD="$c"; break ;
fi ;
done ;
if test x"$CC_FOR_BUILD" = x ; then
CC_FOR_BUILD=no_compiler_found ;
fi
;;
,,*) CC_FOR_BUILD=$CC ;;
,*,*) CC_FOR_BUILD=$HOST_CC ;;
esac ; set_cc_for_build= ;'
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
PATH=$PATH:/.attbin ; export PATH
fi
UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
case "${UNAME_SYSTEM}" in
Linux|GNU|GNU/*)
# If the system lacks a compiler, then just pick glibc.
# We could probably try harder.
LIBC=gnu
eval $set_cc_for_build
cat <<-EOF > $dummy.c
#include
#if defined(__UCLIBC__)
LIBC=uclibc
#elif defined(__dietlibc__)
LIBC=dietlibc
#else
LIBC=gnu
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
;;
esac
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
# compatibility and a consistent mechanism for selecting the
# object file format.
#
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch"
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
/usr/sbin/$sysctl 2>/dev/null || echo unknown)`
case "${UNAME_MACHINE_ARCH}" in
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently, or will in the future.
case "${UNAME_MACHINE_ARCH}" in
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ELF__
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
os=netbsd
else
os=netbsdelf
fi
;;
*)
os=netbsd
;;
esac
# The OS release
# Debian GNU/NetBSD machines have a different userland, and
# thus, need a distinct triplet. However, they do not need
# kernel version information, so it can be replaced with a
# suitable tag, in the style of linux-gnu.
case "${UNAME_VERSION}" in
Debian*)
release='-gnu'
;;
*)
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit ;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
exit ;;
*:ekkoBSD:*:*)
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
exit ;;
*:SolidBSD:*:*)
echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
exit ;;
macppc:MirBSD:*:*)
echo powerpc-unknown-mirbsd${UNAME_RELEASE}
exit ;;
*:MirBSD:*:*)
echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
exit ;;
alpha:OSF1:*:*)
case $UNAME_RELEASE in
*4.0)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
# OSF/1 and Tru64 systems produced since 1995. I hope that
# covers most systems running today. This code pipes the CPU
# types through head -n 1, so we only detect the type of CPU 0.
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
case "$ALPHA_CPU_TYPE" in
"EV4 (21064)")
UNAME_MACHINE="alpha" ;;
"EV4.5 (21064)")
UNAME_MACHINE="alpha" ;;
"LCA4 (21066/21068)")
UNAME_MACHINE="alpha" ;;
"EV5 (21164)")
UNAME_MACHINE="alphaev5" ;;
"EV5.6 (21164A)")
UNAME_MACHINE="alphaev56" ;;
"EV5.6 (21164PC)")
UNAME_MACHINE="alphapca56" ;;
"EV5.7 (21164PC)")
UNAME_MACHINE="alphapca57" ;;
"EV6 (21264)")
UNAME_MACHINE="alphaev6" ;;
"EV6.7 (21264A)")
UNAME_MACHINE="alphaev67" ;;
"EV6.8CB (21264C)")
UNAME_MACHINE="alphaev68" ;;
"EV6.8AL (21264B)")
UNAME_MACHINE="alphaev68" ;;
"EV6.8CX (21264D)")
UNAME_MACHINE="alphaev68" ;;
"EV6.9A (21264/EV69A)")
UNAME_MACHINE="alphaev69" ;;
"EV7 (21364)")
UNAME_MACHINE="alphaev7" ;;
"EV7.9 (21364A)")
UNAME_MACHINE="alphaev79" ;;
esac
# A Pn.n version is a patched version.
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$?
trap '' 0
exit $exitcode ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
# of the specific Alpha model?
echo alpha-pc-interix
exit ;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
exit ;;
Amiga*:UNIX_System_V:4.0:*)
echo m68k-unknown-sysv4
exit ;;
*:[Aa]miga[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-amigaos
exit ;;
*:[Mm]orph[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-morphos
exit ;;
*:OS/390:*:*)
echo i370-ibm-openedition
exit ;;
*:z/VM:*:*)
echo s390-ibm-zvmoe
exit ;;
*:OS400:*:*)
echo powerpc-ibm-os400
exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit ;;
arm*:riscos:*:*|arm*:RISCOS:*:*)
echo arm-unknown-riscos
exit ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
echo hppa1.1-hitachi-hiuxmpp
exit ;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then
echo pyramid-pyramid-sysv3
else
echo pyramid-pyramid-bsd
fi
exit ;;
NILE*:*:*:dcosx)
echo pyramid-pyramid-svr4
exit ;;
DRS?6000:unix:4.0:6*)
echo sparc-icl-nx6
exit ;;
DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
s390x:SunOS:*:*)
echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
echo i386-pc-auroraux${UNAME_RELEASE}
exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
eval $set_cc_for_build
SUN_ARCH="i386"
# If there is a compiler, see if it is configured for 64-bit objects.
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
# This test works for both compilers.
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
SUN_ARCH="x86_64"
fi
fi
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:*:*)
case "`/usr/bin/arch -k`" in
Series*|S4*)
UNAME_RELEASE=`uname -v`
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
exit ;;
sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE}
exit ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
echo m68k-sun-sunos${UNAME_RELEASE}
;;
sun4)
echo sparc-sun-sunos${UNAME_RELEASE}
;;
esac
exit ;;
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
exit ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
# > m68000). The system name ranges from "MiNT" over "FreeMiNT"
# to the lowercase version "mint" (or "freemint"). Finally
# the system name "TOS" denotes a system which is actually not
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
echo m68k-milan-mint${UNAME_RELEASE}
exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
echo m68k-hades-mint${UNAME_RELEASE}
exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit ;;
m68k:machten:*:*)
echo m68k-apple-machten${UNAME_RELEASE}
exit ;;
powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE}
exit ;;
RISC*:Mach:*:*)
echo mips-dec-mach_bsd4.3
exit ;;
RISC*:ULTRIX:*:*)
echo mips-dec-ultrix${UNAME_RELEASE}
exit ;;
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit ;;
2020:CLIX:*:* | 2430:CLIX:*:*)
echo clipper-intergraph-clix${UNAME_RELEASE}
exit ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#ifdef __cplusplus
#include /* for printf() prototype */
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c &&
dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
SYSTEM_NAME=`$dummy $dummyarg` &&
{ echo "$SYSTEM_NAME"; exit; }
echo mips-mips-riscos${UNAME_RELEASE}
exit ;;
Motorola:PowerMAX_OS:*:*)
echo powerpc-motorola-powermax
exit ;;
Motorola:*:4.3:PL8-*)
echo powerpc-harris-powermax
exit ;;
Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
echo powerpc-harris-powermax
exit ;;
Night_Hawk:Power_UNIX:*:*)
echo powerpc-harris-powerunix
exit ;;
m88k:CX/UX:7*:*)
echo m88k-harris-cxux7
exit ;;
m88k:*:4*:R4*)
echo m88k-motorola-sysv4
exit ;;
m88k:*:3*:R3*)
echo m88k-motorola-sysv3
exit ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
[ ${TARGET_BINARY_INTERFACE}x = x ]
then
echo m88k-dg-dgux${UNAME_RELEASE}
else
echo m88k-dg-dguxbcs${UNAME_RELEASE}
fi
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit ;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
echo m88k-motorola-sysv3
exit ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
echo m88k-tektronix-sysv3
exit ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
echo m68k-tektronix-bsd
exit ;;
*:IRIX*:*:*)
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
exit ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i*86:AIX:*:*)
echo i386-ibm-aix
exit ;;
ia64:AIX:*:*)
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
exit ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include
main()
{
if (!__power_pc())
exit(1);
puts("powerpc-ibm-aix3.2.5");
exit(0);
}
EOF
if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
then
echo "$SYSTEM_NAME"
else
echo rs6000-ibm-aix3.2.5
fi
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
else
echo rs6000-ibm-aix3.2
fi
exit ;;
*:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
exit ;;
*:AIX:*:*)
echo rs6000-ibm-aix
exit ;;
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
echo romp-ibm-bsd4.4
exit ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
exit ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
exit ;;
DPX/2?00:B.O.S.:*:*)
echo m68k-bull-sysv3
exit ;;
9000/[34]??:4.3bsd:1.*:*)
echo m68k-hp-bsd
exit ;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4
exit ;;
9000/[34678]??:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
esac ;;
esac
fi
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#define _HPUX_SOURCE
#include
#include
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
EOF
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
if [ ${HP_ARCH} = "hppa2.0w" ]
then
eval $set_cc_for_build
# hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
# 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
# generating 64-bit code. GNU and HP use different nomenclature:
#
# $ CC_FOR_BUILD=cc ./config.guess
# => hppa2.0w-hp-hpux11.23
# $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
# => hppa64-hp-hpux11.23
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
grep -q __LP64__
then
HP_ARCH="hppa2.0w"
else
HP_ARCH="hppa64"
fi
fi
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit ;;
ia64:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ia64-hp-hpux${HPUX_REV}
exit ;;
3050*:HI-UX:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include
int
main ()
{
long cpu = sysconf (_SC_CPU_VERSION);
/* The order matters, because CPU_IS_HP_MC68K erroneously returns
true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
results, however. */
if (CPU_IS_PA_RISC (cpu))
{
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
default: puts ("hppa-hitachi-hiuxwe2"); break;
}
}
else if (CPU_IS_HP_MC68K (cpu))
puts ("m68k-hitachi-hiuxwe2");
else puts ("unknown-hitachi-hiuxwe2");
exit (0);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
{ echo "$SYSTEM_NAME"; exit; }
echo unknown-hitachi-hiuxwe2
exit ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
echo hppa1.1-hp-bsd
exit ;;
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit ;;
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
exit ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
echo hppa1.1-hp-osf
exit ;;
hp8??:OSF1:*:*)
echo hppa1.0-hp-osf
exit ;;
i*86:OSF1:*:*)
if [ -x /usr/sbin/sysversion ] ; then
echo ${UNAME_MACHINE}-unknown-osf1mk
else
echo ${UNAME_MACHINE}-unknown-osf1
fi
exit ;;
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
exit ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
exit ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*[A-Z]90:*:*:*)
echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-e 's/\.[^.]*$/.X/'
exit ;;
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*T3E:*:*:*)
echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*SV1:*:*:*)
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
*:UNICOS/mp:*:*)
echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
5000:UNIX_System_V:4.*:*)
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit ;;
sparc*:BSD/OS:*:*)
echo sparc-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
UNAME_PROCESSOR=`/usr/bin/uname -p`
echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
*:MINGW64*:*)
echo ${UNAME_MACHINE}-pc-mingw64
exit ;;
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:MSYS*:*)
echo ${UNAME_MACHINE}-pc-msys
exit ;;
i*:windows32*:*)
# uname -m includes "-pc" on this system.
echo ${UNAME_MACHINE}-mingw32
exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
*:Interix*:*)
case ${UNAME_MACHINE} in
x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
authenticamd | genuineintel | EM64T)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
IA64)
echo ia64-unknown-interix${UNAME_RELEASE}
exit ;;
esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
8664:Windows_NT:*)
echo x86_64-pc-mks
exit ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
# UNAME_MACHINE based on the output of uname instead of i386?
echo i586-pc-interix
exit ;;
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
exit ;;
amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
echo x86_64-unknown-cygwin
exit ;;
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin
exit ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
*:GNU:*:*)
# the GNU system
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
aarch64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
PCA57) UNAME_MACHINE=alphapca56 ;;
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arc:Linux:*:* | arceb:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
else
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
fi
fi
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
cris:Linux:*:*)
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
crisv32:Linux:*:*)
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
frv:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
hexagon:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:Linux:*:*)
echo ${UNAME_MACHINE}-pc-linux-${LIBC}
exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m32r*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
mips:Linux:*:* | mips64:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef ${UNAME_MACHINE}
#undef ${UNAME_MACHINE}el
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=${UNAME_MACHINE}el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=${UNAME_MACHINE}
#else
CPU=
#endif
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;;
or1k:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
or32:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
padre:Linux:*:*)
echo sparc-unknown-linux-${LIBC}
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-${LIBC}
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
*) echo hppa-unknown-linux-${LIBC} ;;
esac
exit ;;
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-${LIBC}
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-${LIBC}
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
exit ;;
sh64*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
tile*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
exit ;;
x86_64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
# sysname and nodename.
echo i386-sequent-sysv4
exit ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
echo ${UNAME_MACHINE}-pc-os2-emx
exit ;;
i*86:XTS-300:*:STOP)
echo ${UNAME_MACHINE}-unknown-stop
exit ;;
i*86:atheos:*:*)
echo ${UNAME_MACHINE}-unknown-atheos
exit ;;
i*86:syllable:*:*)
echo ${UNAME_MACHINE}-pc-syllable
exit ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit ;;
i*86:*DOS:*:*)
echo ${UNAME_MACHINE}-pc-msdosdjgpp
exit ;;
i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
fi
exit ;;
i*86:*:5:[678]*)
# UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
exit ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
&& UNAME_MACHINE=i686
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-pc-sysv32
fi
exit ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i586.
# Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configury will decide that
# this is a cross-build.
echo i586-pc-msdosdjgpp
exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit ;;
paragon:*:*:*)
echo i860-intel-osf1
exit ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
fi
exit ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
echo m68010-convergent-sysv
exit ;;
mc68k:UNIX:SYSTEM5:3.51m)
echo m68k-convergent-sysv
exit ;;
M680?0:D-NIX:5.3:*)
echo m68k-diab-dnix
exit ;;
M68*:*:R3V[5678]*:*)
test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3${OS_REL}; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
OS_REL='.3'
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3${OS_REL}; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; }
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit ;;
TSUNAMI:LynxOS:2.*:*)
echo sparc-unknown-lynxos${UNAME_RELEASE}
exit ;;
rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
echo powerpc-unknown-lynxos${UNAME_RELEASE}
exit ;;
SM[BE]S:UNIX_SV:*:*)
echo mips-dde-sysv${UNAME_RELEASE}
exit ;;
RM*:ReliantUNIX-*:*:*)
echo mips-sni-sysv4
exit ;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
exit ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
echo ${UNAME_MACHINE}-sni-sysv4
else
echo ns32k-sni-sysv
fi
exit ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says
echo i586-unisys-sysv4
exit ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes .
# How about differentiating between stratus architectures? -djm
echo hppa1.1-stratus-sysv4
exit ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
echo i860-stratus-sysv4
exit ;;
i*86:VOS:*:*)
# From Paul.Green@stratus.com.
echo ${UNAME_MACHINE}-stratus-vos
exit ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
echo hppa1.1-stratus-vos
exit ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit ;;
news*:NEWS-OS:6*:*)
echo mips-sony-newsos6
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
fi
exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit ;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
echo powerpc-apple-beos
exit ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit ;;
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
echo i586-pc-haiku
exit ;;
x86_64:Haiku:*:*)
echo x86_64-unknown-haiku
exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
SX-5:SUPER-UX:*:*)
echo sx5-nec-superux${UNAME_RELEASE}
exit ;;
SX-6:SUPER-UX:*:*)
echo sx6-nec-superux${UNAME_RELEASE}
exit ;;
SX-7:SUPER-UX:*:*)
echo sx7-nec-superux${UNAME_RELEASE}
exit ;;
SX-8:SUPER-UX:*:*)
echo sx8-nec-superux${UNAME_RELEASE}
exit ;;
SX-8R:SUPER-UX:*:*)
echo sx8r-nec-superux${UNAME_RELEASE}
exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;;
*:Rhapsody:*:*)
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
eval $set_cc_for_build
if test "$UNAME_PROCESSOR" = unknown ; then
UNAME_PROCESSOR=powerpc
fi
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
case $UNAME_PROCESSOR in
i386) UNAME_PROCESSOR=x86_64 ;;
powerpc) UNAME_PROCESSOR=powerpc64 ;;
esac
fi
fi
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = "x86"; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
exit ;;
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
NEO-?:NONSTOP_KERNEL:*:*)
echo neo-tandem-nsk${UNAME_RELEASE}
exit ;;
NSE-*:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
NSR-?:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
exit ;;
*:NonStop-UX:*:*)
echo mips-compaq-nonstopux
exit ;;
BS2000:POSIX*:*:*)
echo bs2000-siemens-sysv
exit ;;
DS/*:UNIX_System_V:*:*)
echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
exit ;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
if test "$cputype" = "386"; then
UNAME_MACHINE=i386
else
UNAME_MACHINE="$cputype"
fi
echo ${UNAME_MACHINE}-unknown-plan9
exit ;;
*:TOPS-10:*:*)
echo pdp10-unknown-tops10
exit ;;
*:TENEX:*:*)
echo pdp10-unknown-tenex
exit ;;
KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
echo pdp10-dec-tops20
exit ;;
XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
echo pdp10-xkl-tops20
exit ;;
*:TOPS-20:*:*)
echo pdp10-unknown-tops20
exit ;;
*:ITS:*:*)
echo pdp10-unknown-its
exit ;;
SEI:*:*:SEIUX)
echo mips-sei-seiux${UNAME_RELEASE}
exit ;;
*:DragonFly:*:*)
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
*:*VMS:*:*)
UNAME_MACHINE=`(uname -p) 2>/dev/null`
case "${UNAME_MACHINE}" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
V*) echo vax-dec-vms ; exit ;;
esac ;;
*:XENIX:*:SysV)
echo i386-pc-xenix
exit ;;
i*86:skyos:*:*)
echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
exit ;;
i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos
exit ;;
i*86:AROS:*:*)
echo ${UNAME_MACHINE}-pc-aros
exit ;;
x86_64:VMkernel:*:*)
echo ${UNAME_MACHINE}-unknown-esx
exit ;;
esac
eval $set_cc_for_build
cat >$dummy.c <
# include
#endif
main ()
{
#if defined (sony)
#if defined (MIPSEB)
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
I don't know.... */
printf ("mips-sony-bsd\n"); exit (0);
#else
#include
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
#else
""
#endif
); exit (0);
#endif
#endif
#if defined (__arm) && defined (__acorn) && defined (__unix)
printf ("arm-acorn-riscix\n"); exit (0);
#endif
#if defined (hp300) && !defined (hpux)
printf ("m68k-hp-bsd\n"); exit (0);
#endif
#if defined (NeXT)
#if !defined (__ARCHITECTURE__)
#define __ARCHITECTURE__ "m68k"
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
exit (0);
#endif
#if defined (MULTIMAX) || defined (n16)
#if defined (UMAXV)
printf ("ns32k-encore-sysv\n"); exit (0);
#else
#if defined (CMU)
printf ("ns32k-encore-mach\n"); exit (0);
#else
printf ("ns32k-encore-bsd\n"); exit (0);
#endif
#endif
#endif
#if defined (__386BSD__)
printf ("i386-pc-bsd\n"); exit (0);
#endif
#if defined (sequent)
#if defined (i386)
printf ("i386-sequent-dynix\n"); exit (0);
#endif
#if defined (ns32000)
printf ("ns32k-sequent-dynix\n"); exit (0);
#endif
#endif
#if defined (_SEQUENT_)
struct utsname un;
uname(&un);
if (strncmp(un.version, "V2", 2) == 0) {
printf ("i386-sequent-ptx2\n"); exit (0);
}
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
printf ("i386-sequent-ptx1\n"); exit (0);
}
printf ("i386-sequent-ptx\n"); exit (0);
#endif
#if defined (vax)
# if !defined (ultrix)
# include
# if defined (BSD)
# if BSD == 43
printf ("vax-dec-bsd4.3\n"); exit (0);
# else
# if BSD == 199006
printf ("vax-dec-bsd4.3reno\n"); exit (0);
# else
printf ("vax-dec-bsd\n"); exit (0);
# endif
# endif
# else
printf ("vax-dec-bsd\n"); exit (0);
# endif
# else
printf ("vax-dec-ultrix\n"); exit (0);
# endif
#endif
#if defined (alliant) && defined (i860)
printf ("i860-alliant-bsd\n"); exit (0);
#endif
exit (1);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
{ echo "$SYSTEM_NAME"; exit; }
# Apollos put the system type in the environment.
test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
# Convex versions that predate uname can use getsysinfo(1)
if [ -x /usr/convex/getsysinfo ]
then
case `getsysinfo -f cpu_type` in
c1*)
echo c1-convex-bsd
exit ;;
c2*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit ;;
c34*)
echo c34-convex-bsd
exit ;;
c38*)
echo c38-convex-bsd
exit ;;
c4*)
echo c4-convex-bsd
exit ;;
esac
fi
cat >&2 < in order to provide the needed
information to handle your system.
config.guess timestamp = $timestamp
uname -m = `(uname -m) 2>/dev/null || echo unknown`
uname -r = `(uname -r) 2>/dev/null || echo unknown`
uname -s = `(uname -s) 2>/dev/null || echo unknown`
uname -v = `(uname -v) 2>/dev/null || echo unknown`
/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
hostinfo = `(hostinfo) 2>/dev/null`
/bin/universe = `(/bin/universe) 2>/dev/null`
/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
/bin/arch = `(/bin/arch) 2>/dev/null`
/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
UNAME_MACHINE = ${UNAME_MACHINE}
UNAME_RELEASE = ${UNAME_RELEASE}
UNAME_SYSTEM = ${UNAME_SYSTEM}
UNAME_VERSION = ${UNAME_VERSION}
EOF
exit 1
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
avrdude-6.2/avrdude.h 000644 000153 000000 00000003641 12622456071 014205 0 ustar 00j wheel 000000 000000 /*
* 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 .
*/
/* $Id: avrdude.h 1321 2014-06-13 20:07:40Z awachtler $ */
#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) */
int avrdude_message(const int msglvl, const char *format, ...);
#define MSG_INFO (0) /* no -v option, can be supressed with -qq */
#define MSG_NOTICE (1) /* displayed with -v */
#define MSG_NOTICE2 (2) /* displayed with -vv, used rarely */
#define MSG_DEBUG (3) /* displayed with -vvv */
#define MSG_TRACE (4) /* displayed with -vvvv, show trace commuication */
#define MSG_TRACE2 (5) /* displayed with -vvvvv */
#if defined(WIN32NATIVE)
#include "ac_cfg.h"
#include
#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
avrdude-6.2/par.h 000644 000153 000000 00000001771 12622456074 013342 0 ustar 00j wheel 000000 000000 /*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean
*
* 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 .
*/
/* $Id: par.h 1107 2012-11-20 14:03:50Z joerg_wunsch $ */
#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
avrdude-6.2/pindefs.c 000644 000153 000000 00000030532 12622456071 014175 0 ustar 00j wheel 000000 000000 /*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean
*
* 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 .
*/
/* $Id: pindefs.h 1132 2013-01-09 19:23:30Z rliebscher $ */
#include
#include
#include
#include "avrdude.h"
#include "libavrdude.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 int 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) {
avrdude_message(MSG_INFO, "Multiple pins found\n"); //TODO
return -1;
}
found = true;
*pinno = i;
if(pindef->inverse[i / PIN_FIELD_ELEMENT_SIZE] & (1 << (i % PIN_FIELD_ELEMENT_SIZE))) {
*pinno |= PIN_INVERSE;
}
}
}
return 0;
}
/**
* 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 int 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) {
avrdude_message(MSG_INFO, "Pins of higher index than max field size for old pinno found\n");
return -1;
}
if (pindef->mask[i] == 0) {
/* this pin function is not using any pins */
*pinno = 0;
} else 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 {
avrdude_message(MSG_INFO, "pins have different polarity set\n");
return -1;
}
} else if(pindef->mask[i] != 0) {
avrdude_message(MSG_INFO, "Pins have higher number than fit in old format\n");
return -1;
}
}
return 0;
}
/**
* Convert for given programmer new pin definitions to old pin definitions.
*
* @param[inout] pgm programmer whose pins shall be converted.
*/
int pgm_fill_old_pins(struct programmer_t * const pgm) {
if (pin_fill_old_pinlist(&(pgm->pin[PPI_AVR_VCC]), &(pgm->pinno[PPI_AVR_VCC])) < 0)
return -1;
if (pin_fill_old_pinlist(&(pgm->pin[PPI_AVR_BUFF]), &(pgm->pinno[PPI_AVR_BUFF])) < 0)
return -1;
if (pin_fill_old_pinno(&(pgm->pin[PIN_AVR_RESET]), &(pgm->pinno[PIN_AVR_RESET])) < 0)
return -1;
if (pin_fill_old_pinno(&(pgm->pin[PIN_AVR_SCK]), &(pgm->pinno[PIN_AVR_SCK])) < 0)
return -1;
if (pin_fill_old_pinno(&(pgm->pin[PIN_AVR_MOSI]), &(pgm->pinno[PIN_AVR_MOSI])) < 0)
return -1;
if (pin_fill_old_pinno(&(pgm->pin[PIN_AVR_MISO]), &(pgm->pinno[PIN_AVR_MISO])) < 0)
return -1;
if (pin_fill_old_pinno(&(pgm->pin[PIN_LED_ERR]), &(pgm->pinno[PIN_LED_ERR])) < 0)
return -1;
if (pin_fill_old_pinno(&(pgm->pin[PIN_LED_RDY]), &(pgm->pinno[PIN_LED_RDY])) < 0)
return -1;
if (pin_fill_old_pinno(&(pgm->pin[PIN_LED_PGM]), &(pgm->pinno[PIN_LED_PGM])) < 0)
return -1;
if (pin_fill_old_pinno(&(pgm->pin[PIN_LED_VFY]), &(pgm->pinno[PIN_LED_VFY])) < 0)
return -1;
return 0;
}
/**
* 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) {
avrdude_message(MSG_INFO, "%s: %s: Following pins are not valid pins for this function: %s\n",
progname, avr_pin_name(pinname), pinmask_to_str(invalid_used));
avrdude_message(MSG_NOTICE2, "%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) {
avrdude_message(MSG_INFO, "%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));
avrdude_message(MSG_NOTICE2, "%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) {
avrdude_message(MSG_INFO, "%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) {
avrdude_message(MSG_INFO, "%s: %s: Mandatory pin is not defined.\n",
progname, avr_pin_name(pinname));
}
is_ok = false;
}
if(!is_ok) {
rv = -1;
} else if(output) {
avrdude_message(MSG_DEBUG, "%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 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 "";
}
}
avrdude-6.2/config.h 000644 000153 000000 00000004266 12622456070 014023 0 ustar 00j wheel 000000 000000 /*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean
*
* 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 .
*/
/* $Id: config.h 1322 2014-06-17 20:08:28Z rliebscher $ */
/* These are the internal definitions needed for config parsing */
#ifndef config_h
#define config_h
#include "libavrdude.h"
#define MAX_STR_CONST 1024
enum { V_NONE, V_NUM, V_NUM_REAL, V_STR };
typedef struct value_t {
int type;
/*union { TODO: use an anonymous union here ? */
int number;
double number_real;
char * string;
/*};*/
} VALUE;
typedef struct token_t {
int primary;
VALUE value;
} TOKEN;
typedef struct token_t *token_p;
extern FILE * yyin;
extern PROGRAMMER * current_prog;
extern AVRPART * current_part;
extern AVRMEM * current_mem;
extern int lineno;
extern const char * infile;
extern LISTID string_list;
extern LISTID number_list;
#if !defined(HAS_YYSTYPE)
#define YYSTYPE token_p
#endif
extern YYSTYPE yylval;
extern char string_buf[MAX_STR_CONST];
extern char *string_buf_ptr;
#ifdef __cplusplus
extern "C" {
#endif
int yyparse(void);
int yyerror(char * errmsg, ...);
int yywarning(char * errmsg, ...);
TOKEN * new_token(int primary);
void free_token(TOKEN * tkn);
void free_tokens(int n, ...);
TOKEN * number(char * text);
TOKEN * number_real(char * text);
TOKEN * hexnumber(char * text);
TOKEN * string(char * text);
TOKEN * keyword(int primary);
void print_token(TOKEN * tkn);
void pyytext(void);
char * dup_string(const char * str);
#ifdef __cplusplus
}
#endif
#endif
avrdude-6.2/ppiwin.c 000644 000153 000000 00000021033 12622456074 014052 0 ustar 00j wheel 000000 000000 /*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003, 2004, 2006
* Eric B. Weddington
* Copyright 2008, Joerg Wunsch
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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 .
*/
/* $Id: ppiwin.c 1321 2014-06-13 20:07:40Z awachtler $ */
/*
This is the parallel port interface for Windows built using Cygwin.
In the ppi_* functions that access the parallel port registers,
fd = parallel port address
reg = register as defined in an enum in ppi.h. This must be converted
to a proper offset of the base address.
*/
#include "ac_cfg.h"
#if defined (WIN32NATIVE)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "avrdude.h"
#include "libavrdude.h"
#include "ppi.h"
#define DEVICE_LPT1 "lpt1"
#define DEVICE_LPT2 "lpt2"
#define DEVICE_LPT3 "lpt3"
#define DEVICE_MAX 3
typedef struct
{
const char *name;
int base_address;
} winpp;
static const winpp winports[DEVICE_MAX] =
{
{DEVICE_LPT1, 0x378},
{DEVICE_LPT2, 0x278},
{DEVICE_LPT3, 0x3BC},
};
/* FUNCTION PROTOTYPES */
static int winnt_pp_open(void);
static unsigned short port_get(union filedescriptor *fdp, int reg);
static unsigned char reg2offset(int reg);
static unsigned char inb(unsigned short port);
static void outb(unsigned char value, unsigned short port);
/* FUNCTION DEFINITIONS */
void ppi_open(char *port, union filedescriptor *fdp)
{
unsigned char i;
int fd;
fd = winnt_pp_open();
if(fd < 0)
{
avrdude_message(MSG_INFO, "%s: can't open device \"giveio\"\n\n", progname);
fdp->ifd = -1;
return;
}
/* Search the windows port names for a match */
fd = -1;
for(i = 0; i < DEVICE_MAX; i++)
{
if(strcmp(winports[i].name, port) == 0)
{
/* Set the file descriptor with the Windows parallel port base address. */
fd = winports[i].base_address;
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')
{
avrdude_message(MSG_INFO, "%s: port name \"%s\" is neither lpt1/2/3 nor valid number\n",
progname, port);
fd = -1;
}
}
if(fd < 0)
{
avrdude_message(MSG_INFO, "%s: can't open device \"%s\"\n\n", progname, port);
fdp->ifd = -1;
return;
}
fdp->ifd = fd;
}
#define DRIVERNAME "\\\\.\\giveio"
static int winnt_pp_open(void)
{
// Only try to use giveio under Windows NT/2000/XP.
OSVERSIONINFO ver_info;
memset(&ver_info, 0, sizeof(ver_info));
ver_info.dwOSVersionInfoSize = sizeof(ver_info);
if(!GetVersionEx(&ver_info))
{
return(-1);
}
else if(ver_info.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
HANDLE h = CreateFile(DRIVERNAME,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(h == INVALID_HANDLE_VALUE)
{
return(-1);
}
/* Close immediately. The process now has the rights it needs. */
if(h != NULL)
{
CloseHandle(h);
}
}
return(0);
}
void ppi_close(union filedescriptor *fdp)
{
return;
}
/*
* set the indicated bit of the specified register.
*/
int ppi_set(union filedescriptor *fdp, int reg, int bit)
{
unsigned char v;
unsigned short port;
port = port_get(fdp, reg);
v = inb(port);
v |= bit;
outb(v, port);
return 0;
}
/*
* clear the indicated bit of the specified register.
*/
int ppi_clr(union filedescriptor *fdp, int reg, int bit)
{
unsigned char v;
unsigned short port;
port = port_get(fdp, reg);
v = inb(port);
v &= ~bit;
outb(v, port);
return 0;
}
/*
* get the indicated bit of the specified register.
*/
int ppi_get(union filedescriptor *fdp, int reg, int bit)
{
unsigned char v;
v = inb(port_get(fdp, reg));
v &= bit;
return(v);
}
/*
* toggle the indicated bit of the specified register.
*/
int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
{
unsigned char v;
unsigned short port;
port = port_get(fdp, reg);
v = inb(port);
v ^= bit;
outb(v, port);
return 0;
}
/*
* get all bits of the specified register.
*/
int ppi_getall(union filedescriptor *fdp, int reg)
{
unsigned char v;
v = inb(port_get(fdp, reg));
return((int)v);
}
/*
* set all bits of the specified register to val.
*/
int ppi_setall(union filedescriptor *fdp, int reg, int val)
{
outb((unsigned char)val, port_get(fdp, reg));
return 0;
}
/* Calculate port address to access. */
static unsigned short port_get(union filedescriptor *fdp, int reg)
{
return((unsigned short)(fdp->ifd + reg2offset(reg)));
}
/* Convert register enum to offset of base address. */
static unsigned char reg2offset(int reg)
{
unsigned char offset = 0;
switch(reg)
{
case PPIDATA:
{
offset = 0;
break;
}
case PPISTATUS:
{
offset = 1;
break;
}
case PPICTRL:
{
offset = 2;
break;
}
}
return(offset);
}
/* Read in value from port. */
static unsigned char inb(unsigned short port)
{
unsigned char t;
asm volatile ("in %1, %0"
: "=a" (t)
: "d" (port));
return t;
}
/* Write value to port. */
static void outb(unsigned char value, unsigned short port)
{
asm volatile ("out %1, %0"
:
: "d" (port), "a" (value) );
return;
}
#if !defined(HAVE_GETTIMEOFDAY)
struct timezone;
int gettimeofday(struct timeval *tv, struct timezone *unused){
// i've found only ms resolution, avrdude expects us
SYSTEMTIME st;
GetSystemTime(&st);
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
#ifdef W32USLEEPDBG
# define DEBUG_QueryPerformanceCounter(arg) QueryPerformanceCounter(arg)
# define DEBUG_DisplayTimingInfo(start, stop, freq, us, has_highperf) \
do { \
unsigned long dt; \
dt = (unsigned long)((stop.QuadPart - start.QuadPart) * 1000 * 1000 \
/ freq.QuadPart); \
avrdude_message(MSG_INFO, \
"hpt:%i usleep usec:%lu sleep msec:%lu timed usec:%lu\n", \
has_highperf, us, ((us + 999) / 1000), dt); \
} while (0)
#else
# define DEBUG_QueryPerformanceCounter(arg)
# define DEBUG_DisplayTimingInfo(start, stop, freq, us, has_highperf)
#endif
#if !defined(HAVE_USLEEP)
int usleep(unsigned int us)
{
int has_highperf;
LARGE_INTEGER freq,start,stop,loopend;
// workaround: although usleep is very precise if using
// high-performance-timers there are sometimes problems with
// 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);
has_highperf=QueryPerformanceFrequency(&freq);
//has_highperf=0; // debug
if (has_highperf) {
QueryPerformanceCounter(&start);
loopend.QuadPart=start.QuadPart+freq.QuadPart*us/(1000*1000);
do {
QueryPerformanceCounter(&stop);
} while (stop.QuadPart<=loopend.QuadPart);
}
else {
DEBUG_QueryPerformanceCounter(&start);
Sleep(1);
Sleep( (DWORD)((us+999)/1000) );
DEBUG_QueryPerformanceCounter(&stop);
}
DEBUG_DisplayTimingInfo(start, stop, freq, us, has_highperf);
return 0;
}
#endif /* !HAVE_USLEEP */
#endif
avrdude-6.2/avrftdi.h 000644 000153 000000 00000002041 12622456070 014202 0 ustar 00j wheel 000000 000000 /*
* 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 .
*/
/* $Id: avrftdi.h 1329 2014-07-16 20:38:52Z joerg_wunsch $ */
#ifndef avrftdi_h
#define avrftdi_h
#include
#ifdef __cplusplus
extern "C" {
#endif
extern const char avrftdi_desc[];
void avrftdi_initpgm (PROGRAMMER * pgm);
#ifdef __cplusplus
}
#endif
#endif
avrdude-6.2/freebsd_ppi.h 000644 000153 000000 00000002354 12622456071 015035 0 ustar 00j wheel 000000 000000 /*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2005 Joerg Wunsch
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/* $Id: freebsd_ppi.h 1107 2012-11-20 14:03:50Z joerg_wunsch $ */
#ifndef freebsd_ppi_h
#define freebsd_ppi_h
#include
#define ppi_claim(fd) {}
#define ppi_release(fd) {}
#define DO_PPI_READ(fd, reg, valp) \
(void)ioctl(fd, \
(reg) == PPIDATA? PPIGDATA: ((reg) == PPICTRL? PPIGCTRL: PPIGSTATUS), \
valp)
#define DO_PPI_WRITE(fd, reg, valp) \
(void)ioctl(fd, \
(reg) == PPIDATA? PPISDATA: ((reg) == PPICTRL? PPISCTRL: PPISSTATUS), \
valp)
#endif /* freebsd_ppi_h */
avrdude-6.2/main.c 000644 000153 000000 00000117444 12622456074 013504 0 ustar 00j wheel 000000 000000 /*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2005 Brian S. Dean
* Copyright 2007-2014 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 .
*/
/* $Id: main.c 1347 2014-11-23 21:49:56Z joerg_wunsch $ */
/*
* Code to program an Atmel AVR device through one of the supported
* programmers.
*
* For parallel port connected programmers, the pin definitions can be
* changed via a config file. See the config file for instructions on
* how to add a programmer definition.
*
*/
#include "ac_cfg.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "avrdude.h"
#include "libavrdude.h"
#include "term.h"
/* Get VERSION from ac_cfg.h */
char * version = VERSION;
char * progname;
char progbuf[PATH_MAX]; /* temporary buffer of spaces the same
length as progname; used for lining up
multiline messages */
int avrdude_message(const int msglvl, const char *format, ...)
{
int rc = 0;
va_list ap;
if (verbose >= msglvl) {
va_start(ap, format);
rc = vfprintf(stderr, format, ap);
va_end(ap);
}
return rc;
}
struct list_walk_cookie
{
FILE *f;
const char *prefix;
};
static LISTID updates = NULL;
static LISTID extended_params = NULL;
static LISTID additional_config_files = NULL;
static PROGRAMMER * pgm;
/*
* global options
*/
int verbose; /* verbose output */
int quell_progress; /* un-verebose output */
int ovsigck; /* 1=override sig check, 0=don't */
/*
* usage message
*/
static void usage(void)
{
avrdude_message(MSG_INFO,
"Usage: %s [options]\n"
"Options:\n"
" -p Required. Specify AVR device.\n"
" -b Override RS-232 baud rate.\n"
" -B Specify JTAG/STK500v2 bit clock period (us).\n"
" -C Specify location of configuration file.\n"
" -c Specify programmer type.\n"
" -D Disable auto erase for flash memory\n"
" -i ISP Clock Delay [in microseconds]\n"
" -P Specify connection port.\n"
" -F Override invalid signature check.\n"
" -e Perform a chip erase.\n"
" -O Perform RC oscillator calibration (see AVR053). \n"
" -U :r|w|v:[:format]\n"
" Memory operation specification.\n"
" Multiple -U options are allowed, each request\n"
" is performed in the order specified.\n"
" -n Do not write anything to the device.\n"
" -V Do not verify.\n"
" -u Disable safemode, default when running from a script.\n"
" -s Silent safemode operation, will not ask you if\n"
" fuses should be changed back.\n"
" -t Enter terminal mode.\n"
" -E [,] List programmer exit specifications.\n"
" -x Pass to programmer.\n"
" -y Count # erase cycles in EEPROM.\n"
" -Y Initialize erase cycle # in EEPROM.\n"
" -v Verbose output. -v -v for more.\n"
" -q Quell progress output. -q -q for less.\n"
" -l logfile Use logfile rather than stderr for diagnostics.\n"
" -? Display this usage.\n"
"\navrdude version %s, URL: \n"
,progname, version);
}
static void update_progress_tty (int percent, double etime, char *hdr)
{
static char hashes[51];
static char *header;
static int last = 0;
int i;
setvbuf(stderr, (char*)NULL, _IONBF, 0);
hashes[50] = 0;
memset (hashes, ' ', 50);
for (i=0; i>1)*2;
setvbuf(stderr, (char*)NULL, _IONBF, 0);
if (hdr) {
avrdude_message(MSG_INFO, "\n%s | ", hdr);
last = 0;
done = 0;
}
else {
while ((cnt > last) && (done == 0)) {
avrdude_message(MSG_INFO, "#");
cnt -= 2;
}
}
if ((percent == 100) && (done == 0)) {
avrdude_message(MSG_INFO, " | 100%% %0.2fs\n\n", etime);
last = 0;
done = 1;
}
else
last = (percent>>1)*2; /* Make last a multiple of 2. */
setvbuf(stderr, (char*)NULL, _IOLBF, 0);
}
static void list_programmers_callback(const char *name, const char *desc,
const char *cfgname, int cfglineno,
void *cookie)
{
struct list_walk_cookie *c = (struct list_walk_cookie *)cookie;
if (verbose){
fprintf(c->f, "%s%-16s = %-30s [%s:%d]\n",
c->prefix, name, desc, cfgname, cfglineno);
} else {
fprintf(c->f, "%s%-16s = %-s\n",
c->prefix, name, desc);
}
}
static void list_programmers(FILE * f, const char *prefix, LISTID programmers)
{
struct list_walk_cookie c;
c.f = f;
c.prefix = prefix;
sort_programmers(programmers);
walk_programmers(programmers, list_programmers_callback, &c);
}
static void list_programmer_types_callback(const char *name, const char *desc,
void *cookie)
{
struct list_walk_cookie *c = (struct list_walk_cookie *)cookie;
fprintf(c->f, "%s%-16s = %-s\n",
c->prefix, name, desc);
}
static void list_programmer_types(FILE * f, const char *prefix)
{
struct list_walk_cookie c;
c.f = f;
c.prefix = prefix;
walk_programmer_types(list_programmer_types_callback, &c);
}
static void list_avrparts_callback(const char *name, const char *desc,
const char *cfgname, int cfglineno,
void *cookie)
{
struct list_walk_cookie *c = (struct list_walk_cookie *)cookie;
/* hide ids starting with '.' */
if ((verbose < 2) && (name[0] == '.'))
return;
if (verbose) {
fprintf(c->f, "%s%-8s = %-18s [%s:%d]\n",
c->prefix, name, desc, cfgname, cfglineno);
} else {
fprintf(c->f, "%s%-8s = %s\n",
c->prefix, name, desc);
}
}
static void list_parts(FILE * f, const char *prefix, LISTID avrparts)
{
struct list_walk_cookie c;
c.f = f;
c.prefix = prefix;
sort_avrparts(avrparts);
walk_avrparts(avrparts, list_avrparts_callback, &c);
}
static void exithook(void)
{
if (pgm->teardown)
pgm->teardown(pgm);
}
static void cleanup_main(void)
{
if (updates) {
ldestroy_cb(updates, (void(*)(void*))free_update);
updates = NULL;
}
if (extended_params) {
ldestroy(extended_params);
extended_params = NULL;
}
if (additional_config_files) {
ldestroy(additional_config_files);
additional_config_files = NULL;
}
cleanup_config();
}
/*
* main routine
*/
int main(int argc, char * argv [])
{
int rc; /* general return code checking */
int exitrc; /* exit code for main() */
int i; /* general loop counter */
int ch; /* options flag */
int len; /* length for various strings */
struct avrpart * p; /* which avr part we are programming */
AVRMEM * sig; /* signature data */
struct stat sb;
UPDATE * upd;
LNODEID * ln;
/* options / operating mode variables */
int erase; /* 1=erase chip, 0=don't */
int calibrate; /* 1=calibrate RC oscillator, 0=don't */
char * port; /* device port (/dev/xxx) */
int terminal; /* 1=enter terminal mode, 0=don't */
int verify; /* perform a verify operation */
char * exitspecs; /* exit specs string from command line */
char * programmer; /* programmer id */
char * partdesc; /* part id */
char sys_config[PATH_MAX]; /* system wide config file */
char usr_config[PATH_MAX]; /* per-user config file */
char * e; /* for strtol() error checking */
int baudrate; /* override default programmer baud rate */
double bitclock; /* Specify programmer bit clock (JTAG ICE) */
int ispdelay; /* Specify the delay for ISP clock */
int safemode; /* Enable safemode, 1=safemode on, 0=normal */
int silentsafe; /* Don't ask about fuses, 1=silent, 0=normal */
int init_ok; /* Device initialization worked well */
int is_open; /* Device open succeeded */
char * logfile; /* Use logfile rather than stderr for diagnostics */
enum updateflags uflags = UF_AUTO_ERASE; /* Flags for do_op() */
unsigned char safemode_lfuse = 0xff;
unsigned char safemode_hfuse = 0xff;
unsigned char safemode_efuse = 0xff;
unsigned char safemode_fuse = 0xff;
char * safemode_response;
int fuses_specified = 0;
int fuses_updated = 0;
#if !defined(WIN32NATIVE)
char * homedir;
#endif
/*
* Set line buffering for file descriptors so we see stdout and stderr
* properly interleaved.
*/
setvbuf(stdout, (char*)NULL, _IOLBF, 0);
setvbuf(stderr, (char*)NULL, _IOLBF, 0);
progname = strrchr(argv[0],'/');
#if defined (WIN32NATIVE)
/* take care of backslash as dir sep in W32 */
if (!progname) progname = strrchr(argv[0],'\\');
#endif /* WIN32NATIVE */
if (progname)
progname++;
else
progname = argv[0];
default_parallel[0] = 0;
default_serial[0] = 0;
default_bitclock = 0.0;
default_safemode = -1;
init_config();
atexit(cleanup_main);
updates = lcreat(NULL, 0);
if (updates == NULL) {
avrdude_message(MSG_INFO, "%s: cannot initialize updater list\n", progname);
exit(1);
}
extended_params = lcreat(NULL, 0);
if (extended_params == NULL) {
avrdude_message(MSG_INFO, "%s: cannot initialize extended parameter list\n", progname);
exit(1);
}
additional_config_files = lcreat(NULL, 0);
if (additional_config_files == NULL) {
avrdude_message(MSG_INFO, "%s: cannot initialize additional config files list\n", progname);
exit(1);
}
partdesc = NULL;
port = NULL;
erase = 0;
calibrate = 0;
p = NULL;
ovsigck = 0;
terminal = 0;
verify = 1; /* on by default */
quell_progress = 0;
exitspecs = NULL;
pgm = NULL;
programmer = default_programmer;
verbose = 0;
baudrate = 0;
bitclock = 0.0;
ispdelay = 0;
safemode = 1; /* Safemode on by default */
silentsafe = 0; /* Ask by default */
is_open = 0;
logfile = NULL;
#if defined(WIN32NATIVE)
win_sys_config_set(sys_config);
win_usr_config_set(usr_config);
#else
strcpy(sys_config, CONFIG_DIR);
i = strlen(sys_config);
if (i && (sys_config[i-1] != '/'))
strcat(sys_config, "/");
strcat(sys_config, "avrdude.conf");
usr_config[0] = 0;
homedir = getenv("HOME");
if (homedir != NULL) {
strcpy(usr_config, homedir);
i = strlen(usr_config);
if (i && (usr_config[i-1] != '/'))
strcat(usr_config, "/");
strcat(usr_config, ".avrduderc");
}
#endif
len = strlen(progname) + 2;
for (i=0; iop == DEVICE_WRITE) {
upd = dup_update(upd);
upd->op = DEVICE_VERIFY;
ladd(updates, upd);
}
break;
case 'v':
verbose++;
break;
case 'V':
verify = 0;
break;
case 'x':
ladd(extended_params, optarg);
break;
case 'y':
avrdude_message(MSG_INFO, "%s: erase cycle counter no longer supported\n",
progname);
break;
case 'Y':
avrdude_message(MSG_INFO, "%s: erase cycle counter no longer supported\n",
progname);
break;
case '?': /* help */
usage();
exit(0);
break;
default:
avrdude_message(MSG_INFO, "%s: invalid option -%c\n\n", progname, ch);
usage();
exit(1);
break;
}
}
if (logfile != NULL) {
FILE *newstderr = freopen(logfile, "w", stderr);
if (newstderr == NULL) {
/* Help! There's no stderr to complain to anymore now. */
printf("Cannot create logfile \"%s\": %s\n",
logfile, strerror(errno));
return 1;
}
}
if (quell_progress == 0) {
if (isatty (STDERR_FILENO))
update_progress = update_progress_tty;
else {
update_progress = update_progress_no_tty;
/* disable all buffering of stderr for compatibility with
software that captures and redirects output to a GUI
i.e. Programmers Notepad */
setvbuf( stderr, NULL, _IONBF, 0 );
setvbuf( stdout, NULL, _IONBF, 0 );
}
}
/*
* Print out an identifying string so folks can tell what version
* they are running
*/
avrdude_message(MSG_NOTICE, "\n%s: Version %s, compiled on %s at %s\n"
"%sCopyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/\n"
"%sCopyright (c) 2007-2014 Joerg Wunsch\n\n",
progname, version, __DATE__, __TIME__, progbuf, progbuf);
avrdude_message(MSG_NOTICE, "%sSystem wide configuration file is \"%s\"\n",
progbuf, sys_config);
rc = read_config(sys_config);
if (rc) {
avrdude_message(MSG_INFO, "%s: error reading system wide configuration file \"%s\"\n",
progname, sys_config);
exit(1);
}
if (usr_config[0] != 0) {
avrdude_message(MSG_NOTICE, "%sUser configuration file is \"%s\"\n",
progbuf, usr_config);
rc = stat(usr_config, &sb);
if ((rc < 0) || ((sb.st_mode & S_IFREG) == 0)) {
avrdude_message(MSG_NOTICE, "%sUser configuration file does not exist or is not a "
"regular file, skipping\n",
progbuf);
}
else {
rc = read_config(usr_config);
if (rc) {
avrdude_message(MSG_INFO, "%s: error reading user configuration file \"%s\"\n",
progname, usr_config);
exit(1);
}
}
}
if (lsize(additional_config_files) > 0) {
LNODEID ln1;
const char * p = NULL;
for (ln1=lfirst(additional_config_files); ln1; ln1=lnext(ln1)) {
p = ldata(ln1);
avrdude_message(MSG_NOTICE, "%sAdditional configuration file is \"%s\"\n",
progbuf, p);
rc = read_config(p);
if (rc) {
avrdude_message(MSG_INFO, "%s: error reading additional configuration file \"%s\"\n",
progname, p);
exit(1);
}
}
}
// set bitclock from configuration files unless changed by command line
if (default_bitclock > 0 && bitclock == 0.0) {
bitclock = default_bitclock;
}
avrdude_message(MSG_NOTICE, "\n");
if (partdesc) {
if (strcmp(partdesc, "?") == 0) {
avrdude_message(MSG_INFO, "\n");
avrdude_message(MSG_INFO, "Valid parts are:\n");
list_parts(stderr, " ", part_list);
avrdude_message(MSG_INFO, "\n");
exit(1);
}
}
if (programmer) {
if (strcmp(programmer, "?") == 0) {
avrdude_message(MSG_INFO, "\n");
avrdude_message(MSG_INFO, "Valid programmers are:\n");
list_programmers(stderr, " ", programmers);
avrdude_message(MSG_INFO, "\n");
exit(1);
}
if (strcmp(programmer, "?type") == 0) {
avrdude_message(MSG_INFO, "\n");
avrdude_message(MSG_INFO, "Valid programmer types are:\n");
list_programmer_types(stderr, " ");
avrdude_message(MSG_INFO, "\n");
exit(1);
}
}
if (programmer[0] == 0) {
avrdude_message(MSG_INFO, "\n%s: no programmer has been specified on the command line "
"or the config file\n",
progname);
avrdude_message(MSG_INFO, "%sSpecify a programmer using the -c option and try again\n\n",
progbuf);
exit(1);
}
pgm = locate_programmer(programmers, programmer);
if (pgm == NULL) {
avrdude_message(MSG_INFO, "\n");
avrdude_message(MSG_INFO, "%s: Can't find programmer id \"%s\"\n",
progname, programmer);
avrdude_message(MSG_INFO, "\nValid programmers are:\n");
list_programmers(stderr, " ", programmers);
avrdude_message(MSG_INFO, "\n");
exit(1);
}
if (pgm->initpgm) {
pgm->initpgm(pgm);
} else {
avrdude_message(MSG_INFO, "\n%s: Can't initialize the programmer.\n\n",
progname);
exit(1);
}
if (pgm->setup) {
pgm->setup(pgm);
}
if (pgm->teardown) {
atexit(exithook);
}
if (lsize(extended_params) > 0) {
if (pgm->parseextparams == NULL) {
avrdude_message(MSG_INFO, "%s: WARNING: Programmer doesn't support extended parameters,"
" -x option(s) ignored\n",
progname);
} else {
if (pgm->parseextparams(pgm, extended_params) < 0) {
avrdude_message(MSG_INFO, "%s: Error parsing extended parameter list\n",
progname);
exit(1);
}
}
}
if (port == NULL) {
switch (pgm->conntype)
{
case CONNTYPE_PARALLEL:
port = default_parallel;
break;
case CONNTYPE_SERIAL:
port = default_serial;
break;
case CONNTYPE_USB:
port = DEFAULT_USB;
break;
}
}
if (partdesc == NULL) {
avrdude_message(MSG_INFO, "%s: No AVR part has been specified, use \"-p Part\"\n\n",
progname);
avrdude_message(MSG_INFO, "Valid parts are:\n");
list_parts(stderr, " ", part_list);
avrdude_message(MSG_INFO, "\n");
exit(1);
}
p = locate_part(part_list, partdesc);
if (p == NULL) {
avrdude_message(MSG_INFO, "%s: AVR Part \"%s\" not found.\n\n",
progname, partdesc);
avrdude_message(MSG_INFO, "Valid parts are:\n");
list_parts(stderr, " ", part_list);
avrdude_message(MSG_INFO, "\n");
exit(1);
}
if (exitspecs != NULL) {
if (pgm->parseexitspecs == NULL) {
avrdude_message(MSG_INFO, "%s: WARNING: -E option not supported by this programmer type\n",
progname);
exitspecs = NULL;
}
else if (pgm->parseexitspecs(pgm, exitspecs) < 0) {
usage();
exit(1);
}
}
if (default_safemode == 0) {
/* configuration disables safemode: revert meaning of -u */
if (safemode == 0)
/* -u was given: enable safemode */
safemode = 1;
else
/* -u not given: turn off */
safemode = 0;
}
if (isatty(STDIN_FILENO) == 0 && silentsafe == 0)
safemode = 0; /* Turn off safemode if this isn't a terminal */
if(p->flags & AVRPART_AVR32) {
safemode = 0;
}
if(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_TPI)) {
safemode = 0;
}
if (avr_initmem(p) != 0)
{
avrdude_message(MSG_INFO, "\n%s: failed to initialize memories\n",
progname);
exit(1);
}
/*
* Now that we know which part we are going to program, locate any
* -U options using the default memory region, and fill in the
* device-dependent default region name, either "application" (for
* Xmega devices), or "flash" (everything else).
*/
for (ln=lfirst(updates); ln; ln=lnext(ln)) {
upd = ldata(ln);
if (upd->memtype == NULL) {
const char *mtype = (p->flags & AVRPART_HAS_PDI)? "application": "flash";
avrdude_message(MSG_NOTICE2, "%s: defaulting memtype in -U %c:%s option to \"%s\"\n",
progname,
(upd->op == DEVICE_READ)? 'r': (upd->op == DEVICE_WRITE)? 'w': 'v',
upd->filename, mtype);
if ((upd->memtype = strdup(mtype)) == NULL) {
avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
exit(1);
}
}
}
/*
* open the programmer
*/
if (port[0] == 0) {
avrdude_message(MSG_INFO, "\n%s: no port has been specified on the command line "
"or the config file\n",
progname);
avrdude_message(MSG_INFO, "%sSpecify a port using the -P option and try again\n\n",
progbuf);
exit(1);
}
if (verbose) {
avrdude_message(MSG_NOTICE, "%sUsing Port : %s\n", progbuf, port);
avrdude_message(MSG_NOTICE, "%sUsing Programmer : %s\n", progbuf, programmer);
if ((strcmp(pgm->type, "avr910") == 0)) {
avrdude_message(MSG_NOTICE, "%savr910_devcode (avrdude.conf) : ", progbuf);
if(p->avr910_devcode)avrdude_message(MSG_INFO, "0x%x\n", p->avr910_devcode);
else avrdude_message(MSG_NOTICE, "none\n");
}
}
if (baudrate != 0) {
avrdude_message(MSG_NOTICE, "%sOverriding Baud Rate : %d\n", progbuf, baudrate);
pgm->baudrate = baudrate;
}
if (bitclock != 0.0) {
avrdude_message(MSG_NOTICE, "%sSetting bit clk period : %.1f\n", progbuf, bitclock);
pgm->bitclock = bitclock * 1e-6;
}
if (ispdelay != 0) {
avrdude_message(MSG_NOTICE, "%sSetting isp clock delay : %3i\n", progbuf, ispdelay);
pgm->ispdelay = ispdelay;
}
rc = pgm->open(pgm, port);
if (rc < 0) {
exitrc = 1;
pgm->ppidata = 0; /* clear all bits at exit */
goto main_exit;
}
is_open = 1;
if (calibrate) {
/*
* perform an RC oscillator calibration
* as outlined in appnote AVR053
*/
if (pgm->perform_osccal == 0) {
avrdude_message(MSG_INFO, "%s: programmer does not support RC oscillator calibration\n",
progname);
exitrc = 1;
} else {
avrdude_message(MSG_INFO, "%s: performing RC oscillator calibration\n", progname);
exitrc = pgm->perform_osccal(pgm);
}
if (exitrc == 0 && quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: calibration value is now stored in EEPROM at address 0\n",
progname);
}
goto main_exit;
}
if (verbose) {
avr_display(stderr, p, progbuf, verbose);
avrdude_message(MSG_NOTICE, "\n");
programmer_display(pgm, progbuf);
}
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "\n");
}
exitrc = 0;
/*
* enable the programmer
*/
pgm->enable(pgm);
/*
* turn off all the status leds
*/
pgm->rdy_led(pgm, OFF);
pgm->err_led(pgm, OFF);
pgm->pgm_led(pgm, OFF);
pgm->vfy_led(pgm, OFF);
/*
* initialize the chip in preperation for accepting commands
*/
init_ok = (rc = pgm->initialize(pgm, p)) >= 0;
if (!init_ok) {
avrdude_message(MSG_INFO, "%s: initialization failed, rc=%d\n", progname, rc);
if (!ovsigck) {
avrdude_message(MSG_INFO, "%sDouble check connections and try again, "
"or use -F to override\n"
"%sthis check.\n\n",
progbuf, progbuf);
exitrc = 1;
goto main_exit;
}
}
/* indicate ready */
pgm->rdy_led(pgm, ON);
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: AVR device initialized and ready to accept instructions\n",
progname);
}
/*
* Let's read the signature bytes to make sure there is at least a
* chip on the other end that is responding correctly. A check
* against 0xffffff / 0x000000 should ensure that the signature bytes
* are valid.
*/
if(!(p->flags & AVRPART_AVR32)) {
int attempt = 0;
int waittime = 10000; /* 10 ms */
sig_again:
usleep(waittime);
if (init_ok) {
rc = avr_signature(pgm, p);
if (rc != 0) {
avrdude_message(MSG_INFO, "%s: error reading signature data, rc=%d\n",
progname, rc);
exitrc = 1;
goto main_exit;
}
}
sig = avr_locate_mem(p, "signature");
if (sig == NULL) {
avrdude_message(MSG_INFO, "%s: WARNING: signature data not defined for device \"%s\"\n",
progname, p->desc);
}
if (sig != NULL) {
int ff, zz;
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: Device signature = 0x", progname);
}
ff = zz = 1;
for (i=0; isize; i++) {
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%02x", sig->buf[i]);
}
if (sig->buf[i] != 0xff)
ff = 0;
if (sig->buf[i] != 0x00)
zz = 0;
}
if (quell_progress < 2) {
AVRPART * part;
part = locate_part_by_signature(part_list, sig->buf, sig->size);
if (part) {
avrdude_message(MSG_INFO, " (probably %s)", part->id);
}
}
if (ff || zz) {
if (++attempt < 3) {
waittime *= 5;
if (quell_progress < 2) {
avrdude_message(MSG_INFO, " (retrying)\n");
}
goto sig_again;
}
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "\n");
}
avrdude_message(MSG_INFO, "%s: Yikes! Invalid device signature.\n", progname);
if (!ovsigck) {
avrdude_message(MSG_INFO, "%sDouble check connections and try again, "
"or use -F to override\n"
"%sthis check.\n\n",
progbuf, progbuf);
exitrc = 1;
goto main_exit;
}
} else {
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "\n");
}
}
if (sig->size != 3 ||
sig->buf[0] != p->signature[0] ||
sig->buf[1] != p->signature[1] ||
sig->buf[2] != p->signature[2]) {
avrdude_message(MSG_INFO, "%s: Expected signature for %s is %02X %02X %02X\n",
progname, p->desc,
p->signature[0], p->signature[1], p->signature[2]);
if (!ovsigck) {
avrdude_message(MSG_INFO, "%sDouble check chip, "
"or use -F to override this check.\n",
progbuf);
exitrc = 1;
goto main_exit;
}
}
}
}
if (init_ok && safemode == 1) {
/* If safemode is enabled, go ahead and read the current low, high,
and extended fuse bytes as needed */
rc = safemode_readfuses(&safemode_lfuse, &safemode_hfuse,
&safemode_efuse, &safemode_fuse, pgm, p);
if (rc != 0) {
//Check if the programmer just doesn't support reading
if (rc == -5)
{
avrdude_message(MSG_NOTICE, "%s: safemode: Fuse reading not support by programmer.\n"
" Safemode disabled.\n", progname);
}
else
{
avrdude_message(MSG_INFO, "%s: safemode: To protect your AVR the programming "
"will be aborted\n",
progname);
exitrc = 1;
goto main_exit;
}
} else {
//Save the fuses as default
safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
}
}
if (uflags & UF_AUTO_ERASE) {
if ((p->flags & AVRPART_HAS_PDI) && pgm->page_erase != NULL &&
lsize(updates) > 0) {
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: NOTE: Programmer supports page erase for Xmega devices.\n"
"%sEach page will be erased before programming it, but no chip erase is performed.\n"
"%sTo disable page erases, specify the -D option; for a chip-erase, use the -e option.\n",
progname, progbuf, progbuf);
}
} else {
AVRMEM * m;
const char *memname = (p->flags & AVRPART_HAS_PDI)? "application": "flash";
uflags &= ~UF_AUTO_ERASE;
for (ln=lfirst(updates); ln; ln=lnext(ln)) {
upd = ldata(ln);
m = avr_locate_mem(p, upd->memtype);
if (m == NULL)
continue;
if ((strcasecmp(m->desc, memname) == 0) && (upd->op == DEVICE_WRITE)) {
erase = 1;
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: NOTE: \"%s\" memory has been specified, an erase cycle "
"will be performed\n"
"%sTo disable this feature, specify the -D option.\n",
progname, memname, progbuf);
}
break;
}
}
}
}
if (init_ok && erase) {
/*
* erase the chip's flash and eeprom memories, this is required
* before the chip can accept new programming
*/
if (uflags & UF_NOWRITE) {
avrdude_message(MSG_INFO, "%s: conflicting -e and -n options specified, NOT erasing chip\n",
progname);
} else {
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: erasing chip\n", progname);
}
exitrc = avr_chip_erase(pgm, p);
if(exitrc) goto main_exit;
}
}
if (terminal) {
/*
* terminal mode
*/
exitrc = terminal_mode(pgm, p);
}
if (!init_ok) {
/*
* If we came here by the -tF options, bail out now.
*/
exitrc = 1;
goto main_exit;
}
for (ln=lfirst(updates); ln; ln=lnext(ln)) {
upd = ldata(ln);
rc = do_op(pgm, p, upd, uflags);
if (rc) {
exitrc = 1;
break;
}
}
/* Right before we exit programming mode, which will make the fuse
bits active, check to make sure they are still correct */
if (safemode == 1) {
/* If safemode is enabled, go ahead and read the current low,
* high, and extended fuse bytes as needed */
unsigned char safemodeafter_lfuse = 0xff;
unsigned char safemodeafter_hfuse = 0xff;
unsigned char safemodeafter_efuse = 0xff;
unsigned char safemodeafter_fuse = 0xff;
unsigned char failures = 0;
char yes[1] = {'y'};
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "\n");
}
//Restore the default fuse values
safemode_memfuses(0, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
/* Try reading back fuses, make sure they are reliable to read back */
if (safemode_readfuses(&safemodeafter_lfuse, &safemodeafter_hfuse,
&safemodeafter_efuse, &safemodeafter_fuse, pgm, p) != 0) {
/* Uh-oh.. try once more to read back fuses */
if (safemode_readfuses(&safemodeafter_lfuse, &safemodeafter_hfuse,
&safemodeafter_efuse, &safemodeafter_fuse, pgm, p) != 0) {
avrdude_message(MSG_INFO, "%s: safemode: Sorry, reading back fuses was unreliable. "
"I have given up and exited programming mode\n",
progname);
exitrc = 1;
goto main_exit;
}
}
/* Now check what fuses are against what they should be */
if (safemodeafter_fuse != safemode_fuse) {
fuses_updated = 1;
avrdude_message(MSG_INFO, "%s: safemode: fuse changed! Was %x, and is now %x\n",
progname, safemode_fuse, safemodeafter_fuse);
/* Ask user - should we change them */
if (silentsafe == 0)
safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
else
safemode_response = yes;
if (tolower((int)(safemode_response[0])) == 'y') {
/* Enough chit-chat, time to program some fuses and check them */
if (safemode_writefuse (safemode_fuse, "fuse", pgm, p,
10) == 0) {
avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
}
else {
avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
failures++;
}
}
}
/* Now check what fuses are against what they should be */
if (safemodeafter_lfuse != safemode_lfuse) {
fuses_updated = 1;
avrdude_message(MSG_INFO, "%s: safemode: lfuse changed! Was %x, and is now %x\n",
progname, safemode_lfuse, safemodeafter_lfuse);
/* Ask user - should we change them */
if (silentsafe == 0)
safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
else
safemode_response = yes;
if (tolower((int)(safemode_response[0])) == 'y') {
/* Enough chit-chat, time to program some fuses and check them */
if (safemode_writefuse (safemode_lfuse, "lfuse", pgm, p,
10) == 0) {
avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
}
else {
avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
failures++;
}
}
}
/* Now check what fuses are against what they should be */
if (safemodeafter_hfuse != safemode_hfuse) {
fuses_updated = 1;
avrdude_message(MSG_INFO, "%s: safemode: hfuse changed! Was %x, and is now %x\n",
progname, safemode_hfuse, safemodeafter_hfuse);
/* Ask user - should we change them */
if (silentsafe == 0)
safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
else
safemode_response = yes;
if (tolower((int)(safemode_response[0])) == 'y') {
/* Enough chit-chat, time to program some fuses and check them */
if (safemode_writefuse(safemode_hfuse, "hfuse", pgm, p,
10) == 0) {
avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
}
else {
avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
failures++;
}
}
}
/* Now check what fuses are against what they should be */
if (safemodeafter_efuse != safemode_efuse) {
fuses_updated = 1;
avrdude_message(MSG_INFO, "%s: safemode: efuse changed! Was %x, and is now %x\n",
progname, safemode_efuse, safemodeafter_efuse);
/* Ask user - should we change them */
if (silentsafe == 0)
safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
else
safemode_response = yes;
if (tolower((int)(safemode_response[0])) == 'y') {
/* Enough chit-chat, time to program some fuses and check them */
if (safemode_writefuse (safemode_efuse, "efuse", pgm, p,
10) == 0) {
avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
}
else {
avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
failures++;
}
}
}
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: safemode: ", progname);
if (failures == 0) {
avrdude_message(MSG_INFO, "Fuses OK (E:%02X, H:%02X, L:%02X)\n",
safemode_efuse, safemode_hfuse, safemode_lfuse);
}
else {
avrdude_message(MSG_INFO, "Fuses not recovered, sorry\n");
}
}
if (fuses_updated && fuses_specified) {
exitrc = 1;
}
}
main_exit:
/*
* program complete
*/
if (is_open) {
pgm->powerdown(pgm);
pgm->disable(pgm);
pgm->rdy_led(pgm, OFF);
pgm->close(pgm);
}
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "\n%s done. Thank you.\n\n", progname);
}
return exitrc;
}
avrdude-6.2/ppi.c 000644 000153 000000 00000010660 12622456074 013340 0 ustar 00j wheel 000000 000000 /*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean
*
* 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 .
*/
/* $Id: ppi.c 1321 2014-06-13 20:07:40Z awachtler $ */
#if !defined(WIN32NATIVE)
#include "ac_cfg.h"
#if HAVE_PARPORT
#include
#include
#include
#include
#include
#include
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
# include "freebsd_ppi.h"
#elif defined(__linux__)
# include "linux_ppdev.h"
#elif defined(__sun__) || defined(__sun) /* Solaris */
# include "solaris_ecpp.h"
#endif
#include "avrdude.h"
#include "libavrdude.h"
#include "ppi.h"
enum {
PPI_READ,
PPI_WRITE,
PPI_SHADOWREAD
};
static int ppi_shadow_access(union filedescriptor *fdp, int reg,
unsigned char *v, unsigned char action)
{
static unsigned char shadow[3];
int shadow_num;
switch (reg) {
case PPIDATA:
shadow_num = 0;
break;
case PPICTRL:
shadow_num = 1;
break;
case PPISTATUS:
shadow_num = 2;
break;
default:
avrdude_message(MSG_INFO, "%s: avr_set(): invalid register=%d\n",
progname, reg);
return -1;
break;
}
switch (action) {
case PPI_SHADOWREAD:
*v = shadow[shadow_num];
break;
case PPI_READ:
DO_PPI_READ(fdp->ifd, reg, v);
shadow[shadow_num]=*v;
break;
case PPI_WRITE:
shadow[shadow_num]=*v;
DO_PPI_WRITE(fdp->ifd, reg, v);
break;
}
return 0;
}
/*
* set the indicated bit of the specified register.
*/
int ppi_set(union filedescriptor *fdp, int reg, int bit)
{
unsigned char v;
int rc;
rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
v |= bit;
rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
if (rc)
return -1;
return 0;
}
/*
* clear the indicated bit of the specified register.
*/
int ppi_clr(union filedescriptor *fdp, int reg, int bit)
{
unsigned char v;
int rc;
rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
v &= ~bit;
rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
if (rc)
return -1;
return 0;
}
/*
* get the indicated bit of the specified register.
*/
int ppi_get(union filedescriptor *fdp, int reg, int bit)
{
unsigned char v;
int rc;
rc = ppi_shadow_access(fdp, reg, &v, PPI_READ);
v &= bit;
if (rc)
return -1;
return v; /* v == bit */
}
/*
* toggle the indicated bit of the specified register.
*/
int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
{
unsigned char v;
int rc;
rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
v ^= bit;
rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
if (rc)
return -1;
return 0;
}
/*
* get all bits of the specified register.
*/
int ppi_getall(union filedescriptor *fdp, int reg)
{
unsigned char v;
int rc;
rc = ppi_shadow_access(fdp, reg, &v, PPI_READ);
if (rc)
return -1;
return v; /* v == bit */
}
/*
* set all bits of the specified register to val.
*/
int ppi_setall(union filedescriptor *fdp, int reg, int val)
{
unsigned char v;
int rc;
v = val;
rc = ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
if (rc)
return -1;
return 0;
}
void ppi_open(char * port, union filedescriptor *fdp)
{
int fd;
unsigned char v;
fd = open(port, O_RDWR);
if (fd < 0) {
avrdude_message(MSG_INFO, "%s: can't open device \"%s\": %s\n",
progname, port, strerror(errno));
fdp->ifd = -1;
return;
}
ppi_claim (fd);
/*
* 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);
fdp->ifd = fd;
}
void ppi_close(union filedescriptor *fdp)
{
ppi_release (fdp->ifd);
close(fdp->ifd);
}
#endif /* HAVE_PARPORT */
#endif /* !WIN32NATIVE */
avrdude-6.2/ser_avrdoper.c 000644 000153 000000 00000054742 12622456074 015254 0 ustar 00j wheel 000000 000000 /*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003-2004 Theodore A. Roth
* Copyright (C) 2006 Joerg Wunsch
* 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 .
*/
/* $Id: ser_avrdoper.c 1328 2014-07-16 20:02:01Z rliebscher $ */
/*
* 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
#include
#include
#include "avrdude.h"
#include "libavrdude.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
#include
#if defined(HAVE_DDK_HIDSDI_H)
# include
#else
# include "my_ddk_hidsdi.h"
#endif
#include
#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
#elif defined(HAVE_LUSB0_USB_H)
# include
#else
# error "libusb needs either or "
#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 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;
avrdude_message(MSG_INFO, "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;
avrdude_message(MSG_INFO, "Warning: cannot query manufacturer for device: %s\n",
usb_strerror());
}else{
errorCode = USB_ERROR_NOTFOUND;
/* avrdude_message(MSG_INFO, "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;
avrdude_message(MSG_INFO, "Warning: cannot query product for device: %s\n",
usb_strerror());
}else{
errorCode = USB_ERROR_NOTFOUND;
/* avrdude_message(MSG_INFO, "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)){
avrdude_message(MSG_INFO, "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){
avrdude_message(MSG_INFO, "Warning: could not detach kernel HID driver: %s\n",
usb_strerror());
}
#endif
}
if(rval != 0)
avrdude_message(MSG_INFO, "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)
avrdude_message(MSG_INFO, "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){
avrdude_message(MSG_INFO, "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(const char *prefix, const unsigned char *buf, int len)
{
int i;
if(len <= 8){ /* more compact format for short blocks */
avrdude_message(MSG_INFO, "%s: %d bytes: ", prefix, len);
for(i = 0; i < len; i++){
avrdude_message(MSG_INFO, "%02x ", buf[i]);
}
avrdude_message(MSG_INFO, " \"");
for(i = 0; i < len; i++){
if(buf[i] >= 0x20 && buf[i] < 0x7f){
fputc(buf[i], stderr);
}else{
fputc('.', stderr);
}
}
avrdude_message(MSG_INFO, "\"\n");
}else{
avrdude_message(MSG_INFO, "%s: %d bytes:\n", prefix, len);
while(len > 0){
for(i = 0; i < 16; i++){
if(i < len){
avrdude_message(MSG_INFO, "%02x ", buf[i]);
}else{
avrdude_message(MSG_INFO, " ");
}
if(i == 7)
fputc(' ', stderr);
}
avrdude_message(MSG_INFO, " \"");
for(i = 0; i < 16; i++){
if(i < len){
if(buf[i] >= 0x20 && buf[i] < 0x7f){
fputc(buf[i], stderr);
}else{
fputc('.', stderr);
}
}
}
avrdude_message(MSG_INFO, "\"\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, union pinfo pinfo, 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){
avrdude_message(MSG_INFO, "%s: avrdoper_open(): %s\n", progname, usbErrorText(rval));
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, const 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);
avrdude_message(MSG_TRACE, "Sending %d bytes data chunk\n", thisLen);
rval = usbSetReport(fdp, USB_HID_REPORT_TYPE_FEATURE, (char *)buffer,
reportDataSizes[lenIndex] + 2);
if(rval != 0){
avrdude_message(MSG_INFO, "%s: avrdoper_send(): %s\n", progname, usbErrorText(rval));
return -1;
}
buflen -= thisLen;
buf += thisLen;
}
return 0;
}
/* ------------------------------------------------------------------------- */
static int 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){
avrdude_message(MSG_INFO, "%s: avrdoperFillBuffer(): %s\n", progname, usbErrorText(usbErr));
return -1;
}
avrdude_message(MSG_TRACE, "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)){
avrdude_message(MSG_INFO, "%s: avrdoperFillBuffer(): internal error: buffer overflow\n",
progname);
return -1;
}
memcpy(avrdoperRxBuffer + avrdoperRxLength, buffer + 2, len);
avrdoperRxLength += len;
}
return 0;
}
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 */
if (avrdoperFillBuffer(fdp) < 0)
return -1;
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{
if (avrdoperFillBuffer(fdp) < 0)
return -1;
}while(avrdoperRxLength > 0);
return 0;
}
/* ------------------------------------------------------------------------- */
static int avrdoper_set_dtr_rts(union filedescriptor *fdp, int is_on)
{
avrdude_message(MSG_INFO, "%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)) */
avrdude-6.2/dfu.c 000644 000153 000000 00000034775 12622456070 013337 0 ustar 00j wheel 000000 000000 /*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2012 Kirill Levchenko
*
* 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 .
*/
/* $Id: dfu.c 1328 2014-07-16 20:02:01Z rliebscher $ */
#include "ac_cfg.h"
#include
#include
#include
#include
#include
#include
#include "avrdude.h"
#include "libavrdude.h"
#include "dfu.h"
#include "usbdevs.h" /* for USB_VENDOR_ATMEL */
/* If we don't have LibUSB, define dummy functions that report an error. */
#ifndef HAVE_LIBUSB
struct dfu_dev *dfu_open(char *port_name) {
avrdude_message(MSG_INFO, "%s: Error: No USB support in this compile of avrdude\n",
progname);
return NULL;
}
int dfu_init(struct dfu_dev *dfu, unsigned short usb_vid, unsigned short usb_pid) {
return -1;
}
void dfu_close(struct dfu_dev *dfu) {
/* nothing */
}
int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status)
{
return -1;
}
int dfu_clrstatus(struct dfu_dev *dfu) {
return -1;
}
int dfu_download(struct dfu_dev *dfu, void * ptr, int size) {
return -1;
}
int dfu_upload(struct dfu_dev *dfu, void * ptr, int size) {
return -1;
}
#else
/* If we DO have LibUSB, we can define the real functions. */
/* DFU data structures and constants.
*/
#define DFU_TIMEOUT 200 /* ms */
#define DFU_DNLOAD 1
#define DFU_UPLOAD 2
#define DFU_GETSTATUS 3
#define DFU_CLRSTATUS 4
#define DFU_GETSTATE 5 /* FLIPv1 only; not used */
#define DFU_ABORT 6 /* FLIPv1 only */
/* Block counter global variable. Incremented each time a DFU_DNLOAD command
* is sent to the device.
*/
static uint16_t wIndex = 0;
/* INTERNAL FUNCTION PROTOTYPES
*/
static char * get_usb_string(usb_dev_handle * dev_handle, int index);
/* EXPORTED FUNCTION DEFINITIONS
*/
struct dfu_dev * dfu_open(char *port_spec)
{
struct dfu_dev *dfu;
char *bus_name = NULL;
char *dev_name = NULL;
/* The following USB device spec parsing code was copied from usbtiny.c. The
* expected format is "usb:BUS:DEV" where BUS and DEV are the bus and device
* names. We stash these away in the dfu_dev structure for the dfu_init()
* function, where we actually open the device.
*/
if (strncmp(port_spec, "usb", 3) != 0) {
avrdude_message(MSG_INFO, "%s: Error: "
"Invalid port specification \"%s\" for USB device\n",
progname, port_spec);
return NULL;
}
if(':' == port_spec[3]) {
bus_name = strdup(port_spec + 3 + 1);
if (bus_name == NULL) {
avrdude_message(MSG_INFO, "%s: Out of memory in strdup\n", progname);
return NULL;
}
dev_name = strchr(bus_name, ':');
if(NULL != dev_name)
*dev_name++ = '\0';
}
/* Allocate the dfu_dev structure and save the bus_name and dev_name
* strings for use in dfu_initialize().
*/
dfu = calloc(1, sizeof(struct dfu_dev));
if (dfu == NULL)
{
avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
free(bus_name);
return NULL;
}
dfu->bus_name = bus_name;
dfu->dev_name = dev_name;
dfu->timeout = DFU_TIMEOUT;
/* LibUSB initialization. */
usb_init();
usb_find_busses();
usb_find_devices();
return dfu;
}
int dfu_init(struct dfu_dev *dfu, unsigned short vid, unsigned short pid)
{
struct usb_device *found = NULL;
struct usb_device *dev;
struct usb_bus *bus;
/* At last, we reach out through the USB bus to the part. There are three
* ways to specify the part: by USB address, by USB vendor and product id,
* and by part name. To specify the part by USB address, the user specifies
* a port parameter in the form "usb:BUS:DEV" (see dfu_open()). To specify
* the part by vendor and product, the user must specify a usbvid and usbpid
* in the configuration file. Finally, if the user specifies the part only,
* we use the default vendor and product id.
*/
if (pid == 0 && dfu->dev_name == NULL) {
avrdude_message(MSG_INFO, "%s: Error: No DFU support for part; "
"specify PID in config or USB address (via -P) to override.\n",
progname);
return -1;
}
/* Scan through all the devices for the part. The matching rules are:
*
* 1. If the user specified a USB bus name, it must match.
* 2. If the user specified a USB device name, it must match.
* 3. If the user didn't specify a USB device name and specified a vendor
* id, the vendor id must match.
* 4. If the user didn't specify a USB device name and specified a product
* id, the product id must match.
*/
for (bus = usb_busses; !found && bus != NULL; bus = bus->next) {
for (dev = bus->devices; !found && dev != NULL; dev = dev->next) {
if (dfu->bus_name != NULL && strcmp(bus->dirname, dfu->bus_name))
continue;
if (dfu->dev_name != NULL) {
if (strcmp(dev->filename, dfu->dev_name))
continue;
} else if (vid != dev->descriptor.idVendor)
continue;
else if (pid != 0 && pid != dev->descriptor.idProduct)
continue;
found = dev;
}
}
if (found == NULL) {
/* We could try to be more informative here. For example, we could report
* why the match failed, and if we came across another DFU-capable part.
*/
avrdude_message(MSG_INFO, "%s: Error: No matching USB device found\n", progname);
return -1;
}
if(verbose)
avrdude_message(MSG_INFO, "%s: Found VID=0x%04x PID=0x%04x at %s:%s\n",
progname, found->descriptor.idVendor, found->descriptor.idProduct,
found->bus->dirname, found->filename);
dfu->dev_handle = usb_open(found);
if (dfu->dev_handle == NULL) {
avrdude_message(MSG_INFO, "%s: Error: USB device at %s:%s: %s\n",
progname, found->bus->dirname, found->filename, usb_strerror());
return -1;
}
/* Save device, configuration, interface and endpoint descriptors. */
memcpy(&dfu->dev_desc, &found->descriptor, sizeof(dfu->dev_desc));
memcpy(&dfu->conf_desc, found->config, sizeof(dfu->conf_desc));
dfu->conf_desc.interface = NULL;
memcpy(&dfu->intf_desc, found->config->interface->altsetting,
sizeof(dfu->intf_desc));
dfu->intf_desc.endpoint = &dfu->endp_desc;
if (found->config->interface->altsetting->endpoint != 0)
memcpy(&dfu->endp_desc, found->config->interface->altsetting->endpoint,
sizeof(dfu->endp_desc));
/* Get strings. */
dfu->manf_str = get_usb_string(dfu->dev_handle,
dfu->dev_desc.iManufacturer);
dfu->prod_str = get_usb_string(dfu->dev_handle,
dfu->dev_desc.iProduct);
dfu->serno_str = get_usb_string(dfu->dev_handle,
dfu->dev_desc.iSerialNumber);
return 0;
}
void dfu_close(struct dfu_dev *dfu)
{
if (dfu->dev_handle != NULL)
usb_close(dfu->dev_handle);
if (dfu->bus_name != NULL)
free(dfu->bus_name);
if (dfu->manf_str != NULL)
free(dfu->manf_str);
if (dfu->prod_str != NULL)
free(dfu->prod_str);
if (dfu->serno_str != NULL)
free(dfu->serno_str);
}
int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status)
{
int result;
avrdude_message(MSG_TRACE, "%s: dfu_getstatus(): issuing control IN message\n",
progname);
result = usb_control_msg(dfu->dev_handle,
0x80 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_GETSTATUS, 0, 0,
(char*) status, sizeof(struct dfu_status), dfu->timeout);
if (result < 0) {
avrdude_message(MSG_INFO, "%s: Error: Failed to get DFU status: %s\n",
progname, usb_strerror());
return -1;
}
if (result < sizeof(struct dfu_status)) {
avrdude_message(MSG_INFO, "%s: Error: Failed to get DFU status: %s\n",
progname, "short read");
return -1;
}
if (result > sizeof(struct dfu_status)) {
avrdude_message(MSG_INFO, "%s: Error: Oversize read (should not happen); "
"exiting\n", progname);
exit(1);
}
avrdude_message(MSG_TRACE, "%s: dfu_getstatus(): bStatus 0x%02x, bwPollTimeout %d, bState 0x%02x, iString %d\n",
progname,
status->bStatus,
status->bwPollTimeout[0] | (status->bwPollTimeout[1] << 8) | (status->bwPollTimeout[2] << 16),
status->bState,
status->iString);
return 0;
}
int dfu_clrstatus(struct dfu_dev *dfu)
{
int result;
avrdude_message(MSG_TRACE, "%s: dfu_clrstatus(): issuing control OUT message\n",
progname);
result = usb_control_msg(dfu->dev_handle,
USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_CLRSTATUS, 0, 0,
NULL, 0, dfu->timeout);
if (result < 0) {
avrdude_message(MSG_INFO, "%s: Error: Failed to clear DFU status: %s\n",
progname, usb_strerror());
return -1;
}
return 0;
}
int dfu_abort(struct dfu_dev *dfu)
{
int result;
avrdude_message(MSG_TRACE, "%s: dfu_abort(): issuing control OUT message\n",
progname);
result = usb_control_msg(dfu->dev_handle,
USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_ABORT, 0, 0,
NULL, 0, dfu->timeout);
if (result < 0) {
avrdude_message(MSG_INFO, "%s: Error: Failed to reset DFU state: %s\n",
progname, usb_strerror());
return -1;
}
return 0;
}
int dfu_dnload(struct dfu_dev *dfu, void *ptr, int size)
{
int result;
avrdude_message(MSG_TRACE, "%s: dfu_dnload(): issuing control OUT message, wIndex = %d, ptr = %p, size = %d\n",
progname, wIndex, ptr, size);
result = usb_control_msg(dfu->dev_handle,
USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_DNLOAD, wIndex++, 0,
ptr, size, dfu->timeout);
if (result < 0) {
avrdude_message(MSG_INFO, "%s: Error: DFU_DNLOAD failed: %s\n",
progname, usb_strerror());
return -1;
}
if (result < size) {
avrdude_message(MSG_INFO, "%s: Error: DFU_DNLOAD failed: %s\n",
progname, "short write");
return -1;
}
if (result > size) {
avrdude_message(MSG_INFO, "%s: Error: Oversize write (should not happen); " \
"exiting\n", progname);
exit(1);
}
return 0;
}
int dfu_upload(struct dfu_dev *dfu, void *ptr, int size)
{
int result;
avrdude_message(MSG_TRACE, "%s: dfu_upload(): issuing control IN message, wIndex = %d, ptr = %p, size = %d\n",
progname, wIndex, ptr, size);
result = usb_control_msg(dfu->dev_handle,
0x80 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_UPLOAD, wIndex++, 0,
ptr, size, dfu->timeout);
if (result < 0) {
avrdude_message(MSG_INFO, "%s: Error: DFU_UPLOAD failed: %s\n",
progname, usb_strerror());
return -1;
}
if (result < size) {
avrdude_message(MSG_INFO, "%s: Error: DFU_UPLOAD failed: %s\n",
progname, "short read");
return -1;
}
if (result > size) {
avrdude_message(MSG_INFO, "%s: Error: Oversize read (should not happen); "
"exiting\n", progname);
exit(1);
}
return 0;
}
void dfu_show_info(struct dfu_dev *dfu)
{
if (dfu->manf_str != NULL)
avrdude_message(MSG_INFO, " USB Vendor : %s (0x%04hX)\n",
dfu->manf_str, (unsigned short) dfu->dev_desc.idVendor);
else
avrdude_message(MSG_INFO, " USB Vendor : 0x%04hX\n",
(unsigned short) dfu->dev_desc.idVendor);
if (dfu->prod_str != NULL)
avrdude_message(MSG_INFO, " USB Product : %s (0x%04hX)\n",
dfu->prod_str, (unsigned short) dfu->dev_desc.idProduct);
else
avrdude_message(MSG_INFO, " USB Product : 0x%04hX\n",
(unsigned short) dfu->dev_desc.idProduct);
avrdude_message(MSG_INFO, " USB Release : %hu.%hu.%hu\n",
((unsigned short) dfu->dev_desc.bcdDevice >> 8) & 0xFF,
((unsigned short) dfu->dev_desc.bcdDevice >> 4) & 0xF,
((unsigned short) dfu->dev_desc.bcdDevice >> 0) & 0xF);
if (dfu->serno_str != NULL)
avrdude_message(MSG_INFO, " USB Serial No : %s\n", dfu->serno_str);
}
/* INTERNAL FUNCTION DEFINITIONS
*/
char * get_usb_string(usb_dev_handle * dev_handle, int index) {
char buffer[256];
char * str;
int result;
if (index == 0)
return NULL;
result = usb_get_string_simple(dev_handle, index, buffer, sizeof(buffer)-1);
if (result < 0) {
avrdude_message(MSG_INFO, "%s: Warning: Failed to read USB device string %d: %s\n",
progname, index, usb_strerror());
return NULL;
}
str = malloc(result+1);
if (str == NULL) {
avrdude_message(MSG_INFO, "%s: Out of memory allocating a string\n", progname);
return 0;
}
memcpy(str, buffer, result);
str[result] = '\0';
return str;
}
#endif /* defined(HAVE_LIBUSB) */
/* EXPORTED FUNCTIONS THAT DO NO REQUIRE LIBUSB
*/
const char * dfu_status_str(int bStatus)
{
switch (bStatus) {
case DFU_STATUS_OK: return "OK";
case DFU_STATUS_ERR_TARGET: return "ERR_TARGET";
case DFU_STATUS_ERR_FILE: return "ERR_FILE";
case DFU_STATUS_ERR_WRITE: return "ERR_WRITE";
case DFU_STATUS_ERR_ERASE: return "ERR_ERASE";
case DFU_STATUS_ERR_CHECK_ERASED: return "ERR_CHECK_ERASED";
case DFU_STATUS_ERR_PROG: return "ERR_PROG";
case DFU_STATUS_ERR_VERIFY: return "ERR_VERIFY";
case DFU_STATUS_ERR_ADDRESS: return "ERR_ADDRESS";
case DFU_STATUS_ERR_NOTDONE: return "ERR_NOTDONE";
case DFU_STATUS_ERR_FIRMWARE: return "ERR_FIRMWARE";
case DFU_STATUS_ERR_VENDOR: return "ERR_VENDOR";
case DFU_STATUS_ERR_USBR: return "ERR_USBR";
case DFU_STATUS_ERR_POR: return "ERR_POR";
case DFU_STATUS_ERR_UNKNOWN: return "ERR_UNKNOWN";
case DFU_STATUS_ERR_STALLEDPKT: return "ERR_STALLEDPKT";
default: return "Unknown";
}
}
const char * dfu_state_str(int bState)
{
switch (bState) {
case DFU_STATE_APP_IDLE: return "APP_IDLE";
case DFU_STATE_APP_DETACH: return "APP_DETACH";
case DFU_STATE_DFU_IDLE: return "DFU_IDLE";
case DFU_STATE_DFU_DLOAD_SYNC: return "DFU_DLOAD_SYNC";
case DFU_STATE_DFU_DNBUSY: return "DFU_DNBUSY";
case DFU_STATE_DFU_DNLOAD_IDLE: return "DFU_DNLOAD_IDLE";
case DFU_STATE_DFU_MANIFEST_SYNC: return "DFU_MANIFEST_SYNC";
case DFU_STATE_DFU_MANIFEST: return "DFU_MANIFEST";
case DFU_STATE_DFU_MANIFEST_WAIT_RESET: return "DFU_MANIFEST_WAIT_RESET";
case DFU_STATE_DFU_UPLOAD_IDLE: return "DFU_UPLOAD_IDLE";
case DFU_STATE_DFU_ERROR: return "DFU_ERROR";
default: return "Unknown";
}
}
avrdude-6.2/solaris_ecpp.h 000644 000153 000000 00000003161 12622456071 015233 0 ustar 00j wheel 000000 000000 /*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2005 Joerg Wunsch
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/* $Id: solaris_ecpp.h 1107 2012-11-20 14:03:50Z joerg_wunsch $ */
#ifndef solaris_ecpp_h
#define solaris_ecpp_h
#include
#define ppi_claim(fd) \
do { \
struct ecpp_transfer_parms p; \
(void)ioctl(fd, ECPPIOC_GETPARMS, &p); \
p.mode = ECPP_DIAG_MODE; \
(void)ioctl(fd, ECPPIOC_SETPARMS, &p); \
} while(0);
#define ppi_release(fd)
#define DO_PPI_READ(fd, reg, valp) \
do { struct ecpp_regs r; \
if ((reg) == PPIDATA) { (void)ioctl(fd, ECPPIOC_GETDATA, valp); } \
else { (void)ioctl(fd, ECPPIOC_GETREGS, &r); \
*(valp) = ((reg) == PPICTRL)? r.dcr: r.dsr; } \
} while(0)
#define DO_PPI_WRITE(fd, reg, valp) \
do { struct ecpp_regs r; \
if ((reg) == PPIDATA) { (void)ioctl(fd, ECPPIOC_SETDATA, valp); } \
else { if ((reg) == PPICTRL) r.dcr = *(valp); else r.dsr = *(valp); \
(void)ioctl(fd, ECPPIOC_SETREGS, &r); } \
} while(0)
#endif /* solaris_ecpp_h */
avrdude-6.2/stk500v2.h 000644 000153 000000 00000004124 12622456074 014051 0 ustar 00j wheel 000000 000000 /*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2002-2005 Brian S. Dean
* Copyright (C) 2006 Joerg Wunsch
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/* $Id: stk500v2.h 1119 2012-12-03 15:52:38Z joerg_wunsch $ */
#ifndef stk500v2_h
#define stk500v2_h
#ifdef __cplusplus
extern "C" {
#endif
extern const char stk500v2_desc[];
extern const char stk500hvsp_desc[];
extern const char stk500pp_desc[];
extern const char stk500v2_jtagmkII_desc[];
extern const char stk500v2_dragon_hvsp_desc[];
extern const char stk500v2_dragon_isp_desc[];
extern const char stk500v2_dragon_pp_desc[];
extern const char stk500v2_jtag3_desc[];
extern const char stk600_desc[];
extern const char stk600hvsp_desc[];
extern const char stk600pp_desc[];
void stk500v2_initpgm (PROGRAMMER * pgm);
void stk500hvsp_initpgm (PROGRAMMER * pgm);
void stk500pp_initpgm (PROGRAMMER * pgm);
void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm);
void stk500v2_jtag3_initpgm(PROGRAMMER * pgm);
void stk500v2_dragon_hvsp_initpgm(PROGRAMMER * pgm);
void stk500v2_dragon_isp_initpgm(PROGRAMMER * pgm);
void stk500v2_dragon_pp_initpgm(PROGRAMMER * pgm);
void stk600_initpgm (PROGRAMMER * pgm);
void stk600hvsp_initpgm (PROGRAMMER * pgm);
void stk600pp_initpgm (PROGRAMMER * pgm);
void stk500v2_setup(PROGRAMMER * pgm);
void stk500v2_teardown(PROGRAMMER * pgm);
int stk500v2_drain(PROGRAMMER * pgm, int display);
int stk500v2_getsync(PROGRAMMER * pgm);
#ifdef __cplusplus
}
#endif
#endif
avrdude-6.2/ac_cfg.h.in 000644 000153 000000 00000011641 12622456106 014360 0 ustar 00j wheel 000000 000000 /* ac_cfg.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the header file. */
#undef HAVE_DDK_HIDSDI_H
/* Define to 1 if you have the header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Define to 1 if you have the header file. */
#undef HAVE_INTTYPES_H
/* Define if ELF support is enabled via libelf */
#undef HAVE_LIBELF
/* Define to 1 if you have the header file. */
#undef HAVE_LIBELF_H
/* Define to 1 if you have the header file. */
#undef HAVE_LIBELF_LIBELF_H
/* Define if FTDI support is enabled via libftdi */
#undef HAVE_LIBFTDI
/* Define if FTDI support is enabled via libftdi1 */
#undef HAVE_LIBFTDI1
/* Define if libftdi supports FT232H, libftdi version >= 0.20 */
#undef HAVE_LIBFTDI_TYPE_232H
/* Define if HID support is enabled via the Win32 DDK */
#undef HAVE_LIBHID
/* Define to 1 if you have the `ncurses' library (-lncurses). */
#undef HAVE_LIBNCURSES
/* Define to 1 if you have the `readline' library (-lreadline). */
#undef HAVE_LIBREADLINE
/* Define to 1 if you have the `termcap' library (-ltermcap). */
#undef HAVE_LIBTERMCAP
/* Define if USB support is enabled via libusb */
#undef HAVE_LIBUSB
/* Define if USB support is enabled via a libusb-1.0 compatible libusb */
#undef HAVE_LIBUSB_1_0
/* Define to 1 if you have the header file. */
#undef HAVE_LIBUSB_1_0_LIBUSB_H
/* Define to 1 if you have the header file. */
#undef HAVE_LIBUSB_H
/* Define to 1 if you have the `ws2_32' library (-lws2_32). */
#undef HAVE_LIBWS2_32
/* Define to 1 if you have the header file. */
#undef HAVE_LIMITS_H
/* Linux sysfs GPIO support enabled */
#undef HAVE_LINUXGPIO
/* Define to 1 if you have the header file. */
#undef HAVE_LUSB0_USB_H
/* Define to 1 if you have the header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `memset' function. */
#undef HAVE_MEMSET
/* parallel port access enabled */
#undef HAVE_PARPORT
/* Define to 1 if you have the header file. */
#undef HAVE_PTHREAD_H
/* Define to 1 if you have the `select' function. */
#undef HAVE_SELECT
/* Define to 1 if you have the header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strcasecmp' function. */
#undef HAVE_STRCASECMP
/* Define to 1 if you have the `strdup' function. */
#undef HAVE_STRDUP
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strncasecmp' function. */
#undef HAVE_STRNCASECMP
/* Define to 1 if you have the `strtol' function. */
#undef HAVE_STRTOL
/* Define to 1 if you have the `strtoul' function. */
#undef HAVE_STRTOUL
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_IOCTL_H
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the header file. */
#undef HAVE_TERMIOS_H
/* Define to 1 if the system has the type `uint_t'. */
#undef HAVE_UINT_T
/* Define to 1 if the system has the type `ulong_t'. */
#undef HAVE_ULONG_T
/* Define to 1 if you have the header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the header file. */
#undef HAVE_USB_H
/* Define to 1 if you have the `usleep' function. */
#undef HAVE_USLEEP
/* Define if lex/flex has yylex_destroy */
#undef HAVE_YYLEX_DESTROY
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if you can safely include both and . */
#undef TIME_WITH_SYS_TIME
/* Version number of package */
#undef VERSION
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
`char[]'. */
#undef YYTEXT_POINTER
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
avrdude-6.2/ChangeLog-2011 000644 000153 000000 00000042057 12622456074 014544 0 ustar 00j wheel 000000 000000 2011-12-30 Rene Liebscher
* 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
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
* 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
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
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
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
* 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
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
* 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
* config_gram.y: Restructuring and compacting programmer definition
part of grammar (in preparation of patch #7688)
2011-12-17 Rene Liebscher
* 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
patch #7667: Minor memory handling fixes
* config_gram.y: Added several free_token() calls.
2011-12-16 Rene Liebscher
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
* configure.ac: Replace "cvs" in version number by "svn".
2011-10-10 Joerg Wunsch
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
* avrftdi.c: Remove stray printf()s by fprintf(stderr)
* usbtiny.c: (Ditto.)
2011-09-15 Joerg Wunsch
* 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
* 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
* 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
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
* stk500v2.c (stk500v2_command): Treat warnings as errors rather than
success.
2011-08-30 Joerg Wunsch
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
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
* 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
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
* configure.ac: Bump version for post-5.11.
2011-08-27 Joerg Wunsch
* configure.ac: Bump version for releasing AVRDUDE 5.11.
2011-08-26 Joerg Wunsch
* avrdude.1: Update the list of supported AVR devices.
* doc/avrdude.texi: (Ditto).
2011-08-26 Joerg Wunsch
* configure.ac: add -lusb as "other libraries" when checking
for libftdi.
2011-08-26 Joerg Wunsch
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
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
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
Submitted by an anonymous contributor on the mailinglist:
* avrdude.conf (jtagkey): Add a definition for the Amontec
JTAGKey
2011-08-26 Joerg Wunsch
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
bug #33811: Parallel make fails
* Makefile.am (BUILT_SOURCES): Add this macro.
2011-08-26 Joerg Wunsch
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
Reported by Jason Hecker:
* usbasp.c (libusb_to_errno): Conditionalize some error codes
that apparently are lacking on MinGW.
2011-08-25 Joerg Wunsch
Fix warnings.
* ser_avrdoper.c: add 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
* 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
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
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
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
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
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
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
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
* 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
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
Submitted by Durant Gilles:
* avrdude.conf.in (ATtiny4313): Fix flash addressing bits for manual ISP
algorithm.
2011-08-16 Joerg Wunsch
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
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
* usbasp.c: Add so this actually compiles
again.
2011-08-12 Joerg Wunsch
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
* avrdude.conf.in: Fix part id of ATtiny9.
2011-05-28 Thomas Fischl
Based on patch #7440 commited by Slawomir Fraś:
* usbasp.c: added TPI support for USBasp
* usbasp.h: (Ditto.)
2011-05-11 Joerg Wunsch
* avrdude.conf.in: Add support for ATmega168P.
2011-05-11 Joerg Wunsch
* avrdude.conf.in: Fix abbreviated name for ATmega324PA.
2011-05-11 Joerg Wunsch
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
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
* usb_libusb.c: Bump timeout values to allow for slow clock
speeds.
* jtagmkII.c: (Ditto.)
2011-03-04 Eric B. Weddington
Thanks to Vitaly Chernookiy for the patch.
* avrdude.conf.in: Add support for atmega324pa.
* ChangeLog-2010: New file, rotate ChangeLog for new year.
avrdude-6.2/usbasp.c 000644 000153 000000 00000110611 12622456074 014042 0 ustar 00j wheel 000000 000000 /*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2006 Thomas Fischl
* Copyright 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 .
*/
/* $Id: usbasp.c 1343 2014-11-20 09:20:44Z joerg_wunsch $ */
/*
* Interface to the USBasp programmer.
*
* See http://www.fischl.de/usbasp/
*/
#include "ac_cfg.h"
#include
#include
#include
#include
#include
#include
#include
#include "avrdude.h"
#include "libavrdude.h"
#include "usbasp.h"
#include "usbdevs.h"
#if defined(HAVE_LIBUSB) || defined(HAVE_LIBUSB_1_0)
#ifdef HAVE_LIBUSB_1_0
# define USE_LIBUSB_1_0
#endif
#if defined(USE_LIBUSB_1_0)
# if defined(HAVE_LIBUSB_1_0_LIBUSB_H)
# include
# else
# include
# endif
#else
# if defined(HAVE_USB_H)
# include
# elif defined(HAVE_LUSB0_USB_H)
# include
# else
# error "libusb needs either or "
# endif
#endif
#ifdef USE_LIBUSB_1_0
static libusb_context *ctx = NULL;
static int libusb_to_errno(int result)
{
switch (result) {
case LIBUSB_SUCCESS:
return 0;
case LIBUSB_ERROR_IO:
return EIO;
case LIBUSB_ERROR_INVALID_PARAM:
return EINVAL;
case LIBUSB_ERROR_ACCESS:
return EACCES;
case LIBUSB_ERROR_NO_DEVICE:
return ENXIO;
case LIBUSB_ERROR_NOT_FOUND:
return ENOENT;
case LIBUSB_ERROR_BUSY:
return EBUSY;
#ifdef ETIMEDOUT
case LIBUSB_ERROR_TIMEOUT:
return ETIMEDOUT;
#endif
#ifdef EOVERFLOW
case LIBUSB_ERROR_OVERFLOW:
return EOVERFLOW;
#endif
case LIBUSB_ERROR_PIPE:
return EPIPE;
case LIBUSB_ERROR_INTERRUPTED:
return EINTR;
case LIBUSB_ERROR_NO_MEM:
return ENOMEM;
case LIBUSB_ERROR_NOT_SUPPORTED:
return ENOSYS;
default:
return ERANGE;
}
}
#endif
/*
* Private data for this programmer.
*/
struct pdata
{
#ifdef USE_LIBUSB_1_0
libusb_device_handle *usbhandle;
#else
usb_dev_handle *usbhandle;
#endif
int sckfreq_hz;
unsigned int capabilities;
int use_tpi;
};
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
#define IMPORT_PDATA(pgm) struct pdata *pdata = PDATA(pgm)
/* Prototypes */
// interface - management
static void usbasp_setup(PROGRAMMER * pgm);
static void usbasp_teardown(PROGRAMMER * pgm);
// internal functions
static int usbasp_transmit(PROGRAMMER * pgm, unsigned char receive,
unsigned char functionid, const unsigned char *send,
unsigned char *buffer, int buffersize);
#ifdef USE_LIBUSB_1_0
static int usbOpenDevice(libusb_device_handle **device, int vendor, char *vendorName, int product, char *productName);
#else
static int usbOpenDevice(usb_dev_handle **device, int vendor, char *vendorName, int product, char *productName);
#endif
// interface - prog.
static int usbasp_open(PROGRAMMER * pgm, char * port);
static void usbasp_close(PROGRAMMER * pgm);
// dummy functions
static void usbasp_disable(PROGRAMMER * pgm);
static void usbasp_enable(PROGRAMMER * pgm);
static void usbasp_display(PROGRAMMER * pgm, const char * p);
// universal functions
static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p);
// SPI specific functions
static int usbasp_spi_cmd(PROGRAMMER * pgm, const unsigned char *cmd, unsigned char *res);
static int usbasp_spi_program_enable(PROGRAMMER * pgm, AVRPART * p);
static int usbasp_spi_chip_erase(PROGRAMMER * pgm, AVRPART * p);
static int usbasp_spi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes);
static int usbasp_spi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes);
static int usbasp_spi_set_sck_period(PROGRAMMER *pgm, double sckperiod);
// TPI specific functions
static void usbasp_tpi_send_byte(PROGRAMMER * pgm, uint8_t b);
static int usbasp_tpi_cmd(PROGRAMMER * pgm, const unsigned char *cmd, unsigned char *res);
static int usbasp_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p);
static int usbasp_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p);
static int usbasp_tpi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes);
static int usbasp_tpi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes);
static int usbasp_tpi_set_sck_period(PROGRAMMER *pgm, double sckperiod);
static int usbasp_tpi_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr, unsigned char * value);
static int usbasp_tpi_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr, unsigned char data);
/* Interface - management */
static void usbasp_setup(PROGRAMMER * pgm)
{
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
avrdude_message(MSG_INFO, "%s: usbasp_setup(): Out of memory allocating private data\n",
progname);
exit(1);
}
memset(pgm->cookie, 0, sizeof(struct pdata));
}
static void usbasp_teardown(PROGRAMMER * pgm)
{
free(pgm->cookie);
}
/* Internal functions */
static const char *usbasp_get_funcname(unsigned char functionid)
{
switch (functionid) {
case USBASP_FUNC_CONNECT: return "USBASP_FUNC_CONNECT"; break;
case USBASP_FUNC_DISCONNECT: return "USBASP_FUNC_DISCONNECT"; break;
case USBASP_FUNC_TRANSMIT: return "USBASP_FUNC_TRANSMIT"; break;
case USBASP_FUNC_READFLASH: return "USBASP_FUNC_READFLASH"; break;
case USBASP_FUNC_ENABLEPROG: return "USBASP_FUNC_ENABLEPROG"; break;
case USBASP_FUNC_WRITEFLASH: return "USBASP_FUNC_WRITEFLASH"; break;
case USBASP_FUNC_READEEPROM: return "USBASP_FUNC_READEEPROM"; break;
case USBASP_FUNC_WRITEEEPROM: return "USBASP_FUNC_WRITEEEPROM"; break;
case USBASP_FUNC_SETLONGADDRESS: return "USBASP_FUNC_SETLONGADDRESS"; break;
case USBASP_FUNC_SETISPSCK: return "USBASP_FUNC_SETISPSCK"; break;
case USBASP_FUNC_TPI_CONNECT: return "USBASP_FUNC_TPI_CONNECT"; break;
case USBASP_FUNC_TPI_DISCONNECT: return "USBASP_FUNC_TPI_DISCONNECT"; break;
case USBASP_FUNC_TPI_RAWREAD: return "USBASP_FUNC_TPI_RAWREAD"; break;
case USBASP_FUNC_TPI_RAWWRITE: return "USBASP_FUNC_TPI_RAWWRITE"; break;
case USBASP_FUNC_TPI_READBLOCK: return "USBASP_FUNC_TPI_READBLOCK"; break;
case USBASP_FUNC_TPI_WRITEBLOCK: return "USBASP_FUNC_TPI_WRITEBLOCK"; break;
case USBASP_FUNC_GETCAPABILITIES: return "USBASP_FUNC_GETCAPABILITIES"; break;
default: return "Unknown USBASP function"; break;
}
}
/*
* wrapper for usb_control_msg call
*/
static int usbasp_transmit(PROGRAMMER * pgm,
unsigned char receive, unsigned char functionid,
const unsigned char *send,
unsigned char *buffer, int buffersize)
{
int nbytes;
if (verbose > 3) {
avrdude_message(MSG_TRACE, "%s: usbasp_transmit(\"%s\", 0x%02x, 0x%02x, 0x%02x, 0x%02x)\n",
progname,
usbasp_get_funcname(functionid), send[0], send[1], send[2], send[3]);
if (!receive && buffersize > 0) {
int i;
avrdude_message(MSG_TRACE, "%s => ", progbuf);
for (i = 0; i < buffersize; i++)
avrdude_message(MSG_TRACE, "[%02x] ", buffer[i]);
avrdude_message(MSG_TRACE, "\n");
}
}
#ifdef USE_LIBUSB_1_0
nbytes = libusb_control_transfer(PDATA(pgm)->usbhandle,
(LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | (receive << 7)) & 0xff,
functionid & 0xff,
((send[1] << 8) | send[0]) & 0xffff,
((send[3] << 8) | send[2]) & 0xffff,
buffer,
buffersize & 0xffff,
5000);
if(nbytes < 0){
avrdude_message(MSG_INFO, "%s: error: usbasp_transmit: %s\n", progname, strerror(libusb_to_errno(nbytes)));
return -1;
}
#else
nbytes = usb_control_msg(PDATA(pgm)->usbhandle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | (receive << 7),
functionid,
(send[1] << 8) | send[0],
(send[3] << 8) | send[2],
(char *)buffer, buffersize,
5000);
if(nbytes < 0){
avrdude_message(MSG_INFO, "%s: error: usbasp_transmit: %s\n", progname, usb_strerror());
return -1;
}
#endif
if (verbose > 3 && receive && nbytes > 0) {
int i;
avrdude_message(MSG_TRACE, "%s<= ", progbuf);
for (i = 0; i < nbytes; i++)
avrdude_message(MSG_TRACE, "[%02x] ", buffer[i]);
avrdude_message(MSG_TRACE, "\n");
}
return nbytes;
}
/*
* Try to open USB device with given VID, PID, vendor and product name
* Parts of this function were taken from an example code by OBJECTIVE
* DEVELOPMENT Software GmbH (www.obdev.at) to meet conditions for
* shared VID/PID
*/
#ifdef USE_LIBUSB_1_0
static int usbOpenDevice(libusb_device_handle **device, int vendor,
char *vendorName, int product, char *productName)
{
libusb_device_handle *handle = NULL;
int errorCode = USB_ERROR_NOTFOUND;
static int didUsbInit = 0;
int j;
int r;
if(!didUsbInit){
didUsbInit = 1;
libusb_init(&ctx);
}
libusb_device **dev_list;
int dev_list_len = libusb_get_device_list(ctx, &dev_list);
for (j=0; j%s<-\n",
progname, string);
if ((vendorName != NULL) && (vendorName[0] != 0) && (strcmp(string, vendorName) != 0))
errorCode = USB_ERROR_NOTFOUND;
}
/* if productName not given ignore it (any product matches) */
r = libusb_get_string_descriptor_ascii(handle, descriptor.iProduct & 0xff, (unsigned char*)string, sizeof(string));
if (r < 0) {
if ((productName != NULL) && (productName[0] != 0)) {
errorCode = USB_ERROR_IO;
avrdude_message(MSG_INFO, "%s: Warning: cannot query product for device: %s\n",
progname, strerror(libusb_to_errno(r)));
}
} else {
avrdude_message(MSG_NOTICE2, "%s: seen product ->%s<-\n",
progname, string);
if((productName != NULL) && (productName[0] != 0) && (strcmp(string, productName) != 0))
errorCode = USB_ERROR_NOTFOUND;
}
if (errorCode == 0)
break;
libusb_close(handle);
handle = NULL;
}
}
libusb_free_device_list(dev_list,1);
if (handle != NULL){
errorCode = 0;
*device = handle;
}
return errorCode;
}
#else
static int usbOpenDevice(usb_dev_handle **device, int vendor,
char *vendorName, int product, char *productName)
{
struct usb_bus *bus;
struct usb_device *dev;
usb_dev_handle *handle = NULL;
int errorCode = USB_ERROR_NOTFOUND;
static int didUsbInit = 0;
if(!didUsbInit){
didUsbInit = 1;
usb_init();
}
usb_find_busses();
usb_find_devices();
for(bus=usb_get_busses(); bus; bus=bus->next){
for(dev=bus->devices; dev; dev=dev->next){
if(dev->descriptor.idVendor == vendor &&
dev->descriptor.idProduct == product){
char string[256];
int len;
/* we need to open the device in order to query strings */
handle = usb_open(dev);
if(!handle){
errorCode = USB_ERROR_ACCESS;
avrdude_message(MSG_INFO, "%s: Warning: cannot open USB device: %s\n",
progname, usb_strerror());
continue;
}
errorCode = 0;
/* now check whether the names match: */
/* if vendorName not given ignore it (any vendor matches) */
len = usb_get_string_simple(handle, dev->descriptor.iManufacturer,
string, sizeof(string));
if(len < 0){
if ((vendorName != NULL) && (vendorName[0] != 0)) {
errorCode = USB_ERROR_IO;
avrdude_message(MSG_INFO, "%s: Warning: cannot query manufacturer for device: %s\n",
progname, usb_strerror());
}
} else {
avrdude_message(MSG_NOTICE2, "%s: seen device from vendor ->%s<-\n",
progname, string);
if((vendorName != NULL) && (vendorName[0] != 0) && (strcmp(string, vendorName) != 0))
errorCode = USB_ERROR_NOTFOUND;
}
/* if productName not given ignore it (any product matches) */
len = usb_get_string_simple(handle, dev->descriptor.iProduct,
string, sizeof(string));
if(len < 0){
if ((productName != NULL) && (productName[0] != 0)) {
errorCode = USB_ERROR_IO;
avrdude_message(MSG_INFO, "%s: Warning: cannot query product for device: %s\n",
progname, usb_strerror());
}
} else {
avrdude_message(MSG_NOTICE2, "%s: seen product ->%s<-\n",
progname, string);
if((productName != NULL) && (productName[0] != 0) && (strcmp(string, productName) != 0))
errorCode = USB_ERROR_NOTFOUND;
}
if (errorCode == 0)
break;
usb_close(handle);
handle = NULL;
}
}
if(handle)
break;
}
if(handle != NULL){
errorCode = 0;
*device = handle;
}
return errorCode;
}
#endif
/* Interface - prog. */
static int usbasp_open(PROGRAMMER * pgm, char * port)
{
avrdude_message(MSG_DEBUG, "%s: usbasp_open(\"%s\")\n",
progname, port);
/* usb_init will be done in usbOpenDevice */
LNODEID usbpid = lfirst(pgm->usbpid);
int pid, vid;
if (usbpid) {
pid = *(int *)(ldata(usbpid));
if (lnext(usbpid))
avrdude_message(MSG_INFO, "%s: Warning: using PID 0x%04x, ignoring remaining PIDs in list\n",
progname, pid);
} else {
pid = USBASP_SHARED_PID;
}
vid = pgm->usbvid? pgm->usbvid: USBASP_SHARED_VID;
if (usbOpenDevice(&PDATA(pgm)->usbhandle, vid, pgm->usbvendor, pid, pgm->usbproduct) != 0) {
/* try alternatives */
if(strcasecmp(ldata(lfirst(pgm->id)), "usbasp") == 0) {
/* for id usbasp autodetect some variants */
if(strcasecmp(port, "nibobee") == 0) {
avrdude_message(MSG_INFO, "%s: warning: Using \"-C usbasp -P nibobee\" is deprecated,"
"use \"-C nibobee\" instead.\n",
progname);
if (usbOpenDevice(&PDATA(pgm)->usbhandle, USBASP_NIBOBEE_VID, "www.nicai-systems.com",
USBASP_NIBOBEE_PID, "NIBObee") != 0) {
avrdude_message(MSG_INFO, "%s: error: could not find USB device "
"\"NIBObee\" with vid=0x%x pid=0x%x\n",
progname, USBASP_NIBOBEE_VID, USBASP_NIBOBEE_PID);
return -1;
}
return 0;
}
/* check if device with old VID/PID is available */
if (usbOpenDevice(&PDATA(pgm)->usbhandle, USBASP_OLD_VID, "www.fischl.de",
USBASP_OLD_PID, "USBasp") == 0) {
/* found USBasp with old IDs */
avrdude_message(MSG_INFO, "%s: Warning: Found USB device \"USBasp\" with "
"old VID/PID! Please update firmware of USBasp!\n",
progname);
return 0;
}
/* original USBasp is specified in config file, so no need to check it again here */
/* no alternative found => fall through to generic error message */
}
avrdude_message(MSG_INFO, "%s: error: could not find USB device with vid=0x%x pid=0x%x",
progname, vid, pid);
if (pgm->usbvendor[0] != 0) {
avrdude_message(MSG_INFO, " vendor='%s'", pgm->usbvendor);
}
if (pgm->usbproduct[0] != 0) {
avrdude_message(MSG_INFO, " product='%s'", pgm->usbproduct);
}
avrdude_message(MSG_INFO, "\n");
return -1;
}
return 0;
}
static void usbasp_close(PROGRAMMER * pgm)
{
avrdude_message(MSG_DEBUG, "%s: usbasp_close()\n", progname);
if (PDATA(pgm)->usbhandle!=NULL) {
unsigned char temp[4];
memset(temp, 0, sizeof(temp));
if (PDATA(pgm)->use_tpi) {
usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_DISCONNECT, temp, temp, sizeof(temp));
} else {
usbasp_transmit(pgm, 1, USBASP_FUNC_DISCONNECT, temp, temp, sizeof(temp));
}
#ifdef USE_LIBUSB_1_0
libusb_close(PDATA(pgm)->usbhandle);
#else
usb_close(PDATA(pgm)->usbhandle);
#endif
}
#ifdef USE_LIBUSB_1_0
libusb_exit(ctx);
#else
/* nothing for usb 0.1 ? */
#endif
}
/* Dummy functions */
static void usbasp_disable(PROGRAMMER * pgm)
{
/* Do nothing. */
return;
}
static void usbasp_enable(PROGRAMMER * pgm)
{
/* Do nothing. */
return;
}
static void usbasp_display(PROGRAMMER * pgm, const char * p)
{
return;
}
/* Universal functions: for both SPI and TPI */
static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p)
{
unsigned char temp[4];
unsigned char res[4];
IMPORT_PDATA(pgm);
avrdude_message(MSG_DEBUG, "%s: usbasp_initialize()\n", progname);
/* get capabilities */
memset(temp, 0, sizeof(temp));
if(usbasp_transmit(pgm, 1, USBASP_FUNC_GETCAPABILITIES, temp, res, sizeof(res)) == 4)
pdata->capabilities = res[0] | ((unsigned int)res[1] << 8) | ((unsigned int)res[2] << 16) | ((unsigned int)res[3] << 24);
else
pdata->capabilities = 0;
pdata->use_tpi = ((pdata->capabilities & USBASP_CAP_TPI) != 0 && (p->flags & AVRPART_HAS_TPI) != 0) ? 1 : 0;
if(pdata->use_tpi)
{
/* calc tpiclk delay */
int dly = 1500000.0 * pgm->bitclock;
if(dly < 1)
dly = 1;
else if(dly > 2047)
dly = 2047;
temp[0] = dly;
temp[1] = dly >> 8;
/* connect */
usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_CONNECT, temp, res, sizeof(res));
/* change interface */
pgm->program_enable = usbasp_tpi_program_enable;
pgm->chip_erase = usbasp_tpi_chip_erase;
pgm->cmd = usbasp_tpi_cmd;
pgm->read_byte = usbasp_tpi_read_byte;
pgm->write_byte = usbasp_tpi_write_byte;
pgm->paged_write = usbasp_tpi_paged_write;
pgm->paged_load = usbasp_tpi_paged_load;
pgm->set_sck_period = usbasp_tpi_set_sck_period;
}
else
{
/* set sck period */
pgm->set_sck_period(pgm, pgm->bitclock);
/* connect to target device */
usbasp_transmit(pgm, 1, USBASP_FUNC_CONNECT, temp, res, sizeof(res));
/* change interface */
pgm->program_enable = usbasp_spi_program_enable;
pgm->chip_erase = usbasp_spi_chip_erase;
pgm->cmd = usbasp_spi_cmd;
pgm->read_byte = avr_read_byte_default;
pgm->write_byte = avr_write_byte_default;
pgm->paged_write = usbasp_spi_paged_write;
pgm->paged_load = usbasp_spi_paged_load;
pgm->set_sck_period = usbasp_spi_set_sck_period;
}
/* wait, so device is ready to receive commands */
usleep(100000);
return pgm->program_enable(pgm, p);
}
/* SPI specific functions */
static int usbasp_spi_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
unsigned char *res)
{
avrdude_message(MSG_DEBUG, "%s: usbasp_spi_cmd(0x%02x, 0x%02x, 0x%02x, 0x%02x)%s",
progname, cmd[0], cmd[1], cmd[2], cmd[3],
verbose > 3? "...\n": "");
int nbytes =
usbasp_transmit(pgm, 1, USBASP_FUNC_TRANSMIT, cmd, res, 4);
if(nbytes != 4){
if (verbose == 3)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: error: wrong responds size\n",
progname);
return -1;
}
avrdude_message(MSG_TRACE, "%s: usbasp_spi_cmd()", progname);
avrdude_message(MSG_DEBUG, " => 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
res[0], res[1], res[2], res[3]);
return 0;
}
static int usbasp_spi_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
unsigned char res[4];
unsigned char cmd[4];
memset(cmd, 0, sizeof(cmd));
memset(res, 0, sizeof(res));
cmd[0] = 0;
avrdude_message(MSG_DEBUG, "%s: usbasp_program_enable()\n",
progname);
int nbytes =
usbasp_transmit(pgm, 1, USBASP_FUNC_ENABLEPROG, cmd, res, sizeof(res));
if ((nbytes != 1) | (res[0] != 0)) {
avrdude_message(MSG_INFO, "%s: error: program enable: target doesn't answer. %x \n",
progname, res[0]);
return -1;
}
return 0;
}
static int usbasp_spi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
unsigned char cmd[4];
unsigned char res[4];
avrdude_message(MSG_DEBUG, "%s: usbasp_chip_erase()\n",
progname);
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
avrdude_message(MSG_INFO, "chip erase instruction not defined for part \"%s\"\n",
p->desc);
return -1;
}
memset(cmd, 0, sizeof(cmd));
avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
pgm->cmd(pgm, cmd, res);
usleep(p->chip_erase_delay);
pgm->initialize(pgm, p);
return 0;
}
static int usbasp_spi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int address, unsigned int n_bytes)
{
int n;
unsigned char cmd[4];
int wbytes = n_bytes;
int blocksize;
unsigned char *buffer = m->buf + address;
int function;
avrdude_message(MSG_DEBUG, "%s: usbasp_program_paged_load(\"%s\", 0x%x, %d)\n",
progname, m->desc, address, n_bytes);
if (strcmp(m->desc, "flash") == 0) {
function = USBASP_FUNC_READFLASH;
} else if (strcmp(m->desc, "eeprom") == 0) {
function = USBASP_FUNC_READEEPROM;
} else {
return -2;
}
/* set blocksize depending on sck frequency */
if ((PDATA(pgm)->sckfreq_hz > 0) && (PDATA(pgm)->sckfreq_hz < 10000)) {
blocksize = USBASP_READBLOCKSIZE / 10;
} else {
blocksize = USBASP_READBLOCKSIZE;
}
while (wbytes) {
if (wbytes <= blocksize) {
blocksize = wbytes;
}
wbytes -= blocksize;
/* set address (new mode) - if firmware on usbasp support newmode, then they use address from this command */
unsigned char temp[4];
memset(temp, 0, sizeof(temp));
cmd[0] = address & 0xFF;
cmd[1] = address >> 8;
cmd[2] = address >> 16;
cmd[3] = address >> 24;
usbasp_transmit(pgm, 1, USBASP_FUNC_SETLONGADDRESS, cmd, temp, sizeof(temp));
/* send command with address (compatibility mode) - if firmware on
usbasp doesn't support newmode, then they use address from this */
cmd[0] = address & 0xFF;
cmd[1] = address >> 8;
// for compatibility - previous version of usbasp.c doesn't initialize this fields (firmware ignore it)
cmd[2] = 0;
cmd[3] = 0;
n = usbasp_transmit(pgm, 1, function, cmd, buffer, blocksize);
if (n != blocksize) {
avrdude_message(MSG_INFO, "%s: error: wrong reading bytes %x\n",
progname, n);
return -3;
}
buffer += blocksize;
address += blocksize;
}
return n_bytes;
}
static int usbasp_spi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int address, unsigned int n_bytes)
{
int n;
unsigned char cmd[4];
int wbytes = n_bytes;
int blocksize;
unsigned char *buffer = m->buf + address;
unsigned char blockflags = USBASP_BLOCKFLAG_FIRST;
int function;
avrdude_message(MSG_DEBUG, "%s: usbasp_program_paged_write(\"%s\", 0x%x, %d)\n",
progname, m->desc, address, n_bytes);
if (strcmp(m->desc, "flash") == 0) {
function = USBASP_FUNC_WRITEFLASH;
} else if (strcmp(m->desc, "eeprom") == 0) {
function = USBASP_FUNC_WRITEEEPROM;
} else {
return -2;
}
/* set blocksize depending on sck frequency */
if ((PDATA(pgm)->sckfreq_hz > 0) && (PDATA(pgm)->sckfreq_hz < 10000)) {
blocksize = USBASP_WRITEBLOCKSIZE / 10;
} else {
blocksize = USBASP_WRITEBLOCKSIZE;
}
while (wbytes) {
if (wbytes <= blocksize) {
blocksize = wbytes;
}
wbytes -= blocksize;
/* set address (new mode) - if firmware on usbasp support newmode, then
they use address from this command */
unsigned char temp[4];
memset(temp, 0, sizeof(temp));
cmd[0] = address & 0xFF;
cmd[1] = address >> 8;
cmd[2] = address >> 16;
cmd[3] = address >> 24;
usbasp_transmit(pgm, 1, USBASP_FUNC_SETLONGADDRESS, cmd, temp, sizeof(temp));
/* normal command - firmware what support newmode - use address from previous command,
firmware what doesn't support newmode - ignore previous command and use address from this command */
cmd[0] = address & 0xFF;
cmd[1] = address >> 8;
cmd[2] = page_size & 0xFF;
cmd[3] = (blockflags & 0x0F) + ((page_size & 0xF00) >> 4); //TP: Mega128 fix
blockflags = 0;
n = usbasp_transmit(pgm, 0, function, cmd, buffer, blocksize);
if (n != blocksize) {
avrdude_message(MSG_INFO, "%s: error: wrong count at writing %x\n",
progname, n);
return -3;
}
buffer += blocksize;
address += blocksize;
}
return n_bytes;
}
/* The list of SCK frequencies in Hz supported by USBasp */
static struct sckoptions_t usbaspSCKoptions[] = {
{ USBASP_ISP_SCK_1500, 1500000 },
{ USBASP_ISP_SCK_750, 750000 },
{ USBASP_ISP_SCK_375, 375000 },
{ USBASP_ISP_SCK_187_5, 187500 },
{ USBASP_ISP_SCK_93_75, 93750 },
{ USBASP_ISP_SCK_32, 32000 },
{ USBASP_ISP_SCK_16, 16000 },
{ USBASP_ISP_SCK_8, 8000 },
{ USBASP_ISP_SCK_4, 4000 },
{ USBASP_ISP_SCK_2, 2000 },
{ USBASP_ISP_SCK_1, 1000 },
{ USBASP_ISP_SCK_0_5, 500 }
};
/*
* Set sck period (in seconds)
* Find next possible sck period and write it to the programmer.
*/
static int usbasp_spi_set_sck_period(PROGRAMMER *pgm, double sckperiod)
{
char clockoption = USBASP_ISP_SCK_AUTO;
unsigned char res[4];
unsigned char cmd[4];
avrdude_message(MSG_DEBUG, "%s: usbasp_spi_set_sck_period(%g)\n",
progname, sckperiod);
memset(cmd, 0, sizeof(cmd));
memset(res, 0, sizeof(res));
/* reset global sck frequency to auto */
PDATA(pgm)->sckfreq_hz = 0;
if (sckperiod == 0) {
/* auto sck set */
avrdude_message(MSG_NOTICE, "%s: auto set sck period (because given equals null)\n", progname);
} else {
int sckfreq = 1 / sckperiod; /* sck in Hz */
int usefreq = 0;
avrdude_message(MSG_NOTICE2, "%s: try to set SCK period to %g s (= %i Hz)\n", progname, sckperiod, sckfreq);
if (sckfreq >= usbaspSCKoptions[0].frequency) {
clockoption = usbaspSCKoptions[0].id;
usefreq = usbaspSCKoptions[0].frequency;
} else {
/* find clock option next to given clock */
int i;
for (i = 0; i < sizeof(usbaspSCKoptions) / sizeof(usbaspSCKoptions[0]); i++) {
if (sckfreq >= usbaspSCKoptions[i].frequency - 1) { /* subtract 1 to compensate round errors */
clockoption = usbaspSCKoptions[i].id;
usefreq = usbaspSCKoptions[i].frequency;
break;
}
}
}
/* save used sck frequency */
PDATA(pgm)->sckfreq_hz = usefreq;
avrdude_message(MSG_INFO, "%s: set SCK frequency to %i Hz\n", progname, usefreq);
}
cmd[0] = clockoption;
int nbytes =
usbasp_transmit(pgm, 1, USBASP_FUNC_SETISPSCK, cmd, res, sizeof(res));
if ((nbytes != 1) | (res[0] != 0)) {
avrdude_message(MSG_INFO, "%s: warning: cannot set sck period. please check for usbasp firmware update.\n",
progname);
return -1;
}
return 0;
}
/* TPI specific functions */
static void usbasp_tpi_send_byte(PROGRAMMER * pgm, uint8_t b)
{
unsigned char temp[4];
memset(temp, 0, sizeof(temp));
temp[0] = b;
usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_RAWWRITE, temp, temp, sizeof(temp));
}
static int usbasp_tpi_recv_byte(PROGRAMMER * pgm)
{
unsigned char temp[4];
memset(temp, 0, sizeof(temp));
if(usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_RAWREAD, temp, temp, sizeof(temp)) != 1)
{
avrdude_message(MSG_INFO, "%s: error: wrong responds size\n", progname);
return -1;
}
return temp[0];
}
static int usbasp_tpi_nvm_waitbusy(PROGRAMMER * pgm)
{
int retry;
avrdude_message(MSG_DEBUG, "%s: usbasp_tpi_nvm_waitbusy() ...", progname);
for(retry=50; retry>0; retry--)
{
usbasp_tpi_send_byte(pgm, TPI_OP_SIN(NVMCSR));
if(usbasp_tpi_recv_byte(pgm) & NVMCSR_BSY)
continue;
avrdude_message(MSG_DEBUG, " ready\n");
return 0;
}
avrdude_message(MSG_DEBUG, " failure\n");
return -1;
}
static int usbasp_tpi_cmd(PROGRAMMER * pgm, const unsigned char *cmd, unsigned char *res)
{
avrdude_message(MSG_INFO, "%s: error: spi_cmd used in TPI mode: not allowed\n", progname);
return -1;
}
static int usbasp_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
int retry;
avrdude_message(MSG_DEBUG, "%s: usbasp_tpi_program_enable()\n", progname);
/* change guard time */
usbasp_tpi_send_byte(pgm, TPI_OP_SSTCS(TPIPCR));
usbasp_tpi_send_byte(pgm, TPIPCR_GT_2b);
/* send SKEY */
usbasp_tpi_send_byte(pgm, 0xE0);
usbasp_tpi_send_byte(pgm, 0xFF);
usbasp_tpi_send_byte(pgm, 0x88);
usbasp_tpi_send_byte(pgm, 0xD8);
usbasp_tpi_send_byte(pgm, 0xCD);
usbasp_tpi_send_byte(pgm, 0x45);
usbasp_tpi_send_byte(pgm, 0xAB);
usbasp_tpi_send_byte(pgm, 0x89);
usbasp_tpi_send_byte(pgm, 0x12);
/* check if device is ready */
for(retry=0; retry<10; retry++)
{
usbasp_tpi_send_byte(pgm, TPI_OP_SLDCS(TPIIR));
if(usbasp_tpi_recv_byte(pgm) != 0x80)
continue;
usbasp_tpi_send_byte(pgm, TPI_OP_SLDCS(TPISR));
if((usbasp_tpi_recv_byte(pgm) & TPISR_NVMEN) == 0)
continue;
break;
}
if(retry >= 10)
{
avrdude_message(MSG_INFO, "%s: error: program enable: target doesn't answer.\n", progname);
return -1;
}
return 0;
}
static int usbasp_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
avrdude_message(MSG_DEBUG, "%s: usbasp_tpi_chip_erase()\n", progname);
/* Set PR to flash */
usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0));
usbasp_tpi_send_byte(pgm, 0x01);
usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1));
usbasp_tpi_send_byte(pgm, 0x40);
/* select ERASE */
usbasp_tpi_send_byte(pgm, TPI_OP_SOUT(NVMCMD));
usbasp_tpi_send_byte(pgm, NVMCMD_CHIP_ERASE);
/* dummy write */
usbasp_tpi_send_byte(pgm, TPI_OP_SST_INC);
usbasp_tpi_send_byte(pgm, 0x00);
usbasp_tpi_nvm_waitbusy(pgm);
usleep(p->chip_erase_delay);
pgm->initialize(pgm, p);
return 0;
}
static int usbasp_tpi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
unsigned char cmd[4];
unsigned char* dptr;
int readed, clen, n;
uint16_t pr;
avrdude_message(MSG_DEBUG, "%s: usbasp_tpi_paged_load(\"%s\", 0x%0x, %d)\n",
progname, m->desc, addr, n_bytes);
dptr = addr + m->buf;
pr = addr + m->offset;
readed = 0;
while(readed < n_bytes)
{
clen = n_bytes - readed;
if(clen > 32)
clen = 32;
/* prepare READBLOCK cmd */
cmd[0] = pr & 0xFF;
cmd[1] = pr >> 8;
cmd[2] = 0;
cmd[3] = 0;
n = usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_READBLOCK, cmd, dptr, clen);
if(n != clen)
{
avrdude_message(MSG_INFO, "%s: error: wrong reading bytes %x\n", progname, n);
return -3;
}
readed += clen;
pr += clen;
dptr += clen;
}
return n_bytes;
}
static int usbasp_tpi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
unsigned char cmd[4];
unsigned char* sptr;
int writed, clen, n;
uint16_t pr;
avrdude_message(MSG_DEBUG, "%s: usbasp_tpi_paged_write(\"%s\", 0x%0x, %d)\n",
progname, m->desc, addr, n_bytes);
sptr = addr + m->buf;
pr = addr + m->offset;
writed = 0;
/* Set PR to flash */
usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0));
usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1 );
usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1));
usbasp_tpi_send_byte(pgm, (pr >> 8) );
while(writed < n_bytes)
{
clen = n_bytes - writed;
if(clen > 32)
clen = 32;
/* prepare WRITEBLOCK cmd */
cmd[0] = pr & 0xFF;
cmd[1] = pr >> 8;
cmd[2] = 0;
cmd[3] = 0;
n = usbasp_transmit(pgm, 0, USBASP_FUNC_TPI_WRITEBLOCK, cmd, sptr, clen);
if(n != clen)
{
avrdude_message(MSG_INFO, "%s: error: wrong count at writing %x\n", progname, n);
return -3;
}
writed += clen;
pr += clen;
sptr += clen;
}
return n_bytes;
}
static int usbasp_tpi_set_sck_period(PROGRAMMER *pgm, double sckperiod)
{
return 0;
}
static int usbasp_tpi_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr, unsigned char * value)
{
unsigned char cmd[4];
int n;
uint16_t pr;
avrdude_message(MSG_DEBUG, "%s: usbasp_tpi_read_byte(\"%s\", 0x%0lx)\n",
progname, m->desc, addr);
pr = m->offset + addr;
/* READBLOCK */
cmd[0] = pr & 0xFF;
cmd[1] = pr >> 8;
cmd[2] = 0;
cmd[3] = 0;
n = usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_READBLOCK, cmd, value, 1);
if(n != 1)
{
avrdude_message(MSG_INFO, "%s: error: wrong reading bytes %x\n", progname, n);
return -3;
}
return 0;
}
static int usbasp_tpi_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr, unsigned char data)
{
avrdude_message(MSG_INFO, "%s: error: usbasp_write_byte in TPI mode: all writes have to be done at page level\n", progname);
return -1;
}
void usbasp_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "usbasp");
/*
* mandatory functions
*/
pgm->initialize = usbasp_initialize;
pgm->display = usbasp_display;
pgm->enable = usbasp_enable;
pgm->disable = usbasp_disable;
pgm->program_enable = usbasp_spi_program_enable;
pgm->chip_erase = usbasp_spi_chip_erase;
pgm->cmd = usbasp_spi_cmd;
pgm->open = usbasp_open;
pgm->close = usbasp_close;
pgm->read_byte = avr_read_byte_default;
pgm->write_byte = avr_write_byte_default;
/*
* optional functions
*/
pgm->paged_write = usbasp_spi_paged_write;
pgm->paged_load = usbasp_spi_paged_load;
pgm->setup = usbasp_setup;
pgm->teardown = usbasp_teardown;
pgm->set_sck_period = usbasp_spi_set_sck_period;
}
#else /* HAVE_LIBUSB */
static int usbasp_nousb_open (struct programmer_t *pgm, char * name)
{
avrdude_message(MSG_INFO, "%s: error: no usb support. please compile again with libusb installed.\n",
progname);
return -1;
}
void usbasp_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "usbasp");
pgm->open = usbasp_nousb_open;
}
#endif /* HAVE_LIBUSB */
const char usbasp_desc[] = "USBasp programmer, see http://www.fischl.de/usbasp/";
avrdude-6.2/my_ddk_hidsdi.h 000644 000153 000000 00000004234 12622456074 015350 0 ustar 00j wheel 000000 000000 /*
* 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 .
*/
/* $Id: my_ddk_hidsdi.h 1107 2012-11-20 14:03:50Z joerg_wunsch $ */
/*
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
#include
#include
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
#endif /* MY_DDK_HIDSDI_H */
avrdude-6.2/crc16.h 000644 000153 000000 00000001361 12622456074 013471 0 ustar 00j wheel 000000 000000 #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.
*/
extern unsigned short crcsum(const unsigned char* message,
unsigned long length,
unsigned short crc);
/*
* Verify that the last two bytes is a (LSB first) valid CRC of the
* message.
*/
extern int crcverify(const unsigned char* message,
unsigned long length);
/*
* Append a two byte CRC (LSB first) to message. length is size of
* message excluding crc. Space for the CRC bytes must be allocated
* in advance!
*/
extern void crcappend(unsigned char* message,
unsigned long length);
#ifdef __cplusplus
}
#endif
#endif
avrdude-6.2/jtagmkII.c 000644 000153 000000 00000356055 12622456070 014256 0 ustar 00j wheel 000000 000000 /*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2005-2007 Joerg Wunsch
*
* Derived from stk500 code which is:
* Copyright (C) 2002-2004 Brian S. Dean
* Copyright (C) 2005 Erik Walthinsen
*
*
* 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 .
*/
/* $Id: jtagmkII.c 1338 2014-10-15 20:01:12Z joerg_wunsch $ */
/*
* avrdude interface for Atmel JTAG ICE mkII programmer
*
* The AVR Dragon also uses the same protocol, so it is handled here
* as well.
*/
#include "ac_cfg.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "avrdude.h"
#include "libavrdude.h"
#include "crc16.h"
#include "jtagmkII.h"
#include "jtagmkII_private.h"
#include "usbdevs.h"
/*
* Private data for this programmer.
*/
struct pdata
{
unsigned short command_sequence; /* Next cmd seqno to issue. */
/*
* See jtagmkII_read_byte() for an explanation of the flash and
* EEPROM page caches.
*/
unsigned char *flash_pagecache;
unsigned long flash_pageaddr;
unsigned int flash_pagesize;
unsigned char *eeprom_pagecache;
unsigned long eeprom_pageaddr;
unsigned int eeprom_pagesize;
int prog_enabled; /* Cached value of PROGRAMMING status. */
unsigned char serno[6]; /* JTAG ICE serial number. */
/* JTAG chain stuff */
unsigned char jtagchain[4];
/* The length of the device descriptor is firmware-dependent. */
size_t device_descriptor_length;
/* Start address of Xmega boot area */
unsigned long boot_start;
/* Major firmware version (needed for Xmega programming) */
unsigned int fwver;
};
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
/*
* The OCDEN fuse is bit 7 of the high fuse (hfuse). In order to
* perform memory operations on MTYPE_SPM and MTYPE_EEPROM, OCDEN
* needs to be programmed.
*
* OCDEN should probably rather be defined via the configuration, but
* if this ever changes to a different fuse byte for one MCU, quite
* some code here needs to be generalized anyway.
*/
#define OCDEN (1 << 7)
#define RC(x) { x, #x },
static struct {
unsigned int code;
const char *descr;
} jtagresults[] = {
RC(RSP_DEBUGWIRE_SYNC_FAILED)
RC(RSP_FAILED)
RC(RSP_ILLEGAL_BREAKPOINT)
RC(RSP_ILLEGAL_COMMAND)
RC(RSP_ILLEGAL_EMULATOR_MODE)
RC(RSP_ILLEGAL_JTAG_ID)
RC(RSP_ILLEGAL_MCU_STATE)
RC(RSP_ILLEGAL_MEMORY_TYPE)
RC(RSP_ILLEGAL_MEMORY_RANGE)
RC(RSP_ILLEGAL_PARAMETER)
RC(RSP_ILLEGAL_POWER_STATE)
RC(RSP_ILLEGAL_VALUE)
RC(RSP_NO_TARGET_POWER)
RC(RSP_SET_N_PARAMETERS)
};
/*
* pgm->flag is marked as "for private use of the programmer".
* The following defines this programmer's use of that field.
*/
#define PGM_FL_IS_DW (0x0001)
#define PGM_FL_IS_PDI (0x0002)
#define PGM_FL_IS_JTAG (0x0004)
static int jtagmkII_open(PROGRAMMER * pgm, char * port);
static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p);
static int jtagmkII_chip_erase(PROGRAMMER * pgm, AVRPART * p);
static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value);
static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data);
static int jtagmkII_reset(PROGRAMMER * pgm, unsigned char flags);
static int jtagmkII_set_sck_period(PROGRAMMER * pgm, double v);
static int jtagmkII_setparm(PROGRAMMER * pgm, unsigned char parm,
unsigned char * value);
static void jtagmkII_print_parms1(PROGRAMMER * pgm, const char * p);
static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes);
static unsigned char jtagmkII_memtype(PROGRAMMER * pgm, AVRPART * p, unsigned long addr);
static unsigned int jtagmkII_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr);
// AVR32
#define ERROR_SAB 0xFFFFFFFF
static int jtagmkII_open32(PROGRAMMER * pgm, char * port);
static void jtagmkII_close32(PROGRAMMER * pgm);
static int jtagmkII_reset32(PROGRAMMER * pgm, unsigned short flags);
static int jtagmkII_initialize32(PROGRAMMER * pgm, AVRPART * p);
static int jtagmkII_chip_erase32(PROGRAMMER * pgm, AVRPART * p);
static unsigned long jtagmkII_read_SABaddr(PROGRAMMER * pgm, unsigned long addr,
unsigned int prefix); // ERROR_SAB illegal
static int jtagmkII_write_SABaddr(PROGRAMMER * pgm, unsigned long addr,
unsigned int prefix, unsigned long val);
static int jtagmkII_avr32_reset(PROGRAMMER * pgm, unsigned char val,
unsigned char ret1, unsigned char ret2);
static int jtagmkII_smc_init32(PROGRAMMER * pgm);
static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes);
static int jtagmkII_flash_lock32(PROGRAMMER * pgm, unsigned char lock,
unsigned int page);
static int jtagmkII_flash_erase32(PROGRAMMER * pgm, unsigned int page);
static int jtagmkII_flash_write_page32(PROGRAMMER * pgm, unsigned int page);
static int jtagmkII_flash_clear_pagebuffer32(PROGRAMMER * pgm);
static int jtagmkII_paged_load32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes);
void jtagmkII_setup(PROGRAMMER * pgm)
{
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
avrdude_message(MSG_INFO, "%s: jtagmkII_setup(): Out of memory allocating private data\n",
progname);
exit(1);
}
memset(pgm->cookie, 0, sizeof(struct pdata));
}
void jtagmkII_teardown(PROGRAMMER * pgm)
{
free(pgm->cookie);
}
static unsigned long
b4_to_u32(unsigned char *b)
{
unsigned long l;
l = b[0];
l += (unsigned)b[1] << 8;
l += (unsigned)b[2] << 16;
l += (unsigned)b[3] << 24;
return l;
}
static unsigned long
b4_to_u32r(unsigned char *b)
{
unsigned long l;
l = b[3];
l += (unsigned)b[2] << 8;
l += (unsigned)b[1] << 16;
l += (unsigned)b[0] << 24;
return l;
}
static void
u32_to_b4(unsigned char *b, unsigned long l)
{
b[0] = l & 0xff;
b[1] = (l >> 8) & 0xff;
b[2] = (l >> 16) & 0xff;
b[3] = (l >> 24) & 0xff;
}
static void
u32_to_b4r(unsigned char *b, unsigned long l)
{
b[3] = l & 0xff;
b[2] = (l >> 8) & 0xff;
b[1] = (l >> 16) & 0xff;
b[0] = (l >> 24) & 0xff;
}
static unsigned short
b2_to_u16(unsigned char *b)
{
unsigned short l;
l = b[0];
l += (unsigned)b[1] << 8;
return l;
}
static void
u16_to_b2(unsigned char *b, unsigned short l)
{
b[0] = l & 0xff;
b[1] = (l >> 8) & 0xff;
}
static const char *
jtagmkII_get_rc(unsigned int rc)
{
int i;
static char msg[50];
for (i = 0; i < sizeof jtagresults / sizeof jtagresults[0]; i++)
if (jtagresults[i].code == rc)
return jtagresults[i].descr;
sprintf(msg, "Unknown JTAG ICE mkII result code 0x%02x", rc);
return msg;
}
static void jtagmkII_print_memory(unsigned char *b, size_t s)
{
int i;
if (s < 2)
return;
for (i = 0; i < s - 1; i++) {
avrdude_message(MSG_INFO, "0x%02x ", b[i + 1]);
if (i % 16 == 15)
putc('\n', stderr);
else
putc(' ', stderr);
}
if (i % 16 != 0)
putc('\n', stderr);
}
static void jtagmkII_prmsg(PROGRAMMER * pgm, unsigned char * data, size_t len)
{
int i;
if (verbose >= 4) {
avrdude_message(MSG_TRACE, "Raw message:\n");
for (i = 0; i < len; i++) {
avrdude_message(MSG_TRACE, "0x%02x", data[i]);
if (i % 16 == 15)
putc('\n', stderr);
else
putc(' ', stderr);
}
if (i % 16 != 0)
putc('\n', stderr);
}
switch (data[0]) {
case RSP_OK:
avrdude_message(MSG_INFO, "OK\n");
break;
case RSP_FAILED:
avrdude_message(MSG_INFO, "FAILED\n");
break;
case RSP_ILLEGAL_BREAKPOINT:
avrdude_message(MSG_INFO, "Illegal breakpoint\n");
break;
case RSP_ILLEGAL_COMMAND:
avrdude_message(MSG_INFO, "Illegal command\n");
break;
case RSP_ILLEGAL_EMULATOR_MODE:
avrdude_message(MSG_INFO, "Illegal emulator mode");
if (len > 1)
switch (data[1]) {
case EMULATOR_MODE_DEBUGWIRE: avrdude_message(MSG_INFO, ": DebugWire"); break;
case EMULATOR_MODE_JTAG: avrdude_message(MSG_INFO, ": JTAG"); break;
case EMULATOR_MODE_HV: avrdude_message(MSG_INFO, ": HVSP/PP"); break;
case EMULATOR_MODE_SPI: avrdude_message(MSG_INFO, ": SPI"); break;
case EMULATOR_MODE_JTAG_XMEGA: avrdude_message(MSG_INFO, ": JTAG/Xmega"); break;
}
putc('\n', stderr);
break;
case RSP_ILLEGAL_JTAG_ID:
avrdude_message(MSG_INFO, "Illegal JTAG ID\n");
break;
case RSP_ILLEGAL_MCU_STATE:
avrdude_message(MSG_INFO, "Illegal MCU state");
if (len > 1)
switch (data[1]) {
case STOPPED: avrdude_message(MSG_INFO, ": Stopped"); break;
case RUNNING: avrdude_message(MSG_INFO, ": Running"); break;
case PROGRAMMING: avrdude_message(MSG_INFO, ": Programming"); break;
}
putc('\n', stderr);
break;
case RSP_ILLEGAL_MEMORY_TYPE:
avrdude_message(MSG_INFO, "Illegal memory type\n");
break;
case RSP_ILLEGAL_MEMORY_RANGE:
avrdude_message(MSG_INFO, "Illegal memory range\n");
break;
case RSP_ILLEGAL_PARAMETER:
avrdude_message(MSG_INFO, "Illegal parameter\n");
break;
case RSP_ILLEGAL_POWER_STATE:
avrdude_message(MSG_INFO, "Illegal power state\n");
break;
case RSP_ILLEGAL_VALUE:
avrdude_message(MSG_INFO, "Illegal value\n");
break;
case RSP_NO_TARGET_POWER:
avrdude_message(MSG_INFO, "No target power\n");
break;
case RSP_SIGN_ON:
avrdude_message(MSG_INFO, "Sign-on succeeded\n");
/* Sign-on data will be printed below anyway. */
break;
case RSP_MEMORY:
avrdude_message(MSG_INFO, "memory contents:\n");
jtagmkII_print_memory(data, len);
break;
case RSP_PARAMETER:
avrdude_message(MSG_INFO, "parameter values:\n");
jtagmkII_print_memory(data, len);
break;
case RSP_SPI_DATA:
avrdude_message(MSG_INFO, "SPI data returned:\n");
for (i = 1; i < len; i++)
avrdude_message(MSG_INFO, "0x%02x ", data[i]);
putc('\n', stderr);
break;
case EVT_BREAK:
avrdude_message(MSG_INFO, "BREAK event");
if (len >= 6) {
avrdude_message(MSG_INFO, ", PC = 0x%lx, reason ", b4_to_u32(data + 1));
switch (data[5]) {
case 0x00:
avrdude_message(MSG_INFO, "unspecified");
break;
case 0x01:
avrdude_message(MSG_INFO, "program break");
break;
case 0x02:
avrdude_message(MSG_INFO, "data break PDSB");
break;
case 0x03:
avrdude_message(MSG_INFO, "data break PDMSB");
break;
default:
avrdude_message(MSG_INFO, "unknown: 0x%02x", data[5]);
}
}
putc('\n', stderr);
break;
default:
avrdude_message(MSG_INFO, "unknown message 0x%02x\n", data[0]);
}
putc('\n', stderr);
}
int jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
{
unsigned char *buf;
avrdude_message(MSG_DEBUG, "\n%s: jtagmkII_send(): sending %lu bytes\n",
progname, (unsigned long)len);
if ((buf = malloc(len + 10)) == NULL)
{
avrdude_message(MSG_INFO, "%s: jtagmkII_send(): out of memory",
progname);
return -1;
}
buf[0] = MESSAGE_START;
u16_to_b2(buf + 1, PDATA(pgm)->command_sequence);
u32_to_b4(buf + 3, len);
buf[7] = TOKEN;
memcpy(buf + 8, data, len);
crcappend(buf, len + 8);
if (serial_send(&pgm->fd, buf, len + 10) != 0) {
avrdude_message(MSG_INFO, "%s: jtagmkII_send(): failed to send command to serial port\n",
progname);
free(buf);
return -1;
}
free(buf);
return 0;
}
static int jtagmkII_drain(PROGRAMMER * pgm, int display)
{
return serial_drain(&pgm->fd, display);
}
/*
* Receive one frame, return it in *msg. Received sequence number is
* returned in seqno. Any valid frame will be returned, regardless
* whether it matches the expected sequence number, including event
* notification frames (seqno == 0xffff).
*
* Caller must eventually free the buffer.
*/
static int jtagmkII_recv_frame(PROGRAMMER * pgm, unsigned char **msg,
unsigned short * seqno) {
enum states { sSTART,
/* NB: do NOT change the sequence of the following: */
sSEQNUM1, sSEQNUM2,
sSIZE1, sSIZE2, sSIZE3, sSIZE4,
sTOKEN,
sDATA,
sCSUM1, sCSUM2,
/* end NB */
sDONE
} state = sSTART;
unsigned long msglen = 0, l = 0;
int headeridx = 0;
int timeout = 0;
int ignorpkt = 0;
int rv;
unsigned char c, *buf = NULL, header[8];
unsigned short r_seqno = 0;
unsigned short checksum = 0;
struct timeval tv;
double timeoutval = 100; /* seconds */
double tstart, tnow;
avrdude_message(MSG_TRACE, "%s: jtagmkII_recv():\n", progname);
gettimeofday(&tv, NULL);
tstart = tv.tv_sec;
while ( (state != sDONE ) && (!timeout) ) {
if (state == sDATA) {
rv = 0;
if (ignorpkt) {
/* skip packet's contents */
for(l = 0; l < msglen; l++)
rv += serial_recv(&pgm->fd, &c, 1);
} else {
rv += serial_recv(&pgm->fd, buf + 8, msglen);
}
if (rv != 0) {
timedout:
/* timeout in receive */
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_recv(): Timeout receiving packet\n",
progname);
free(buf);
return -1;
}
} else {
if (serial_recv(&pgm->fd, &c, 1) != 0)
goto timedout;
}
checksum ^= c;
if (state < sDATA)
header[headeridx++] = c;
switch (state) {
case sSTART:
if (c == MESSAGE_START) {
state = sSEQNUM1;
} else {
headeridx = 0;
}
break;
case sSEQNUM1:
case sSEQNUM2:
r_seqno >>= 8;
r_seqno |= ((unsigned)c << 8);
state++;
break;
case sSIZE1:
case sSIZE2:
case sSIZE3:
case sSIZE4:
msglen >>= 8;
msglen |= ((unsigned)c << 24);
state++;
break;
case sTOKEN:
if (c == TOKEN) {
state = sDATA;
if (msglen > MAX_MESSAGE) {
avrdude_message(MSG_INFO, "%s: jtagmkII_recv(): msglen %lu exceeds max message "
"size %u, ignoring message\n",
progname, msglen, MAX_MESSAGE);
state = sSTART;
headeridx = 0;
} else if ((buf = malloc(msglen + 10)) == NULL) {
avrdude_message(MSG_INFO, "%s: jtagmkII_recv(): out of memory\n",
progname);
ignorpkt++;
} else {
memcpy(buf, header, 8);
}
} else {
state = sSTART;
headeridx = 0;
}
break;
case sDATA:
/* The entire payload has been read above. */
l = msglen + 8;
state = sCSUM1;
break;
case sCSUM1:
case sCSUM2:
buf[l++] = c;
if (state == sCSUM2) {
if (crcverify(buf, msglen + 10)) {
if (verbose >= 9)
avrdude_message(MSG_TRACE2, "%s: jtagmkII_recv(): CRC OK",
progname);
state = sDONE;
} else {
avrdude_message(MSG_INFO, "%s: jtagmkII_recv(): checksum error\n",
progname);
free(buf);
return -4;
}
} else
state++;
break;
default:
avrdude_message(MSG_INFO, "%s: jtagmkII_recv(): unknown state\n",
progname);
free(buf);
return -5;
}
gettimeofday(&tv, NULL);
tnow = tv.tv_sec;
if (tnow - tstart > timeoutval) {
avrdude_message(MSG_INFO, "%s: jtagmkII_recv_frame(): timeout\n",
progname);
return -1;
}
}
avrdude_message(MSG_DEBUG, "\n");
*seqno = r_seqno;
*msg = buf;
return msglen;
}
int jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg) {
unsigned short r_seqno;
int rv;
for (;;) {
if ((rv = jtagmkII_recv_frame(pgm, msg, &r_seqno)) <= 0)
return rv;
avrdude_message(MSG_DEBUG, "%s: jtagmkII_recv(): "
"Got message seqno %d (command_sequence == %d)\n",
progname, r_seqno, PDATA(pgm)->command_sequence);
if (r_seqno == PDATA(pgm)->command_sequence) {
if (++(PDATA(pgm)->command_sequence) == 0xffff)
PDATA(pgm)->command_sequence = 0;
/*
* We move the payload to the beginning of the buffer, to make
* the job easier for the caller. We have to return the
* original pointer though, as the caller must free() it.
*/
memmove(*msg, *msg + 8, rv);
if (verbose == 4)
{
int i = rv;
unsigned char *p = *msg;
avrdude_message(MSG_TRACE, "%s: Recv: ", progname);
while (i) {
unsigned char c = *p;
if (isprint(c)) {
avrdude_message(MSG_TRACE, "%c ", c);
}
else {
avrdude_message(MSG_TRACE, ". ");
}
avrdude_message(MSG_TRACE, "[%02x] ", c);
p++;
i--;
}
avrdude_message(MSG_TRACE, "\n");
}
return rv;
}
if (r_seqno == 0xffff) {
avrdude_message(MSG_DEBUG, "%s: jtagmkII_recv(): got asynchronous event\n",
progname);
} else {
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_recv(): "
"got wrong sequence number, %u != %u\n",
progname, r_seqno, PDATA(pgm)->command_sequence);
}
free(*msg);
}
}
int jtagmkII_getsync(PROGRAMMER * pgm, int mode) {
int tries;
#define MAXTRIES 33
unsigned char buf[3], *resp, c = 0xff;
int status;
unsigned int fwver, hwver;
int is_dragon;
avrdude_message(MSG_DEBUG, "%s: jtagmkII_getsync()\n", progname);
if (strncmp(pgm->type, "JTAG", strlen("JTAG")) == 0) {
is_dragon = 0;
} else if (strncmp(pgm->type, "DRAGON", strlen("DRAGON")) == 0) {
is_dragon = 1;
} else {
avrdude_message(MSG_INFO, "%s: Programmer is neither JTAG ICE mkII nor AVR Dragon\n",
progname);
return -1;
}
for (tries = 0; tries < MAXTRIES; tries++) {
/* Get the sign-on information. */
buf[0] = CMND_GET_SIGN_ON;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_getsync(): Sending sign-on command: ",
progname);
jtagmkII_send(pgm, buf, 1);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): sign-on command: "
"status %d\n",
progname, status);
} else if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
if (status > 0) {
if ((c = resp[0]) == RSP_SIGN_ON) {
fwver = ((unsigned)resp[8] << 8) | (unsigned)resp[7];
PDATA(pgm)->fwver = fwver;
hwver = (unsigned)resp[9];
memcpy(PDATA(pgm)->serno, resp + 10, 6);
if (status > 17) {
avrdude_message(MSG_NOTICE, "JTAG ICE mkII sign-on message:\n");
avrdude_message(MSG_NOTICE, "Communications protocol version: %u\n",
(unsigned)resp[1]);
avrdude_message(MSG_NOTICE, "M_MCU:\n");
avrdude_message(MSG_NOTICE, " boot-loader FW version: %u\n",
(unsigned)resp[2]);
avrdude_message(MSG_NOTICE, " firmware version: %u.%02u\n",
(unsigned)resp[4], (unsigned)resp[3]);
avrdude_message(MSG_NOTICE, " hardware version: %u\n",
(unsigned)resp[5]);
avrdude_message(MSG_NOTICE, "S_MCU:\n");
avrdude_message(MSG_NOTICE, " boot-loader FW version: %u\n",
(unsigned)resp[6]);
avrdude_message(MSG_NOTICE, " firmware version: %u.%02u\n",
(unsigned)resp[8], (unsigned)resp[7]);
avrdude_message(MSG_NOTICE, " hardware version: %u\n",
(unsigned)resp[9]);
avrdude_message(MSG_NOTICE, "Serial number: "
"%02x:%02x:%02x:%02x:%02x:%02x\n",
PDATA(pgm)->serno[0], PDATA(pgm)->serno[1], PDATA(pgm)->serno[2], PDATA(pgm)->serno[3], PDATA(pgm)->serno[4], PDATA(pgm)->serno[5]);
resp[status - 1] = '\0';
avrdude_message(MSG_NOTICE, "Device ID: %s\n",
resp + 16);
}
break;
}
free(resp);
}
}
if (tries >= MAXTRIES) {
if (status <= 0)
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
else
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
"bad response to sign-on command: %s\n",
progname, jtagmkII_get_rc(c));
return -1;
}
PDATA(pgm)->device_descriptor_length = sizeof(struct device_descriptor);
/*
* There's no official documentation from Atmel about what firmware
* revision matches what device descriptor length. The algorithm
* below has been found empirically.
*/
#define FWVER(maj, min) ((maj << 8) | (min))
if (!is_dragon && fwver < FWVER(3, 16)) {
PDATA(pgm)->device_descriptor_length -= 2;
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
"S_MCU firmware version might be too old to work correctly\n",
progname);
} else if (!is_dragon && fwver < FWVER(4, 0)) {
PDATA(pgm)->device_descriptor_length -= 2;
}
if (mode != EMULATOR_MODE_SPI)
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_getsync(): Using a %u-byte device descriptor\n",
progname, (unsigned)PDATA(pgm)->device_descriptor_length);
if (mode == EMULATOR_MODE_SPI) {
PDATA(pgm)->device_descriptor_length = 0;
if (!is_dragon && fwver < FWVER(4, 14)) {
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): ISP functionality requires firmware "
"version >= 4.14\n",
progname);
return -1;
}
}
if (mode == EMULATOR_MODE_PDI || mode == EMULATOR_MODE_JTAG_XMEGA) {
if (!is_dragon && mode == EMULATOR_MODE_PDI && hwver < 1) {
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): Xmega PDI support requires hardware "
"revision >= 1\n",
progname);
return -1;
}
if (!is_dragon && fwver < FWVER(5, 37)) {
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): Xmega support requires firmware "
"version >= 5.37\n",
progname);
return -1;
}
if (is_dragon && fwver < FWVER(6, 11)) {
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): Xmega support requires firmware "
"version >= 6.11\n",
progname);
return -1;
}
}
#undef FWVER
if(mode < 0) return 0; // for AVR32
tries = 0;
retry:
/* Turn the ICE into JTAG or ISP mode as requested. */
buf[0] = mode;
if (jtagmkII_setparm(pgm, PAR_EMULATOR_MODE, buf) < 0) {
if (mode == EMULATOR_MODE_SPI) {
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
"ISP activation failed, trying debugWire\n",
progname);
buf[0] = EMULATOR_MODE_DEBUGWIRE;
if (jtagmkII_setparm(pgm, PAR_EMULATOR_MODE, buf) < 0)
return -1;
else {
/*
* We are supposed to send a CMND_RESET with the
* MONCOM_DISABLE flag set right now, and then
* restart from scratch.
*
* As this will make the ICE sign off from USB, so
* we risk losing our USB connection, it's easier
* to instruct the user to restart AVRDUDE rather
* than trying to cope with all this inside the
* program.
*/
(void)jtagmkII_reset(pgm, 0x04);
if (tries++ > 3) {
avrdude_message(MSG_INFO, "%s: Failed to return from debugWIRE to ISP.\n",
progname);
return -1;
}
avrdude_message(MSG_INFO, "%s: Target prepared for ISP, signed off.\n"
"%s: Now retrying without power-cycling the target.\n",
progname, progname);
goto retry;
}
} else {
return -1;
}
}
/* GET SYNC forces the target into STOPPED mode */
buf[0] = CMND_GET_SYNC;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_getsync(): Sending get sync command: ",
progname);
jtagmkII_send(pgm, buf, 1);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
return -1;
}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
c = resp[0];
free(resp);
if (c != RSP_OK) {
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
"bad response to set parameter command: %s\n",
progname, jtagmkII_get_rc(c));
return -1;
}
return 0;
}
/*
* issue the 'chip erase' command to the AVR device
*/
static int jtagmkII_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
int status, len;
unsigned char buf[6], *resp, c;
if (p->flags & AVRPART_HAS_PDI) {
buf[0] = CMND_XMEGA_ERASE;
buf[1] = XMEGA_ERASE_CHIP;
memset(buf + 2, 0, 4); /* address of area to be erased */
len = 6;
} else {
buf[0] = CMND_CHIP_ERASE;
len = 1;
}
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_chip_erase(): Sending %schip erase command: ",
progname,
(p->flags & AVRPART_HAS_PDI)? "Xmega ": "");
jtagmkII_send(pgm, buf, len);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_chip_erase(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
return -1;
}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
c = resp[0];
free(resp);
if (c != RSP_OK) {
avrdude_message(MSG_INFO, "%s: jtagmkII_chip_erase(): "
"bad response to chip erase command: %s\n",
progname, jtagmkII_get_rc(c));
return -1;
}
if (!(p->flags & AVRPART_HAS_PDI))
pgm->initialize(pgm, p);
return 0;
}
/*
* There is no chip erase functionality in debugWire mode.
*/
static int jtagmkII_chip_erase_dw(PROGRAMMER * pgm, AVRPART * p)
{
avrdude_message(MSG_INFO, "%s: Chip erase not supported in debugWire mode\n",
progname);
return 0;
}
static void jtagmkII_set_devdescr(PROGRAMMER * pgm, AVRPART * p)
{
int status;
unsigned char *resp, c;
LNODEID ln;
AVRMEM * m;
struct {
unsigned char cmd;
struct device_descriptor dd;
} sendbuf;
memset(&sendbuf, 0, sizeof sendbuf);
sendbuf.cmd = CMND_SET_DEVICE_DESCRIPTOR;
sendbuf.dd.ucSPMCRAddress = p->spmcr;
sendbuf.dd.ucRAMPZAddress = p->rampz;
sendbuf.dd.ucIDRAddress = p->idr;
u16_to_b2(sendbuf.dd.EECRAddress, p->eecr);
sendbuf.dd.ucAllowFullPageBitstream =
(p->flags & AVRPART_ALLOWFULLPAGEBITSTREAM) != 0;
sendbuf.dd.EnablePageProgramming =
(p->flags & AVRPART_ENABLEPAGEPROGRAMMING) != 0;
for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
m = ldata(ln);
if (strcmp(m->desc, "flash") == 0) {
if (m->page_size > 256)
PDATA(pgm)->flash_pagesize = 256;
else
PDATA(pgm)->flash_pagesize = m->page_size;
u32_to_b4(sendbuf.dd.ulFlashSize, m->size);
u16_to_b2(sendbuf.dd.uiFlashPageSize, m->page_size);
u16_to_b2(sendbuf.dd.uiFlashpages, m->size / m->page_size);
if (p->flags & AVRPART_HAS_DW) {
memcpy(sendbuf.dd.ucFlashInst, p->flash_instr, FLASH_INSTR_SIZE);
memcpy(sendbuf.dd.ucEepromInst, p->eeprom_instr, EEPROM_INSTR_SIZE);
}
} else if (strcmp(m->desc, "eeprom") == 0) {
sendbuf.dd.ucEepromPageSize = PDATA(pgm)->eeprom_pagesize = m->page_size;
}
}
sendbuf.dd.ucCacheType =
(p->flags & AVRPART_HAS_PDI)? 0x02 /* ATxmega */: 0x00;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_set_devdescr(): "
"Sending set device descriptor command: ",
progname);
jtagmkII_send(pgm, (unsigned char *)&sendbuf,
PDATA(pgm)->device_descriptor_length + sizeof(unsigned char));
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_set_devdescr(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
return;
}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
c = resp[0];
free(resp);
if (c != RSP_OK) {
avrdude_message(MSG_INFO, "%s: jtagmkII_set_devdescr(): "
"bad response to set device descriptor command: %s\n",
progname, jtagmkII_get_rc(c));
}
}
static void jtagmkII_set_xmega_params(PROGRAMMER * pgm, AVRPART * p)
{
int status;
unsigned char *resp, c;
LNODEID ln;
AVRMEM * m;
struct {
unsigned char cmd;
struct xmega_device_desc dd;
} sendbuf;
memset(&sendbuf, 0, sizeof sendbuf);
sendbuf.cmd = CMND_SET_XMEGA_PARAMS;
u16_to_b2(sendbuf.dd.whatever, 0x0002);
sendbuf.dd.datalen = 47;
u16_to_b2(sendbuf.dd.nvm_base_addr, p->nvm_base);
u16_to_b2(sendbuf.dd.mcu_base_addr, p->mcu_base);
for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
m = ldata(ln);
if (strcmp(m->desc, "flash") == 0) {
if (m->page_size > 256)
PDATA(pgm)->flash_pagesize = 256;
else
PDATA(pgm)->flash_pagesize = m->page_size;
u16_to_b2(sendbuf.dd.flash_page_size, m->page_size);
} else if (strcmp(m->desc, "eeprom") == 0) {
sendbuf.dd.eeprom_page_size = m->page_size;
u16_to_b2(sendbuf.dd.eeprom_size, m->size);
u32_to_b4(sendbuf.dd.nvm_eeprom_offset, m->offset);
} else if (strcmp(m->desc, "application") == 0) {
u32_to_b4(sendbuf.dd.app_size, m->size);
u32_to_b4(sendbuf.dd.nvm_app_offset, m->offset);
} else if (strcmp(m->desc, "boot") == 0) {
u16_to_b2(sendbuf.dd.boot_size, m->size);
u32_to_b4(sendbuf.dd.nvm_boot_offset, m->offset);
} else if (strcmp(m->desc, "fuse1") == 0) {
u32_to_b4(sendbuf.dd.nvm_fuse_offset, m->offset & ~7);
} else if (strncmp(m->desc, "lock", 4) == 0) {
u32_to_b4(sendbuf.dd.nvm_lock_offset, m->offset);
} else if (strcmp(m->desc, "usersig") == 0) {
u32_to_b4(sendbuf.dd.nvm_user_sig_offset, m->offset);
} else if (strcmp(m->desc, "prodsig") == 0) {
u32_to_b4(sendbuf.dd.nvm_prod_sig_offset, m->offset);
} else if (strcmp(m->desc, "data") == 0) {
u32_to_b4(sendbuf.dd.nvm_data_offset, m->offset);
}
}
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_set_xmega_params(): "
"Sending set Xmega params command: ",
progname);
jtagmkII_send(pgm, (unsigned char *)&sendbuf, sizeof sendbuf);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_set_xmega_params(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
return;
}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
c = resp[0];
free(resp);
if (c != RSP_OK) {
avrdude_message(MSG_INFO, "%s: jtagmkII_set_xmega_params(): "
"bad response to set device descriptor command: %s\n",
progname, jtagmkII_get_rc(c));
}
}
/*
* Reset the target.
*/
static int jtagmkII_reset(PROGRAMMER * pgm, unsigned char flags)
{
int status;
unsigned char buf[2], *resp, c;
/*
* In debugWire mode, don't reset. Do a forced stop, and tell the
* ICE to stop any timers, too.
*/
if (pgm->flag & PGM_FL_IS_DW) {
unsigned char parm[] = { 0 };
(void)jtagmkII_setparm(pgm, PAR_TIMERS_RUNNING, parm);
}
buf[0] = (pgm->flag & PGM_FL_IS_DW)? CMND_FORCED_STOP: CMND_RESET;
buf[1] = (pgm->flag & PGM_FL_IS_DW)? 1: flags;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_reset(): Sending %s command: ",
progname, (pgm->flag & PGM_FL_IS_DW)? "stop": "reset");
jtagmkII_send(pgm, buf, 2);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_reset(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
return -1;
}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
c = resp[0];
free(resp);
if (c != RSP_OK) {
avrdude_message(MSG_INFO, "%s: jtagmkII_reset(): "
"bad response to reset command: %s\n",
progname, jtagmkII_get_rc(c));
return -1;
}
return 0;
}
static int jtagmkII_program_enable_INFO(PROGRAMMER * pgm, AVRPART * p)
{
return 0;
}
static int jtagmkII_program_enable(PROGRAMMER * pgm)
{
int status;
unsigned char buf[1], *resp, c;
int use_ext_reset;
if (PDATA(pgm)->prog_enabled)
return 0;
for (use_ext_reset = 0; use_ext_reset <= 1; use_ext_reset++) {
buf[0] = CMND_ENTER_PROGMODE;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_program_enable(): "
"Sending enter progmode command: ",
progname);
jtagmkII_send(pgm, buf, 1);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_program_enable(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
return -1;
}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
c = resp[0];
free(resp);
if (c != RSP_OK) {
avrdude_message(MSG_INFO, "%s: jtagmkII_program_enable(): "
"bad response to enter progmode command: %s\n",
progname, jtagmkII_get_rc(c));
if (c == RSP_ILLEGAL_JTAG_ID) {
if (use_ext_reset == 0) {
unsigned char parm[] = { 1};
avrdude_message(MSG_INFO, "%s: retrying with external reset applied\n",
progname);
(void)jtagmkII_setparm(pgm, PAR_EXTERNAL_RESET, parm);
continue;
}
avrdude_message(MSG_INFO, "%s: JTAGEN fuse disabled?\n", progname);
return -1;
}
}
}
PDATA(pgm)->prog_enabled = 1;
return 0;
}
static int jtagmkII_program_disable(PROGRAMMER * pgm)
{
int status;
unsigned char buf[1], *resp, c;
if (!PDATA(pgm)->prog_enabled)
return 0;
buf[0] = CMND_LEAVE_PROGMODE;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_program_disable(): "
"Sending leave progmode command: ",
progname);
jtagmkII_send(pgm, buf, 1);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_program_disable(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
return -1;
}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
c = resp[0];
free(resp);
if (c != RSP_OK) {
avrdude_message(MSG_INFO, "%s: jtagmkII_program_disable(): "
"bad response to leave progmode command: %s\n",
progname, jtagmkII_get_rc(c));
return -1;
}
PDATA(pgm)->prog_enabled = 0;
(void)jtagmkII_reset(pgm, 0x01);
return 0;
}
static unsigned char jtagmkII_get_baud(long baud)
{
static struct {
long baud;
unsigned char val;
} baudtab[] = {
{ 2400L, PAR_BAUD_2400 },
{ 4800L, PAR_BAUD_4800 },
{ 9600L, PAR_BAUD_9600 },
{ 19200L, PAR_BAUD_19200 },
{ 38400L, PAR_BAUD_38400 },
{ 57600L, PAR_BAUD_57600 },
{ 115200L, PAR_BAUD_115200 },
{ 14400L, PAR_BAUD_14400 },
};
int i;
for (i = 0; i < sizeof baudtab / sizeof baudtab[0]; i++)
if (baud == baudtab[i].baud)
return baudtab[i].val;
return 0;
}
/*
* initialize the AVR device and prepare it to accept commands
*/
static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
{
AVRMEM hfuse;
unsigned char b;
int ok;
const char *ifname;
ok = 0;
if (pgm->flag & PGM_FL_IS_DW) {
ifname = "debugWire";
if (p->flags & AVRPART_HAS_DW)
ok = 1;
} else if (pgm->flag & PGM_FL_IS_PDI) {
ifname = "PDI";
if (p->flags & AVRPART_HAS_PDI)
ok = 1;
} else {
ifname = "JTAG";
if (p->flags & AVRPART_HAS_JTAG)
ok = 1;
}
if (!ok) {
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): part %s has no %s interface\n",
progname, p->desc, ifname);
return -1;
}
if ((serdev->flags & SERDEV_FL_CANSETSPEED) && pgm->baudrate && pgm->baudrate != 19200) {
if ((b = jtagmkII_get_baud(pgm->baudrate)) == 0) {
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): unsupported baudrate %d\n",
progname, pgm->baudrate);
} else {
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_initialize(): "
"trying to set baudrate to %d\n",
progname, pgm->baudrate);
if (jtagmkII_setparm(pgm, PAR_BAUD_RATE, &b) == 0)
serial_setspeed(&pgm->fd, pgm->baudrate);
}
}
if ((pgm->flag & PGM_FL_IS_JTAG) && pgm->bitclock != 0.0) {
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_initialize(): "
"trying to set JTAG clock period to %.1f us\n",
progname, pgm->bitclock);
if (jtagmkII_set_sck_period(pgm, pgm->bitclock) != 0)
return -1;
}
if ((pgm->flag & PGM_FL_IS_JTAG) &&
jtagmkII_setparm(pgm, PAR_DAISY_CHAIN_INFO, PDATA(pgm)->jtagchain) < 0) {
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Failed to setup JTAG chain\n",
progname);
return -1;
}
/*
* If this is an ATxmega device in JTAG mode, change the emulator
* mode from JTAG to JTAG_XMEGA.
*/
if ((pgm->flag & PGM_FL_IS_JTAG) &&
(p->flags & AVRPART_HAS_PDI)) {
if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG_XMEGA) < 0)
return -1;
}
/*
* Must set the device descriptor before entering programming mode.
*/
if (PDATA(pgm)->fwver >= 0x700 && (p->flags & AVRPART_HAS_PDI) != 0)
jtagmkII_set_xmega_params(pgm, p);
else
jtagmkII_set_devdescr(pgm, p);
PDATA(pgm)->boot_start = ULONG_MAX;
/*
* If this is an ATxmega device in JTAG mode, change the emulator
* mode from JTAG to JTAG_XMEGA.
*/
if ((pgm->flag & PGM_FL_IS_JTAG) &&
(p->flags & AVRPART_HAS_PDI)) {
/*
* Find out where the border between application and boot area
* is.
*/
AVRMEM *bootmem = avr_locate_mem(p, "boot");
AVRMEM *flashmem = avr_locate_mem(p, "flash");
if (bootmem == NULL || flashmem == NULL) {
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Cannot locate \"flash\" and \"boot\" memories in description\n",
progname);
} else {
if (PDATA(pgm)->fwver < 0x700) {
/* V7+ firmware does not need this anymore */
unsigned char par[4];
u32_to_b4(par, flashmem->offset);
(void) jtagmkII_setparm(pgm, PAR_PDI_OFFSET_START, par);
u32_to_b4(par, bootmem->offset);
(void) jtagmkII_setparm(pgm, PAR_PDI_OFFSET_END, par);
}
PDATA(pgm)->boot_start = bootmem->offset - flashmem->offset;
}
}
free(PDATA(pgm)->flash_pagecache);
free(PDATA(pgm)->eeprom_pagecache);
if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) {
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Out of memory\n",
progname);
return -1;
}
if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Out of memory\n",
progname);
free(PDATA(pgm)->flash_pagecache);
return -1;
}
PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
if (PDATA(pgm)->fwver >= 0x700 && (p->flags & AVRPART_HAS_PDI)) {
/*
* Work around for
* https://savannah.nongnu.org/bugs/index.php?37942
*
* Firmware version 7.24 (at least) on the Dragon behaves very
* strange when it gets a RESET request here. All subsequent
* responses are completely off, so the emulator becomes unusable.
* This appears to be a firmware bug (earlier versions, at least
* 7.14, didn't experience this), but by omitting the RESET for
* Xmega devices, we can work around it.
*/
} else {
if (jtagmkII_reset(pgm, 0x01) < 0)
return -1;
}
if ((pgm->flag & PGM_FL_IS_JTAG) && !(p->flags & AVRPART_HAS_PDI)) {
strcpy(hfuse.desc, "hfuse");
if (jtagmkII_read_byte(pgm, p, &hfuse, 1, &b) < 0)
return -1;
if ((b & OCDEN) != 0)
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): warning: OCDEN fuse not programmed, "
"single-byte EEPROM updates not possible\n",
progname);
}
return 0;
}
static void jtagmkII_disable(PROGRAMMER * pgm)
{
free(PDATA(pgm)->flash_pagecache);
PDATA(pgm)->flash_pagecache = NULL;
free(PDATA(pgm)->eeprom_pagecache);
PDATA(pgm)->eeprom_pagecache = NULL;
/*
* jtagmkII_program_disable() doesn't do anything if the
* device is currently not in programming mode, so just
* call it unconditionally here.
*/
(void)jtagmkII_program_disable(pgm);
}
static void jtagmkII_enable(PROGRAMMER * pgm)
{
return;
}
static int jtagmkII_parseextparms(PROGRAMMER * pgm, LISTID extparms)
{
LNODEID ln;
const char *extended_param;
int rv = 0;
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
extended_param = ldata(ln);
if (strncmp(extended_param, "jtagchain=", strlen("jtagchain=")) == 0) {
unsigned int ub, ua, bb, ba;
if (sscanf(extended_param, "jtagchain=%u,%u,%u,%u", &ub, &ua, &bb, &ba)
!= 4) {
avrdude_message(MSG_INFO, "%s: jtagmkII_parseextparms(): invalid JTAG chain '%s'\n",
progname, extended_param);
rv = -1;
continue;
}
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_parseextparms(): JTAG chain parsed as:\n"
"%s %u units before, %u units after, %u bits before, %u bits after\n",
progname,
progbuf, ub, ua, bb, ba);
PDATA(pgm)->jtagchain[0] = ub;
PDATA(pgm)->jtagchain[1] = ua;
PDATA(pgm)->jtagchain[2] = bb;
PDATA(pgm)->jtagchain[3] = ba;
continue;
}
avrdude_message(MSG_INFO, "%s: jtagmkII_parseextparms(): invalid extended parameter '%s'\n",
progname, extended_param);
rv = -1;
}
return rv;
}
static int jtagmkII_open(PROGRAMMER * pgm, char * port)
{
union pinfo pinfo;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_open()\n", progname);
/*
* The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
* attaching. If the config file or command-line parameters specify
* a higher baud rate, we switch to it later on, after establishing
* the connection with the ICE.
*/
pinfo.baud = 19200;
/*
* If the port name starts with "usb", divert the serial routines
* to the USB ones. The serial_open() function for USB overrides
* the meaning of the "baud" parameter to be the USB device ID to
* search for.
*/
if (strncmp(port, "usb", 3) == 0) {
#if defined(HAVE_LIBUSB)
serdev = &usb_serdev;
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
pinfo.usbinfo.flags = 0;
pinfo.usbinfo.pid = USB_DEVICE_JTAGICEMKII;
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
pgm->fd.usb.eep = 0; /* no seperate EP for events */
#else
avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
return -1;
#endif
}
strcpy(pgm->port, port);
if (serial_open(port, pinfo, &pgm->fd)==-1) {
return -1;
}
/*
* drain any extraneous input
*/
jtagmkII_drain(pgm, 0);
if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG) < 0)
return -1;
return 0;
}
static int jtagmkII_open_dw(PROGRAMMER * pgm, char * port)
{
union pinfo pinfo;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_open_dw()\n", progname);
/*
* The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
* attaching. If the config file or command-line parameters specify
* a higher baud rate, we switch to it later on, after establishing
* the connection with the ICE.
*/
pinfo.baud = 19200;
/*
* If the port name starts with "usb", divert the serial routines
* to the USB ones. The serial_open() function for USB overrides
* the meaning of the "baud" parameter to be the USB device ID to
* search for.
*/
if (strncmp(port, "usb", 3) == 0) {
#if defined(HAVE_LIBUSB)
serdev = &usb_serdev;
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
pinfo.usbinfo.flags = 0;
pinfo.usbinfo.pid = USB_DEVICE_JTAGICEMKII;
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
pgm->fd.usb.eep = 0; /* no seperate EP for events */
#else
avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
return -1;
#endif
}
strcpy(pgm->port, port);
if (serial_open(port, pinfo, &pgm->fd)==-1) {
return -1;
}
/*
* drain any extraneous input
*/
jtagmkII_drain(pgm, 0);
if (jtagmkII_getsync(pgm, EMULATOR_MODE_DEBUGWIRE) < 0)
return -1;
return 0;
}
static int jtagmkII_open_pdi(PROGRAMMER * pgm, char * port)
{
union pinfo pinfo;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_open_pdi()\n", progname);
/*
* The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
* attaching. If the config file or command-line parameters specify
* a higher baud rate, we switch to it later on, after establishing
* the connection with the ICE.
*/
pinfo.baud = 19200;
/*
* If the port name starts with "usb", divert the serial routines
* to the USB ones. The serial_open() function for USB overrides
* the meaning of the "baud" parameter to be the USB device ID to
* search for.
*/
if (strncmp(port, "usb", 3) == 0) {
#if defined(HAVE_LIBUSB)
serdev = &usb_serdev;
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
pinfo.usbinfo.flags = 0;
pinfo.usbinfo.pid = USB_DEVICE_JTAGICEMKII;
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
pgm->fd.usb.eep = 0; /* no seperate EP for events */
#else
avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
return -1;
#endif
}
strcpy(pgm->port, port);
if (serial_open(port, pinfo, &pgm->fd)==-1) {
return -1;
}
/*
* drain any extraneous input
*/
jtagmkII_drain(pgm, 0);
if (jtagmkII_getsync(pgm, EMULATOR_MODE_PDI) < 0)
return -1;
return 0;
}
static int jtagmkII_dragon_open(PROGRAMMER * pgm, char * port)
{
union pinfo pinfo;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_dragon_open()\n", progname);
/*
* The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
* attaching. If the config file or command-line parameters specify
* a higher baud rate, we switch to it later on, after establishing
* the connection with the ICE.
*/
pinfo.baud = 19200;
/*
* If the port name starts with "usb", divert the serial routines
* to the USB ones. The serial_open() function for USB overrides
* the meaning of the "baud" parameter to be the USB device ID to
* search for.
*/
if (strncmp(port, "usb", 3) == 0) {
#if defined(HAVE_LIBUSB)
serdev = &usb_serdev;
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
pinfo.usbinfo.flags = 0;
pinfo.usbinfo.pid = USB_DEVICE_AVRDRAGON;
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
pgm->fd.usb.eep = 0; /* no seperate EP for events */
#else
avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
return -1;
#endif
}
strcpy(pgm->port, port);
if (serial_open(port, pinfo, &pgm->fd)==-1) {
return -1;
}
/*
* drain any extraneous input
*/
jtagmkII_drain(pgm, 0);
if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG) < 0)
return -1;
return 0;
}
static int jtagmkII_dragon_open_dw(PROGRAMMER * pgm, char * port)
{
union pinfo pinfo;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_dragon_open_dw()\n", progname);
/*
* The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
* attaching. If the config file or command-line parameters specify
* a higher baud rate, we switch to it later on, after establishing
* the connection with the ICE.
*/
pinfo.baud = 19200;
/*
* If the port name starts with "usb", divert the serial routines
* to the USB ones. The serial_open() function for USB overrides
* the meaning of the "baud" parameter to be the USB device ID to
* search for.
*/
if (strncmp(port, "usb", 3) == 0) {
#if defined(HAVE_LIBUSB)
serdev = &usb_serdev;
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
pinfo.usbinfo.flags = 0;
pinfo.usbinfo.pid = USB_DEVICE_AVRDRAGON;
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
pgm->fd.usb.eep = 0; /* no seperate EP for events */
#else
avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
return -1;
#endif
}
strcpy(pgm->port, port);
if (serial_open(port, pinfo, &pgm->fd)==-1) {
return -1;
}
/*
* drain any extraneous input
*/
jtagmkII_drain(pgm, 0);
if (jtagmkII_getsync(pgm, EMULATOR_MODE_DEBUGWIRE) < 0)
return -1;
return 0;
}
static int jtagmkII_dragon_open_pdi(PROGRAMMER * pgm, char * port)
{
union pinfo pinfo;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_dragon_open_pdi()\n", progname);
/*
* The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
* attaching. If the config file or command-line parameters specify
* a higher baud rate, we switch to it later on, after establishing
* the connection with the ICE.
*/
pinfo.baud = 19200;
/*
* If the port name starts with "usb", divert the serial routines
* to the USB ones. The serial_open() function for USB overrides
* the meaning of the "baud" parameter to be the USB device ID to
* search for.
*/
if (strncmp(port, "usb", 3) == 0) {
#if defined(HAVE_LIBUSB)
serdev = &usb_serdev;
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
pinfo.usbinfo.flags = 0;
pinfo.usbinfo.pid = USB_DEVICE_AVRDRAGON;
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
pgm->fd.usb.eep = 0; /* no seperate EP for events */
#else
avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
return -1;
#endif
}
strcpy(pgm->port, port);
if (serial_open(port, pinfo, &pgm->fd)==-1) {
return -1;
}
/*
* drain any extraneous input
*/
jtagmkII_drain(pgm, 0);
if (jtagmkII_getsync(pgm, EMULATOR_MODE_PDI) < 0)
return -1;
return 0;
}
void jtagmkII_close(PROGRAMMER * pgm)
{
int status;
unsigned char buf[1], *resp, c;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_close()\n", progname);
if (pgm->flag & PGM_FL_IS_PDI) {
/* When in PDI mode, restart target. */
buf[0] = CMND_GO;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_close(): Sending GO command: ",
progname);
jtagmkII_send(pgm, buf, 1);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
} else {
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
c = resp[0];
free(resp);
if (c != RSP_OK) {
avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
"bad response to GO command: %s\n",
progname, jtagmkII_get_rc(c));
}
}
}
buf[0] = CMND_SIGN_OFF;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_close(): Sending sign-off command: ",
progname);
jtagmkII_send(pgm, buf, 1);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
return;
}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
c = resp[0];
free(resp);
if (c != RSP_OK) {
avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
"bad response to sign-off command: %s\n",
progname, jtagmkII_get_rc(c));
}
serial_close(&pgm->fd);
pgm->fd.ifd = -1;
}
static int jtagmkII_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int addr)
{
unsigned char cmd[6];
unsigned char *resp;
int status, tries;
long otimeout = serial_recv_timeout;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_page_erase(.., %s, 0x%x)\n",
progname, m->desc, addr);
if (!(p->flags & AVRPART_HAS_PDI)) {
avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase: not an Xmega device\n",
progname);
return -1;
}
if ((pgm->flag & PGM_FL_IS_DW)) {
avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase: not applicable to debugWIRE\n",
progname);
return -1;
}
if (jtagmkII_program_enable(pgm) < 0)
return -1;
cmd[0] = CMND_XMEGA_ERASE;
if (strcmp(m->desc, "flash") == 0) {
if (jtagmkII_memtype(pgm, p, addr) == MTYPE_FLASH)
cmd[1] = XMEGA_ERASE_APP_PAGE;
else
cmd[1] = XMEGA_ERASE_BOOT_PAGE;
} else if (strcmp(m->desc, "eeprom") == 0) {
cmd[1] = XMEGA_ERASE_EEPROM_PAGE;
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
cmd[1] = XMEGA_ERASE_USERSIG;
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
cmd[1] = XMEGA_ERASE_BOOT_PAGE;
} else {
cmd[1] = XMEGA_ERASE_APP_PAGE;
}
serial_recv_timeout = 100;
/*
* Don't use jtagmkII_memaddr() here. While with all other
* commands, firmware 7+ doesn't require the NVM offsets being
* applied, the erase page commands make an exception, and do
* require the NVM offsets as part of the (page) address.
*/
u32_to_b4(cmd + 2, addr + m->offset);
tries = 0;
retry:
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_page_erase(): "
"Sending xmega erase command: ",
progname);
jtagmkII_send(pgm, cmd, sizeof cmd);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
if (tries++ < 4) {
serial_recv_timeout *= 2;
goto retry;
}
avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase(): fatal timeout/"
"error communicating with programmer (status %d)\n",
progname, status);
serial_recv_timeout = otimeout;
return -1;
}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
if (resp[0] != RSP_OK) {
avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase(): "
"bad response to xmega erase command: %s\n",
progname, jtagmkII_get_rc(resp[0]));
free(resp);
serial_recv_timeout = otimeout;
return -1;
}
free(resp);
serial_recv_timeout = otimeout;
return 0;
}
static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
unsigned int block_size;
unsigned int maxaddr = addr + n_bytes;
unsigned char *cmd;
unsigned char *resp;
int status, tries, dynamic_memtype = 0;
long otimeout = serial_recv_timeout;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_paged_write(.., %s, %d, %d)\n",
progname, m->desc, page_size, n_bytes);
if (!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0)
return -1;
if (page_size == 0) page_size = 256;
else if (page_size > 256) page_size = 256;
if ((cmd = malloc(page_size + 10)) == NULL) {
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write(): Out of memory\n",
progname);
return -1;
}
cmd[0] = CMND_WRITE_MEMORY;
if (strcmp(m->desc, "flash") == 0) {
PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
cmd[1] = jtagmkII_memtype(pgm, p, addr);
if (p->flags & AVRPART_HAS_PDI)
/* dynamically decide between flash/boot memtype */
dynamic_memtype = 1;
} else if (strcmp(m->desc, "eeprom") == 0) {
if (pgm->flag & PGM_FL_IS_DW) {
/*
* jtagmkII_paged_write() to EEPROM attempted while in
* DW mode. Use jtagmkII_write_byte() instead.
*/
for (; addr < maxaddr; addr++) {
status = jtagmkII_write_byte(pgm, p, m, addr, m->buf[addr]);
if (status < 0) {
free(cmd);
return -1;
}
}
free(cmd);
return n_bytes;
}
cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
cmd[1] = MTYPE_USERSIG;
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
cmd[1] = MTYPE_BOOT_FLASH;
} else if ( p->flags & AVRPART_HAS_PDI ) {
cmd[1] = MTYPE_FLASH;
} else {
cmd[1] = MTYPE_SPM;
}
serial_recv_timeout = 100;
for (; addr < maxaddr; addr += page_size) {
if ((maxaddr - addr) < page_size)
block_size = maxaddr - addr;
else
block_size = page_size;
avrdude_message(MSG_DEBUG, "%s: jtagmkII_paged_write(): "
"block_size at addr %d is %d\n",
progname, addr, block_size);
if (dynamic_memtype)
cmd[1] = jtagmkII_memtype(pgm, p, addr);
u32_to_b4(cmd + 2, page_size);
u32_to_b4(cmd + 6, jtagmkII_memaddr(pgm, p, m, addr));
/*
* The JTAG ICE will refuse to write anything but a full page, at
* least for the flash ROM. If a partial page has been requested,
* set the remainder to 0xff. (Maybe we should rather read back
* the existing contents instead before? Doesn't matter much, as
* bits cannot be written to 1 anyway.)
*/
memset(cmd + 10, 0xff, page_size);
memcpy(cmd + 10, m->buf + addr, block_size);
tries = 0;
retry:
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_paged_write(): "
"Sending write memory command: ",
progname);
jtagmkII_send(pgm, cmd, page_size + 10);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
if (tries++ < 4) {
serial_recv_timeout *= 2;
goto retry;
}
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write(): fatal timeout/"
"error communicating with programmer (status %d)\n",
progname, status);
free(cmd);
serial_recv_timeout = otimeout;
return -1;
}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
if (resp[0] != RSP_OK) {
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write(): "
"bad response to write memory command: %s\n",
progname, jtagmkII_get_rc(resp[0]));
free(resp);
free(cmd);
serial_recv_timeout = otimeout;
return -1;
}
free(resp);
}
free(cmd);
serial_recv_timeout = otimeout;
return n_bytes;
}
static int jtagmkII_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
unsigned int block_size;
unsigned int maxaddr = addr + n_bytes;
unsigned char cmd[10];
unsigned char *resp;
int status, tries, dynamic_memtype = 0;
long otimeout = serial_recv_timeout;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_paged_load(.., %s, %d, %d)\n",
progname, m->desc, page_size, n_bytes);
if (!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0)
return -1;
page_size = m->readsize;
cmd[0] = CMND_READ_MEMORY;
if (strcmp(m->desc, "flash") == 0) {
cmd[1] = jtagmkII_memtype(pgm, p, addr);
if (p->flags & AVRPART_HAS_PDI)
/* dynamically decide between flash/boot memtype */
dynamic_memtype = 1;
} else if (strcmp(m->desc, "eeprom") == 0) {
cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
if (pgm->flag & PGM_FL_IS_DW)
return -1;
} else if ( ( strcmp(m->desc, "prodsig") == 0 ) ) {
cmd[1] = MTYPE_PRODSIG;
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
cmd[1] = MTYPE_USERSIG;
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
cmd[1] = MTYPE_BOOT_FLASH;
} else if ( p->flags & AVRPART_HAS_PDI ) {
cmd[1] = MTYPE_FLASH;
} else {
cmd[1] = MTYPE_SPM;
}
serial_recv_timeout = 100;
for (; addr < maxaddr; addr += page_size) {
if ((maxaddr - addr) < page_size)
block_size = maxaddr - addr;
else
block_size = page_size;
avrdude_message(MSG_DEBUG, "%s: jtagmkII_paged_load(): "
"block_size at addr %d is %d\n",
progname, addr, block_size);
if (dynamic_memtype)
cmd[1] = jtagmkII_memtype(pgm, p, addr);
u32_to_b4(cmd + 2, block_size);
u32_to_b4(cmd + 6, jtagmkII_memaddr(pgm, p, m, addr));
tries = 0;
retry:
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_paged_load(): Sending read memory command: ",
progname);
jtagmkII_send(pgm, cmd, 10);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_load(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
if (tries++ < 4) {
serial_recv_timeout *= 2;
goto retry;
}
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_load(): fatal timeout/"
"error communicating with programmer (status %d)\n",
progname, status);
serial_recv_timeout = otimeout;
return -1;
}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
if (resp[0] != RSP_MEMORY) {
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_load(): "
"bad response to read memory command: %s\n",
progname, jtagmkII_get_rc(resp[0]));
free(resp);
serial_recv_timeout = otimeout;
return -1;
}
memcpy(m->buf + addr, resp + 1, status-1);
free(resp);
}
serial_recv_timeout = otimeout;
return n_bytes;
}
static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value)
{
unsigned char cmd[10];
unsigned char *resp = NULL, *cache_ptr = NULL;
int status, tries, unsupp;
unsigned long paddr = 0UL, *paddr_ptr = NULL;
unsigned int pagesize = 0;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_read_byte(.., %s, 0x%lx, ...)\n",
progname, mem->desc, addr);
if (!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0)
return -1;
cmd[0] = CMND_READ_MEMORY;
unsupp = 0;
addr += mem->offset;
cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_FLASH_PAGE;
if (strcmp(mem->desc, "flash") == 0 ||
strcmp(mem->desc, "application") == 0 ||
strcmp(mem->desc, "apptable") == 0 ||
strcmp(mem->desc, "boot") == 0) {
pagesize = PDATA(pgm)->flash_pagesize;
paddr = addr & ~(pagesize - 1);
paddr_ptr = &PDATA(pgm)->flash_pageaddr;
cache_ptr = PDATA(pgm)->flash_pagecache;
} else if (strcmp(mem->desc, "eeprom") == 0) {
if ( (pgm->flag & PGM_FL_IS_DW) || ( p->flags & AVRPART_HAS_PDI ) ) {
/* debugWire cannot use page access for EEPROM */
cmd[1] = MTYPE_EEPROM;
} else {
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;
}
} else if (strcmp(mem->desc, "lfuse") == 0) {
cmd[1] = MTYPE_FUSE_BITS;
addr = 0;
if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1;
} else if (strcmp(mem->desc, "hfuse") == 0) {
cmd[1] = MTYPE_FUSE_BITS;
addr = 1;
if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1;
} else if (strcmp(mem->desc, "efuse") == 0) {
cmd[1] = MTYPE_FUSE_BITS;
addr = 2;
if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1;
} else if (strncmp(mem->desc, "lock", 4) == 0) {
cmd[1] = MTYPE_LOCK_BITS;
if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1;
} else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
cmd[1] = MTYPE_FUSE_BITS;
} else if (strcmp(mem->desc, "usersig") == 0) {
cmd[1] = MTYPE_USERSIG;
} else if (strcmp(mem->desc, "prodsig") == 0) {
cmd[1] = MTYPE_PRODSIG;
} else if (strcmp(mem->desc, "calibration") == 0) {
cmd[1] = MTYPE_OSCCAL_BYTE;
if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1;
} else if (strcmp(mem->desc, "signature") == 0) {
cmd[1] = MTYPE_SIGN_JTAG;
if (pgm->flag & PGM_FL_IS_DW) {
/*
* In debugWire mode, there is no accessible memory area to read
* the signature from, but the essential two bytes can be read
* as a parameter from the ICE.
*/
unsigned char parm[4];
switch (addr) {
case 0:
*value = 0x1E; /* Atmel vendor ID */
break;
case 1:
case 2:
if (jtagmkII_getparm(pgm, PAR_TARGET_SIGNATURE, parm) < 0)
return -1;
*value = parm[2 - addr];
break;
default:
avrdude_message(MSG_INFO, "%s: illegal address %lu for signature memory\n",
progname, addr);
return -1;
}
return 0;
}
}
/*
* If the respective memory area is not supported under debugWire,
* leave here.
*/
if (unsupp) {
*value = 42;
return -1;
}
/*
* To improve the read speed, we used paged reads for flash and
* EEPROM, and cache the results in a page cache.
*
* Page cache validation is based on "{flash,eeprom}_pageaddr"
* (holding the base address of the most recent cache fill
* operation). This variable is set to (unsigned long)-1L when the
* cache needs to be invalidated.
*/
if (pagesize && paddr == *paddr_ptr) {
*value = cache_ptr[addr & (pagesize - 1)];
return 0;
}
if (pagesize) {
u32_to_b4(cmd + 2, pagesize);
u32_to_b4(cmd + 6, paddr);
} else {
u32_to_b4(cmd + 2, 1);
u32_to_b4(cmd + 6, addr);
}
tries = 0;
retry:
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_read_byte(): Sending read memory command: ",
progname);
jtagmkII_send(pgm, cmd, 10);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_read_byte(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
if (tries++ < 3)
goto retry;
avrdude_message(MSG_INFO, "%s: jtagmkII_read_byte(): "
"fatal timeout/error communicating with programmer (status %d)\n",
progname, status);
if (status < 0)
resp = 0;
goto fail;
}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
if (resp[0] != RSP_MEMORY) {
avrdude_message(MSG_INFO, "%s: jtagmkII_read_byte(): "
"bad response to read memory command: %s\n",
progname, jtagmkII_get_rc(resp[0]));
goto fail;
}
if (pagesize) {
*paddr_ptr = paddr;
memcpy(cache_ptr, resp + 1, pagesize);
*value = cache_ptr[addr & (pagesize - 1)];
} else
*value = resp[1];
free(resp);
return 0;
fail:
free(resp);
return -1;
}
static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data)
{
unsigned char cmd[12];
unsigned char *resp = NULL, writedata, writedata2 = 0xFF;
int status, tries, need_progmode = 1, unsupp = 0, writesize = 1;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_write_byte(.., %s, 0x%lx, ...)\n",
progname, mem->desc, addr);
addr += mem->offset;
writedata = data;
cmd[0] = CMND_WRITE_MEMORY;
cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_SPM;
if (strcmp(mem->desc, "flash") == 0) {
if ((addr & 1) == 1) {
/* odd address = high byte */
writedata = 0xFF; /* don't modify the low byte */
writedata2 = data;
addr &= ~1L;
}
writesize = 2;
need_progmode = 0;
PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1;
} else if (strcmp(mem->desc, "eeprom") == 0) {
cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM_XMEGA: MTYPE_EEPROM;
need_progmode = 0;
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
} else if (strcmp(mem->desc, "lfuse") == 0) {
cmd[1] = MTYPE_FUSE_BITS;
addr = 0;
if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1;
} else if (strcmp(mem->desc, "hfuse") == 0) {
cmd[1] = MTYPE_FUSE_BITS;
addr = 1;
if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1;
} else if (strcmp(mem->desc, "efuse") == 0) {
cmd[1] = MTYPE_FUSE_BITS;
addr = 2;
if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1;
} else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
cmd[1] = MTYPE_FUSE_BITS;
} else if (strcmp(mem->desc, "usersig") == 0) {
cmd[1] = MTYPE_USERSIG;
} else if (strcmp(mem->desc, "prodsig") == 0) {
cmd[1] = MTYPE_PRODSIG;
} else if (strncmp(mem->desc, "lock", 4) == 0) {
cmd[1] = MTYPE_LOCK_BITS;
if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1;
} else if (strcmp(mem->desc, "calibration") == 0) {
cmd[1] = MTYPE_OSCCAL_BYTE;
if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1;
} else if (strcmp(mem->desc, "signature") == 0) {
cmd[1] = MTYPE_SIGN_JTAG;
if (pgm->flag & PGM_FL_IS_DW)
unsupp = 1;
}
if (unsupp)
return -1;
if (need_progmode) {
if (jtagmkII_program_enable(pgm) < 0)
return -1;
} else {
if (jtagmkII_program_disable(pgm) < 0)
return -1;
}
u32_to_b4(cmd + 2, writesize);
u32_to_b4(cmd + 6, addr);
cmd[10] = writedata;
cmd[11] = writedata2;
tries = 0;
retry:
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_write_byte(): Sending write memory command: ",
progname);
jtagmkII_send(pgm, cmd, 10 + writesize);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_write_byte(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
if (tries++ < 3)
goto retry;
avrdude_message(MSG_INFO, "%s: jtagmkII_write_byte(): "
"fatal timeout/error communicating with programmer (status %d)\n",
progname, status);
goto fail;
}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
if (resp[0] != RSP_OK) {
avrdude_message(MSG_INFO, "%s: jtagmkII_write_byte(): "
"bad response to write memory command: %s\n",
progname, jtagmkII_get_rc(resp[0]));
goto fail;
}
free(resp);
return 0;
fail:
free(resp);
return -1;
}
/*
* Set the JTAG clock. The actual frequency is quite a bit of
* guesswork, based on the values claimed by AVR Studio. Inside the
* JTAG ICE, the value is the delay count of a delay loop between the
* JTAG clock edges. A count of 0 bypasses the delay loop.
*
* As the STK500 expresses it as a period length (and we actualy do
* program a period length as well), we rather call it by that name.
*/
static int jtagmkII_set_sck_period(PROGRAMMER * pgm, double v)
{
unsigned char dur;
v = 1 / v; /* convert to frequency */
if (v >= 6.4e6)
dur = 0;
else if (v >= 2.8e6)
dur = 1;
else if (v >= 20.9e3)
dur = (unsigned char)(5.35e6 / v);
else
dur = 255;
return jtagmkII_setparm(pgm, PAR_OCD_JTAG_CLK, &dur);
}
/*
* Read an emulator parameter. As the maximal parameter length is 4
* bytes by now, we always copy out 4 bytes to *value, so the caller
* must have allocated sufficient space.
*/
int jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm,
unsigned char * value)
{
int status;
unsigned char buf[2], *resp, c;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_getparm()\n", progname);
buf[0] = CMND_GET_PARAMETER;
buf[1] = parm;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_getparm(): "
"Sending get parameter command (parm 0x%02x): ",
progname, parm);
jtagmkII_send(pgm, buf, 2);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_getparm(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
return -1;
}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
c = resp[0];
if (c != RSP_PARAMETER) {
avrdude_message(MSG_INFO, "%s: jtagmkII_getparm(): "
"bad response to get parameter command: %s\n",
progname, jtagmkII_get_rc(c));
free(resp);
return -1;
}
memcpy(value, resp + 1, 4);
free(resp);
return 0;
}
/*
* Write an emulator parameter.
*/
static int jtagmkII_setparm(PROGRAMMER * pgm, unsigned char parm,
unsigned char * value)
{
int status;
/*
* As the maximal parameter length is 4 bytes, we use a fixed-length
* buffer, as opposed to malloc()ing it.
*/
unsigned char buf[2 + 4], *resp, c;
size_t size;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_setparm()\n", progname);
switch (parm) {
case PAR_HW_VERSION: size = 2; break;
case PAR_FW_VERSION: size = 4; break;
case PAR_EMULATOR_MODE: size = 1; break;
case PAR_BAUD_RATE: size = 1; break;
case PAR_OCD_VTARGET: size = 2; break;
case PAR_OCD_JTAG_CLK: size = 1; break;
case PAR_TIMERS_RUNNING: size = 1; break;
case PAR_EXTERNAL_RESET: size = 1; break;
case PAR_DAISY_CHAIN_INFO: size = 4; break;
case PAR_PDI_OFFSET_START:
case PAR_PDI_OFFSET_END: size = 4; break;
default:
avrdude_message(MSG_INFO, "%s: jtagmkII_setparm(): unknown parameter 0x%02x\n",
progname, parm);
return -1;
}
buf[0] = CMND_SET_PARAMETER;
buf[1] = parm;
memcpy(buf + 2, value, size);
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_setparm(): "
"Sending set parameter command (parm 0x%02x, %u bytes): ",
progname, parm, (unsigned)size);
jtagmkII_send(pgm, buf, size + 2);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_setparm(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
return -1;
}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
c = resp[0];
free(resp);
if (c != RSP_OK) {
avrdude_message(MSG_INFO, "%s: jtagmkII_setparm(): "
"bad response to set parameter command: %s\n",
progname, jtagmkII_get_rc(c));
return -1;
}
return 0;
}
static void jtagmkII_display(PROGRAMMER * pgm, const char * p)
{
unsigned char hw[4], fw[4];
if (jtagmkII_getparm(pgm, PAR_HW_VERSION, hw) < 0 ||
jtagmkII_getparm(pgm, PAR_FW_VERSION, fw) < 0)
return;
avrdude_message(MSG_INFO, "%sM_MCU hardware version: %d\n", p, hw[0]);
avrdude_message(MSG_INFO, "%sM_MCU firmware version: %d.%02d\n", p, fw[1], fw[0]);
avrdude_message(MSG_INFO, "%sS_MCU hardware version: %d\n", p, hw[1]);
avrdude_message(MSG_INFO, "%sS_MCU firmware version: %d.%02d\n", p, fw[3], fw[2]);
avrdude_message(MSG_INFO, "%sSerial number: %02x:%02x:%02x:%02x:%02x:%02x\n",
p, PDATA(pgm)->serno[0], PDATA(pgm)->serno[1], PDATA(pgm)->serno[2], PDATA(pgm)->serno[3], PDATA(pgm)->serno[4], PDATA(pgm)->serno[5]);
jtagmkII_print_parms1(pgm, p);
return;
}
static void jtagmkII_print_parms1(PROGRAMMER * pgm, const char * p)
{
unsigned char vtarget[4], jtag_clock[4];
char clkbuf[20];
double clk;
if (jtagmkII_getparm(pgm, PAR_OCD_VTARGET, vtarget) < 0)
return;
avrdude_message(MSG_INFO, "%sVtarget : %.1f V\n", p,
b2_to_u16(vtarget) / 1000.0);
if ((pgm->flag & PGM_FL_IS_JTAG)) {
if (jtagmkII_getparm(pgm, PAR_OCD_JTAG_CLK, jtag_clock) < 0)
return;
if (jtag_clock[0] == 0) {
strcpy(clkbuf, "6.4 MHz");
clk = 6.4e6;
} else if (jtag_clock[0] == 1) {
strcpy(clkbuf, "2.8 MHz");
clk = 2.8e6;
} else if (jtag_clock[0] <= 5) {
sprintf(clkbuf, "%.1f MHz", 5.35 / (double)jtag_clock[0]);
clk = 5.35e6 / (double)jtag_clock[0];
} else {
sprintf(clkbuf, "%.1f kHz", 5.35e3 / (double)jtag_clock[0]);
clk = 5.35e6 / (double)jtag_clock[0];
avrdude_message(MSG_INFO, "%sJTAG clock : %s (%.1f us)\n", p, clkbuf,
1.0e6 / clk);
}
}
return;
}
static void jtagmkII_print_parms(PROGRAMMER * pgm)
{
jtagmkII_print_parms1(pgm, "");
}
static unsigned char jtagmkII_memtype(PROGRAMMER * pgm, AVRPART * p, unsigned long addr)
{
if ( p->flags & AVRPART_HAS_PDI ) {
if (addr >= PDATA(pgm)->boot_start)
return MTYPE_BOOT_FLASH;
else
return MTYPE_FLASH;
} else {
return MTYPE_FLASH_PAGE;
}
}
static unsigned int jtagmkII_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr)
{
/*
* Xmega devices handled by V7+ firmware don't want to be told their
* m->offset within the write memory command.
*/
if (PDATA(pgm)->fwver >= 0x700 && (p->flags & AVRPART_HAS_PDI) != 0) {
if (addr >= PDATA(pgm)->boot_start)
/*
* all memories but "flash" are smaller than boot_start anyway, so
* no need for an extra check we are operating on "flash"
*/
return addr - PDATA(pgm)->boot_start;
else
/* normal flash, or anything else */
return addr;
}
/*
* Old firmware, or non-Xmega device. Non-Xmega (and non-AVR32)
* devices always have an m->offset of 0, so we don't have to
* distinguish them here.
*/
return addr + m->offset;
}
#ifdef __OBJC__
#pragma mark -
#endif
static int jtagmkII_avr32_reset(PROGRAMMER * pgm, unsigned char val,
unsigned char ret1, unsigned char ret2)
{
int status;
unsigned char buf[3], *resp;
avrdude_message(MSG_NOTICE, "%s: jtagmkII_avr32_reset(%2.2x)\n",
progname, val);
buf[0] = CMND_GET_IR;
buf[1] = 0x0C;
status = jtagmkII_send(pgm, buf, 2);
if(status < 0) return -1;
status = jtagmkII_recv(pgm, &resp);
if (status != 2 || resp[0] != 0x87 || resp[1] != ret1) {
avrdude_message(MSG_NOTICE, "%s: jtagmkII_avr32_reset(): "
"Get_IR, expecting %2.2x but got %2.2x\n",
progname, ret1, resp[1]);
//return -1;
}
buf[0] = CMND_GET_xxx;
buf[1] = 5;
buf[2] = val;
status = jtagmkII_send(pgm, buf, 3);
if(status < 0) return -1;
status = jtagmkII_recv(pgm, &resp);
if (status != 2 || resp[0] != 0x87 || resp[1] != ret2) {
avrdude_message(MSG_NOTICE, "%s: jtagmkII_avr32_reset(): "
"Get_XXX, expecting %2.2x but got %2.2x\n",
progname, ret2, resp[1]);
//return -1;
}
return 0;
}
// At init: AVR32_RESET_READ_IR | AVR32_RESET_READ_READ_CHIPINFO
static int jtagmkII_reset32(PROGRAMMER * pgm, unsigned short flags)
{
int status, j, lineno;
unsigned char *resp, buf[3];
unsigned long val=0;
avrdude_message(MSG_NOTICE, "%s: jtagmkII_reset32(%2.2x)\n",
progname, flags);
status = -1;
// Happens at the start of a programming operation
if(flags & AVR32_RESET_READ) {
buf[0] = CMND_GET_IR;
buf[1] = 0x11;
status = jtagmkII_send(pgm, buf, 2);
if(status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_recv(pgm, &resp);
if (status != 2 || resp[0] != 0x87 || resp[1] != 01)
{lineno = __LINE__; goto eRR;};
}
if(flags & (AVR32_RESET_WRITE | AVR32_SET4RUNNING)) {
// AVR_RESET(0x1F)
status = jtagmkII_avr32_reset(pgm, 0x1F, 0x01, 0x00);
if(status < 0) {lineno = __LINE__; goto eRR;}
// AVR_RESET(0x07)
status = jtagmkII_avr32_reset(pgm, 0x07, 0x11, 0x1F);
if(status < 0) {lineno = __LINE__; goto eRR;}
}
//if(flags & AVR32_RESET_COMMON)
{
val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
if(val != 0) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, AVR32_DC, 0x01);
if(val != 0) {lineno = __LINE__; goto eRR;}
}
if(flags & (AVR32_RESET_READ | AVR32_RESET_CHIP_ERASE)) {
status = jtagmkII_write_SABaddr(pgm, AVR32_DC, 0x01,
AVR32_DC_DBE | AVR32_DC_DBR);
if(status < 0) return -1;
}
if(flags & (AVR32_RESET_WRITE | AVR32_SET4RUNNING)) {
status = jtagmkII_write_SABaddr(pgm, AVR32_DC, 0x01,
AVR32_DC_ABORT | AVR32_DC_RESET | AVR32_DC_DBE | AVR32_DC_DBR);
if(status < 0) return -1;
for(j=0; j<21; ++j) {
val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
}
if(val != 0x04000000) {lineno = __LINE__; goto eRR;}
// AVR_RESET(0x00)
status = jtagmkII_avr32_reset(pgm, 0x00, 0x01, 0x07);
if(status < 0) {lineno = __LINE__; goto eRR;}
}
// if(flags & (AVR32_RESET_READ | AVR32_RESET_WRITE))
{
for(j=0; j<2; ++j) {
val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;}
}
}
//if(flags & (AVR32_RESET_READ | AVR32_RESET_WRITE | AVR32_RESET_CHIP_ERASE))
{
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
if(status < 0) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
}
// Read chip configuration - common for all
if(flags & (AVR32_RESET_READ | AVR32_RESET_WRITE | AVR32_RESET_CHIP_ERASE)) {
for(j=0; j<2; ++j) {
val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;}
}
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
if(status < 0) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00040); // mfsr R0, 256
if(status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
if(status < 0) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, AVR32_DCEMU, 0x01, 0x00000000);
if(status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045); // mtdr R0, 276
if(status < 0) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
if(status < 0) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00041); // mfsr R0, 260
if(status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
if(status < 0) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, AVR32_DCEMU, 0x01, 0x00000000);
if(status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045); // mtdr R0, 276
if(status < 0) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, 0x00000010, 0x06); // need to recheck who does this...
if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
}
if(flags & AVR32_RESET_CHIP_ERASE) {
status = jtagmkII_avr32_reset(pgm, 0x1f, 0x01, 0x00);
if(status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_avr32_reset(pgm, 0x01, 0x11, 0x1f);
if(status < 0) {lineno = __LINE__; goto eRR;}
}
if(flags & AVR32_SET4RUNNING) {
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00014); // mfsr R0, 80
if(status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
if(status < 0) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, AVR32_DCEMU, 0x01, 0x00000000);
if(status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045); // mfdr R0, 276
if(status < 0) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xd623d703); // retd
if(status < 0) {lineno = __LINE__; goto eRR;}
}
return 0;
eRR:
avrdude_message(MSG_INFO, "%s: jtagmkII_reset32(): "
"failed at line %d (status=%x val=%lx)\n",
progname, lineno, status, val);
return -1;
}
static int jtagmkII_smc_init32(PROGRAMMER * pgm)
{
int status, lineno;
unsigned long val;
// HMATRIX 0xFFFF1000
status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x04000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x04000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x04000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x04000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x04000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x08000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x08000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x08000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x08000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x08000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x10000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x10000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x10000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x10000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x10000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x00020000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x00020000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x00020000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x00020000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x00020000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x02000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x02000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x02000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x02000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x02000000);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xfffe1c00, 0x05, 0x00010001);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xfffe1c04, 0x05, 0x05070a0b);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xfffe1c08, 0x05, 0x000b000c);
if (status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_write_SABaddr(pgm, 0xfffe1c0c, 0x05, 0x00031103);
if (status < 0) {lineno = __LINE__; goto eRR;}
// switchToClockSource
val = jtagmkII_read_SABaddr(pgm, 0xffff0c28, 0x05);
if (val != 0x00000000) {lineno = __LINE__; goto eRR;} // OSC 0
status = jtagmkII_write_SABaddr(pgm, 0xffff0c28, 0x05, 0x0000607);
if (status < 0) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, 0xffff0c00, 0x05);
if (val != 0x00000000) {lineno = __LINE__; goto eRR;} // PLL 0
status = jtagmkII_write_SABaddr(pgm, 0xffff0c00, 0x05, 0x0000004);
if (status < 0) {lineno = __LINE__; goto eRR;} // Power Manager
status = jtagmkII_write_SABaddr(pgm, 0xffff0c00, 0x05, 0x0000005);
if (status < 0) {lineno = __LINE__; goto eRR;}
usleep(1000000);
val = jtagmkII_read_SABaddr(pgm, 0xfffe1408, 0x05);
if (val != 0x0000a001) {lineno = __LINE__; goto eRR;} // PLL 0
// need a small delay to let clock stabliize
usleep(50*1000);
return 0;
eRR:
avrdude_message(MSG_INFO, "%s: jtagmkII_smc_init32(): "
"failed at line %d\n",
progname, lineno);
return -1;
}
/*
* initialize the AVR device and prepare it to accept commands
*/
static int jtagmkII_initialize32(PROGRAMMER * pgm, AVRPART * p)
{
int status, j;
unsigned char buf[6], *resp;
if (jtagmkII_setparm(pgm, PAR_DAISY_CHAIN_INFO, PDATA(pgm)->jtagchain) < 0) {
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Failed to setup JTAG chain\n",
progname);
return -1;
}
free(PDATA(pgm)->flash_pagecache);
free(PDATA(pgm)->eeprom_pagecache);
if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) {
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Out of memory\n",
progname);
return -1;
}
if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize32(): Out of memory\n",
progname);
free(PDATA(pgm)->flash_pagecache);
return -1;
}
PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
for(j=0; j<2; ++j) {
buf[0] = CMND_GET_IR;
buf[1] = 0x1;
if(jtagmkII_send(pgm, buf, 2) < 0)
return -1;
status = jtagmkII_recv(pgm, &resp);
if(status <= 0 || resp[0] != 0x87) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize32(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
return -1;
}
free(resp);
memset(buf, 0, sizeof(buf));
buf[0] = CMND_GET_xxx;
buf[1] = 0x20;
if(jtagmkII_send(pgm, buf, 6) < 0)
return -1;
status = jtagmkII_recv(pgm, &resp);
if(status <= 0 || resp[0] != 0x87) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize32(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
return -1;
}
if (status != 5 ||
resp[2] != p->signature[0] ||
resp[3] != p->signature[1] ||
resp[4] != p->signature[2]) {
avrdude_message(MSG_INFO, "%s: Expected signature for %s is %02X %02X %02X\n",
progname, p->desc,
p->signature[0], p->signature[1], p->signature[2]);
if (!ovsigck) {
avrdude_message(MSG_INFO, "%sDouble check chip, "
"or use -F to override this check.\n",
progbuf);
return -1;
}
}
free(resp);
}
return 0;
}
static int jtagmkII_chip_erase32(PROGRAMMER * pgm, AVRPART * p)
{
int status=0, loops;
unsigned char *resp, buf[3], x, ret[4], *retP;
unsigned long val=0;
unsigned int lineno;
avrdude_message(MSG_NOTICE, "%s: jtagmkII_chip_erase32()\n",
progname);
status = jtagmkII_reset32(pgm, AVR32_RESET_CHIP_ERASE);
if(status != 0) {lineno = __LINE__; goto eRR;}
// sequence of IR transitions
ret[0] = 0x01;
ret[1] = 0x05;
ret[2] = 0x01;
ret[3] = 0x00;
retP = ret;
for(loops=0; loops<1000; ++loops) {
buf[0] = CMND_GET_IR;
buf[1] = 0x0F;
status = jtagmkII_send(pgm, buf, 2);
if(status < 0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_recv(pgm, &resp);
if (status != 2 || resp[0] != 0x87) {
{lineno = __LINE__; goto eRR;}
}
x = resp[1];
free(resp);
if(x == *retP) ++retP;
if(*retP == 0x00) break;
}
if(loops == 1000) {lineno = __LINE__; goto eRR;}
status = jtagmkII_avr32_reset(pgm, 0x00, 0x01, 0x01);
if(status < 0) {lineno = __LINE__; goto eRR;}
val = jtagmkII_read_SABaddr(pgm, 0x00000010, 0x06);
if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
// AVR32 "special"
buf[0] = CMND_SET_PARAMETER;
buf[1] = 0x03;
buf[2] = 0x02;
jtagmkII_send(pgm, buf, 3);
status = jtagmkII_recv(pgm, &resp);
if(status < 0 || resp[0] != RSP_OK) {lineno = __LINE__; goto eRR;}
free(resp);
return 0;
eRR:
avrdude_message(MSG_INFO, "%s: jtagmkII_reset32(): "
"failed at line %d (status=%x val=%lx)\n",
progname, lineno, status, val);
return -1;
}
static unsigned long jtagmkII_read_SABaddr(PROGRAMMER * pgm, unsigned long addr,
unsigned int prefix)
{
unsigned char buf[6], *resp;
int status;
unsigned long val;
unsigned long otimeout = serial_recv_timeout;
serial_recv_timeout = 256;
buf[0] = CMND_READ_SAB;
buf[1] = prefix;
u32_to_b4r(&buf[2], addr);
if(jtagmkII_send(pgm, buf, 6) < 0)
return ERROR_SAB;
status = jtagmkII_recv(pgm, &resp);
if(status <= 0 || resp[0] != 0x87) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_read_SABaddr(): "
"timeout/error communicating with programmer (status %d) resp=%x\n",
progname, status, resp[0]);
serial_recv_timeout = otimeout;
if(status > 0) {
int i;
avrdude_message(MSG_INFO, "Cmd: ");
for(i=0; i<6; ++i) avrdude_message(MSG_INFO, "%2.2x ", buf[i]);
avrdude_message(MSG_INFO, "\n");
avrdude_message(MSG_INFO, "Data: ");
for(i=0; i= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_read_SABaddr(): "
"wrong number of bytes (status %d)\n",
progname, status);
serial_recv_timeout = otimeout;
return ERROR_SAB;
}
val = b4_to_u32r(&resp[1]);
free(resp);
if (verbose) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_read_SABaddr(): "
"OCD Register %lx -> %4.4lx\n",
progname, addr, val);
}
serial_recv_timeout = otimeout;
return val;
}
static int jtagmkII_write_SABaddr(PROGRAMMER * pgm, unsigned long addr,
unsigned int prefix, unsigned long val)
{
unsigned char buf[10], *resp;
int status;
buf[0] = CMND_WRITE_SAB;
buf[1] = prefix;
u32_to_b4r(&buf[2], addr);
u32_to_b4r(&buf[6], val);
if(jtagmkII_send(pgm, buf, 10) < 0)
return -1;
status = jtagmkII_recv(pgm, &resp);
if(status <= 0 || resp[0] != RSP_OK) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_write_SABaddr(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
return -1;
}
if (verbose) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_write_SABaddr(): "
"OCD Register %lx -> %4.4lx\n",
progname, addr, val);
}
return 0;
}
static int jtagmkII_open32(PROGRAMMER * pgm, char * port)
{
int status;
unsigned char buf[6], *resp;
union pinfo pinfo;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_open32()\n", progname);
/*
* The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
* attaching. If the config file or command-line parameters specify
* a higher baud rate, we switch to it later on, after establishing
* the connection with the ICE.
*/
pinfo.baud = 19200;
/*
* If the port name starts with "usb", divert the serial routines
* to the USB ones. The serial_open() function for USB overrides
* the meaning of the "baud" parameter to be the USB device ID to
* search for.
*/
if (strncmp(port, "usb", 3) == 0) {
#if defined(HAVE_LIBUSB)
serdev = &usb_serdev;
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
pinfo.usbinfo.flags = 0;
pinfo.usbinfo.pid = USB_DEVICE_JTAGICEMKII;
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
pgm->fd.usb.eep = 0; /* no seperate EP for events */
#else
avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
return -1;
#endif
}
strcpy(pgm->port, port);
if (serial_open(port, pinfo, &pgm->fd)==-1) {
return -1;
}
/*
* drain any extraneous input
*/
jtagmkII_drain(pgm, 0);
status = jtagmkII_getsync(pgm, -1);
if(status < 0) return -1;
// AVR32 "special"
buf[0] = CMND_SET_PARAMETER;
buf[1] = 0x2D;
buf[2] = 0x03;
jtagmkII_send(pgm, buf, 3);
status = jtagmkII_recv(pgm, &resp);
if(status < 0 || resp[0] != RSP_OK)
return -1;
free(resp);
buf[1] = 0x03;
buf[2] = 0x02;
jtagmkII_send(pgm, buf, 3);
status = jtagmkII_recv(pgm, &resp);
if(status < 0 || resp[0] != RSP_OK)
return -1;
free(resp);
buf[1] = 0x03;
buf[2] = 0x04;
jtagmkII_send(pgm, buf, 3);
status = jtagmkII_recv(pgm, &resp);
if(status < 0 || resp[0] != RSP_OK)
return -1;
free(resp);
return 0;
}
static void jtagmkII_close32(PROGRAMMER * pgm)
{
int status, lineno;
unsigned char *resp, buf[3], c;
unsigned long val=0;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_close32()\n", progname);
// AVR32 "special"
buf[0] = CMND_SET_PARAMETER;
buf[1] = 0x03;
buf[2] = 0x02;
jtagmkII_send(pgm, buf, 3);
status = jtagmkII_recv(pgm, &resp);
if(status < 0 || resp[0] != RSP_OK) {lineno = __LINE__; goto eRR;}
free(resp);
buf[0] = CMND_SIGN_OFF;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_close(): Sending sign-off command: ",
progname);
jtagmkII_send(pgm, buf, 1);
status = jtagmkII_recv(pgm, &resp);
if (status <= 0) {
if (verbose >= 2)
putc('\n', stderr);
avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
"timeout/error communicating with programmer (status %d)\n",
progname, status);
return;
}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
c = resp[0];
free(resp);
if (c != RSP_OK) {
avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
"bad response to sign-off command: %s\n",
progname, jtagmkII_get_rc(c));
}
ret:
serial_close(&pgm->fd);
pgm->fd.ifd = -1;
return;
eRR:
avrdude_message(MSG_INFO, "%s: jtagmkII_reset32(): "
"failed at line %d (status=%x val=%lx)\n",
progname, lineno, status, val);
goto ret;
}
static int jtagmkII_paged_load32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
unsigned int block_size;
unsigned int maxaddr = addr + n_bytes;
unsigned char cmd[7];
unsigned char *resp;
int lineno, status;
unsigned long val=0;
long otimeout = serial_recv_timeout;
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_paged_load32(.., %s, %d, %d)\n",
progname, m->desc, page_size, n_bytes);
serial_recv_timeout = 256;
if(!(p->flags & AVRPART_WRITE)) {
status = jtagmkII_reset32(pgm, AVR32_RESET_READ);
if(status != 0) {lineno = __LINE__; goto eRR;}
}
// Init SMC and set clocks
if(!(p->flags & AVRPART_INIT_SMC)) {
status = jtagmkII_smc_init32(pgm);
if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
p->flags |= AVRPART_INIT_SMC;
}
// Init SMC and set clocks
if(!(p->flags & AVRPART_INIT_SMC)) {
status = jtagmkII_smc_init32(pgm);
if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
p->flags |= AVRPART_INIT_SMC;
}
//avrdude_message(MSG_INFO, "\n pageSize=%d bytes=%d pages=%d m->offset=0x%x pgm->page_size %d\n",
// page_size, n_bytes, pages, m->offset, pgm->page_size);
cmd[0] = CMND_READ_MEMORY32;
cmd[1] = 0x40;
cmd[2] = 0x05;
for (; addr < maxaddr; addr += block_size) {
block_size = ((maxaddr-addr) < pgm->page_size) ? (maxaddr - addr) : pgm->page_size;
avrdude_message(MSG_DEBUG, "%s: jtagmkII_paged_load32(): "
"block_size at addr %d is %d\n",
progname, addr, block_size);
u32_to_b4r(cmd + 3, m->offset + addr);
status = jtagmkII_send(pgm, cmd, 7);
if(status<0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_recv(pgm, &resp);
if(status<0) {lineno = __LINE__; goto eRR;}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
if (resp[0] != 0x87) {
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_load32(): "
"bad response to write memory command: %s\n",
progname, jtagmkII_get_rc(resp[0]));
free(resp);
return -1;
}
memcpy(m->buf + addr, resp + 1, block_size);
free(resp);
}
serial_recv_timeout = otimeout;
status = jtagmkII_reset32(pgm, AVR32_SET4RUNNING);
if(status < 0) {lineno = __LINE__; goto eRR;}
return addr;
eRR:
serial_recv_timeout = otimeout;
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_load32(): "
"failed at line %d (status=%x val=%lx)\n",
progname, lineno, status, val);
return -1;
}
static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
unsigned int block_size;
unsigned char *cmd=NULL;
unsigned char *resp;
int lineno, status, pages, sPageNum, pageNum, blocks;
unsigned long val=0;
unsigned long otimeout = serial_recv_timeout;
unsigned int maxaddr = addr + n_bytes;
serial_recv_timeout = 256;
if(n_bytes == 0) return -1;
status = jtagmkII_reset32(pgm, AVR32_RESET_WRITE);
if(status != 0) {lineno = __LINE__; goto eRR;}
p->flags |= AVRPART_WRITE;
pages = (n_bytes - addr - 1)/page_size + 1;
sPageNum = addr/page_size;
//avrdude_message(MSG_INFO, "\n pageSize=%d bytes=%d pages=%d m->offset=0x%x pgm->page_size %d\n",
// page_size, n_bytes, pages, m->offset, pgm->page_size);
// Before any errors can happen
if ((cmd = malloc(pgm->page_size + 10)) == NULL) {
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write32(): Out of memory\n", progname);
return -1;
}
// Init SMC and set clocks
if(!(p->flags & AVRPART_INIT_SMC)) {
status = jtagmkII_smc_init32(pgm);
if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
p->flags |= AVRPART_INIT_SMC;
}
// First unlock the pages
for(pageNum=sPageNum; pageNum < pages; ++pageNum) {
status =jtagmkII_flash_lock32(pgm, 0, pageNum);
if(status < 0) {lineno = __LINE__; goto eRR;}
}
// Then erase them (guess could do this in the same loop above?)
for(pageNum=sPageNum; pageNum < pages; ++pageNum) {
status =jtagmkII_flash_erase32(pgm, pageNum);
if(status < 0) {lineno = __LINE__; goto eRR;}
}
cmd[0] = CMND_WRITE_MEMORY32;
u32_to_b4r(&cmd[1], 0x40000000); // who knows
cmd[5] = 0x5;
for(pageNum=sPageNum; pageNum < pages; ++pageNum) {
status = jtagmkII_flash_clear_pagebuffer32(pgm);
if(status != 0) {lineno = __LINE__; goto eRR;}
for(blocks=0; blocks<2; ++blocks) {
block_size = ((maxaddr-addr) < pgm->page_size) ? (maxaddr - addr) : pgm->page_size;
avrdude_message(MSG_DEBUG, "%s: jtagmkII_paged_write32(): "
"block_size at addr %d is %d\n",
progname, addr, block_size);
u32_to_b4r(cmd + 6, m->offset + addr);
memset(cmd + 10, 0xff, pgm->page_size);
memcpy(cmd + 10, m->buf + addr, block_size);
status = jtagmkII_send(pgm, cmd, pgm->page_size + 10);
if(status<0) {lineno = __LINE__; goto eRR;}
status = jtagmkII_recv(pgm, &resp);
if (status<0) {lineno = __LINE__; goto eRR;}
if (verbose >= 3) {
putc('\n', stderr);
jtagmkII_prmsg(pgm, resp, status);
} else if (verbose == 2)
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
if (resp[0] != RSP_OK) {
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write32(): "
"bad response to write memory command: %s\n",
progname, jtagmkII_get_rc(resp[0]));
free(resp);
free(cmd);
return -1;
}
free(resp);
addr += block_size;
}
status = jtagmkII_flash_write_page32(pgm, pageNum);
if(status < 0) {lineno = __LINE__; goto eRR;}
}
free(cmd);
serial_recv_timeout = otimeout;
status = jtagmkII_reset32(pgm, AVR32_SET4RUNNING); // AVR32_SET4RUNNING | AVR32_RELEASE_JTAG
if(status < 0) {lineno = __LINE__; goto eRR;}
return addr;
eRR:
serial_recv_timeout = otimeout;
free(cmd);
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write32(): "
"failed at line %d (status=%x val=%lx)\n",
progname, lineno, status, val);
return -1;
}
static int jtagmkII_flash_lock32(PROGRAMMER * pgm, unsigned char lock, unsigned int page)
{
int status, lineno, i;
unsigned long val, cmd=0;
for(i=0; i<256; ++i) {
val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05);
if(val == ERROR_SAB) continue;
if(val & AVR32_FLASHC_FSR_RDY) break;
}
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
if(!(val&AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;} // Flash better be ready
page <<= 8;
cmd = AVR32_FLASHC_FCMD_KEY | page | (lock ? AVR32_FLASHC_FCMD_LOCK : AVR32_FLASHC_FCMD_UNLOCK);
status = jtagmkII_write_SABaddr(pgm, AVR32_FLASHC_FCMD, 0x05, cmd);
if (status < 0) {lineno = __LINE__; goto eRR;}
return 0;
eRR:
avrdude_message(MSG_INFO, "%s: jtagmkII_flash_lock32(): "
"failed at line %d page %d cmd %8.8lx\n",
progname, lineno, page, cmd);
return -1;
}
static int jtagmkII_flash_erase32(PROGRAMMER * pgm, unsigned int page)
{
int status, lineno, i;
unsigned long val=0, cmd=0, err=0;
for(i=0; i<256; ++i) {
val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05);
if(val == ERROR_SAB) continue;
if(val & AVR32_FLASHC_FSR_RDY) break;
}
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
if(!(val&AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;} // Flash better be ready
page <<= 8;
cmd = AVR32_FLASHC_FCMD_KEY | page | AVR32_FLASHC_FCMD_ERASE_PAGE;
status = jtagmkII_write_SABaddr(pgm, AVR32_FLASHC_FCMD, 0x05, cmd);
if (status < 0) {lineno = __LINE__; goto eRR;}
//avrdude_message(MSG_INFO, "ERASE %x -> %x\n", cmd, AVR32_FLASHC_FCMD);
err = 0;
for(i=0; i<256; ++i) {
val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05);
if(val == ERROR_SAB) continue;
err |= val;
if(val & AVR32_FLASHC_FSR_RDY) break;
}
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
if(!(val & AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;}
if(err & AVR32_FLASHC_FSR_ERR) {lineno = __LINE__; goto eRR;}
return 0;
eRR:
avrdude_message(MSG_INFO, "%s: jtagmkII_flash_erase32(): "
"failed at line %d page %d cmd %8.8lx val %lx\n",
progname, lineno, page, cmd, val);
return -1;
}
static int jtagmkII_flash_write_page32(PROGRAMMER * pgm, unsigned int page)
{
int status, lineno, i;
unsigned long val=0, cmd, err;
page <<= 8;
cmd = AVR32_FLASHC_FCMD_KEY | page | AVR32_FLASHC_FCMD_WRITE_PAGE;
status = jtagmkII_write_SABaddr(pgm, AVR32_FLASHC_FCMD, 0x05, cmd);
if (status < 0) {lineno = __LINE__; goto eRR;}
err = 0;
for(i=0; i<256; ++i) {
val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05);
if(val == ERROR_SAB) continue;
err |= val;
if(val & AVR32_FLASHC_FSR_RDY) break;
}
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
if(!(val & AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;}
if(err & AVR32_FLASHC_FSR_ERR) {lineno = __LINE__; goto eRR;}
return 0;
eRR:
avrdude_message(MSG_INFO, "%s: jtagmkII_flash_write_page32(): "
"failed at line %d page %d cmd %8.8lx val %lx\n",
progname, lineno, page, cmd, val);
return -1;
}
static int jtagmkII_flash_clear_pagebuffer32(PROGRAMMER * pgm)
{
int status, lineno, i;
unsigned long val=0, cmd, err;
cmd = AVR32_FLASHC_FCMD_KEY | AVR32_FLASHC_FCMD_CLEAR_PAGE_BUFFER;
status = jtagmkII_write_SABaddr(pgm, AVR32_FLASHC_FCMD, 0x05, cmd);
if (status < 0) {lineno = __LINE__; goto eRR;}
err = 0;
for(i=0; i<256; ++i) {
val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05);
if(val == ERROR_SAB) continue;
err |= val;
if(val & AVR32_FLASHC_FSR_RDY) break;
}
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
if(!(val & AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;}
if(err & AVR32_FLASHC_FSR_ERR) {lineno = __LINE__; goto eRR;}
return 0;
eRR:
avrdude_message(MSG_INFO, "%s: jtagmkII_flash_clear_pagebuffer32(): "
"failed at line %d cmd %8.8lx val %lx\n",
progname, lineno, cmd, val);
return -1;
}
#ifdef __OBJC__
#pragma mark -
#endif
const char jtagmkII_desc[] = "Atmel JTAG ICE mkII";
void jtagmkII_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "JTAGMKII");
/*
* mandatory functions
*/
pgm->initialize = jtagmkII_initialize;
pgm->display = jtagmkII_display;
pgm->enable = jtagmkII_enable;
pgm->disable = jtagmkII_disable;
pgm->program_enable = jtagmkII_program_enable_INFO;
pgm->chip_erase = jtagmkII_chip_erase;
pgm->open = jtagmkII_open;
pgm->close = jtagmkII_close;
pgm->read_byte = jtagmkII_read_byte;
pgm->write_byte = jtagmkII_write_byte;
/*
* optional functions
*/
pgm->paged_write = jtagmkII_paged_write;
pgm->paged_load = jtagmkII_paged_load;
pgm->page_erase = jtagmkII_page_erase;
pgm->print_parms = jtagmkII_print_parms;
pgm->set_sck_period = jtagmkII_set_sck_period;
pgm->parseextparams = jtagmkII_parseextparms;
pgm->setup = jtagmkII_setup;
pgm->teardown = jtagmkII_teardown;
pgm->page_size = 256;
pgm->flag = PGM_FL_IS_JTAG;
}
const char jtagmkII_dw_desc[] = "Atmel JTAG ICE mkII in debugWire mode";
void jtagmkII_dw_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "JTAGMKII_DW");
/*
* mandatory functions
*/
pgm->initialize = jtagmkII_initialize;
pgm->display = jtagmkII_display;
pgm->enable = jtagmkII_enable;
pgm->disable = jtagmkII_disable;
pgm->program_enable = jtagmkII_program_enable_INFO;
pgm->chip_erase = jtagmkII_chip_erase_dw;
pgm->open = jtagmkII_open_dw;
pgm->close = jtagmkII_close;
pgm->read_byte = jtagmkII_read_byte;
pgm->write_byte = jtagmkII_write_byte;
/*
* optional functions
*/
pgm->paged_write = jtagmkII_paged_write;
pgm->paged_load = jtagmkII_paged_load;
pgm->print_parms = jtagmkII_print_parms;
pgm->setup = jtagmkII_setup;
pgm->teardown = jtagmkII_teardown;
pgm->page_size = 256;
pgm->flag = PGM_FL_IS_DW;
}
const char jtagmkII_pdi_desc[] = "Atmel JTAG ICE mkII in PDI mode";
void jtagmkII_pdi_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "JTAGMKII_PDI");
/*
* mandatory functions
*/
pgm->initialize = jtagmkII_initialize;
pgm->display = jtagmkII_display;
pgm->enable = jtagmkII_enable;
pgm->disable = jtagmkII_disable;
pgm->program_enable = jtagmkII_program_enable_INFO;
pgm->chip_erase = jtagmkII_chip_erase;
pgm->open = jtagmkII_open_pdi;
pgm->close = jtagmkII_close;
pgm->read_byte = jtagmkII_read_byte;
pgm->write_byte = jtagmkII_write_byte;
/*
* optional functions
*/
pgm->paged_write = jtagmkII_paged_write;
pgm->paged_load = jtagmkII_paged_load;
pgm->page_erase = jtagmkII_page_erase;
pgm->print_parms = jtagmkII_print_parms;
pgm->setup = jtagmkII_setup;
pgm->teardown = jtagmkII_teardown;
pgm->page_size = 256;
pgm->flag = PGM_FL_IS_PDI;
}
const char jtagmkII_dragon_desc[] = "Atmel AVR Dragon in JTAG mode";
void jtagmkII_dragon_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "DRAGON_JTAG");
/*
* mandatory functions
*/
pgm->initialize = jtagmkII_initialize;
pgm->display = jtagmkII_display;
pgm->enable = jtagmkII_enable;
pgm->disable = jtagmkII_disable;
pgm->program_enable = jtagmkII_program_enable_INFO;
pgm->chip_erase = jtagmkII_chip_erase;
pgm->open = jtagmkII_dragon_open;
pgm->close = jtagmkII_close;
pgm->read_byte = jtagmkII_read_byte;
pgm->write_byte = jtagmkII_write_byte;
/*
* optional functions
*/
pgm->paged_write = jtagmkII_paged_write;
pgm->paged_load = jtagmkII_paged_load;
pgm->page_erase = jtagmkII_page_erase;
pgm->print_parms = jtagmkII_print_parms;
pgm->set_sck_period = jtagmkII_set_sck_period;
pgm->parseextparams = jtagmkII_parseextparms;
pgm->setup = jtagmkII_setup;
pgm->teardown = jtagmkII_teardown;
pgm->page_size = 256;
pgm->flag = PGM_FL_IS_JTAG;
}
const char jtagmkII_dragon_dw_desc[] = "Atmel AVR Dragon in debugWire mode";
void jtagmkII_dragon_dw_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "DRAGON_DW");
/*
* mandatory functions
*/
pgm->initialize = jtagmkII_initialize;
pgm->display = jtagmkII_display;
pgm->enable = jtagmkII_enable;
pgm->disable = jtagmkII_disable;
pgm->program_enable = jtagmkII_program_enable_INFO;
pgm->chip_erase = jtagmkII_chip_erase_dw;
pgm->open = jtagmkII_dragon_open_dw;
pgm->close = jtagmkII_close;
pgm->read_byte = jtagmkII_read_byte;
pgm->write_byte = jtagmkII_write_byte;
/*
* optional functions
*/
pgm->paged_write = jtagmkII_paged_write;
pgm->paged_load = jtagmkII_paged_load;
pgm->print_parms = jtagmkII_print_parms;
pgm->setup = jtagmkII_setup;
pgm->teardown = jtagmkII_teardown;
pgm->page_size = 256;
pgm->flag = PGM_FL_IS_DW;
}
const char jtagmkII_avr32_desc[] = "Atmel JTAG ICE mkII in AVR32 mode";
void jtagmkII_avr32_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "JTAGMKII_AVR32");
/*
* mandatory functions
*/
pgm->initialize = jtagmkII_initialize32;
pgm->display = jtagmkII_display;
pgm->enable = jtagmkII_enable;
pgm->disable = jtagmkII_disable;
pgm->program_enable = jtagmkII_program_enable_INFO;
pgm->chip_erase = jtagmkII_chip_erase32;
pgm->open = jtagmkII_open32;
pgm->close = jtagmkII_close32;
pgm->read_byte = jtagmkII_read_byte;
pgm->write_byte = jtagmkII_write_byte;
/*
* optional functions
*/
pgm->paged_write = jtagmkII_paged_write32;
pgm->paged_load = jtagmkII_paged_load32;
pgm->print_parms = jtagmkII_print_parms;
//pgm->set_sck_period = jtagmkII_set_sck_period;
//pgm->parseextparams = jtagmkII_parseextparms;
pgm->setup = jtagmkII_setup;
pgm->teardown = jtagmkII_teardown;
pgm->page_size = 256;
pgm->flag = PGM_FL_IS_JTAG;
}
const char jtagmkII_dragon_pdi_desc[] = "Atmel AVR Dragon in PDI mode";
void jtagmkII_dragon_pdi_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "DRAGON_PDI");
/*
* mandatory functions
*/
pgm->initialize = jtagmkII_initialize;
pgm->display = jtagmkII_display;
pgm->enable = jtagmkII_enable;
pgm->disable = jtagmkII_disable;
pgm->program_enable = jtagmkII_program_enable_INFO;
pgm->chip_erase = jtagmkII_chip_erase;
pgm->open = jtagmkII_dragon_open_pdi;
pgm->close = jtagmkII_close;
pgm->read_byte = jtagmkII_read_byte;
pgm->write_byte = jtagmkII_write_byte;
/*
* optional functions
*/
pgm->paged_write = jtagmkII_paged_write;
pgm->paged_load = jtagmkII_paged_load;
pgm->page_erase = jtagmkII_page_erase;
pgm->print_parms = jtagmkII_print_parms;
pgm->setup = jtagmkII_setup;
pgm->teardown = jtagmkII_teardown;
pgm->page_size = 256;
pgm->flag = PGM_FL_IS_PDI;
}
avrdude-6.2/ft245r.h 000644 000153 000000 00000000204 12622456071 013571 0 ustar 00j wheel 000000 000000 #ifndef ft245r_h
#define ft245r_h
extern const char ft245r_desc[];
void ft245r_initpgm (PROGRAMMER * pgm);
#endif /* ft245r_h */
avrdude-6.2/term.c 000644 000153 000000 00000053415 12622456070 013520 0 ustar 00j wheel 000000 000000 /*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean
*
* 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 .
*/
/* $Id: term.c 1321 2014-06-13 20:07:40Z awachtler $ */
#include "ac_cfg.h"
#include
#include
#include
#include
#include
#if defined(HAVE_LIBREADLINE)
#if !defined(WIN32NATIVE)
# include
# include
#endif
#endif
#include "avrdude.h"
#include "term.h"
struct command {
char * name;
int (*func)(PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
char * desc;
};
static int cmd_dump (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
static int cmd_write (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
static int cmd_erase (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
static int cmd_sig (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
static int cmd_part (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
static int cmd_help (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
static int cmd_quit (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
static int cmd_send (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
static int cmd_parms (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
static int cmd_vtarg (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
static int cmd_varef (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
static int cmd_fosc (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
static int cmd_sck (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
static int cmd_spi (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
static int cmd_pgm (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
static int cmd_verbose (PROGRAMMER * pgm, struct avrpart * p,
int argc, char *argv[]);
struct command cmd[] = {
{ "dump", cmd_dump, "dump memory : %s " },
{ "read", cmd_dump, "alias for dump" },
{ "write", cmd_write, "write memory : %s ... " },
{ "erase", cmd_erase, "perform a chip erase" },
{ "sig", cmd_sig, "display device signature bytes" },
{ "part", cmd_part, "display the current part information" },
{ "send", cmd_send, "send a raw command : %s " },
{ "parms", cmd_parms, "display adjustable parameters (STK500 only)" },
{ "vtarg", cmd_vtarg, "set (STK500 only)" },
{ "varef", cmd_varef, "set (STK500 only)" },
{ "fosc", cmd_fosc, "set (STK500 only)" },
{ "sck", cmd_sck, "set (STK500 only)" },
{ "spi", cmd_spi, "enter direct SPI mode" },
{ "pgm", cmd_pgm, "return to programming mode" },
{ "verbose", cmd_verbose, "change verbosity" },
{ "help", cmd_help, "help" },
{ "?", cmd_help, "help" },
{ "quit", cmd_quit, "quit" }
};
#define NCMDS (sizeof(cmd)/sizeof(struct command))
static int spi_mode = 0;
static int nexttok(char * buf, char ** tok, char ** next)
{
char * q, * n;
q = buf;
while (isspace((int)*q))
q++;
/* isolate first token */
n = q+1;
while (*n && !isspace((int)*n))
n++;
if (*n) {
*n = 0;
n++;
}
/* find start of next token */
while (isspace((int)*n))
n++;
*tok = q;
*next = n;
return 0;
}
static int hexdump_line(char * buffer, unsigned char * p, int n, int pad)
{
char * hexdata = "0123456789abcdef";
char * b;
int i, j;
b = buffer;
j = 0;
for (i=0; i> 4];
b[j++] = hexdata[(p[i] & 0x0f)];
if (i < 15)
b[j++] = ' ';
}
for (i=j; i len)
n = len;
hexdump_line(dst1, p, n, 48);
chardump_line(dst2, p, n, 16);
fprintf(stdout, "%04x %s |%s|\n", addr, dst1, dst2);
len -= n;
addr += n;
p += n;
}
return 0;
}
static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
static char prevmem[128] = {0};
char * e;
unsigned char * buf;
int maxsize;
unsigned long i;
static unsigned long addr=0;
static int len=64;
AVRMEM * mem;
char * memtype = NULL;
int rc;
if (!((argc == 2) || (argc == 4))) {
avrdude_message(MSG_INFO, "Usage: dump [ ]\n");
return -1;
}
memtype = argv[1];
if (strncmp(prevmem, memtype, strlen(memtype)) != 0) {
addr = 0;
len = 64;
strncpy(prevmem, memtype, sizeof(prevmem)-1);
prevmem[sizeof(prevmem)-1] = 0;
}
mem = avr_locate_mem(p, memtype);
if (mem == NULL) {
avrdude_message(MSG_INFO, "\"%s\" memory type not defined for part \"%s\"\n",
memtype, p->desc);
return -1;
}
if (argc == 4) {
addr = strtoul(argv[2], &e, 0);
if (*e || (e == argv[2])) {
avrdude_message(MSG_INFO, "%s (dump): can't parse address \"%s\"\n",
progname, argv[2]);
return -1;
}
len = strtol(argv[3], &e, 0);
if (*e || (e == argv[3])) {
avrdude_message(MSG_INFO, "%s (dump): can't parse length \"%s\"\n",
progname, argv[3]);
return -1;
}
}
maxsize = mem->size;
if (addr >= maxsize) {
if (argc == 2) {
/* wrap around */
addr = 0;
}
else {
avrdude_message(MSG_INFO, "%s (dump): address 0x%05lx is out of range for %s memory\n",
progname, addr, mem->desc);
return -1;
}
}
/* trim len if nessary to not read past the end of memory */
if ((addr + len) > maxsize)
len = maxsize - addr;
buf = malloc(len);
if (buf == NULL) {
avrdude_message(MSG_INFO, "%s (dump): out of memory\n", progname);
return -1;
}
for (i=0; iread_byte(pgm, p, mem, addr+i, &buf[i]);
if (rc != 0) {
avrdude_message(MSG_INFO, "error reading %s address 0x%05lx of part %s\n",
mem->desc, addr+i, p->desc);
if (rc == -1)
avrdude_message(MSG_INFO, "read operation not supported on memory type \"%s\"\n",
mem->desc);
return -1;
}
}
hexdump_buf(stdout, addr, buf, len);
fprintf(stdout, "\n");
free(buf);
addr = addr + len;
return 0;
}
static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
char * e;
int len, maxsize;
char * memtype;
unsigned long addr, i;
unsigned char * buf;
unsigned char b;
int rc;
int werror;
AVRMEM * mem;
if (argc < 4) {
avrdude_message(MSG_INFO, "Usage: write "
" ... byteN>\n");
return -1;
}
memtype = argv[1];
mem = avr_locate_mem(p, memtype);
if (mem == NULL) {
avrdude_message(MSG_INFO, "\"%s\" memory type not defined for part \"%s\"\n",
memtype, p->desc);
return -1;
}
maxsize = mem->size;
addr = strtoul(argv[2], &e, 0);
if (*e || (e == argv[2])) {
avrdude_message(MSG_INFO, "%s (write): can't parse address \"%s\"\n",
progname, argv[2]);
return -1;
}
if (addr > maxsize) {
avrdude_message(MSG_INFO, "%s (write): address 0x%05lx is out of range for %s memory\n",
progname, addr, memtype);
return -1;
}
/* number of bytes to write at the specified address */
len = argc - 3;
if ((addr + len) > maxsize) {
avrdude_message(MSG_INFO, "%s (write): selected address and # bytes exceed "
"range for %s memory\n",
progname, memtype);
return -1;
}
buf = malloc(len);
if (buf == NULL) {
avrdude_message(MSG_INFO, "%s (write): out of memory\n", progname);
return -1;
}
for (i=3; ierr_led(pgm, OFF);
for (werror=0, i=0; idesc);
werror = 1;
}
rc = pgm->read_byte(pgm, p, mem, addr+i, &b);
if (b != buf[i]) {
avrdude_message(MSG_INFO, "%s (write): error writing 0x%02x at 0x%05lx cell=0x%02x\n",
progname, buf[i], addr+i, b);
werror = 1;
}
if (werror) {
pgm->err_led(pgm, ON);
}
}
free(buf);
fprintf(stdout, "\n");
return 0;
}
static int cmd_send(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
unsigned char cmd[4], res[4];
char * e;
int i;
int len;
if (pgm->cmd == NULL) {
avrdude_message(MSG_INFO, "The %s programmer does not support direct ISP commands.\n",
pgm->type);
return -1;
}
if (spi_mode && (pgm->spi == NULL)) {
avrdude_message(MSG_INFO, "The %s programmer does not support direct SPI transfers.\n",
pgm->type);
return -1;
}
if ((argc > 5) || ((argc < 5) && (!spi_mode))) {
avrdude_message(MSG_INFO, spi_mode?
"Usage: send [ [