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:
joerg_wunsch 2011-08-26 20:22:09 +00:00
parent 14b1f57a8d
commit b7c70ab98c
14 changed files with 405 additions and 53 deletions

View File

@ -20,5 +20,7 @@ Contributors:
Ville Voipio
Hannes Weisbach
Doug Springer
Brett Hagman
For minor contributions, please see the ChangeLog files.

View File

@ -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>
Submitted by an anonymous contributor on the mailinglist:

View File

@ -152,7 +152,9 @@ libavrdude_a_SOURCES = \
usbtiny.h \
usbtiny.c \
update.h \
update.c
update.c \
wiring.h \
wiring.c
avrdude_SOURCES = \
main.c \

1
NEWS
View File

@ -16,6 +16,7 @@ Current:
- TPI programming through bitbang programmers (both, serial
and parallel ones)
- FT2232 (and relatives) based programmers (MPSSE bitbang mode)
- Wiring environment (http://wiring.org.co/)
* Bugfixes

View File

@ -107,6 +107,10 @@ Using firmware version 2, high-voltage programming is also supported,
both parallel and serial
(programmer types stk500pp and stk500hvsp).
.Pp
Wiring boards are supported, utilizing STK500 V2.x protocol, but
a simple DTR/RTS toggle is used to set the boards into programming mode.
The programmer type is ``wiring''.
.Pp
The Arduino (which is very similar to the STK500 1.x) is supported via
its own programmer type specification ``arduino''.
.Pp
@ -975,6 +979,18 @@ and
.Ar speed=
parameters unavailable.
.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
.Sh FILES
.Bl -tag -offset indent -width /dev/ppi0XXX

View File

@ -21,7 +21,7 @@
# jtagmki | jtagmkii | jtagmkii_isp | jtagmkii_dw |
# jtagmkII_avr32 | jtagmkii_pdi |
# 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
# vcc = <num1> [, <num2> ... ] ; # pin number(s)
# reset = <num> ; # pin number
@ -322,6 +322,15 @@ default_serial = "@DEFAULT_SER_PORT@";
# PROGRAMMER DEFINITIONS
#
# http://wiring.org.co/
# Basically STK500v2 protocol, with some glue to trigger the
# bootloader.
programmer
id = "wiring";
desc = "Wiring";
type = wiring;
;
programmer
id = "arduino";
desc = "Arduino";

View File

@ -40,6 +40,7 @@
#include "arduino.h"
#include "buspirate.h"
#include "stk500v2.h"
#include "wiring.h"
#include "stk500generic.h"
#include "avr910.h"
#include "butterfly.h"
@ -162,6 +163,7 @@ static int parse_cmdbits(OPCODE * op);
%token K_TYPE
%token K_VCC
%token K_VFYLED
%token K_WIRING
%token K_NO
%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 {
{
stk500hvsp_initpgm(current_prog);

View File

@ -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
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
its own programmer type specification ``arduino''.
@ -571,6 +575,9 @@ USBtiny simple USB programmer,@*
@url{http://www.ladyada.net/make/usbtinyisp/}
@item @code{xil} @tab
Xilinx JTAG cable
@item @code{wiring} @tab
Wiring board, utilizing STK500 V2.x protocol,@*
@url{http://wiring.org.co/}
@end multitable
@ -1014,6 +1021,17 @@ and
parameters unavailable.
@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
@page

View File

@ -206,6 +206,7 @@ usbvendor { yylval=NULL; return K_USBVENDOR; }
usbvid { yylval=NULL; return K_USBVID; }
vcc { yylval=NULL; return K_VCC; }
vfyled { yylval=NULL; return K_VFYLED; }
wiring { yylval=NULL; return K_WIRING; }
timeout { yylval=NULL; return K_TIMEOUT; }
stabdelay { yylval=NULL; return K_STABDELAY; }

View File

@ -69,6 +69,12 @@
#define STK500V2_XTAL 7372800U
// Timeout (in seconds) for waiting for serial response
#define SERIAL_TIMEOUT 2
// Retry count
#define RETRIES 5
#if 0
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
#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))
@ -314,7 +280,7 @@ static void stk600_setup_xprog(PROGRAMMER * pgm);
static void stk600_setup_isp(PROGRAMMER * pgm);
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) {
fprintf(stderr,
@ -350,7 +316,7 @@ static void stk500v2_jtagmkII_setup(PROGRAMMER * pgm)
PDATA(pgm)->chained_pdata = theircookie;
}
static void stk500v2_teardown(PROGRAMMER * pgm)
void stk500v2_teardown(PROGRAMMER * pgm)
{
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);
}
@ -554,7 +520,7 @@ static int stk500v2_recv(PROGRAMMER * pgm, unsigned char msg[], size_t maxsize)
int timeout = 0;
unsigned char c, checksum = 0;
long timeoutval = 5; // seconds
long timeoutval = SERIAL_TIMEOUT; // seconds
struct timeval tv;
double tstart, tnow;
@ -647,7 +613,7 @@ static int stk500v2_recv(PROGRAMMER * pgm, unsigned char msg[], size_t maxsize)
tnow = tv.tv_sec;
if (tnow-tstart > timeoutval) { // wuff - signed/unsigned/overflow
timedout:
fprintf(stderr, "%s: stk500_2_ReceiveMessage(): timeout\n",
fprintf(stderr, "%s: stk500v2_ReceiveMessage(): timeout\n",
progname);
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;
unsigned char buf[1], resp[32];
int status;
@ -713,7 +679,7 @@ retry:
progname, pgmname[PDATA(pgm)->pgmtype]);
return 0;
} else {
if (tries > 33) {
if (tries > RETRIES) {
fprintf(stderr,
"%s: stk500v2_getsync(): can't communicate with device: resp=0x%02x\n",
progname, resp[0]);
@ -724,7 +690,7 @@ retry:
// or if we got a timeout
} else if (status == -1) {
if (tries > 33) {
if (tries > RETRIES) {
fprintf(stderr,"%s: stk500v2_getsync(): timeout communicating with programmer\n",
progname);
return -1;
@ -733,7 +699,7 @@ retry:
// or any other error
} else {
if (tries > 33) {
if (tries > RETRIES) {
fprintf(stderr,"%s: stk500v2_getsync(): error communicating with programmer: (%d)\n",
progname,status);
} else
@ -750,7 +716,7 @@ static int stk500v2_command(PROGRAMMER * pgm, unsigned char * buf,
int status;
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);
retry:
@ -840,7 +806,7 @@ retry:
// otherwise try to sync up again
status = stk500v2_getsync(pgm);
if (status != 0) {
if (tries > 33) {
if (tries > RETRIES) {
fprintf(stderr,"%s: stk500v2_command(): failed miserably to execute command 0x%02x\n",
progname,buf[0]);
return -1;

View File

@ -38,6 +38,11 @@ void stk600_initpgm (PROGRAMMER * pgm);
void stk600hvsp_initpgm (PROGRAMMER * pgm);
void stk600pp_initpgm (PROGRAMMER * pgm);
void stk500v2_setup(PROGRAMMER * pgm);
void stk500v2_teardown(PROGRAMMER * pgm);
int stk500v2_drain(PROGRAMMER * pgm, int display);
int stk500v2_getsync(PROGRAMMER * pgm);
#ifdef __cplusplus
}
#endif

View File

@ -9,6 +9,8 @@
//*
//**************************************************************************
#include "pgm.h"
// *****************[ STK message constants ]***************************
#define MESSAGE_START 0x1B //= ESC = 27 decimal
@ -278,3 +280,43 @@
#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;
};

235
wiring.c Normal file
View File

@ -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;
}

29
wiring.h Normal file
View File

@ -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