Submitted by Brett Hagman:
Add support for the "Wiring" board/bootloader * 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. git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@987 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
14b1f57a8d
commit
b7c70ab98c
2
AUTHORS
2
AUTHORS
|
@ -20,5 +20,7 @@ Contributors:
|
||||||
Ville Voipio
|
Ville Voipio
|
||||||
Hannes Weisbach
|
Hannes Weisbach
|
||||||
Doug Springer
|
Doug Springer
|
||||||
|
Brett Hagman
|
||||||
|
|
||||||
For minor contributions, please see the ChangeLog files.
|
For minor contributions, please see the ChangeLog files.
|
||||||
|
|
||||||
|
|
18
ChangeLog
18
ChangeLog
|
@ -1,3 +1,21 @@
|
||||||
|
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||||
|
|
||||||
|
Submitted by Brett Hagman:
|
||||||
|
Add support for the "Wiring" board/bootloader
|
||||||
|
* wiring.c: New file.
|
||||||
|
* wiring.h: (Ditto.)
|
||||||
|
* Makefile.am: Add new files.
|
||||||
|
* stk500v2_private.h: Reorganize so some functions and struct
|
||||||
|
pdata are globally known.
|
||||||
|
* stk500v2.c: (Ditto.)
|
||||||
|
* stk500v2.h: (Ditto.)
|
||||||
|
* lexer.l: Add new programmer keywords.
|
||||||
|
* config_gram.y: (Ditto.)
|
||||||
|
* avrdude.conf.in: Add "wiring" programmer entry.
|
||||||
|
* avrdude.1: Document the new programmer.
|
||||||
|
* doc/avrdude.texi: (Ditto.)
|
||||||
|
* AUTHORS: Add Brett Hagman.
|
||||||
|
|
||||||
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
2011-08-26 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||||
|
|
||||||
Submitted by an anonymous contributor on the mailinglist:
|
Submitted by an anonymous contributor on the mailinglist:
|
||||||
|
|
|
@ -152,7 +152,9 @@ libavrdude_a_SOURCES = \
|
||||||
usbtiny.h \
|
usbtiny.h \
|
||||||
usbtiny.c \
|
usbtiny.c \
|
||||||
update.h \
|
update.h \
|
||||||
update.c
|
update.c \
|
||||||
|
wiring.h \
|
||||||
|
wiring.c
|
||||||
|
|
||||||
avrdude_SOURCES = \
|
avrdude_SOURCES = \
|
||||||
main.c \
|
main.c \
|
||||||
|
|
1
NEWS
1
NEWS
|
@ -16,6 +16,7 @@ Current:
|
||||||
- TPI programming through bitbang programmers (both, serial
|
- TPI programming through bitbang programmers (both, serial
|
||||||
and parallel ones)
|
and parallel ones)
|
||||||
- FT2232 (and relatives) based programmers (MPSSE bitbang mode)
|
- FT2232 (and relatives) based programmers (MPSSE bitbang mode)
|
||||||
|
- Wiring environment (http://wiring.org.co/)
|
||||||
|
|
||||||
* Bugfixes
|
* Bugfixes
|
||||||
|
|
||||||
|
|
16
avrdude.1
16
avrdude.1
|
@ -107,6 +107,10 @@ Using firmware version 2, high-voltage programming is also supported,
|
||||||
both parallel and serial
|
both parallel and serial
|
||||||
(programmer types stk500pp and stk500hvsp).
|
(programmer types stk500pp and stk500hvsp).
|
||||||
.Pp
|
.Pp
|
||||||
|
Wiring boards are supported, utilizing STK500 V2.x protocol, but
|
||||||
|
a simple DTR/RTS toggle is used to set the boards into programming mode.
|
||||||
|
The programmer type is ``wiring''.
|
||||||
|
.Pp
|
||||||
The Arduino (which is very similar to the STK500 1.x) is supported via
|
The Arduino (which is very similar to the STK500 1.x) is supported via
|
||||||
its own programmer type specification ``arduino''.
|
its own programmer type specification ``arduino''.
|
||||||
.Pp
|
.Pp
|
||||||
|
@ -975,6 +979,18 @@ and
|
||||||
.Ar speed=
|
.Ar speed=
|
||||||
parameters unavailable.
|
parameters unavailable.
|
||||||
.El
|
.El
|
||||||
|
.It Ar Wiring
|
||||||
|
When using the Wiring programmer type, the
|
||||||
|
following optional extended parameter is accepted:
|
||||||
|
.Bl -tag -offset indent -width indent
|
||||||
|
.It Ar snooze=<0..32767>
|
||||||
|
After performing the port open phase, AVRDUDE will wait/snooze for
|
||||||
|
.Ar snooze
|
||||||
|
milliseconds before continuing to the protocol sync phase.
|
||||||
|
No toggling of DTR/RTS is performed if
|
||||||
|
.Ar snooze
|
||||||
|
is greater than 0.
|
||||||
|
.El
|
||||||
.El
|
.El
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -offset indent -width /dev/ppi0XXX
|
.Bl -tag -offset indent -width /dev/ppi0XXX
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
# jtagmki | jtagmkii | jtagmkii_isp | jtagmkii_dw |
|
# jtagmki | jtagmkii | jtagmkii_isp | jtagmkii_dw |
|
||||||
# jtagmkII_avr32 | jtagmkii_pdi |
|
# jtagmkII_avr32 | jtagmkii_pdi |
|
||||||
# dragon_dw | dragon_jtag | dragon_isp | dragon_pp |
|
# dragon_dw | dragon_jtag | dragon_isp | dragon_pp |
|
||||||
# dragon_hvsp | dragon_pdi | arduino; # programmer type
|
# dragon_hvsp | dragon_pdi | arduino | wiring; # programmer type
|
||||||
# baudrate = <num> ; # baudrate for avr910-programmer
|
# baudrate = <num> ; # baudrate for avr910-programmer
|
||||||
# vcc = <num1> [, <num2> ... ] ; # pin number(s)
|
# vcc = <num1> [, <num2> ... ] ; # pin number(s)
|
||||||
# reset = <num> ; # pin number
|
# reset = <num> ; # pin number
|
||||||
|
@ -322,6 +322,15 @@ default_serial = "@DEFAULT_SER_PORT@";
|
||||||
# PROGRAMMER DEFINITIONS
|
# PROGRAMMER DEFINITIONS
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# http://wiring.org.co/
|
||||||
|
# Basically STK500v2 protocol, with some glue to trigger the
|
||||||
|
# bootloader.
|
||||||
|
programmer
|
||||||
|
id = "wiring";
|
||||||
|
desc = "Wiring";
|
||||||
|
type = wiring;
|
||||||
|
;
|
||||||
|
|
||||||
programmer
|
programmer
|
||||||
id = "arduino";
|
id = "arduino";
|
||||||
desc = "Arduino";
|
desc = "Arduino";
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "arduino.h"
|
#include "arduino.h"
|
||||||
#include "buspirate.h"
|
#include "buspirate.h"
|
||||||
#include "stk500v2.h"
|
#include "stk500v2.h"
|
||||||
|
#include "wiring.h"
|
||||||
#include "stk500generic.h"
|
#include "stk500generic.h"
|
||||||
#include "avr910.h"
|
#include "avr910.h"
|
||||||
#include "butterfly.h"
|
#include "butterfly.h"
|
||||||
|
@ -162,6 +163,7 @@ static int parse_cmdbits(OPCODE * op);
|
||||||
%token K_TYPE
|
%token K_TYPE
|
||||||
%token K_VCC
|
%token K_VCC
|
||||||
%token K_VFYLED
|
%token K_VFYLED
|
||||||
|
%token K_WIRING
|
||||||
|
|
||||||
%token K_NO
|
%token K_NO
|
||||||
%token K_YES
|
%token K_YES
|
||||||
|
@ -416,6 +418,12 @@ prog_parm :
|
||||||
}
|
}
|
||||||
} |
|
} |
|
||||||
|
|
||||||
|
K_TYPE TKN_EQUAL K_WIRING {
|
||||||
|
{
|
||||||
|
wiring_initpgm(current_prog);
|
||||||
|
}
|
||||||
|
} |
|
||||||
|
|
||||||
K_TYPE TKN_EQUAL K_STK500HVSP {
|
K_TYPE TKN_EQUAL K_STK500HVSP {
|
||||||
{
|
{
|
||||||
stk500hvsp_initpgm(current_prog);
|
stk500hvsp_initpgm(current_prog);
|
||||||
|
|
|
@ -214,6 +214,10 @@ option might be required to achieve a stable ISP communication.
|
||||||
For ATxmega devices, the AVR Dragon is supported in PDI mode, provided it
|
For ATxmega devices, the AVR Dragon is supported in PDI mode, provided it
|
||||||
has a firmware version of at least 6.11 (decimal).
|
has a firmware version of at least 6.11 (decimal).
|
||||||
|
|
||||||
|
Wiring boards are supported, utilizing STK500 V2.x protocol, but
|
||||||
|
a simple DTR/RTS toggle to set the boards into programming mode.
|
||||||
|
The programmer type is ``wiring''.
|
||||||
|
|
||||||
The Arduino (which is very similar to the STK500 1.x) is supported via
|
The Arduino (which is very similar to the STK500 1.x) is supported via
|
||||||
its own programmer type specification ``arduino''.
|
its own programmer type specification ``arduino''.
|
||||||
|
|
||||||
|
@ -571,6 +575,9 @@ USBtiny simple USB programmer,@*
|
||||||
@url{http://www.ladyada.net/make/usbtinyisp/}
|
@url{http://www.ladyada.net/make/usbtinyisp/}
|
||||||
@item @code{xil} @tab
|
@item @code{xil} @tab
|
||||||
Xilinx JTAG cable
|
Xilinx JTAG cable
|
||||||
|
@item @code{wiring} @tab
|
||||||
|
Wiring board, utilizing STK500 V2.x protocol,@*
|
||||||
|
@url{http://wiring.org.co/}
|
||||||
@end multitable
|
@end multitable
|
||||||
|
|
||||||
|
|
||||||
|
@ -1014,6 +1021,17 @@ and
|
||||||
parameters unavailable.
|
parameters unavailable.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@item Wiring
|
||||||
|
|
||||||
|
When using the Wiring programmer type, the
|
||||||
|
following optional extended parameter is accepted:
|
||||||
|
@table @code
|
||||||
|
@item @samp{snooze=@var{0..32767}}
|
||||||
|
After performing the port open phase, AVRDUDE will wait/snooze for
|
||||||
|
@var{snooze} milliseconds before continuing to the protocol sync phase.
|
||||||
|
No toggling of DTR/RTS is performed if @var{snooze} > 0.
|
||||||
|
@end table
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@page
|
@page
|
||||||
|
|
1
lexer.l
1
lexer.l
|
@ -206,6 +206,7 @@ usbvendor { yylval=NULL; return K_USBVENDOR; }
|
||||||
usbvid { yylval=NULL; return K_USBVID; }
|
usbvid { yylval=NULL; return K_USBVID; }
|
||||||
vcc { yylval=NULL; return K_VCC; }
|
vcc { yylval=NULL; return K_VCC; }
|
||||||
vfyled { yylval=NULL; return K_VFYLED; }
|
vfyled { yylval=NULL; return K_VFYLED; }
|
||||||
|
wiring { yylval=NULL; return K_WIRING; }
|
||||||
|
|
||||||
timeout { yylval=NULL; return K_TIMEOUT; }
|
timeout { yylval=NULL; return K_TIMEOUT; }
|
||||||
stabdelay { yylval=NULL; return K_STABDELAY; }
|
stabdelay { yylval=NULL; return K_STABDELAY; }
|
||||||
|
|
68
stk500v2.c
68
stk500v2.c
|
@ -69,6 +69,12 @@
|
||||||
|
|
||||||
#define STK500V2_XTAL 7372800U
|
#define STK500V2_XTAL 7372800U
|
||||||
|
|
||||||
|
// Timeout (in seconds) for waiting for serial response
|
||||||
|
#define SERIAL_TIMEOUT 2
|
||||||
|
|
||||||
|
// Retry count
|
||||||
|
#define RETRIES 5
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
|
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
|
@ -87,46 +93,6 @@ enum hvmode
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Private data for this programmer.
|
|
||||||
*/
|
|
||||||
struct pdata
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* See stk500pp_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;
|
|
||||||
|
|
||||||
unsigned char command_sequence;
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
PGMTYPE_UNKNOWN,
|
|
||||||
PGMTYPE_STK500,
|
|
||||||
PGMTYPE_AVRISP,
|
|
||||||
PGMTYPE_AVRISP_MKII,
|
|
||||||
PGMTYPE_JTAGICE_MKII,
|
|
||||||
PGMTYPE_STK600,
|
|
||||||
}
|
|
||||||
pgmtype;
|
|
||||||
|
|
||||||
AVRPART *lastpart;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Chained pdata for the JTAG ICE mkII backend. This is used when
|
|
||||||
* calling the backend functions for ISP/HVSP/PP programming
|
|
||||||
* functionality of the JTAG ICE mkII and AVR Dragon.
|
|
||||||
*/
|
|
||||||
void *chained_pdata;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
||||||
|
|
||||||
|
|
||||||
|
@ -314,7 +280,7 @@ static void stk600_setup_xprog(PROGRAMMER * pgm);
|
||||||
static void stk600_setup_isp(PROGRAMMER * pgm);
|
static void stk600_setup_isp(PROGRAMMER * pgm);
|
||||||
static int stk600_xprog_program_enable(PROGRAMMER * pgm, AVRPART * p);
|
static int stk600_xprog_program_enable(PROGRAMMER * pgm, AVRPART * p);
|
||||||
|
|
||||||
static void stk500v2_setup(PROGRAMMER * pgm)
|
void stk500v2_setup(PROGRAMMER * pgm)
|
||||||
{
|
{
|
||||||
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
|
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
@ -350,7 +316,7 @@ static void stk500v2_jtagmkII_setup(PROGRAMMER * pgm)
|
||||||
PDATA(pgm)->chained_pdata = theircookie;
|
PDATA(pgm)->chained_pdata = theircookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stk500v2_teardown(PROGRAMMER * pgm)
|
void stk500v2_teardown(PROGRAMMER * pgm)
|
||||||
{
|
{
|
||||||
free(pgm->cookie);
|
free(pgm->cookie);
|
||||||
}
|
}
|
||||||
|
@ -486,7 +452,7 @@ static int stk500v2_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int stk500v2_drain(PROGRAMMER * pgm, int display)
|
int stk500v2_drain(PROGRAMMER * pgm, int display)
|
||||||
{
|
{
|
||||||
return serial_drain(&pgm->fd, display);
|
return serial_drain(&pgm->fd, display);
|
||||||
}
|
}
|
||||||
|
@ -554,7 +520,7 @@ static int stk500v2_recv(PROGRAMMER * pgm, unsigned char msg[], size_t maxsize)
|
||||||
int timeout = 0;
|
int timeout = 0;
|
||||||
unsigned char c, checksum = 0;
|
unsigned char c, checksum = 0;
|
||||||
|
|
||||||
long timeoutval = 5; // seconds
|
long timeoutval = SERIAL_TIMEOUT; // seconds
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
double tstart, tnow;
|
double tstart, tnow;
|
||||||
|
|
||||||
|
@ -647,7 +613,7 @@ static int stk500v2_recv(PROGRAMMER * pgm, unsigned char msg[], size_t maxsize)
|
||||||
tnow = tv.tv_sec;
|
tnow = tv.tv_sec;
|
||||||
if (tnow-tstart > timeoutval) { // wuff - signed/unsigned/overflow
|
if (tnow-tstart > timeoutval) { // wuff - signed/unsigned/overflow
|
||||||
timedout:
|
timedout:
|
||||||
fprintf(stderr, "%s: stk500_2_ReceiveMessage(): timeout\n",
|
fprintf(stderr, "%s: stk500v2_ReceiveMessage(): timeout\n",
|
||||||
progname);
|
progname);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -660,7 +626,7 @@ static int stk500v2_recv(PROGRAMMER * pgm, unsigned char msg[], size_t maxsize)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int stk500v2_getsync(PROGRAMMER * pgm) {
|
int stk500v2_getsync(PROGRAMMER * pgm) {
|
||||||
int tries = 0;
|
int tries = 0;
|
||||||
unsigned char buf[1], resp[32];
|
unsigned char buf[1], resp[32];
|
||||||
int status;
|
int status;
|
||||||
|
@ -713,7 +679,7 @@ retry:
|
||||||
progname, pgmname[PDATA(pgm)->pgmtype]);
|
progname, pgmname[PDATA(pgm)->pgmtype]);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
if (tries > 33) {
|
if (tries > RETRIES) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s: stk500v2_getsync(): can't communicate with device: resp=0x%02x\n",
|
"%s: stk500v2_getsync(): can't communicate with device: resp=0x%02x\n",
|
||||||
progname, resp[0]);
|
progname, resp[0]);
|
||||||
|
@ -724,7 +690,7 @@ retry:
|
||||||
|
|
||||||
// or if we got a timeout
|
// or if we got a timeout
|
||||||
} else if (status == -1) {
|
} else if (status == -1) {
|
||||||
if (tries > 33) {
|
if (tries > RETRIES) {
|
||||||
fprintf(stderr,"%s: stk500v2_getsync(): timeout communicating with programmer\n",
|
fprintf(stderr,"%s: stk500v2_getsync(): timeout communicating with programmer\n",
|
||||||
progname);
|
progname);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -733,7 +699,7 @@ retry:
|
||||||
|
|
||||||
// or any other error
|
// or any other error
|
||||||
} else {
|
} else {
|
||||||
if (tries > 33) {
|
if (tries > RETRIES) {
|
||||||
fprintf(stderr,"%s: stk500v2_getsync(): error communicating with programmer: (%d)\n",
|
fprintf(stderr,"%s: stk500v2_getsync(): error communicating with programmer: (%d)\n",
|
||||||
progname,status);
|
progname,status);
|
||||||
} else
|
} else
|
||||||
|
@ -750,7 +716,7 @@ static int stk500v2_command(PROGRAMMER * pgm, unsigned char * buf,
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
DEBUG("STK500V2: stk500v2_command(");
|
DEBUG("STK500V2: stk500v2_command(");
|
||||||
for (i=0;i<len;i++) DEBUG("0x%02hhx ",buf[i]);
|
for (i=0;i<len;i++) DEBUG("0x%02x ",buf[i]);
|
||||||
DEBUG(", %d)\n",len);
|
DEBUG(", %d)\n",len);
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
|
@ -840,7 +806,7 @@ retry:
|
||||||
// otherwise try to sync up again
|
// otherwise try to sync up again
|
||||||
status = stk500v2_getsync(pgm);
|
status = stk500v2_getsync(pgm);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
if (tries > 33) {
|
if (tries > RETRIES) {
|
||||||
fprintf(stderr,"%s: stk500v2_command(): failed miserably to execute command 0x%02x\n",
|
fprintf(stderr,"%s: stk500v2_command(): failed miserably to execute command 0x%02x\n",
|
||||||
progname,buf[0]);
|
progname,buf[0]);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -38,6 +38,11 @@ void stk600_initpgm (PROGRAMMER * pgm);
|
||||||
void stk600hvsp_initpgm (PROGRAMMER * pgm);
|
void stk600hvsp_initpgm (PROGRAMMER * pgm);
|
||||||
void stk600pp_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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
//*
|
//*
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
|
#include "pgm.h"
|
||||||
|
|
||||||
// *****************[ STK message constants ]***************************
|
// *****************[ STK message constants ]***************************
|
||||||
|
|
||||||
#define MESSAGE_START 0x1B //= ESC = 27 decimal
|
#define MESSAGE_START 0x1B //= ESC = 27 decimal
|
||||||
|
@ -278,3 +280,43 @@
|
||||||
|
|
||||||
#define ANSWER_CKSUM_ERROR 0xB0
|
#define ANSWER_CKSUM_ERROR 0xB0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Private data for this programmer.
|
||||||
|
*/
|
||||||
|
struct pdata
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* See stk500pp_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;
|
||||||
|
|
||||||
|
unsigned char command_sequence;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PGMTYPE_UNKNOWN,
|
||||||
|
PGMTYPE_STK500,
|
||||||
|
PGMTYPE_AVRISP,
|
||||||
|
PGMTYPE_AVRISP_MKII,
|
||||||
|
PGMTYPE_JTAGICE_MKII,
|
||||||
|
PGMTYPE_STK600,
|
||||||
|
}
|
||||||
|
pgmtype;
|
||||||
|
|
||||||
|
AVRPART *lastpart;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chained pdata for the JTAG ICE mkII backend. This is used when
|
||||||
|
* calling the backend functions for ISP/HVSP/PP programming
|
||||||
|
* functionality of the JTAG ICE mkII and AVR Dragon.
|
||||||
|
*/
|
||||||
|
void *chained_pdata;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,235 @@
|
||||||
|
/*
|
||||||
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||||
|
* Copyright (C) 2011 Brett Hagman
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* avrdude interface for Wiring bootloaders
|
||||||
|
*
|
||||||
|
* http://wiring.org.co/
|
||||||
|
*
|
||||||
|
* The Wiring bootloader uses a near-complete STK500v2 protocol.
|
||||||
|
* (Only ISP specific programming commands are not implemented
|
||||||
|
* e.g. chip erase).
|
||||||
|
* DTR and RTS signals are diddled to set the board into programming mode.
|
||||||
|
*
|
||||||
|
* Also includes an extended parameter to introduce a delay after opening
|
||||||
|
* to accommodate multi-layered programmers/bootloaders. If the extended
|
||||||
|
* parameter 'snooze' > 0, then no DTR/RTS toggle takes place, and
|
||||||
|
* AVRDUDE will wait that amount of time in milliseconds before syncing.
|
||||||
|
*
|
||||||
|
* Unfortunately, there is no way to easily chain private programmer data
|
||||||
|
* when we "inherit" programmer types as we have (stk500v2). Sooooo, a
|
||||||
|
* *cringe* global variable is used to store the snooze time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ac_cfg.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "avrdude.h"
|
||||||
|
#include "pgm.h"
|
||||||
|
#include "stk500v2_private.h"
|
||||||
|
#include "stk500v2.h"
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Private data for this programmer.
|
||||||
|
*/
|
||||||
|
struct wiringpdata
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We just have the single snooze integer to carry around for now.
|
||||||
|
*/
|
||||||
|
int snoozetime;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* wiringpdata is our private data */
|
||||||
|
/* pdata is stk500v2's private data (inherited) */
|
||||||
|
|
||||||
|
#define WIRINGPDATA(x) ((struct wiringpdata *)(x))
|
||||||
|
|
||||||
|
#define STK500V2PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
||||||
|
|
||||||
|
|
||||||
|
static void wiring_setup(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
void *mycookie;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First, have STK500v2 backend allocate its own private data.
|
||||||
|
*/
|
||||||
|
stk500v2_setup(pgm);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now prepare our data
|
||||||
|
*/
|
||||||
|
if ((mycookie = malloc(sizeof(struct wiringpdata))) == 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: wiring_setup(): Out of memory allocating private data\n",
|
||||||
|
progname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
memset(mycookie, 0, sizeof(struct wiringpdata));
|
||||||
|
WIRINGPDATA(mycookie)->snoozetime = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Store our own cookie in a safe place for the time being.
|
||||||
|
*/
|
||||||
|
STK500V2PDATA(pgm)->chained_pdata = mycookie;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wiring_teardown(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
void *mycookie;
|
||||||
|
|
||||||
|
mycookie = STK500V2PDATA(pgm)->chained_pdata;
|
||||||
|
|
||||||
|
free(mycookie);
|
||||||
|
|
||||||
|
stk500v2_teardown(pgm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wiring_parseextparms(PROGRAMMER * pgm, LISTID extparms)
|
||||||
|
{
|
||||||
|
LNODEID ln;
|
||||||
|
const char *extended_param;
|
||||||
|
int rv = 0;
|
||||||
|
void *mycookie = STK500V2PDATA(pgm)->chained_pdata;
|
||||||
|
|
||||||
|
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
|
||||||
|
extended_param = ldata(ln);
|
||||||
|
|
||||||
|
if (strncmp(extended_param, "snooze=", strlen("snooze=")) == 0) {
|
||||||
|
int newsnooze;
|
||||||
|
if (sscanf(extended_param, "snooze=%i", &newsnooze) != 1 ||
|
||||||
|
newsnooze < 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: wiring_parseextparms(): invalid snooze time '%s'\n",
|
||||||
|
progname, extended_param);
|
||||||
|
rv = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (verbose >= 2) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: wiring_parseextparms(): snooze time set to %d ms\n",
|
||||||
|
progname, newsnooze);
|
||||||
|
}
|
||||||
|
WIRINGPDATA(mycookie)->snoozetime = newsnooze;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: wiring_parseextparms(): invalid extended parameter '%s'\n",
|
||||||
|
progname, extended_param);
|
||||||
|
rv = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wiring_open(PROGRAMMER * pgm, char * port)
|
||||||
|
{
|
||||||
|
int timetosnooze;
|
||||||
|
void *mycookie = STK500V2PDATA(pgm)->chained_pdata;
|
||||||
|
|
||||||
|
strcpy(pgm->port, port);
|
||||||
|
serial_open(port, pgm->baudrate ? pgm->baudrate: 115200, &pgm->fd);
|
||||||
|
|
||||||
|
/* If we have a snoozetime, then we wait and do NOT toggle DTR/RTS */
|
||||||
|
|
||||||
|
if (WIRINGPDATA(mycookie)->snoozetime > 0) {
|
||||||
|
timetosnooze = WIRINGPDATA(mycookie)->snoozetime;
|
||||||
|
|
||||||
|
if (verbose >= 2) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: wiring_open(): snoozing for %d ms\n",
|
||||||
|
progname, timetosnooze);
|
||||||
|
}
|
||||||
|
while (timetosnooze--)
|
||||||
|
usleep(1000);
|
||||||
|
if (verbose >= 2) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: wiring_open(): done snoozing\n",
|
||||||
|
progname);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* Perform Wiring programming mode RESET. */
|
||||||
|
/* This effectively *releases* both DTR and RTS. */
|
||||||
|
/* i.e. both DTR and RTS rise to a HIGH logic level */
|
||||||
|
/* since they are active LOW signals. */
|
||||||
|
|
||||||
|
if (verbose >= 2) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: wiring_open(): releasing DTR/RTS\n",
|
||||||
|
progname);
|
||||||
|
}
|
||||||
|
|
||||||
|
serial_set_dtr_rts(&pgm->fd, 0);
|
||||||
|
usleep(50*1000);
|
||||||
|
|
||||||
|
/* After releasing for 50 milliseconds, DTR and RTS */
|
||||||
|
/* are asserted (i.e. logic LOW) again. */
|
||||||
|
|
||||||
|
if (verbose >= 2) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: wiring_open(): asserting DTR/RTS\n",
|
||||||
|
progname);
|
||||||
|
}
|
||||||
|
|
||||||
|
serial_set_dtr_rts(&pgm->fd, 1);
|
||||||
|
usleep(50*1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* drain any extraneous input */
|
||||||
|
stk500v2_drain(pgm, 0);
|
||||||
|
|
||||||
|
if (stk500v2_getsync(pgm) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wiring_close(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
serial_set_dtr_rts(&pgm->fd, 0);
|
||||||
|
serial_close(&pgm->fd);
|
||||||
|
pgm->fd.ifd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wiring_initpgm(PROGRAMMER * pgm)
|
||||||
|
{
|
||||||
|
/* The Wiring bootloader uses a near-complete STK500v2 protocol. */
|
||||||
|
|
||||||
|
stk500v2_initpgm(pgm);
|
||||||
|
|
||||||
|
strcpy(pgm->type, "Wiring");
|
||||||
|
pgm->open = wiring_open;
|
||||||
|
pgm->close = wiring_close;
|
||||||
|
|
||||||
|
pgm->setup = wiring_setup;
|
||||||
|
pgm->teardown = wiring_teardown;
|
||||||
|
pgm->parseextparams = wiring_parseextparms;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||||
|
* Copyright (C) 2011 Brett Hagman
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#ifndef wiring_h__
|
||||||
|
#define wiring_h__
|
||||||
|
|
||||||
|
void wiring_initpgm(PROGRAMMER * pgm);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue