Add initial support for the Atmel STK600, for
"classic" AVRs (AT90, ATtiny, ATmega) in both, ISP and high-voltage programming modes. * Makefile.am: Add -lm. * avrdude.conf.in: Add stk600, stk600pp, and stk600hvsp. * config_gram.y: Add support for the stk600* keywords. * lexer.l: (Ditto.) * pgm.h: Add the "chan" parameter to set_varef(). * stk500.c: (Ditto.) * serial.h: Add USB endpoint support to struct filedescriptor. * stk500v2.c: Implement the meat of the STK600 support. * stk500v2.h: Add new prototypes for stk600*() programmers. * stk500v2_private.h: Add new constants used in the STK600. * term.c: Add AREF channel support. * usb_libusb.c: Automatically determine the correct write endpoint ID, the STK600 uses 0x83 while all other tools use 0x82. Propagate the EP to use through struct filedescriptor. * usbdevs.h: Add the STK600 USB product ID. * tools/get-stk600-cards.xsl: XSL transformation for targetboards.xml to obtain the list of socket and routing card IDs, to be used in stk500v2.c (for displaying the names). * tools/get-stk600-devices.xsl: XSL transformation for targetboards.xml to obtain the table of socket/routing cards and their respective AVR device support for doc/avrdude.texi. * avrdude.1: Document all the STK600 stuff. * doc/avrdude.texi: Ditto. Added a new chapter for Programmer Specific Information. Thanks to Eirik Rasmussen from Atmel Norway for his support in getting this code running within that short amount of time! git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@768 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
255f873185
commit
ec2df64017
31
ChangeLog
31
ChangeLog
|
@ -1,3 +1,34 @@
|
|||
2008-03-14 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Add initial support for the Atmel STK600, for
|
||||
"classic" AVRs (AT90, ATtiny, ATmega) in both,
|
||||
ISP and high-voltage programming modes.
|
||||
* Makefile.am: Add -lm.
|
||||
* avrdude.conf.in: Add stk600, stk600pp, and stk600hvsp.
|
||||
* config_gram.y: Add support for the stk600* keywords.
|
||||
* lexer.l: (Ditto.)
|
||||
* pgm.h: Add the "chan" parameter to set_varef().
|
||||
* stk500.c: (Ditto.)
|
||||
* serial.h: Add USB endpoint support to struct filedescriptor.
|
||||
* stk500v2.c: Implement the meat of the STK600 support.
|
||||
* stk500v2.h: Add new prototypes for stk600*() programmers.
|
||||
* stk500v2_private.h: Add new constants used in the STK600.
|
||||
* term.c: Add AREF channel support.
|
||||
* usb_libusb.c: Automatically determine the correct write
|
||||
endpoint ID, the STK600 uses 0x83 while all other tools use
|
||||
0x82. Propagate the EP to use through struct filedescriptor.
|
||||
* usbdevs.h: Add the STK600 USB product ID.
|
||||
* tools/get-stk600-cards.xsl: XSL transformation for
|
||||
targetboards.xml to obtain the list of socket and routing
|
||||
card IDs, to be used in stk500v2.c (for displaying the
|
||||
names).
|
||||
* tools/get-stk600-devices.xsl: XSL transformation for
|
||||
targetboards.xml to obtain the table of socket/routing cards
|
||||
and their respective AVR device support for doc/avrdude.texi.
|
||||
* avrdude.1: Document all the STK600 stuff.
|
||||
* doc/avrdude.texi: Ditto. Added a new chapter for
|
||||
Programmer Specific Information.
|
||||
|
||||
2008-01-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* stk500v2.c (stk500v2_recv): Make length computation unsigned so
|
||||
|
|
|
@ -52,7 +52,7 @@ avrdude_CFLAGS = @ENABLE_WARNINGS@
|
|||
|
||||
libavrdude_a_CFLAGS = @ENABLE_WARNINGS@
|
||||
|
||||
avrdude_LDADD = $(top_builddir)/$(noinst_LIBRARIES) @LIBUSB@ @LIBHID@
|
||||
avrdude_LDADD = $(top_builddir)/$(noinst_LIBRARIES) @LIBUSB@ @LIBHID@ -lm
|
||||
|
||||
bin_PROGRAMS = avrdude
|
||||
|
||||
|
|
3
NEWS
3
NEWS
|
@ -13,6 +13,9 @@ Current:
|
|||
* Add support for JTAG daisy-chains, using the -x daisychain=
|
||||
option.
|
||||
|
||||
* Add support for the Atmel STK600 for "classic" AVRs (AT90, ATtiny,
|
||||
ATmega), using either ISP or high-voltage programming modes.
|
||||
|
||||
Version 5.5:
|
||||
|
||||
* Add support for the USBtinyISP programmer (patch #6233)
|
||||
|
|
28
avrdude.1
28
avrdude.1
|
@ -19,7 +19,7 @@
|
|||
.\"
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd DATE November 6, 2007
|
||||
.Dd DATE March 14, 2008
|
||||
.Os
|
||||
.Dt AVRDUDE 1
|
||||
.Sh NAME
|
||||
|
@ -59,6 +59,7 @@ microcontrollers.
|
|||
.Nm Avrdude
|
||||
supports Atmel's STK500 programmer,
|
||||
Atmel's AVRISP and AVRISP mkII devices,
|
||||
Atmel's STK600,
|
||||
Atmel's JTAG ICE (both mkI and mkII, the latter also in ISP mode),
|
||||
programmers complying to AppNote AVR910 and AVR109 (including the Butterfly),
|
||||
as well as a simple hard-wired
|
||||
|
@ -106,6 +107,9 @@ Using firmware version 2, high-voltage programming is also supported,
|
|||
both parallel and serial
|
||||
(programmer types stk500pp and stk500hvsp).
|
||||
.Pp
|
||||
Atmel's STK600 programmer is supported in ISP and high-voltage
|
||||
programming modes, and connects through the USB.
|
||||
.Pp
|
||||
The simple serial programmer described in Atmel's application note
|
||||
AVR910, and the bootloader described in Atmel's application note
|
||||
AVR109 (which is also used by the AVR Butterfly evaluation board), are
|
||||
|
@ -161,7 +165,7 @@ been code-protected previously, of course) and store the data in a
|
|||
file. Finally, a ``terminal'' mode is available that allows one to
|
||||
interactively communicate with the MCU, and to display or program
|
||||
individual memory cells.
|
||||
On the STK500 programmer, several operational parameters (target supply
|
||||
On the STK500 and STK600 programmer, several operational parameters (target supply
|
||||
voltage, target Aref voltage, master clock) can be examined and changed
|
||||
from within terminal mode as well.
|
||||
.Ss Options
|
||||
|
@ -661,15 +665,19 @@ device, read/write timing, etc.
|
|||
Set the target's supply voltage to
|
||||
.Ar voltage
|
||||
Volts.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.It Ar varef voltage
|
||||
.Em Only supported on the STK500 and STK600 programmer.
|
||||
.It Ar varef Op channel Ar voltage
|
||||
Set the adjustable voltage source to
|
||||
.Ar voltage
|
||||
Volts.
|
||||
This voltage is normally used to drive the target's
|
||||
.Em Aref
|
||||
input on the STK500.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
On the Atmel STK600, two reference voltages are available, which
|
||||
can be selected by the optional
|
||||
.Ar channel
|
||||
argument (either 0 or 1).
|
||||
.Em Only supported on the STK500 and STK600 programmer.
|
||||
.It Ar fosc freq Ns Op M Ns \&| Ns k
|
||||
Set the master oscillator to
|
||||
.Ar freq
|
||||
|
@ -679,12 +687,12 @@ An optional trailing letter
|
|||
multiplies by 1E6, a trailing letter
|
||||
.Ar \&k
|
||||
by 1E3.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.Em Only supported on the STK500 and STK600 programmer.
|
||||
.It Ar fosc off
|
||||
Turn the master oscillator off.
|
||||
.Em Only supported on the STK500 programmer.
|
||||
.Em Only supported on the STK500 and STK600 programmer.
|
||||
.It Ar sck period
|
||||
.Em STK500 programmer only:
|
||||
.Em STK500 and STK600 programmer only:
|
||||
Set the SCK clock period to
|
||||
.Ar period
|
||||
microseconds.
|
||||
|
@ -699,7 +707,7 @@ software signs off from the JTAG ICE.
|
|||
This parameter can also be used on the JTAG ICE mkII to specify the
|
||||
ISP clock period when operating the ICE in ISP mode.
|
||||
.It Ar parms
|
||||
.Em STK500 programmer only:
|
||||
.Em STK500 and STK600 programmer only:
|
||||
Display the current voltage and master oscillator parameters.
|
||||
.Pp
|
||||
.Em JTAG ICE only:
|
||||
|
@ -844,7 +852,7 @@ Page-mode programming the EEPROM through JTAG (i.e. through an
|
|||
.Fl U
|
||||
option) requires a prior chip erase.
|
||||
This is an inherent feature of the way JTAG EEPROM programming works.
|
||||
This also applies to the STK500 in parallel programming mode.
|
||||
This also applies to the STK500 and STK600 in parallel programming mode.
|
||||
.Pp
|
||||
The USBasp and USBtinyISP drivers do not offer any option to distinguish multiple
|
||||
devices connected simultaneously, so effectively only a single device
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
# id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
|
||||
# desc = <description> ; # quoted string
|
||||
# type = par | stk500 | stk500v2 | stk500pp | stk500hvsp | stk500generic |
|
||||
# stk600 | stk600pp | stk600hvsp |
|
||||
# avr910 | butterfly | usbasp |
|
||||
# jtagmki | jtagmkii | jtagmkii_isp | jtagmkii_dw |
|
||||
# dragon_dw | dragon_jtag | dragon_isp | dragon_pp |
|
||||
|
@ -367,6 +368,24 @@ programmer
|
|||
type = stk500hvsp;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "stk600";
|
||||
desc = "Atmel STK600";
|
||||
type = stk600;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "stk600pp";
|
||||
desc = "Atmel STK600 in parallel programming mode";
|
||||
type = stk600pp;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "stk600hvsp";
|
||||
desc = "Atmel STK600 in high-voltage serial programming mode";
|
||||
type = stk600hvsp;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "avr910";
|
||||
desc = "Atmel Low Cost Serial Programmer";
|
||||
|
|
|
@ -135,6 +135,9 @@ static int parse_cmdbits(OPCODE * op);
|
|||
%token K_STK500PP
|
||||
%token K_STK500V2
|
||||
%token K_STK500GENERIC
|
||||
%token K_STK600
|
||||
%token K_STK600HVSP
|
||||
%token K_STK600PP
|
||||
%token K_AVR910
|
||||
%token K_USBASP
|
||||
%token K_USBTINY
|
||||
|
@ -411,6 +414,24 @@ prog_parm :
|
|||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_STK600 {
|
||||
{
|
||||
stk600_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_STK600HVSP {
|
||||
{
|
||||
stk600hvsp_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_STK600PP {
|
||||
{
|
||||
stk600pp_initpgm(current_prog);
|
||||
}
|
||||
} |
|
||||
|
||||
K_TYPE TKN_EQUAL K_AVR910 {
|
||||
{
|
||||
avr910_initpgm(current_prog);
|
||||
|
|
113
doc/avrdude.texi
113
doc/avrdude.texi
|
@ -30,7 +30,7 @@ For avrdude version @value{VERSION}, @value{UPDATED}.
|
|||
|
||||
Copyright @copyright{} 2003, 2005 Brian Dean
|
||||
|
||||
Copyright @copyright{} 2006, 2007 J@"org Wunsch
|
||||
Copyright @copyright{} 2006 - 2008 J@"org Wunsch
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
|
@ -67,7 +67,7 @@ Use @uref{http://savannah.nongnu.org/bugs/?group=avrdude} to report bugs.
|
|||
|
||||
Copyright @copyright{} 2003,2005 Brian S. Dean
|
||||
|
||||
Copyright @copyright{} 2006 J@"org Wunsch
|
||||
Copyright @copyright{} 2006 - 2008 J@"org Wunsch
|
||||
@sp 2
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
|
@ -113,6 +113,7 @@ Copyright @copyright{} 2006 J@"org Wunsch
|
|||
* Command Line Options::
|
||||
* Terminal Mode Operation::
|
||||
* Configuration File::
|
||||
* Programmer Specific Information::
|
||||
* Platform Dependent Information::
|
||||
* Troubleshooting::
|
||||
@end menu
|
||||
|
@ -143,6 +144,7 @@ programming fuse/lock bits, etc.
|
|||
|
||||
AVRDUDE supports the following basic programmer types: Atmel's STK500,
|
||||
Atmel's AVRISP and AVRISP mkII devices,
|
||||
Atmel's STK600,
|
||||
Atmel's JTAG ICE (both mkI and mkII, the latter also in ISP mode), appnote
|
||||
avr910, appnote avr109 (including the AVR Butterfly),
|
||||
serial bit-bang adapters,
|
||||
|
@ -164,7 +166,10 @@ emulated on top of USB is likely to not work at all, or to work
|
|||
abysmally slow.
|
||||
|
||||
The STK500, JTAG ICE, avr910, and avr109/butterfly use the serial port to communicate with the PC.
|
||||
The STK500, JTAG ICE, and avr910 contain on-board logic to control the programming of the target
|
||||
The STK600, JTAG ICE mkII, AVRISP mkII, USBasp, and USBtinyISP
|
||||
programmers communicate through the USB, using @code{libusb} as a
|
||||
platform abstraction layer.
|
||||
The STK500, STK600, JTAG ICE, and avr910 contain on-board logic to control the programming of the target
|
||||
device.
|
||||
The avr109 bootloader implements a protocol similar to avr910, but is
|
||||
actually implemented in the boot area of the target's flash ROM, as
|
||||
|
@ -186,7 +191,6 @@ For the JTAG ICE mkII, JTAG, debugWire and ISP mode are supported.
|
|||
See below for the limitations of debugWire.
|
||||
|
||||
The AVR Dragon is supported in all modes (ISP, JTAG, HVSP, PP, debugWire).
|
||||
(High-voltage programming is not yet supported.)
|
||||
When used in JTAG and debugWire mode, the AVR Dragon behaves similar to a
|
||||
JTAG ICE mkII, so all device-specific comments for that device
|
||||
will apply as well.
|
||||
|
@ -463,6 +467,12 @@ Atmel STK500 in parallel programming mode (version 2.xfirmware only)
|
|||
Atmel STK500, running a version 1.x firmware
|
||||
@item @code{stk500v2} @tab
|
||||
Atmel STK500, running a version 2.x firmware
|
||||
@item @code{stk600} @tab
|
||||
Atmel STK600 in ISP mode
|
||||
@item @code{stk600hvsp} @tab
|
||||
Atmel STK600 in high-voltage serial programming mode
|
||||
@item @code{stk600pp} @tab
|
||||
Atmel STK600 in parallel programming mode
|
||||
@item @code{usbasp} @tab
|
||||
USBasp,@*
|
||||
@url{http://www.fischl.de/usbasp/}
|
||||
|
@ -1043,17 +1053,20 @@ Leave terminal mode and thus AVRDUDE.
|
|||
|
||||
@noindent
|
||||
In addition, the following commands are supported on the STK500
|
||||
programmer:
|
||||
and STK600 programmer:
|
||||
|
||||
@table @code
|
||||
|
||||
@item vtarg @var{voltage}
|
||||
Set the target's supply voltage to @var{voltage} Volts.
|
||||
|
||||
@item varef @var{voltage}
|
||||
@item varef @var{[channel]} @var{voltage}
|
||||
Set the adjustable voltage source to @var{voltage} Volts.
|
||||
This voltage is normally used to drive the target's
|
||||
@emph{Aref} input on the STK500.
|
||||
@emph{Aref} input on the STK500 and STK600.
|
||||
The STK600 offers two reference voltages, which can be
|
||||
selected by the optional parameter @var{channel} (either
|
||||
0 or 1).
|
||||
|
||||
@item fosc @var{freq}[@var{M}|@var{k}]
|
||||
Set the master oscillator to @var{freq} Hz.
|
||||
|
@ -1064,7 +1077,7 @@ multiplies by 1E6, a trailing letter @var{k} by 1E3.
|
|||
Turn the master oscillator off.
|
||||
|
||||
@item sck @var{period}
|
||||
@emph{STK500 only:}
|
||||
@emph{STK500 and STK600 only:}
|
||||
Set the SCK clock period to @var{period} microseconds.
|
||||
|
||||
@emph{JTAG ICE only:}
|
||||
|
@ -1076,7 +1089,7 @@ This parameter can also be used on the JTAG ICE mkII to specify the
|
|||
ISP clock period when operating the ICE in ISP mode.
|
||||
|
||||
@item parms
|
||||
@emph{STK500 only:}
|
||||
@emph{STK500 and STK600 only:}
|
||||
Display the current voltage and master oscillator parameters.
|
||||
|
||||
@emph{JTAG ICE only:}
|
||||
|
@ -1191,7 +1204,7 @@ avrdude>
|
|||
@c
|
||||
@c Node
|
||||
@c
|
||||
@node Configuration File, Platform Dependent Information, Terminal Mode Operation, Top
|
||||
@node Configuration File, Programmer Specific Information, Terminal Mode Operation, Top
|
||||
@chapter Configuration File
|
||||
|
||||
@noindent
|
||||
|
@ -1432,11 +1445,87 @@ functionality does not make sense for these boot loaders.
|
|||
|
||||
@end itemize
|
||||
|
||||
@c
|
||||
@c Node
|
||||
@c
|
||||
@node Programmer Specific Information, Platform Dependent Information, Configuration File, Top
|
||||
@chapter Programmer Specific Information
|
||||
|
||||
@menu
|
||||
* Atmel STK600::
|
||||
@end menu
|
||||
|
||||
@c
|
||||
@c Node
|
||||
@c
|
||||
@node Platform Dependent Information, Troubleshooting, Configuration File, Top
|
||||
@node Atmel STK600, , Programmer Specific Information, Programmer Specific Information
|
||||
@section Atmel STK600
|
||||
|
||||
@c
|
||||
@c Update the table below by running the tools/get-stk600-devices.xsl
|
||||
@c XSLT transformation on targetboard.xml as shipped by the latest
|
||||
@c release of AVR Studio.
|
||||
@c
|
||||
The following devices are supported by the respective STK600 routing
|
||||
and socket card:
|
||||
|
||||
@multitable @columnfractions .25 .25 .5
|
||||
@headitem Routing card @tab Socket card @tab Devices
|
||||
@item @code{STK600-RC008T-2} @tab @code{STK600-DIP} @tab ATtiny11 ATtiny12 ATtiny13 ATtiny25 ATtiny45 ATtiny85
|
||||
@item @code{STK600-RC008T-7} @tab @code{STK600-DIP} @tab ATtiny15
|
||||
@item @code{STK600-RC020T-1} @tab @code{STK600-DIP} @tab ATtiny2313
|
||||
@item @code{} @tab @code{STK600-TinyX3U} @tab ATtiny43U
|
||||
@item @code{STK600-RC014T-12} @tab @code{STK600-DIP} @tab ATtiny24 ATtiny44 ATtiny84
|
||||
@item @code{STK600-RC020T-8} @tab @code{STK600-DIP} @tab ATtiny26 ATtiny261 ATtiny461 ATtiny861
|
||||
@item @code{STK600-RC020T-23} @tab @code{STK600-SOIC} @tab ATtiny167
|
||||
@item @code{STK600-RC028T-3} @tab @code{STK600-DIP} @tab ATtiny28
|
||||
@item @code{STK600-RC028M-6} @tab @code{STK600-DIP} @tab ATtiny48 ATtiny88 ATmega8 ATmega48 ATmega88 ATmega168 ATmega48P ATmega88P ATmega168P ATmega328P
|
||||
@item @code{STK600-RC040M-4} @tab @code{STK600-DIP} @tab ATmega8515 ATmega162
|
||||
@item @code{STK600-RC040M-5} @tab @code{STK600-DIP} @tab ATmega8535 ATmega16 ATmega32 ATmega164P ATmega324P ATmega644 ATmega644P ATmega1284P
|
||||
@item @code{STK600-RC064M-9} @tab @code{STK600-TQFP64} @tab ATmega64 ATmega128 ATmega1281 ATmega2561 AT90CAN32 AT90CAN64 AT90CAN128
|
||||
@item @code{STK600-RC064M-10} @tab @code{STK600-TQFP64} @tab ATmega165 ATmega165P ATmega169 ATmega169P ATmega325 ATmega325P ATmega329 ATmega329P ATmega645 ATmega649
|
||||
@item @code{STK600-RC100M-11} @tab @code{STK600-TQFP100} @tab ATmega640 ATmega1280 ATmega2560
|
||||
@item @code{} @tab @code{STK600-ATMEGA2560} @tab ATmega2560
|
||||
@item @code{STK600-RC100M-18} @tab @code{STK600-TQFP100} @tab ATmega3250 ATmega3250P ATmega3290 ATmega3290P ATmega6450 ATmega6490
|
||||
@item @code{STK600-RC32U-20} @tab @code{STK600-TQFP32} @tab AT90USB82 AT90USB162
|
||||
@item @code{STK600-RC044U-25} @tab @code{STK600-TQFP44} @tab ATmega32U4
|
||||
@item @code{STK600-RC064U-17} @tab @code{STK600-TQFP64} @tab AT90USB646 AT90USB1286 AT90USB647 AT90USB1287
|
||||
@item @code{STK600-RCPWM-22} @tab @code{STK600-TQFP32} @tab ATmega32C1 ATmega32M1
|
||||
@item @code{STK600-RCPWM-19} @tab @code{STK600-SOIC} @tab AT90PWM2 AT90PWM3 AT90PWM2B AT90PWM3B AT90PWM216 AT90PWM316
|
||||
@item @code{STK600-RC044M-24} @tab @code{STK600-TSSOP44} @tab ATmega32HVB
|
||||
@item @code{STK600-RC100X-13} @tab @code{STK600-TQFP100} @tab ATxmega128A1 ATxmega128A1_revD ATxmega64A1
|
||||
@item @code{} @tab @code{STK600-uC3-144} @tab AT32UC3A0512 AT32UC3A0256 AT32UC3A0128
|
||||
@item @code{STK600-RCuC3B0-21} @tab @code{STK600-TQFP64-2} @tab AT32UC3B0256 AT32UC3B0128 AT32UC3B064
|
||||
@end multitable
|
||||
|
||||
Ensure the correct socket and routing card are mounted @emph{before}
|
||||
powering on the STK600. While the STK600 firmware ensures the socket
|
||||
and routing card mounted match each other (using a table stored
|
||||
internally in nonvolatile memory), it cannot handle the case where a
|
||||
wrong routing card is used, e. g. the routing card
|
||||
@code{STK600-RC040M-5} (which is meant for 40-pin DIP AVRs that have
|
||||
an ADC, with the power supply pins in the center of the package) was
|
||||
used but an ATmega8515 inserted (which uses the ``industry standard''
|
||||
pinout with Vcc and GND at opposite corners).
|
||||
|
||||
Note that for devices that use the routing card @code{STK600-RC008T-2},
|
||||
in order to use ISP mode, the jumper for @code{AREF0} must be removed
|
||||
as it would otherwise block one of the ISP signals. High-voltage
|
||||
serial programming can be used even with that jumper installed.
|
||||
|
||||
The ISP system of the STK600 contains a detection against shortcuts
|
||||
and other wiring errors. AVRDUDE initiates a connection check before
|
||||
trying to enter ISP programming mode, and display the result if the
|
||||
target is not found ready to be ISP programmed.
|
||||
|
||||
High-voltage programming requires the target voltage to be set to at
|
||||
least 4.5 V in order to work. This can be done using
|
||||
@emph{Terminal Mode}, see @ref{Terminal Mode Operation}.
|
||||
|
||||
@c
|
||||
@c Node
|
||||
@c
|
||||
@node Platform Dependent Information, Troubleshooting, Programmer Specific Information, Top
|
||||
@appendix Platform Dependent Information
|
||||
|
||||
@menu
|
||||
|
@ -1951,7 +2040,7 @@ programming works, and is documented that way in the Atmel AVR
|
|||
datasheets.
|
||||
In order to successfully program the EEPROM that way, a prior chip
|
||||
erase (with the EESAVE fuse unprogrammed) is required.
|
||||
This also applies to the STK500 in high-voltage programming mode.
|
||||
This also applies to the STK500 and STK600 in high-voltage programming mode.
|
||||
|
||||
@item
|
||||
Problem: How do I turn off the @var{DWEN} fuse?
|
||||
|
|
3
lexer.l
3
lexer.l
|
@ -183,6 +183,9 @@ stk500pp { yylval=NULL; return K_STK500PP; }
|
|||
stk500v2 { yylval=NULL; return K_STK500V2; }
|
||||
stk500generic { yylval=NULL; return K_STK500GENERIC; }
|
||||
stk500_devcode { yylval=NULL; return K_STK500_DEVCODE; }
|
||||
stk600 { yylval=NULL; return K_STK600; }
|
||||
stk600hvsp { yylval=NULL; return K_STK600HVSP; }
|
||||
stk600pp { yylval=NULL; return K_STK600PP; }
|
||||
type { yylval=NULL; return K_TYPE; }
|
||||
vcc { yylval=NULL; return K_VCC; }
|
||||
vfyled { yylval=NULL; return K_VFYLED; }
|
||||
|
|
2
pgm.h
2
pgm.h
|
@ -92,7 +92,7 @@ typedef struct programmer_t {
|
|||
int (*read_sig_bytes) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
|
||||
void (*print_parms) (struct programmer_t * pgm);
|
||||
int (*set_vtarget) (struct programmer_t * pgm, double v);
|
||||
int (*set_varef) (struct programmer_t * pgm, double v);
|
||||
int (*set_varef) (struct programmer_t * pgm, unsigned int chan, double v);
|
||||
int (*set_fosc) (struct programmer_t * pgm, double v);
|
||||
int (*set_sck_period) (struct programmer_t * pgm, double v);
|
||||
int (*setpin) (struct programmer_t * pgm, int pin, int value);
|
||||
|
|
5
serial.h
5
serial.h
|
@ -35,6 +35,11 @@ union filedescriptor
|
|||
{
|
||||
int ifd;
|
||||
void *pfd;
|
||||
struct
|
||||
{
|
||||
void *handle;
|
||||
int ep;
|
||||
} usb;
|
||||
};
|
||||
|
||||
struct serial_device
|
||||
|
|
3
stk500.c
3
stk500.c
|
@ -913,7 +913,8 @@ static int stk500_set_vtarget(PROGRAMMER * pgm, double v)
|
|||
}
|
||||
|
||||
|
||||
static int stk500_set_varef(PROGRAMMER * pgm, double v)
|
||||
static int stk500_set_varef(PROGRAMMER * pgm, unsigned int chan /* unused */,
|
||||
double v)
|
||||
{
|
||||
unsigned uaref, utarg;
|
||||
|
||||
|
|
592
stk500v2.c
592
stk500v2.c
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -109,6 +110,16 @@ struct pdata
|
|||
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
||||
|
||||
|
||||
/*
|
||||
* Data structure for displaying STK600 routing and socket cards.
|
||||
*/
|
||||
struct carddata
|
||||
{
|
||||
int id;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
/* XXX That should become part of the private pgm-> data. */
|
||||
static enum
|
||||
{
|
||||
PGMTYPE_UNKNOWN,
|
||||
|
@ -116,6 +127,7 @@ static enum
|
|||
PGMTYPE_AVRISP,
|
||||
PGMTYPE_AVRISP_MKII,
|
||||
PGMTYPE_JTAGICE_MKII,
|
||||
PGMTYPE_STK600,
|
||||
}
|
||||
pgmtype;
|
||||
|
||||
|
@ -126,8 +138,12 @@ static const char *pgmname[] =
|
|||
"AVRISP",
|
||||
"AVRISP mkII",
|
||||
"JTAG ICE mkII",
|
||||
"STK600",
|
||||
};
|
||||
|
||||
/* XXX That should become part of the private pgm-> data. */
|
||||
static AVRPART *lastpart;
|
||||
|
||||
struct jtagispentry
|
||||
{
|
||||
unsigned char cmd;
|
||||
|
@ -191,6 +207,9 @@ static struct jtagispentry jtagispcmds[] = {
|
|||
|
||||
static int stk500v2_getparm(PROGRAMMER * pgm, unsigned char parm, unsigned char * value);
|
||||
static int stk500v2_setparm(PROGRAMMER * pgm, unsigned char parm, unsigned char value);
|
||||
static int stk500v2_getparm2(PROGRAMMER * pgm, unsigned char parm, unsigned int * value);
|
||||
static int stk500v2_setparm2(PROGRAMMER * pgm, unsigned char parm, unsigned int value);
|
||||
static int stk500v2_setparm_real(PROGRAMMER * pgm, unsigned char parm, unsigned char value);
|
||||
static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p);
|
||||
static int stk500v2_is_page_empty(unsigned int address, int page_size,
|
||||
const unsigned char *buf);
|
||||
|
@ -199,6 +218,8 @@ static unsigned int stk500v2_mode_for_pagesize(unsigned int pagesize);
|
|||
|
||||
static int stk500v2_set_sck_period_mk2(PROGRAMMER * pgm, double v);
|
||||
|
||||
static int stk600_set_sck_period(PROGRAMMER * pgm, double v);
|
||||
|
||||
static void stk500v2_setup(PROGRAMMER * pgm)
|
||||
{
|
||||
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
|
||||
|
@ -301,7 +322,7 @@ static int stk500v2_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
|||
unsigned char buf[275 + 6]; // max MESSAGE_BODY of 275 bytes, 6 bytes overhead
|
||||
int i;
|
||||
|
||||
if (pgmtype == PGMTYPE_AVRISP_MKII)
|
||||
if (pgmtype == PGMTYPE_AVRISP_MKII || pgmtype == PGMTYPE_STK600)
|
||||
return stk500v2_send_mk2(pgm, data, len);
|
||||
else if (pgmtype == PGMTYPE_JTAGICE_MKII)
|
||||
return stk500v2_jtagmkII_send(pgm, data, len);
|
||||
|
@ -399,7 +420,7 @@ static int stk500v2_recv(PROGRAMMER * pgm, unsigned char msg[], size_t maxsize)
|
|||
struct timeval tv;
|
||||
double tstart, tnow;
|
||||
|
||||
if (pgmtype == PGMTYPE_AVRISP_MKII)
|
||||
if (pgmtype == PGMTYPE_AVRISP_MKII || pgmtype == PGMTYPE_STK600)
|
||||
return stk500v2_recv_mk2(pgm, msg, maxsize);
|
||||
else if (pgmtype == PGMTYPE_JTAGICE_MKII)
|
||||
return stk500v2_jtagmkII_recv(pgm, msg, maxsize);
|
||||
|
@ -535,6 +556,9 @@ retry:
|
|||
} else if (siglen >= strlen("AVRISP_MK2") &&
|
||||
memcmp(resp + 3, "AVRISP_MK2", strlen("AVRISP_MK2")) == 0) {
|
||||
pgmtype = PGMTYPE_AVRISP_MKII;
|
||||
} else if (siglen >= strlen("STK600") &&
|
||||
memcmp(resp + 3, "STK600", strlen("STK600")) == 0) {
|
||||
pgmtype = PGMTYPE_STK600;
|
||||
} else {
|
||||
resp[siglen + 3] = 0;
|
||||
if (verbose)
|
||||
|
@ -740,12 +764,38 @@ static int stk500hvsp_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
|||
return stk500hv_chip_erase(pgm, p, HVSPMODE);
|
||||
}
|
||||
|
||||
static struct
|
||||
{
|
||||
unsigned int state;
|
||||
const char *description;
|
||||
} connection_status[] =
|
||||
{
|
||||
{ STATUS_CONN_FAIL_MOSI, "MOSI fail" },
|
||||
{ STATUS_CONN_FAIL_RST, "RST fail" },
|
||||
{ STATUS_CONN_FAIL_SCK, "SCK fail" },
|
||||
{ STATUS_TGT_NOT_DETECTED, "Target not detected" },
|
||||
{ STATUS_TGT_REVERSE_INSERTED, "Target reverse inserted" },
|
||||
{ STATUS_CONN_FAIL_MOSI | STATUS_CONN_FAIL_RST,
|
||||
"MOSI and RST fail" },
|
||||
{ STATUS_CONN_FAIL_MOSI | STATUS_CONN_FAIL_RST | STATUS_CONN_FAIL_SCK,
|
||||
"MOSI, RST, and SCK fail" },
|
||||
{ STATUS_CONN_FAIL_RST | STATUS_CONN_FAIL_SCK,
|
||||
"RST and SCK fail" },
|
||||
{ STATUS_CONN_FAIL_MOSI | STATUS_CONN_FAIL_SCK,
|
||||
"MOSI and SCK fail" },
|
||||
};
|
||||
|
||||
/*
|
||||
* issue the 'program enable' command to the AVR device
|
||||
*/
|
||||
static int stk500v2_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
unsigned char buf[16];
|
||||
size_t i;
|
||||
const char *msg;
|
||||
int rv;
|
||||
|
||||
lastpart = p;
|
||||
|
||||
if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
|
||||
fprintf(stderr, "%s: stk500v2_program_enable(): program enable instruction not defined for part \"%s\"\n",
|
||||
|
@ -753,6 +803,35 @@ static int stk500v2_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (pgmtype == PGMTYPE_STK500 || pgmtype == PGMTYPE_STK600)
|
||||
/* Activate AVR-style (low active) RESET */
|
||||
stk500v2_setparm_real(pgm, PARAM_RESET_POLARITY, 0x01);
|
||||
|
||||
if (pgmtype == PGMTYPE_STK600) {
|
||||
buf[0] = CMD_CHECK_TARGET_CONNECTION;
|
||||
if (stk500v2_command(pgm, buf, 1, sizeof(buf)) < 0) {
|
||||
fprintf(stderr, "%s: stk500v2_program_enable(): cannot get connection status\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
if (buf[2] != STATUS_ISP_READY) {
|
||||
msg = "Unknown";
|
||||
|
||||
for (i = 0;
|
||||
i < sizeof connection_status / sizeof connection_status[0];
|
||||
i++)
|
||||
if (connection_status[i].state == (unsigned)buf[2]) {
|
||||
msg = connection_status[i].description;
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: stk500v2_program_enable():"
|
||||
" bad STK600 connection status: %s (0x%02x)\n",
|
||||
progname, msg, buf[2]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
buf[0] = CMD_ENTER_PROGMODE_ISP;
|
||||
buf[1] = p->timeout;
|
||||
buf[2] = p->stabdelay;
|
||||
|
@ -762,8 +841,34 @@ static int stk500v2_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
|||
buf[6] = p->pollvalue;
|
||||
buf[7] = p->pollindex;
|
||||
avr_set_bits(p->op[AVR_OP_PGM_ENABLE], buf+8);
|
||||
buf[10] = buf[11] = 0;
|
||||
|
||||
return stk500v2_command(pgm, buf, 12, sizeof(buf));
|
||||
rv = stk500v2_command(pgm, buf, 12, sizeof(buf));
|
||||
|
||||
if (rv < 0) {
|
||||
buf[0] = CMD_CHECK_TARGET_CONNECTION;
|
||||
if (stk500v2_command(pgm, buf, 1, sizeof(buf)) < 0) {
|
||||
fprintf(stderr, "%s: stk500v2_program_enable(): cannot get connection status\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg = "Unknown";
|
||||
|
||||
for (i = 0;
|
||||
i < sizeof connection_status / sizeof connection_status[0];
|
||||
i++)
|
||||
if (connection_status[i].state == (unsigned)buf[2]) {
|
||||
msg = connection_status[i].description;
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: stk500v2_program_enable():"
|
||||
" bad STK600 connection status: %s (0x%02x)\n",
|
||||
progname, msg, buf[2]);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -773,6 +878,8 @@ static int stk500pp_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
|||
{
|
||||
unsigned char buf[16];
|
||||
|
||||
lastpart = p;
|
||||
|
||||
buf[0] = CMD_ENTER_PROGMODE_PP;
|
||||
buf[1] = p->hventerstabdelay;
|
||||
buf[2] = p->progmodedelay;
|
||||
|
@ -792,7 +899,11 @@ static int stk500hvsp_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
|||
{
|
||||
unsigned char buf[16];
|
||||
|
||||
buf[0] = CMD_ENTER_PROGMODE_HVSP;
|
||||
lastpart = p;
|
||||
|
||||
buf[0] = pgmtype == PGMTYPE_STK600?
|
||||
CMD_ENTER_PROGMODE_HVSP_STK600:
|
||||
CMD_ENTER_PROGMODE_HVSP;
|
||||
buf[1] = p->hventerstabdelay;
|
||||
buf[2] = p->hvspcmdexedelay;
|
||||
buf[3] = p->synchcycles;
|
||||
|
@ -934,7 +1045,10 @@ static void stk500hv_disable(PROGRAMMER * pgm, enum hvmode mode)
|
|||
free(PDATA(pgm)->eeprom_pagecache);
|
||||
PDATA(pgm)->eeprom_pagecache = NULL;
|
||||
|
||||
buf[0] = mode == PPMODE? CMD_LEAVE_PROGMODE_PP: CMD_LEAVE_PROGMODE_HVSP;
|
||||
buf[0] = mode == PPMODE? CMD_LEAVE_PROGMODE_PP:
|
||||
(pgmtype == PGMTYPE_STK600?
|
||||
CMD_LEAVE_PROGMODE_HVSP_STK600:
|
||||
CMD_LEAVE_PROGMODE_HVSP);
|
||||
buf[1] = 15; // p->hvleavestabdelay;
|
||||
buf[2] = 15; // p->resetdelay;
|
||||
|
||||
|
@ -1033,6 +1147,56 @@ static int stk500v2_open(PROGRAMMER * pgm, char * port)
|
|||
}
|
||||
|
||||
|
||||
static int stk600_open(PROGRAMMER * pgm, char * port)
|
||||
{
|
||||
long baud = 115200;
|
||||
|
||||
DEBUG("STK500V2: stk600_open()\n");
|
||||
|
||||
if (pgm->baudrate)
|
||||
baud = pgm->baudrate;
|
||||
|
||||
pgmtype = PGMTYPE_UNKNOWN;
|
||||
|
||||
/*
|
||||
* 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_frame;
|
||||
baud = USB_DEVICE_STK600;
|
||||
pgmtype = PGMTYPE_STK600;
|
||||
pgm->set_sck_period = stk600_set_sck_period;
|
||||
#else
|
||||
fprintf(stderr, "avrdude was compiled without usb support.\n");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
strcpy(pgm->port, port);
|
||||
serial_open(port, baud, &pgm->fd);
|
||||
|
||||
/*
|
||||
* drain any extraneous input
|
||||
*/
|
||||
stk500v2_drain(pgm, 0);
|
||||
|
||||
stk500v2_getsync(pgm);
|
||||
|
||||
stk500v2_drain(pgm, 0);
|
||||
|
||||
if (pgm->bitclock != 0.0) {
|
||||
if (pgm->set_sck_period(pgm, pgm->bitclock) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void stk500v2_close(PROGRAMMER * pgm)
|
||||
{
|
||||
DEBUG("STK500V2: stk500v2_close()\n");
|
||||
|
@ -1837,7 +2001,8 @@ static int stk500v2_set_vtarget(PROGRAMMER * pgm, double v)
|
|||
}
|
||||
|
||||
|
||||
static int stk500v2_set_varef(PROGRAMMER * pgm, double v)
|
||||
static int stk500v2_set_varef(PROGRAMMER * pgm, unsigned int chan /* unused */,
|
||||
double v)
|
||||
{
|
||||
unsigned char uaref, utarg;
|
||||
|
||||
|
@ -2006,6 +2171,122 @@ static int stk500v2_set_sck_period(PROGRAMMER * pgm, double v)
|
|||
}
|
||||
|
||||
|
||||
static int stk600_set_vtarget(PROGRAMMER * pgm, double v)
|
||||
{
|
||||
unsigned char utarg;
|
||||
unsigned int uaref;
|
||||
int rv;
|
||||
|
||||
utarg = (unsigned)((v + 0.049) * 10);
|
||||
|
||||
if (stk500v2_getparm2(pgm, PARAM2_AREF0, &uaref) != 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500v2_set_vtarget(): cannot obtain V[aref][0]\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (uaref > (unsigned)utarg * 10) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500v2_set_vtarget(): reducing V[aref][0] from %.2f to %.1f\n",
|
||||
progname, uaref / 100.0, v);
|
||||
uaref = 10 * (unsigned)utarg;
|
||||
if (stk500v2_setparm2(pgm, PARAM2_AREF0, uaref)
|
||||
!= 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stk500v2_getparm2(pgm, PARAM2_AREF1, &uaref) != 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500v2_set_vtarget(): cannot obtain V[aref][1]\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (uaref > (unsigned)utarg * 10) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500v2_set_vtarget(): reducing V[aref][1] from %.2f to %.1f\n",
|
||||
progname, uaref / 100.0, v);
|
||||
uaref = 10 * (unsigned)utarg;
|
||||
if (stk500v2_setparm2(pgm, PARAM2_AREF1, uaref)
|
||||
!= 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Vtarget on the STK600 can only be adjusted while not being in
|
||||
* programming mode.
|
||||
*/
|
||||
pgm->disable(pgm);
|
||||
rv = stk500v2_setparm(pgm, PARAM_VTARGET, utarg);
|
||||
pgm->program_enable(pgm, lastpart);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
static int stk600_set_varef(PROGRAMMER * pgm, unsigned int chan, double v)
|
||||
{
|
||||
unsigned char utarg;
|
||||
unsigned int uaref;
|
||||
|
||||
uaref = (unsigned)((v + 0.0049) * 100);
|
||||
|
||||
if (stk500v2_getparm(pgm, PARAM_VTARGET, &utarg) != 0) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500v2_set_varef(): cannot obtain V[target]\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (uaref > (unsigned)utarg * 10) {
|
||||
fprintf(stderr,
|
||||
"%s: stk500v2_set_varef(): V[aref] must not be greater than "
|
||||
"V[target] = %.1f\n",
|
||||
progname, utarg / 10.0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (chan)
|
||||
{
|
||||
case 0:
|
||||
return stk500v2_setparm2(pgm, PARAM2_AREF0, uaref);
|
||||
|
||||
case 1:
|
||||
return stk500v2_setparm2(pgm, PARAM2_AREF1, uaref);
|
||||
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"%s: stk500v2_set_varef(): invalid channel %d\n",
|
||||
progname, chan);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int stk600_set_fosc(PROGRAMMER * pgm, double v)
|
||||
{
|
||||
unsigned int oct, dac;
|
||||
|
||||
oct = 1.443 * log(v / 1039.0);
|
||||
dac = 2048 - (2078.0 * pow(2, (double)(10 + oct))) / v;
|
||||
|
||||
return stk500v2_setparm2(pgm, PARAM2_CLOCK_CONF, (oct << 12) | (dac << 2));
|
||||
}
|
||||
|
||||
static int stk600_set_sck_period(PROGRAMMER * pgm, double v)
|
||||
{
|
||||
unsigned int sck;
|
||||
|
||||
sck = ceil((16e6 / (2 * 1.0 / v)) - 1);
|
||||
|
||||
if (sck >= 4096)
|
||||
sck = 4095;
|
||||
|
||||
return stk500v2_setparm2(pgm, PARAM2_SCK_DURATION, sck);
|
||||
}
|
||||
|
||||
|
||||
static int stk500v2_getparm(PROGRAMMER * pgm, unsigned char parm, unsigned char * value)
|
||||
{
|
||||
unsigned char buf[32];
|
||||
|
@ -2059,9 +2340,108 @@ static int stk500v2_setparm(PROGRAMMER * pgm, unsigned char parm, unsigned char
|
|||
return stk500v2_setparm_real(pgm, parm, value);
|
||||
}
|
||||
|
||||
static int stk500v2_getparm2(PROGRAMMER * pgm, unsigned char parm, unsigned int * value)
|
||||
{
|
||||
unsigned char buf[32];
|
||||
|
||||
buf[0] = CMD_GET_PARAMETER;
|
||||
buf[1] = parm;
|
||||
|
||||
if (stk500v2_command(pgm, buf, 2, sizeof(buf)) < 0) {
|
||||
fprintf(stderr,"%s: stk500v2_getparm2(): failed to get parameter 0x%02x\n",
|
||||
progname, parm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*value = ((unsigned)buf[2] << 8) | buf[3];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stk500v2_setparm2(PROGRAMMER * pgm, unsigned char parm, unsigned int value)
|
||||
{
|
||||
unsigned char buf[32];
|
||||
|
||||
buf[0] = CMD_SET_PARAMETER;
|
||||
buf[1] = parm;
|
||||
buf[2] = value >> 8;
|
||||
buf[3] = value;
|
||||
|
||||
if (stk500v2_command(pgm, buf, 4, sizeof(buf)) < 0) {
|
||||
fprintf(stderr, "\n%s: stk500v2_setparm2(): failed to set parameter 0x%02x\n",
|
||||
progname, parm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* These two tables can be semi-automatically updated from
|
||||
* targetboards.xml using tools/get-stk600-cards.xsl.
|
||||
*/
|
||||
static struct carddata routing_cards[] =
|
||||
{
|
||||
{ 0x01, "STK600-RC020T-1" },
|
||||
{ 0x03, "STK600-RC028T-3" },
|
||||
{ 0x05, "STK600-RC040M-5" },
|
||||
{ 0x08, "STK600-RC020T-8" },
|
||||
{ 0x0A, "STK600-RC040M-4" },
|
||||
{ 0x0C, "STK600-RC008T-2" },
|
||||
{ 0x0D, "STK600-RC028M-6" },
|
||||
{ 0x10, "STK600-RC064M-10" },
|
||||
{ 0x11, "STK600-RC100M-11" },
|
||||
{ 0x13, "STK600-RC100X-13" },
|
||||
{ 0x18, "STK600-RC100M-18" },
|
||||
{ 0x19, "STK600-RCPWM-19" },
|
||||
{ 0x1B, "STK600-RC32U-20" },
|
||||
{ 0x1C, "STK600-RC014T-12" },
|
||||
{ 0x1E, "STK600-RC064U-17" },
|
||||
{ 0x1F, "STK600-RCuC3B0-21" },
|
||||
{ 0x20, "STK600-RCPWM-22" },
|
||||
{ 0x21, "STK600-RC020T-23" },
|
||||
{ 0x22, "STK600-RC044M-24" },
|
||||
{ 0x23, "STK600-RC044U-25" },
|
||||
{ 0x55, "STK600-RC064M-9" },
|
||||
{ 0xA0, "STK600-RC008T-7" },
|
||||
};
|
||||
|
||||
static struct carddata socket_cards[] =
|
||||
{
|
||||
{ 0x02, "STK600-TQFP32" },
|
||||
{ 0x03, "STK600-TQFP100" },
|
||||
{ 0x04, "STK600-SOIC" },
|
||||
{ 0x09, "STK600-TinyX3U" },
|
||||
{ 0x0C, "STK600-TSSOP44" },
|
||||
{ 0x0D, "STK600-TQFP44" },
|
||||
{ 0x0E, "STK600-TQFP64-2" },
|
||||
{ 0x0F, "STK600-ATMEGA2560" },
|
||||
{ 0x55, "STK600-TQFP64" },
|
||||
{ 0x69, "STK600-uC3-144" },
|
||||
{ 0xF1, "STK600-DIP" },
|
||||
};
|
||||
|
||||
static const char *stk600_get_cardname(const struct carddata *table,
|
||||
size_t nele, int id)
|
||||
{
|
||||
const struct carddata *cdp;
|
||||
|
||||
if (id == 0xFF)
|
||||
/* 0xFF means this card is not present at all. */
|
||||
return "Not present";
|
||||
|
||||
for (cdp = table; nele > 0; cdp++, nele--)
|
||||
if (cdp->id == id)
|
||||
return cdp->name;
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
|
||||
static void stk500v2_display(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
unsigned char maj, min, hdw, topcard;
|
||||
unsigned char maj, min, hdw, topcard, maj_s1, min_s1, maj_s2, min_s2;
|
||||
unsigned int rev;
|
||||
const char *topcard_name, *pgmname;
|
||||
|
||||
switch (pgmtype) {
|
||||
|
@ -2069,6 +2449,7 @@ static void stk500v2_display(PROGRAMMER * pgm, const char * p)
|
|||
case PGMTYPE_STK500: pgmname = "STK500"; break;
|
||||
case PGMTYPE_AVRISP: pgmname = "AVRISP"; break;
|
||||
case PGMTYPE_AVRISP_MKII: pgmname = "AVRISP mkII"; break;
|
||||
case PGMTYPE_STK600: pgmname = "STK600"; break;
|
||||
default: pgmname = "None";
|
||||
}
|
||||
if (pgmtype != PGMTYPE_JTAGICE_MKII) {
|
||||
|
@ -2077,7 +2458,15 @@ static void stk500v2_display(PROGRAMMER * pgm, const char * p)
|
|||
stk500v2_getparm(pgm, PARAM_SW_MAJOR, &maj);
|
||||
stk500v2_getparm(pgm, PARAM_SW_MINOR, &min);
|
||||
fprintf(stderr, "%sHardware Version: %d\n", p, hdw);
|
||||
fprintf(stderr, "%sFirmware Version: %d.%02d\n", p, maj, min);
|
||||
fprintf(stderr, "%sFirmware Version Master : %d.%02d\n", p, maj, min);
|
||||
if (pgmtype == PGMTYPE_STK600) {
|
||||
stk500v2_getparm(pgm, PARAM_SW_MAJOR_SLAVE1, &maj_s1);
|
||||
stk500v2_getparm(pgm, PARAM_SW_MINOR_SLAVE1, &min_s1);
|
||||
stk500v2_getparm(pgm, PARAM_SW_MAJOR_SLAVE2, &maj_s2);
|
||||
stk500v2_getparm(pgm, PARAM_SW_MINOR_SLAVE2, &min_s2);
|
||||
fprintf(stderr, "%sFirmware Version Slave 1: %d.%02d\n", p, maj_s1, min_s1);
|
||||
fprintf(stderr, "%sFirmware Version Slave 2: %d.%02d\n", p, maj_s2, min_s2);
|
||||
}
|
||||
}
|
||||
|
||||
if (pgmtype == PGMTYPE_STK500) {
|
||||
|
@ -2092,17 +2481,50 @@ static void stk500v2_display(PROGRAMMER * pgm, const char * p)
|
|||
default: topcard_name = "Unknown"; break;
|
||||
}
|
||||
fprintf(stderr, "%sTopcard : %s\n", p, topcard_name);
|
||||
} else if (pgmtype == PGMTYPE_STK600) {
|
||||
stk500v2_getparm(pgm, PARAM_ROUTINGCARD_ID, &topcard);
|
||||
fprintf(stderr, "%sRouting card : %s\n", p,
|
||||
stk600_get_cardname(routing_cards,
|
||||
sizeof routing_cards / sizeof routing_cards[0],
|
||||
topcard));
|
||||
stk500v2_getparm(pgm, PARAM_SOCKETCARD_ID, &topcard);
|
||||
fprintf(stderr, "%sSocket card : %s\n", p,
|
||||
stk600_get_cardname(socket_cards,
|
||||
sizeof socket_cards / sizeof socket_cards[0],
|
||||
topcard));
|
||||
stk500v2_getparm2(pgm, PARAM2_RC_ID_TABLE_REV, &rev);
|
||||
fprintf(stderr, "%sRC_ID table rev : %d\n", p, rev);
|
||||
stk500v2_getparm2(pgm, PARAM2_EC_ID_TABLE_REV, &rev);
|
||||
fprintf(stderr, "%sEC_ID table rev : %d\n", p, rev);
|
||||
}
|
||||
stk500v2_print_parms1(pgm, p);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static double
|
||||
f_to_kHz_MHz(double f, const char **unit)
|
||||
{
|
||||
if (f > 1e6) {
|
||||
f /= 1e6;
|
||||
*unit = "MHz";
|
||||
} else if (f > 1e3) {
|
||||
f /= 1000;
|
||||
*unit = "kHz";
|
||||
} else
|
||||
*unit = "Hz";
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
unsigned char vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration;
|
||||
unsigned int sck_stk600, clock_conf, dac, oct, varef;
|
||||
unsigned char vtarget_jtag[4];
|
||||
int prescale;
|
||||
double f;
|
||||
const char *unit;
|
||||
|
||||
if (pgmtype == PGMTYPE_JTAGICE_MKII) {
|
||||
jtagmkII_getparm(pgm, PAR_OCD_VTARGET, vtarget_jtag);
|
||||
|
@ -2112,20 +2534,22 @@ static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p)
|
|||
stk500v2_getparm(pgm, PARAM_VTARGET, &vtarget);
|
||||
fprintf(stderr, "%sVtarget : %.1f V\n", p, vtarget / 10.0);
|
||||
}
|
||||
stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration);
|
||||
|
||||
if (pgmtype == PGMTYPE_STK500) {
|
||||
switch (pgmtype) {
|
||||
case PGMTYPE_STK500:
|
||||
stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration);
|
||||
stk500v2_getparm(pgm, PARAM_VADJUST, &vadjust);
|
||||
stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale);
|
||||
stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch);
|
||||
fprintf(stderr, "%sSCK period : %.1f us\n", p,
|
||||
sck_duration * 8.0e6 / STK500V2_XTAL + 0.05);
|
||||
fprintf(stderr, "%sVaref : %.1f V\n", p, vadjust / 10.0);
|
||||
fprintf(stderr, "%sOscillator : ", p);
|
||||
if (osc_pscale == 0)
|
||||
fprintf(stderr, "Off\n");
|
||||
else {
|
||||
int prescale = 1;
|
||||
double f = STK500V2_XTAL / 2;
|
||||
const char *unit;
|
||||
prescale = 1;
|
||||
f = STK500V2_XTAL / 2;
|
||||
|
||||
switch (osc_pscale) {
|
||||
case 2: prescale = 8; break;
|
||||
|
@ -2137,23 +2561,40 @@ static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p)
|
|||
}
|
||||
f /= prescale;
|
||||
f /= (osc_cmatch + 1);
|
||||
if (f > 1e6) {
|
||||
f /= 1e6;
|
||||
unit = "MHz";
|
||||
} else if (f > 1e3) {
|
||||
f /= 1000;
|
||||
unit = "kHz";
|
||||
} else
|
||||
unit = "Hz";
|
||||
f = f_to_kHz_MHz(f, &unit);
|
||||
fprintf(stderr, "%.3f %s\n", f, unit);
|
||||
}
|
||||
}
|
||||
if (pgmtype == PGMTYPE_AVRISP_MKII || pgmtype == PGMTYPE_JTAGICE_MKII)
|
||||
break;
|
||||
|
||||
case PGMTYPE_AVRISP_MKII:
|
||||
case PGMTYPE_JTAGICE_MKII:
|
||||
stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration);
|
||||
fprintf(stderr, "%sSCK period : %.2f us\n", p,
|
||||
(float) 1000000 / avrispmkIIfreqs[sck_duration]);
|
||||
else
|
||||
break;
|
||||
|
||||
case PGMTYPE_STK600:
|
||||
stk500v2_getparm2(pgm, PARAM2_AREF0, &varef);
|
||||
fprintf(stderr, "%sVaref 0 : %.2f V\n", p, varef / 100.0);
|
||||
stk500v2_getparm2(pgm, PARAM2_AREF1, &varef);
|
||||
fprintf(stderr, "%sVaref 1 : %.2f V\n", p, varef / 100.0);
|
||||
stk500v2_getparm2(pgm, PARAM2_SCK_DURATION, &sck_stk600);
|
||||
fprintf(stderr, "%sSCK period : %.2f us\n", p,
|
||||
(float) (sck_stk600 + 1) / 8.0);
|
||||
stk500v2_getparm2(pgm, PARAM2_CLOCK_CONF, &clock_conf);
|
||||
oct = (clock_conf & 0xf000) >> 12u;
|
||||
dac = (clock_conf & 0x0ffc) >> 2u;
|
||||
f = pow(2, (double)oct) * 2078.0 / (2 - (double)dac / 1024.0);
|
||||
f = f_to_kHz_MHz(f, &unit);
|
||||
fprintf(stderr, "%sOscillator : %.3f %s\n",
|
||||
p, f, unit);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%sSCK period : %.1f us\n", p,
|
||||
sck_duration * 8.0e6 / STK500V2_XTAL + 0.05);
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -2181,7 +2622,6 @@ static int stk500v2_perform_osccal(PROGRAMMER * pgm)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wrapper functions for the JTAG ICE mkII in ISP mode. This mode
|
||||
* uses the normal JTAG ICE mkII packet stream to communicate with the
|
||||
|
@ -2612,3 +3052,105 @@ void stk500v2_dragon_hvsp_initpgm(PROGRAMMER * pgm)
|
|||
pgm->teardown = stk500v2_teardown;
|
||||
pgm->page_size = 256;
|
||||
}
|
||||
|
||||
void stk600_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
strcpy(pgm->type, "STK600");
|
||||
|
||||
/*
|
||||
* mandatory functions
|
||||
*/
|
||||
pgm->initialize = stk500v2_initialize;
|
||||
pgm->display = stk500v2_display;
|
||||
pgm->enable = stk500v2_enable;
|
||||
pgm->disable = stk500v2_disable;
|
||||
pgm->program_enable = stk500v2_program_enable;
|
||||
pgm->chip_erase = stk500v2_chip_erase;
|
||||
pgm->cmd = stk500v2_cmd;
|
||||
pgm->open = stk600_open;
|
||||
pgm->close = stk500v2_close;
|
||||
pgm->read_byte = avr_read_byte_default;
|
||||
pgm->write_byte = avr_write_byte_default;
|
||||
|
||||
/*
|
||||
* optional functions
|
||||
*/
|
||||
pgm->paged_write = stk500v2_paged_write;
|
||||
pgm->paged_load = stk500v2_paged_load;
|
||||
pgm->print_parms = stk500v2_print_parms;
|
||||
pgm->set_vtarget = stk600_set_vtarget;
|
||||
pgm->set_varef = stk600_set_varef;
|
||||
pgm->set_fosc = stk600_set_fosc;
|
||||
pgm->set_sck_period = stk600_set_sck_period;
|
||||
pgm->perform_osccal = stk500v2_perform_osccal;
|
||||
pgm->setup = stk500v2_setup;
|
||||
pgm->teardown = stk500v2_teardown;
|
||||
pgm->page_size = 256;
|
||||
}
|
||||
|
||||
void stk600pp_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
strcpy(pgm->type, "STK600PP");
|
||||
|
||||
/*
|
||||
* mandatory functions
|
||||
*/
|
||||
pgm->initialize = stk500pp_initialize;
|
||||
pgm->display = stk500v2_display;
|
||||
pgm->enable = stk500v2_enable;
|
||||
pgm->disable = stk500pp_disable;
|
||||
pgm->program_enable = stk500pp_program_enable;
|
||||
pgm->chip_erase = stk500pp_chip_erase;
|
||||
pgm->open = stk600_open;
|
||||
pgm->close = stk500v2_close;
|
||||
pgm->read_byte = stk500pp_read_byte;
|
||||
pgm->write_byte = stk500pp_write_byte;
|
||||
|
||||
/*
|
||||
* optional functions
|
||||
*/
|
||||
pgm->paged_write = stk500pp_paged_write;
|
||||
pgm->paged_load = stk500pp_paged_load;
|
||||
pgm->print_parms = stk500v2_print_parms;
|
||||
pgm->set_vtarget = stk600_set_vtarget;
|
||||
pgm->set_varef = stk600_set_varef;
|
||||
pgm->set_fosc = stk600_set_fosc;
|
||||
pgm->set_sck_period = stk600_set_sck_period;
|
||||
pgm->setup = stk500v2_setup;
|
||||
pgm->teardown = stk500v2_teardown;
|
||||
pgm->page_size = 256;
|
||||
}
|
||||
|
||||
void stk600hvsp_initpgm(PROGRAMMER * pgm)
|
||||
{
|
||||
strcpy(pgm->type, "STK600HVSP");
|
||||
|
||||
/*
|
||||
* mandatory functions
|
||||
*/
|
||||
pgm->initialize = stk500hvsp_initialize;
|
||||
pgm->display = stk500v2_display;
|
||||
pgm->enable = stk500v2_enable;
|
||||
pgm->disable = stk500hvsp_disable;
|
||||
pgm->program_enable = stk500hvsp_program_enable;
|
||||
pgm->chip_erase = stk500hvsp_chip_erase;
|
||||
pgm->open = stk600_open;
|
||||
pgm->close = stk500v2_close;
|
||||
pgm->read_byte = stk500hvsp_read_byte;
|
||||
pgm->write_byte = stk500hvsp_write_byte;
|
||||
|
||||
/*
|
||||
* optional functions
|
||||
*/
|
||||
pgm->paged_write = stk500hvsp_paged_write;
|
||||
pgm->paged_load = stk500hvsp_paged_load;
|
||||
pgm->print_parms = stk500v2_print_parms;
|
||||
pgm->set_vtarget = stk600_set_vtarget;
|
||||
pgm->set_varef = stk600_set_varef;
|
||||
pgm->set_fosc = stk600_set_fosc;
|
||||
pgm->set_sck_period = stk600_set_sck_period;
|
||||
pgm->setup = stk500v2_setup;
|
||||
pgm->teardown = stk500v2_teardown;
|
||||
pgm->page_size = 256;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,9 @@ void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm);
|
|||
void stk500v2_dragon_hvsp_initpgm(PROGRAMMER * pgm);
|
||||
void stk500v2_dragon_isp_initpgm(PROGRAMMER * pgm);
|
||||
void stk500v2_dragon_pp_initpgm(PROGRAMMER * pgm);
|
||||
void stk600_initpgm (PROGRAMMER * pgm);
|
||||
void stk600hvsp_initpgm (PROGRAMMER * pgm);
|
||||
void stk600pp_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
#define CMD_OSCCAL 0x05
|
||||
#define CMD_LOAD_ADDRESS 0x06
|
||||
#define CMD_FIRMWARE_UPGRADE 0x07
|
||||
#define CMD_CHECK_TARGET_CONNECTION 0x0D
|
||||
#define CMD_LOAD_RC_ID_TABLE 0x0E
|
||||
#define CMD_LOAD_EC_ID_TABLE 0x0F
|
||||
|
||||
|
||||
// *****************[ STK ISP command constants ]******************************
|
||||
|
@ -75,6 +78,27 @@
|
|||
#define CMD_READ_LOCK_HVSP 0x3A
|
||||
#define CMD_READ_SIGNATURE_HVSP 0x3B
|
||||
#define CMD_READ_OSCCAL_HVSP 0x3C
|
||||
// These two are redefined since 0x30/0x31 collide
|
||||
// with the STK600 bootloader.
|
||||
#define CMD_ENTER_PROGMODE_HVSP_STK600 0x3D
|
||||
#define CMD_LEAVE_PROGMODE_HVSP_STK600 0x3E
|
||||
|
||||
// *** XPROG command constants ***
|
||||
|
||||
#define CMD_XPROG 0x50
|
||||
#define CMD_XPROG_SETMODE 0x51
|
||||
|
||||
|
||||
// *** AVR32 JTAG Programming command ***
|
||||
|
||||
#define CMD_JTAG_AVR32 0x80
|
||||
#define CMD_ENTER_PROGMODE_JTAG_AVR32 0x81
|
||||
#define CMD_LEAVE_PROGMODE_JTAG_AVR32 0x82
|
||||
|
||||
|
||||
// *** AVR JTAG Programming command ***
|
||||
|
||||
#define CMD_JTAG_AVR 0x90
|
||||
|
||||
// *****************[ STK test command constants ]***************************
|
||||
|
||||
|
@ -110,24 +134,136 @@
|
|||
#define STATUS_CMD_FAILED 0xC0
|
||||
#define STATUS_CKSUM_ERROR 0xC1
|
||||
#define STATUS_CMD_UNKNOWN 0xC9
|
||||
#define STATUS_CMD_ILLEGAL_PARAMETER 0xCA
|
||||
|
||||
// Status
|
||||
#define STATUS_CONN_FAIL_MOSI 0x01
|
||||
#define STATUS_CONN_FAIL_RST 0x02
|
||||
#define STATUS_CONN_FAIL_SCK 0x04
|
||||
#define STATUS_TGT_NOT_DETECTED 0x00
|
||||
#define STATUS_ISP_READY 0x10
|
||||
#define STATUS_TGT_REVERSE_INSERTED 0x20
|
||||
|
||||
// hw_status
|
||||
// Bits in status variable
|
||||
// Bit 0-3: Slave MCU
|
||||
// Bit 4-7: Master MCU
|
||||
|
||||
#define STATUS_AREF_ERROR 0
|
||||
// Set to '1' if AREF is short circuited
|
||||
|
||||
#define STATUS_VTG_ERROR 4
|
||||
// Set to '1' if VTG is short circuited
|
||||
|
||||
#define STATUS_RC_CARD_ERROR 5
|
||||
// Set to '1' if board id changes when board is powered
|
||||
|
||||
#define STATUS_PROGMODE 6
|
||||
// Set to '1' if board is in programming mode
|
||||
|
||||
#define STATUS_POWER_SURGE 7
|
||||
// Set to '1' if board draws excessive current
|
||||
|
||||
// *****************[ STK parameter constants ]***************************
|
||||
#define PARAM_BUILD_NUMBER_LOW 0x80
|
||||
#define PARAM_BUILD_NUMBER_HIGH 0x81
|
||||
#define PARAM_BUILD_NUMBER_LOW 0x80 /* ??? */
|
||||
#define PARAM_BUILD_NUMBER_HIGH 0x81 /* ??? */
|
||||
#define PARAM_HW_VER 0x90
|
||||
#define PARAM_SW_MAJOR 0x91
|
||||
#define PARAM_SW_MINOR 0x92
|
||||
#define PARAM_VTARGET 0x94
|
||||
#define PARAM_VADJUST 0x95
|
||||
#define PARAM_OSC_PSCALE 0x96
|
||||
#define PARAM_OSC_CMATCH 0x97
|
||||
#define PARAM_SCK_DURATION 0x98
|
||||
#define PARAM_TOPCARD_DETECT 0x9A
|
||||
#define PARAM_STATUS 0x9C
|
||||
#define PARAM_DATA 0x9D
|
||||
#define PARAM_RESET_POLARITY 0x9E
|
||||
#define PARAM_VADJUST 0x95 /* STK500 only */
|
||||
#define PARAM_OSC_PSCALE 0x96 /* STK500 only */
|
||||
#define PARAM_OSC_CMATCH 0x97 /* STK500 only */
|
||||
#define PARAM_SCK_DURATION 0x98 /* STK500 only */
|
||||
#define PARAM_TOPCARD_DETECT 0x9A /* STK500 only */
|
||||
#define PARAM_STATUS 0x9C /* STK500 only */
|
||||
#define PARAM_DATA 0x9D /* STK500 only */
|
||||
#define PARAM_RESET_POLARITY 0x9E /* STK500 only, and STK600 FW
|
||||
* version <= 2.0.3 */
|
||||
#define PARAM_CONTROLLER_INIT 0x9F
|
||||
|
||||
/* STK600 parameters */
|
||||
#define PARAM_STATUS_TGT_CONN 0xA1
|
||||
#define PARAM_DISCHARGEDELAY 0xA4
|
||||
#define PARAM_SOCKETCARD_ID 0xA5
|
||||
#define PARAM_ROUTINGCARD_ID 0xA6
|
||||
#define PARAM_EXPCARD_ID 0xA7
|
||||
#define PARAM_SW_MAJOR_SLAVE1 0xA8
|
||||
#define PARAM_SW_MINOR_SLAVE1 0xA9
|
||||
#define PARAM_SW_MAJOR_SLAVE2 0xAA
|
||||
#define PARAM_SW_MINOR_SLAVE2 0xAB
|
||||
#define PARAM_BOARD_ID_STATUS 0xAD
|
||||
#define PARAM_RESET 0xB4
|
||||
|
||||
#define PARAM_JTAG_ALLOW_FULL_PAGE_STREAM 0x50
|
||||
#define PARAM_JTAG_EEPROM_PAGE_SIZE 0x52
|
||||
#define PARAM_JTAG_DAISY_BITS_BEFORE 0x53
|
||||
#define PARAM_JTAG_DAISY_BITS_AFTER 0x54
|
||||
#define PARAM_JTAG_DAISY_UNITS_BEFORE 0x55
|
||||
#define PARAM_JTAG_DAISY_UNITS_AFTER 0x56
|
||||
|
||||
// *** Parameter constants for 2 byte values ***
|
||||
#define PARAM2_SCK_DURATION 0xC0
|
||||
#define PARAM2_CLOCK_CONF 0xC1
|
||||
#define PARAM2_AREF0 0xC2
|
||||
#define PARAM2_AREF1 0xC3
|
||||
|
||||
#define PARAM2_JTAG_FLASH_SIZE_H 0xC5
|
||||
#define PARAM2_JTAG_FLASH_SIZE_L 0xC6
|
||||
#define PARAM2_JTAG_FLASH_PAGE_SIZE 0xC7
|
||||
#define PARAM2_RC_ID_TABLE_REV 0xC8
|
||||
#define PARAM2_EC_ID_TABLE_REV 0xC9
|
||||
|
||||
/* STK600 XPROG section */
|
||||
// XPROG commands
|
||||
#define XPRG_CMD_ENTER_PROGMODE 0x01
|
||||
#define XPRG_CMD_LEAVE_PROGMODE 0x02
|
||||
#define XPRG_CMD_ERASE 0x03
|
||||
#define XPRG_CMD_WRITE_MEM 0x04
|
||||
#define XPRG_CMD_READ_MEM 0x05
|
||||
#define XPRG_CMD_CRC 0x06
|
||||
#define XPRG_CMD_SET_PARAM 0x07
|
||||
|
||||
// Memory types
|
||||
#define XPRG_MEM_TYPE_APPL 1
|
||||
#define XPRG_MEM_TYPE_BOOT 2
|
||||
#define XPRG_MEM_TYPE_EEPROM 3
|
||||
#define XPRG_MEM_TYPE_FUSE 4
|
||||
#define XPRG_MEM_TYPE_LOCKBITS 5
|
||||
#define XPRG_MEM_TYPE_USERSIG 6
|
||||
#define XPRG_MEM_TYPE_FACTORY_CALIBRATION 7
|
||||
|
||||
// Erase types
|
||||
#define XPRG_ERASE_CHIP 1
|
||||
#define XPRG_ERASE_APP 2
|
||||
#define XPRG_ERASE_BOOT 3
|
||||
#define XPRG_ERASE_EEPROM 4
|
||||
#define XPRG_ERASE_APP_PAGE 5
|
||||
#define XPRG_ERASE_BOOT_PAGE 6
|
||||
#define XPRG_ERASE_EEPROM_PAGE 7
|
||||
#define XPRG_ERASE_USERSIG 8
|
||||
|
||||
// Write mode flags
|
||||
#define XPRG_MEM_WRITE_ERASE 0
|
||||
#define XPRG_MEM_WRITE_WRITE 1
|
||||
|
||||
// CRC types
|
||||
#define XPRG_CRC_APP 1
|
||||
#define XPRG_CRC_BOOT 2
|
||||
#define XPRG_CRC_FLASH 3
|
||||
|
||||
// Error codes
|
||||
#define XPRG_ERR_OK 0
|
||||
#define XPRG_ERR_FAILED 1
|
||||
#define XPRG_ERR_COLLISION 2
|
||||
#define XPRG_ERR_TIMEOUT 3
|
||||
|
||||
// XPROG parameters of different sizes
|
||||
// 4-byte address
|
||||
#define XPRG_PARAM_NVMBASE 0x01
|
||||
// 2-byte page size
|
||||
#define XPRG_PARAM_EEPPAGESIZE 0x02
|
||||
|
||||
// *****************[ STK answer constants ]***************************
|
||||
|
||||
#define ANSWER_CKSUM_ERROR 0xB0
|
||||
|
|
23
term.c
23
term.c
|
@ -662,25 +662,42 @@ static int cmd_varef(PROGRAMMER * pgm, struct avrpart * p,
|
|||
int argc, char * argv[])
|
||||
{
|
||||
int rc;
|
||||
unsigned int chan;
|
||||
double v;
|
||||
char *endp;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: varef <value>\n");
|
||||
if (argc != 2 && argc != 3) {
|
||||
fprintf(stderr, "Usage: varef [channel] <value>\n");
|
||||
return -1;
|
||||
}
|
||||
if (argc == 2) {
|
||||
chan = 0;
|
||||
v = strtod(argv[1], &endp);
|
||||
if (endp == argv[1]) {
|
||||
fprintf(stderr, "%s (varef): can't parse voltage \"%s\"\n",
|
||||
progname, argv[1]);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
chan = strtoul(argv[1], &endp, 10);
|
||||
if (endp == argv[1]) {
|
||||
fprintf(stderr, "%s (varef): can't parse channel \"%s\"\n",
|
||||
progname, argv[1]);
|
||||
return -1;
|
||||
}
|
||||
v = strtod(argv[2], &endp);
|
||||
if (endp == argv[2]) {
|
||||
fprintf(stderr, "%s (varef): can't parse voltage \"%s\"\n",
|
||||
progname, argv[2]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (pgm->set_varef == NULL) {
|
||||
fprintf(stderr, "%s (varef): the %s programmer cannot set V[aref]\n",
|
||||
progname, pgm->type);
|
||||
return -2;
|
||||
}
|
||||
if ((rc = pgm->set_varef(pgm, v)) != 0) {
|
||||
if ((rc = pgm->set_varef(pgm, chan, v)) != 0) {
|
||||
fprintf(stderr, "%s (varef): failed to set V[aref] (rc = %d)\n",
|
||||
progname, rc);
|
||||
return -3;
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding='ISO-8859-1' ?>
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<!--
|
||||
* Copyright (c) 2008 Joerg Wunsch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
*
|
||||
* $Id$
|
||||
-->
|
||||
<!--
|
||||
* Extract STK600 routing and socket card information out of
|
||||
* targetboards.xml.
|
||||
*
|
||||
* Run this like:
|
||||
*
|
||||
* xsltproc -param what "'RC'" \
|
||||
* tools/get-stk600-cards.xsl targetboard.xml | sort -u
|
||||
*
|
||||
* xsltproc -param what "'SC'" \
|
||||
* tools/get-stk600-cards.xsl targetboard.xml | sort -u
|
||||
*
|
||||
* and copy&paste the results into the respective tables.
|
||||
-->
|
||||
<xsl:output method="text"/>
|
||||
<xsl:template match="/">
|
||||
<xsl:if test="$what = 'RC'">
|
||||
<xsl:for-each select="/STK600/ROUTING/CARD">
|
||||
<xsl:if test="RC_NAME != ''">
|
||||
<xsl:text> { </xsl:text>
|
||||
<xsl:value-of select="RC_ID" />
|
||||
<xsl:text>, "</xsl:text>
|
||||
<xsl:value-of select="RC_NAME" />
|
||||
<xsl:text>" },
</xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:for-each> <!-- All cards -->
|
||||
</xsl:if> <!-- Routing cards -->
|
||||
|
||||
<xsl:if test="$what = 'SC'">
|
||||
<xsl:for-each select="/STK600/ROUTING/CARD">
|
||||
<xsl:if test="SC_NAME != ''">
|
||||
<xsl:text> { </xsl:text>
|
||||
<xsl:value-of select="SC_ID" />
|
||||
<xsl:text>, "</xsl:text>
|
||||
<xsl:value-of select="SC_NAME" />
|
||||
<xsl:text>" },
</xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:for-each> <!-- All cards -->
|
||||
</xsl:if> <!-- Socket cards -->
|
||||
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding='ISO-8859-1' ?>
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<!--
|
||||
* Copyright (c) 2008 Joerg Wunsch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
*
|
||||
* $Id$
|
||||
-->
|
||||
<!--
|
||||
* Extract STK600 device support out of
|
||||
* targetboards.xml.
|
||||
*
|
||||
* Run this like:
|
||||
*
|
||||
* xsltproc \
|
||||
* tools/get-stk600-devices.xsl targetboard.xml
|
||||
*
|
||||
* and copy&paste the results into the respective table.
|
||||
-->
|
||||
<xsl:output method="text"/>
|
||||
<xsl:template match="/">
|
||||
<xsl:text>@multitable @columnfractions .15 .15 .6
</xsl:text>
|
||||
<xsl:text>Routing card @tab Socket card @tab Devices
</xsl:text>
|
||||
<xsl:for-each select="/STK600/ROUTING/CARD">
|
||||
<xsl:text>@item @code{</xsl:text>
|
||||
<xsl:value-of select="RC_NAME" />
|
||||
<xsl:text>} @tab @code{</xsl:text>
|
||||
<xsl:value-of select="SC_NAME" />
|
||||
<xsl:text>} @tab</xsl:text>
|
||||
<xsl:for-each select="TARGET">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:value-of select="NAME" />
|
||||
</xsl:for-each>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:for-each> <!-- All cards -->
|
||||
<xsl:text>@end multitable
</xsl:text>
|
||||
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
49
usb_libusb.c
49
usb_libusb.c
|
@ -59,6 +59,7 @@ static void usbdev_open(char * port, long baud, union filedescriptor *fd)
|
|||
struct usb_device *dev;
|
||||
usb_dev_handle *udev;
|
||||
char *serno, *cp2;
|
||||
int i;
|
||||
size_t x;
|
||||
|
||||
/*
|
||||
|
@ -187,7 +188,33 @@ static void usbdev_open(char * port, long baud, union filedescriptor *fd)
|
|||
goto trynext;
|
||||
}
|
||||
|
||||
fd->pfd = udev;
|
||||
fd->usb.handle = udev;
|
||||
fd->usb.ep = -1;
|
||||
/* Try finding out what our read endpoint is. */
|
||||
for (i = 0; i < dev->config[0].interface[0].altsetting[0].bNumEndpoints; i++)
|
||||
{
|
||||
int possible_ep = dev->config[0].interface[0].altsetting[0].
|
||||
endpoint[i].bEndpointAddress;
|
||||
|
||||
if ((possible_ep & USB_ENDPOINT_DIR_MASK) != 0)
|
||||
{
|
||||
if (verbose > 1)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: usbdev_open(): using read endpoint 0x%02x\n",
|
||||
progname, possible_ep);
|
||||
}
|
||||
fd->usb.ep = possible_ep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fd->usb.ep == -1)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: usbdev_open(): cannot find a read endpoint, using 0x%02x\n",
|
||||
progname, USBDEV_BULK_EP_READ);
|
||||
fd->usb.ep = USBDEV_BULK_EP_READ;
|
||||
}
|
||||
return;
|
||||
}
|
||||
trynext:
|
||||
|
@ -203,7 +230,7 @@ static void usbdev_open(char * port, long baud, union filedescriptor *fd)
|
|||
|
||||
static void usbdev_close(union filedescriptor *fd)
|
||||
{
|
||||
usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
|
||||
usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
|
||||
|
||||
(void)usb_release_interface(udev, usb_interface);
|
||||
|
||||
|
@ -219,7 +246,7 @@ static void usbdev_close(union filedescriptor *fd)
|
|||
|
||||
static int usbdev_send(union filedescriptor *fd, unsigned char *bp, size_t mlen)
|
||||
{
|
||||
usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
|
||||
usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
|
||||
int rv;
|
||||
int i = mlen;
|
||||
unsigned char * p = bp;
|
||||
|
@ -276,11 +303,11 @@ static int usbdev_send(union filedescriptor *fd, unsigned char *bp, size_t mlen)
|
|||
* empty and more data are requested.
|
||||
*/
|
||||
static int
|
||||
usb_fill_buf(usb_dev_handle *udev)
|
||||
usb_fill_buf(usb_dev_handle *udev, int ep)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = usb_bulk_read(udev, USBDEV_BULK_EP_READ, usbbuf, USBDEV_MAX_XFER, 5000);
|
||||
rv = usb_bulk_read(udev, ep, usbbuf, USBDEV_MAX_XFER, 5000);
|
||||
if (rv < 0)
|
||||
{
|
||||
if (verbose > 1)
|
||||
|
@ -297,7 +324,7 @@ usb_fill_buf(usb_dev_handle *udev)
|
|||
|
||||
static int usbdev_recv(union filedescriptor *fd, unsigned char *buf, size_t nbytes)
|
||||
{
|
||||
usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
|
||||
usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
|
||||
int i, amnt;
|
||||
unsigned char * p = buf;
|
||||
|
||||
|
@ -305,7 +332,7 @@ static int usbdev_recv(union filedescriptor *fd, unsigned char *buf, size_t nbyt
|
|||
{
|
||||
if (buflen <= bufptr)
|
||||
{
|
||||
if (usb_fill_buf(udev) < 0)
|
||||
if (usb_fill_buf(udev, fd->usb.ep) < 0)
|
||||
return -1;
|
||||
}
|
||||
amnt = buflen - bufptr > nbytes? nbytes: buflen - bufptr;
|
||||
|
@ -349,7 +376,7 @@ static int usbdev_recv(union filedescriptor *fd, unsigned char *buf, size_t nbyt
|
|||
*/
|
||||
static int usbdev_recv_frame(union filedescriptor *fd, unsigned char *buf, size_t nbytes)
|
||||
{
|
||||
usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
|
||||
usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
|
||||
int rv, n;
|
||||
int i;
|
||||
unsigned char * p = buf;
|
||||
|
@ -357,7 +384,7 @@ static int usbdev_recv_frame(union filedescriptor *fd, unsigned char *buf, size_
|
|||
n = 0;
|
||||
do
|
||||
{
|
||||
rv = usb_bulk_read(udev, USBDEV_BULK_EP_READ, usbbuf,
|
||||
rv = usb_bulk_read(udev, fd->usb.ep, usbbuf,
|
||||
USBDEV_MAX_XFER, 10000);
|
||||
if (rv < 0)
|
||||
{
|
||||
|
@ -406,11 +433,11 @@ static int usbdev_recv_frame(union filedescriptor *fd, unsigned char *buf, size_
|
|||
|
||||
static int usbdev_drain(union filedescriptor *fd, int display)
|
||||
{
|
||||
usb_dev_handle *udev = (usb_dev_handle *)fd->pfd;
|
||||
usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
|
||||
int rv;
|
||||
|
||||
do {
|
||||
rv = usb_bulk_read(udev, USBDEV_BULK_EP_READ, usbbuf, USBDEV_MAX_XFER, 100);
|
||||
rv = usb_bulk_read(udev, fd->usb.ep, usbbuf, USBDEV_MAX_XFER, 100);
|
||||
if (rv > 0 && verbose >= 4)
|
||||
fprintf(stderr, "%s: usbdev_drain(): flushed %d characters\n",
|
||||
progname, rv);
|
||||
|
|
Loading…
Reference in New Issue