1 Commits

Author SHA1 Message Date
Joerg Wunsch
b1c7bc8c83 This commit was manufactured by cvs2svn to create tag
'release_4_2_0'.

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/tags/release_4_2_0@366 81a1dc3b-b13d-400b-aceb-764788c761c2
2003-09-06 17:47:17 +00:00
64 changed files with 3068 additions and 14318 deletions

View File

@@ -1,17 +1,10 @@
AVRDUDE was written by:
Brian S. Dean <bsd@bdmicro.com>
Brian S. Dean <bsd@bsdhome.com>.
Contributors:
Joerg Wunsch <j@uriah.heep.sax.de>
Eric Weddington <ericw@evcohs.com>
Jan-Hinnerk Reichert <hinni@despammed.com>
Alex Shepherd <maillists@ajsystems.co.nz>
Martin Thomas <mthomas@rhrk.uni-kl.de>
Eric Weddington <eric@ecentral.com>
Theodore A. Roth <troth@openavr.org>
Michael Holzt <kju-avr@fqdn.org>
Colin O'Flynn <coflynn@newae.com>
For minor contributions, please see the ChangeLog files.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
#
# avrdude - A Downloader/Uploader for AVR device programmers
# Copyright (C) 2003, 2004 Theodore A. Roth <troth@openavr.org>
# Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
#
# 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
@@ -24,8 +24,8 @@
EXTRA_DIST = \
ChangeLog-2001 \
ChangeLog-2002 \
ChangeLog-2003 \
avrdude.1 \
avrdude.pdf \
avrdude.spec \
bootstrap
@@ -34,11 +34,8 @@ CLEANFILES = \
config_gram.h \
lexer.c
#SUBDIRS = doc @WINDOWS_DIRS@
#DIST_SUBDIRS = doc windows
SUBDIRS = @SUBDIRS_AC@
DIST_SUBDIRS = @DIST_SUBDIRS_AC@
SUBDIRS = doc @WINDOWS_DIRS@
DIST_SUBDIRS = doc windows
AM_YFLAGS = -d
@@ -55,23 +52,13 @@ avrdude_SOURCES = \
avr.h \
avr910.c \
avr910.h \
avrpart.c \
avrpart.h \
bitbang.c \
bitbang.h \
butterfly.c \
butterfly.h \
config.c \
config.h \
confwin.c \
confwin.h \
crc16.c \
crc16.h \
fileio.c \
fileio.h \
jtagmkII.c \
jtagmkII.h \
jtagmkII_private.h \
linux_ppdev.h \
lists.c \
lists.h \
@@ -84,23 +71,14 @@ avrdude_SOURCES = \
ppi.c \
ppi.h \
ppiwin.c \
safemode.c \
safemode.h \
serial.h \
serbb.h \
serbb_posix.c \
serbb_win32.c \
ser_posix.c \
ser_win32.c \
stk500.c \
stk500.h \
stk500_private.h \
stk500v2.c \
stk500v2.h \
stk500v2_private.h \
term.c \
term.h \
usb_libusb.c
term.h
man_MANS = avrdude.1

View File

@@ -5,92 +5,6 @@ Approximate change log for AVRDUDE by version.
(For more detailed changes, see the ChangeLog file.)
----------------------------------------------------------------------
Current:
Version 5.0:
* Support for JTAGICE MkII device
* Support for STK500 Version 2 Protocol
* New devices supported:
- AT90CAN128
- ATmega329x/649x
- ATmega164/324/644
- AT90PWM2/3,
- ATmega164/324/644
- ATmega329x/649x
- ATtiny25/45/85
* Support for serial bit-bang adapters: Ponyprog serial, UISP DASA,
UISP DASA3.
* DAPA programmer pinout supported
* New "safemode" feature where fuse bits are verified before exit
and if possible recovered if they have changed. This is intended
to protect against changed fuses which were not requested which is
reported to sometimes happen due to improper power supply or other
reasons.
* Various fixes for avr910 and butterfly programmers
* Full support for AVR109 boot loaders (butterfly)
* Adding -q -q suppresses most terminal output
Version 4.4.0:
* Native Win32 support: The windows build doesn't need Cygwin
anymore. Additionally, the delay timing on windows should be
more accurate now.
Contributed by Martin Thomas
* Add support for
- ATmega48, ATmega88 (contributed by Galen Seitz)
- ATtiny2313 (contributed by Bob Paddock)
- ATtiny13 (contributed by Pawel Moll)
* Added command to change the SCK of STK500-programmers. Now it
is possible to program uC with slow oscillator.
Contributed by Galen Seitz
* Baudrate for serial programmers (STK500 and AVR910) is
configurable in the config or at the command-line.
This way some more tweaked bootloaders and programmers can be used.
* Deprecated options have been removed.
Now the "-U" option must be used.
* MacOS X now supported by default.
Version 4.3.0:
* Added support for "Butterfly" evaluation board.
* Make cycle-count work with AVR910-programmers.
* Added "Troubleshooting"-Appendix to the manual.
* Add ATmega8515 support.
Contributed by: Matthias Wei<65>er <matthias@matwei.de>
* Add ATmega64 support.
Contributed by: Erik Christiansen <erik@dd.nec.com.au>
* Improved polling algorithm to speed up
programming of byte oriented parallel programmers.
Contributed by: Jan-Hinnerk Reichert <jan-hinnerk_reichert@hamburg.de>
* Add "fuse" and "lock" definitions for the AT90S8535.
* STK500 skips empty pages in paged write resulting in faster downloads
when there are empty blocks in between code (such as files that contain
application code and bootloader code).
Version 4.2.0:

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,15 +25,13 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include "avr.h"
#include "config.h"
#include "lists.h"
#include "pindefs.h"
#include "ppi.h"
#include "safemode.h"
#define DEBUG 0
@@ -45,6 +43,250 @@ extern PROGRAMMER * pgm;
extern int do_cycles;
AVRPART * avr_new_part(void)
{
AVRPART * p;
p = (AVRPART *)malloc(sizeof(AVRPART));
if (p == NULL) {
fprintf(stderr, "new_part(): out of memory\n");
exit(1);
}
memset(p, 0, sizeof(*p));
p->id[0] = 0;
p->desc[0] = 0;
p->reset_disposition = RESET_DEDICATED;
p->retry_pulse = PIN_AVR_SCK;
p->flags = AVRPART_SERIALOK | AVRPART_PARALLELOK;
p->config_file[0] = 0;
p->lineno = 0;
p->mem = lcreat(NULL, 0);
return p;
}
OPCODE * avr_new_opcode(void)
{
OPCODE * m;
m = (OPCODE *)malloc(sizeof(*m));
if (m == NULL) {
fprintf(stderr, "avr_new_opcode(): out of memory\n");
exit(1);
}
memset(m, 0, sizeof(*m));
return m;
}
AVRMEM * avr_new_memtype(void)
{
AVRMEM * m;
m = (AVRMEM *)malloc(sizeof(*m));
if (m == NULL) {
fprintf(stderr, "avr_new_memtype(): out of memory\n");
exit(1);
}
memset(m, 0, sizeof(*m));
return m;
}
AVRMEM * avr_dup_mem(AVRMEM * m)
{
AVRMEM * n;
n = avr_new_memtype();
*n = *m;
n->buf = (unsigned char *)malloc(n->size);
if (n->buf == NULL) {
fprintf(stderr,
"avr_dup_mem(): out of memory (memsize=%d)\n",
n->size);
exit(1);
}
memset(n->buf, 0, n->size);
return n;
}
AVRPART * avr_dup_part(AVRPART * d)
{
AVRPART * p;
LISTID save;
LNODEID ln;
p = avr_new_part();
save = p->mem;
*p = *d;
p->mem = save;
for (ln=lfirst(d->mem); ln; ln=lnext(ln)) {
ladd(p->mem, avr_dup_mem(ldata(ln)));
}
return p;
}
AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
{
AVRMEM * m, * match;
LNODEID ln;
int matches;
int l;
l = strlen(desc);
matches = 0;
match = NULL;
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
m = ldata(ln);
if (strncmp(desc, m->desc, l) == 0) {
match = m;
matches++;
}
}
if (matches == 1)
return match;
return NULL;
}
/*
* avr_set_bits()
*
* Set instruction bits in the specified command based on the opcode.
*/
int avr_set_bits(OPCODE * op, unsigned char * cmd)
{
int i, j, bit;
unsigned char mask;
for (i=0; i<32; i++) {
if (op->bit[i].type == AVR_CMDBIT_VALUE) {
j = 3 - i / 8;
bit = i % 8;
mask = 1 << bit;
if (op->bit[i].value)
cmd[j] = cmd[j] | mask;
else
cmd[j] = cmd[j] & ~mask;
}
}
return 0;
}
/*
* avr_set_addr()
*
* Set address bits in the specified command based on the opcode, and
* the address.
*/
int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr)
{
int i, j, bit;
unsigned long value;
unsigned char mask;
for (i=0; i<32; i++) {
if (op->bit[i].type == AVR_CMDBIT_ADDRESS) {
j = 3 - i / 8;
bit = i % 8;
mask = 1 << bit;
value = addr >> op->bit[i].bitno & 0x01;
if (value)
cmd[j] = cmd[j] | mask;
else
cmd[j] = cmd[j] & ~mask;
}
}
return 0;
}
/*
* avr_set_input()
*
* Set input data bits in the specified command based on the opcode,
* and the data byte.
*/
int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data)
{
int i, j, bit;
unsigned char value;
unsigned char mask;
for (i=0; i<32; i++) {
if (op->bit[i].type == AVR_CMDBIT_INPUT) {
j = 3 - i / 8;
bit = i % 8;
mask = 1 << bit;
value = data >> op->bit[i].bitno & 0x01;
if (value)
cmd[j] = cmd[j] | mask;
else
cmd[j] = cmd[j] & ~mask;
}
}
return 0;
}
/*
* avr_get_output()
*
* Retreive output data bits from the command results based on the
* opcode data.
*/
int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data)
{
int i, j, bit;
unsigned char value;
unsigned char mask;
for (i=0; i<32; i++) {
if (op->bit[i].type == AVR_CMDBIT_OUTPUT) {
j = 3 - i / 8;
bit = i % 8;
mask = 1 << bit;
value = ((res[j] & mask) >> bit) & 0x01;
value = value << op->bit[i].bitno;
if (value)
*data = *data | value;
else
*data = *data & ~value;
}
}
return 0;
}
int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value)
{
@@ -262,7 +504,7 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
/*
* since we don't know what voltage the target AVR is powered by, be
* conservative and delay the max amount the spec says to wait
* conservative and delay the max amount the spec says to wait
*/
usleep(mem->max_write_delay);
@@ -279,14 +521,11 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned char r;
int ready;
int tries;
unsigned long start_time;
unsigned long prog_time;
unsigned char b;
unsigned short caddr;
OPCODE * writeop;
int rc;
int readok=0;
struct timeval tv;
if (!mem->paged) {
/*
@@ -376,6 +615,13 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
tries = 0;
ready = 0;
while (!ready) {
usleep(mem->min_write_delay);
rc = avr_read_byte(pgm, p, mem, addr, &r);
if (rc != 0) {
pgm->pgm_led(pgm, OFF);
pgm->err_led(pgm, ON);
return -4;
}
if ((data == mem->readback[0]) ||
(data == mem->readback[1])) {
@@ -393,29 +639,6 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
return -5;
}
}
else {
gettimeofday (&tv, NULL);
start_time = (tv.tv_sec * 1000000) + tv.tv_usec;
do {
/*
* Do polling, but timeout after max_write_delay.
*/
rc = avr_read_byte(pgm, p, mem, addr, &r);
if (rc != 0) {
pgm->pgm_led(pgm, OFF);
pgm->err_led(pgm, ON);
return -4;
}
gettimeofday (&tv, NULL);
prog_time = (tv.tv_sec * 1000000) + tv.tv_usec;
} while ((r != data) &&
((prog_time-start_time) < mem->max_write_delay));
}
/*
* At this point we either have a valid readback or the
* max_write_delay is expired.
*/
if (r == data) {
ready = 1;
@@ -428,6 +651,7 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
* memory bits but not all. We only actually power-off the
* device if the data read back does not match what we wrote.
*/
usleep(mem->max_write_delay); /* maximum write delay */
pgm->pgm_led(pgm, OFF);
fprintf(stderr,
"%s: this device must be powered off and back on to continue\n",
@@ -480,31 +704,8 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data)
{
unsigned char safemode_lfuse;
unsigned char safemode_hfuse;
unsigned char safemode_efuse;
unsigned char safemode_fuse;
int rc;
/* If we write the fuses, then we need to tell safemode that they *should* change */
safemode_memfuses(0, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
if (strcmp(mem->desc, "fuse")==0) {
safemode_fuse = data;
}
if (strcmp(mem->desc, "lfuse")==0) {
safemode_lfuse = data;
}
if (strcmp(mem->desc, "hfuse")==0) {
safemode_hfuse = data;
}
if (strcmp(mem->desc, "efuse")==0) {
safemode_efuse = data;
}
safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
if (pgm->write_byte) {
rc = pgm->write_byte(pgm, p, mem, addr, data);
if (rc == 0) {
@@ -611,12 +812,11 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
if (werror) {
/*
* make sure the error led stay on if there was a previous write
* error, otherwise it gets cleared in avr_write_byte()
* error, otherwise it gets cleared in avr_write_byte()
*/
pgm->err_led(pgm, ON);
}
}
return i;
}
@@ -632,7 +832,7 @@ int avr_signature(PROGRAMMER * pgm, AVRPART * p)
report_progress (0,1,"Reading");
rc = avr_read(pgm, p, "signature", 0, 0);
if (rc < 0) {
fprintf(stderr,
fprintf(stderr,
"%s: error reading signature data for part \"%s\", rc=%d\n",
progname, p->desc, rc);
return -1;
@@ -643,12 +843,35 @@ int avr_signature(PROGRAMMER * pgm, AVRPART * p)
}
/*
* Allocate and initialize memory buffers for each of the device's
* defined memory regions.
*/
int avr_initmem(AVRPART * p)
{
LNODEID ln;
AVRMEM * m;
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
m = ldata(ln);
m->buf = (unsigned char *) malloc(m->size);
if (m->buf == NULL) {
fprintf(stderr, "%s: can't alloc buffer for %s size of %d bytes\n",
progname, m->desc, m->size);
return -1;
}
}
return 0;
}
/*
* Verify the memory buffer of p with that of v. The byte range of v,
* may be a subset of p. The byte range of p should cover the whole
* chip's memory size.
*
* Return the number of bytes verified, or -1 if they don't match.
* Return the number of bytes verified, or -1 if they don't match.
*/
int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
{
@@ -706,37 +929,54 @@ int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles)
{
AVRMEM * a;
unsigned int cycle_count = 0;
unsigned char v1;
int cycle_count;
unsigned char v1, v2, v3, v4;
int rc;
int i;
a = avr_locate_mem(p, "eeprom");
if (a == NULL) {
return -1;
}
for (i=4; i>0; i--) {
rc = avr_read_byte(pgm, p, a, a->size-i, &v1);
rc = avr_read_byte(pgm, p, a, a->size-4, &v1);
if (rc < 0) {
fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n",
progname, rc);
return -1;
}
cycle_count = (cycle_count << 8) | v1;
rc = avr_read_byte(pgm, p, a, a->size-3, &v2);
if (rc < 0) {
fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n",
progname, rc);
return -1;
}
/*
* If the EEPROM is erased, the cycle count reads 0xffffffff.
* In this case we return a cycle_count of zero.
* So, the calling function don't have to care about whether or not
* the cycle count was initialized.
*/
if (cycle_count == 0xffffffff) {
cycle_count = 0;
rc = avr_read_byte(pgm, p, a, a->size-2, &v3);
if (rc < 0) {
fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n",
progname, rc);
return -1;
}
*cycles = (int) cycle_count;
rc = avr_read_byte(pgm, p, a, a->size-1, &v4);
if (rc < 0) {
fprintf(stderr, "%s: WARNING: can't read memory for cycle count, rc=%d\n",
progname, rc);
return -1;
}
if ((v1 == 0xff) && (v2 == 0xff) && (v3 != 0xff) && (v4 != 0xff)) {
v1 = 0;
v2 = 0;
}
cycle_count = (((unsigned int)v1) << 24) |
(((unsigned int)v2) << 16) |
(((unsigned int)v3) << 8) |
v4;
*cycles = cycle_count;
return 0;
}
@@ -745,56 +985,214 @@ int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles)
int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles)
{
AVRMEM * a;
unsigned char v1;
unsigned char v1, v2, v3, v4;
int rc;
int i;
a = avr_locate_mem(p, "eeprom");
if (a == NULL) {
return -1;
}
for (i=1; i<=4; i++) {
v1 = cycles & 0xff;
cycles = cycles >> 8;
v4 = cycles & 0x0ff;
v3 = (cycles & 0x0ff00) >> 8;
v2 = (cycles & 0x0ff0000) >> 16;
v1 = (cycles & 0x0ff000000) >> 24;
rc = avr_write_byte(pgm, p, a, a->size-i, v1);
if (rc < 0) {
fprintf(stderr, "%s: WARNING: can't write memory for cycle count, rc=%d\n",
progname, rc);
return -1;
}
rc = avr_write_byte(pgm, p, a, a->size-4, v1);
if (rc < 0) {
fprintf(stderr, "%s: WARNING: can't write memory for cycle count, rc=%d\n",
progname, rc);
return -1;
}
rc = avr_write_byte(pgm, p, a, a->size-3, v2);
if (rc < 0) {
fprintf(stderr, "%s: WARNING: can't write memory for cycle count, rc=%d\n",
progname, rc);
return -1;
}
rc = avr_write_byte(pgm, p, a, a->size-2, v3);
if (rc < 0) {
fprintf(stderr, "%s: WARNING: can't write memory for cycle count, rc=%d\n",
progname, rc);
return -1;
}
rc = avr_write_byte(pgm, p, a, a->size-1, v4);
if (rc < 0) {
fprintf(stderr, "%s: WARNING: can't write memory for cycle count, rc=%d\n",
progname, rc);
return -1;
}
return 0;
}
}
int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p)
char * avr_op_str(int op)
{
int cycles;
int rc;
switch (op) {
case AVR_OP_READ : return "READ"; break;
case AVR_OP_WRITE : return "WRITE"; break;
case AVR_OP_READ_LO : return "READ_LO"; break;
case AVR_OP_READ_HI : return "READ_HI"; break;
case AVR_OP_WRITE_LO : return "WRITE_LO"; break;
case AVR_OP_WRITE_HI : return "WRITE_HI"; break;
case AVR_OP_LOADPAGE_LO : return "LOADPAGE_LO"; break;
case AVR_OP_LOADPAGE_HI : return "LOADPAGE_HI"; break;
case AVR_OP_WRITEPAGE : return "WRITEPAGE"; break;
case AVR_OP_CHIP_ERASE : return "CHIP_ERASE"; break;
case AVR_OP_PGM_ENABLE : return "PGM_ENABLE"; break;
default : return "<unknown opcode>"; break;
}
}
if (do_cycles) {
rc = avr_get_cycle_count(pgm, p, &cycles);
/*
* Don't update the cycle counter, if read failed
*/
if(rc != 0) {
do_cycles = 0;
char * bittype(int type)
{
switch (type) {
case AVR_CMDBIT_IGNORE : return "IGNORE"; break;
case AVR_CMDBIT_VALUE : return "VALUE"; break;
case AVR_CMDBIT_ADDRESS : return "ADDRESS"; break;
case AVR_CMDBIT_INPUT : return "INPUT"; break;
case AVR_CMDBIT_OUTPUT : return "OUTPUT"; break;
default : return "<unknown bit type>"; break;
}
}
void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
int verbose)
{
int i, j;
char * optr;
if (m == NULL) {
fprintf(f,
"%s Page Polled\n"
"%sMemory Type Paged Size Size #Pages MinW MaxW ReadBack\n"
"%s----------- ------ ------ ---- ------ ----- ----- ---------\n",
prefix, prefix, prefix);
}
else {
if (verbose > 2) {
fprintf(f,
"%s Page Polled\n"
"%sMemory Type Paged Size Size #Pages MinW MaxW ReadBack\n"
"%s----------- ------ ------ ---- ------ ----- ----- ---------\n",
prefix, prefix, prefix);
}
fprintf(f,
"%s%-11s %-6s %6d %4d %5d %5d %5d 0x%02x 0x%02x\n",
prefix, m->desc,
m->paged ? "yes" : "no",
m->size,
m->page_size,
m->num_pages,
m->min_write_delay,
m->max_write_delay,
m->readback[0],
m->readback[1]);
if (verbose > 2) {
fprintf(stderr,
"%s Memory Ops:\n"
"%s Oeration Inst Bit Bit Type Bitno Value\n"
"%s ----------- -------- -------- ----- -----\n",
prefix, prefix, prefix);
for (i=0; i<AVR_OP_MAX; i++) {
if (m->op[i]) {
for (j=31; j>=0; j--) {
if (j==31)
optr = avr_op_str(i);
else
optr = " ";
fprintf(f,
"%s %-11s %8d %8s %5d %5d\n",
prefix, optr, j,
bittype(m->op[i]->bit[j].type),
m->op[i]->bit[j].bitno,
m->op[i]->bit[j].value);
}
}
}
}
}
}
rc = pgm->chip_erase(pgm, p);
/*
* Don't update the cycle counter, if erase failed
*/
if (do_cycles && (rc == 0)) {
cycles++;
fprintf(stderr, "%s: erase-rewrite cycle count is now %d\n",
progname, cycles);
avr_put_cycle_count(pgm, p, cycles);
char * reset_disp_str(int r)
{
switch (r) {
case RESET_DEDICATED : return "dedicated";
case RESET_IO : return "possible i/o";
default : return "<invalid>";
}
}
char * pin_name(int pinno)
{
switch (pinno) {
case PIN_AVR_RESET : return "RESET";
case PIN_AVR_MISO : return "MISO";
case PIN_AVR_MOSI : return "MOSI";
case PIN_AVR_SCK : return "SCK";
default : return "<unknown>";
}
}
void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose)
{
int i;
char * buf;
char * px;
LNODEID ln;
AVRMEM * m;
fprintf(f,
"%sAVR Part : %s\n"
"%sChip Erase delay : %d us\n"
"%sPAGEL : P%02X\n"
"%sBS2 : P%02X\n"
"%sRESET disposition : %s\n"
"%sRETRY pulse : %s\n"
"%sserial program mode : %s\n"
"%sparallel program mode : %s\n"
"%sMemory Detail :\n\n",
prefix, p->desc,
prefix, p->chip_erase_delay,
prefix, p->pagel,
prefix, p->bs2,
prefix, reset_disp_str(p->reset_disposition),
prefix, pin_name(p->retry_pulse),
prefix, (p->flags & AVRPART_SERIALOK) ? "yes" : "no",
prefix, (p->flags & AVRPART_PARALLELOK) ?
((p->flags & AVRPART_PSEUDOPARALLEL) ? "psuedo" : "yes") : "no",
prefix);
px = prefix;
i = strlen(prefix) + 5;
buf = (char *)malloc(i);
if (buf == NULL) {
/* ugh, this is not important enough to bail, just ignore it */
}
else {
strcpy(buf, prefix);
strcat(buf, " ");
px = buf;
}
if (verbose <= 2) {
avr_mem_display(px, f, NULL, 0, verbose);
}
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
m = ldata(ln);
avr_mem_display(px, f, m, i, verbose);
}
return rc;
if (buf)
free(buf);
}

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@
#include <stdio.h>
#include "avrpart.h"
#include "lists.h"
#include "pgm.h"
@@ -32,10 +33,29 @@
extern struct avrpart parts[];
int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
AVRPART * avr_find_part(char * p);
AVRPART * avr_new_part(void);
OPCODE * avr_new_opcode(void);
AVRMEM * avr_new_memtype(void);
AVRPART * avr_dup_part(AVRPART * d);
AVRMEM * avr_locate_mem(AVRPART * p, char * desc);
int avr_txrx_bit(int fd, int bit);
unsigned char avr_txrx(int fd, unsigned char byte);
int avr_set_bits(OPCODE * op, unsigned char * cmd);
int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value);
int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
int verbose);
int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
@@ -44,21 +64,28 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data);
int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
int verbose);
int avr_signature(PROGRAMMER * pgm, AVRPART * p);
char * avr_memtstr(int memtype);
int avr_initmem(AVRPART * p);
int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size);
void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
int verbose);
void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose);
int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles);
int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);;
int avr_mem_hiaddr(AVRMEM * mem);
int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p);
extern void report_progress (int completed, int total, char *hdr);
#endif

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
*
* 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
@@ -30,8 +30,6 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <unistd.h>
#include "avr.h"
#include "pgm.h"
@@ -43,30 +41,36 @@ extern int do_cycles;
static char has_auto_incr_addr;
/* These two defines are only for debugging. Will remove them once it starts
working. */
#define show_func_info() \
fprintf(stderr, "%s: line %d: called %s()\n", \
__FILE__, __LINE__, __FUNCTION__)
#define no_show_func_info()
static int avr910_send(PROGRAMMER * pgm, char * buf, size_t len)
{
return serial_send(pgm->fd, (unsigned char *)buf, len);
no_show_func_info();
return serial_send(pgm->fd, buf, len);
}
static int avr910_recv(PROGRAMMER * pgm, char * buf, size_t len)
{
int rv;
no_show_func_info();
rv = serial_recv(pgm->fd, (unsigned char *)buf, len);
if (rv < 0) {
fprintf(stderr,
"%s: avr910_recv(): programmer is not responding\n",
progname);
exit(1);
}
return 0;
return serial_recv(pgm->fd, buf, len);
}
static int avr910_drain(PROGRAMMER * pgm, int display)
{
no_show_func_info();
return serial_drain(pgm->fd, display);
}
@@ -84,19 +88,56 @@ static void avr910_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
}
static int avr910_rdy_led(PROGRAMMER * pgm, int value)
{
no_show_func_info();
/* Do nothing. */
return 0;
}
static int avr910_err_led(PROGRAMMER * pgm, int value)
{
no_show_func_info();
/* Do nothing. */
return 0;
}
static int avr910_pgm_led(PROGRAMMER * pgm, int value)
{
no_show_func_info();
/* Do nothing. */
return 0;
}
static int avr910_vfy_led(PROGRAMMER * pgm, int value)
{
no_show_func_info();
/* Do nothing. */
return 0;
}
/*
* issue the 'chip erase' command to the AVR device
*/
static int avr910_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
no_show_func_info();
avr910_send(pgm, "e", 1);
avr910_vfy_cmd_sent(pgm, "chip erase");
/*
* avr910 firmware may not delay long enough
*/
usleep (p->chip_erase_delay);
return 0;
}
@@ -120,10 +161,38 @@ static void avr910_leave_prog_mode(PROGRAMMER * pgm)
*/
static int avr910_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
no_show_func_info();
return -1;
}
/*
* apply power to the AVR processor
*/
static void avr910_powerup(PROGRAMMER * pgm)
{
no_show_func_info();
/* Do nothing. */
return;
}
/*
* remove power from the AVR processor
*/
static void avr910_powerdown(PROGRAMMER * pgm)
{
no_show_func_info();
/* Do nothing. */
return;
}
/*
* initialize the AVR device and prepare it to accept commands
*/
@@ -134,9 +203,10 @@ static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
char hw[2];
char buf[10];
char type;
char c;
unsigned char c;
int dev_supported = 0;
AVRPART * part;
no_show_func_info();
/* Get the programmer identifier. Programmer returns exactly 7 chars
_without_ the null.*/
@@ -177,9 +247,7 @@ static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
avr910_recv(pgm, &c, 1);
if (c == 0)
break;
part = locate_part_by_avr910_devcode(part_list, c);
fprintf(stderr, " Device code: 0x%02x = %s\n", c, part ? part->desc : "(unknown)");
fprintf(stderr, " Device code: 0x%02x\n", c);
/* FIXME: Need to lookup devcode and report the device. */
@@ -209,8 +277,30 @@ static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
}
static int avr910_save(PROGRAMMER * pgm)
{
no_show_func_info();
/* Do nothing. */
return 0;
}
static void avr910_restore(PROGRAMMER * pgm)
{
no_show_func_info();
/* Do nothing. */
return;
}
static void avr910_disable(PROGRAMMER * pgm)
{
no_show_func_info();
/* Do nothing. */
return;
@@ -219,6 +309,8 @@ static void avr910_disable(PROGRAMMER * pgm)
static void avr910_enable(PROGRAMMER * pgm)
{
no_show_func_info();
/* Do nothing. */
return;
@@ -232,7 +324,9 @@ static void avr910_enable(PROGRAMMER * pgm)
static int avr910_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
unsigned char res[4])
{
char buf[5];
unsigned char buf[5];
no_show_func_info();
/* FIXME: Insert version check here */
@@ -254,28 +348,23 @@ static int avr910_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
}
static int avr910_open(PROGRAMMER * pgm, char * port)
static void avr910_open(PROGRAMMER * pgm, char * port)
{
/*
* If baudrate was not specified use 19.200 Baud
*/
if(pgm->baudrate == 0) {
pgm->baudrate = 19200;
}
no_show_func_info();
strcpy(pgm->port, port);
pgm->fd = serial_open(port, pgm->baudrate);
pgm->fd = serial_open(port, 19200);
/*
* drain any extraneous input
*/
avr910_drain (pgm, 0);
return 0;
}
static void avr910_close(PROGRAMMER * pgm)
{
no_show_func_info();
avr910_leave_prog_mode(pgm);
serial_close(pgm->fd);
@@ -285,13 +374,15 @@ static void avr910_close(PROGRAMMER * pgm)
static void avr910_display(PROGRAMMER * pgm, char * p)
{
no_show_func_info();
return;
}
static void avr910_set_addr(PROGRAMMER * pgm, unsigned long addr)
{
char cmd[3];
unsigned char cmd[3];
cmd[0] = 'A';
cmd[1] = (addr >> 8) & 0xff;
@@ -302,10 +393,26 @@ static void avr910_set_addr(PROGRAMMER * pgm, unsigned long addr)
}
/*
* For some reason, if we don't do this when writing to flash, the first byte
* of flash is not programmed. I susect that the board got out of sync after
* the erase and sending another command gets us back in sync. -TRoth
*/
static void avr910_write_setup(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
{
if (strcmp(m->desc, "flash") == 0) {
avr910_send(pgm, "y", 1);
avr910_vfy_cmd_sent(pgm, "clear LED");
}
}
static int avr910_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned long addr, unsigned char value)
{
char cmd[2];
unsigned char cmd[2];
no_show_func_info();
if (strcmp(m->desc, "flash") == 0) {
if (addr & 0x01) {
@@ -347,7 +454,7 @@ static int avr910_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
cached = 0;
}
else {
char buf[2];
unsigned char buf[2];
avr910_set_addr(pgm, addr >> 1);
@@ -358,7 +465,7 @@ static int avr910_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
if ((addr & 0x01) == 0) {
*value = buf[1];
// cached = 1;
cached = 1;
cvalue = buf[0];
caddr = addr;
}
@@ -376,7 +483,7 @@ static int avr910_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
{
avr910_set_addr(pgm, addr);
avr910_send(pgm, "d", 1);
avr910_recv(pgm, (char *)value, 1);
avr910_recv(pgm, value, 1);
return 0;
}
@@ -385,6 +492,8 @@ static int avr910_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int avr910_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned long addr, unsigned char * value)
{
no_show_func_info();
if (strcmp(m->desc, "flash") == 0) {
return avr910_read_byte_flash(pgm, p, m, addr, value);
}
@@ -401,13 +510,15 @@ static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes)
{
unsigned char cmd[] = {'c', 'C'};
char buf[2];
unsigned char buf[2];
unsigned int addr = 0;
unsigned int max_addr = n_bytes;
unsigned int page_addr;
int page_bytes = page_size;
int page_wr_cmd_pending = 0;
avr910_write_setup(pgm, p, m);
page_addr = addr;
avr910_set_addr(pgm, addr>>1);
@@ -421,25 +532,21 @@ static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
addr++;
page_bytes--;
if (m->paged && (page_bytes == 0)) {
if ((has_auto_incr_addr != 'Y') && ((addr & 0x01) == 0)) {
avr910_set_addr(pgm, addr>>1);
}
else if (m->paged && (page_bytes == 0)) {
/* Send the "Issue Page Write" if we have sent a whole page. */
avr910_set_addr(pgm, page_addr>>1);
avr910_send(pgm, "m", 1);
avr910_vfy_cmd_sent(pgm, "flush page");
page_wr_cmd_pending = 0;
usleep(m->max_write_delay);
avr910_set_addr(pgm, addr>>1);
/* Set page address for next page. */
page_addr = addr;
page_bytes = page_size;
}
else if ((has_auto_incr_addr != 'Y') && ((addr & 0x01) == 0)) {
avr910_set_addr(pgm, addr>>1);
}
report_progress (addr, max_addr, NULL);
}
@@ -451,7 +558,6 @@ static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
avr910_set_addr(pgm, page_addr>>1);
avr910_send(pgm, "m", 1);
avr910_vfy_cmd_sent(pgm, "flush final page");
usleep(m->max_write_delay);
}
return addr;
@@ -461,7 +567,7 @@ static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
AVRMEM * m, int page_size, int n_bytes)
{
char cmd[2];
unsigned char cmd[2];
unsigned int addr = 0;
unsigned int max_addr = n_bytes;
@@ -473,7 +579,6 @@ static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
cmd[1] = m->buf[addr];
avr910_send(pgm, cmd, sizeof(cmd));
avr910_vfy_cmd_sent(pgm, "write byte");
usleep(m->max_write_delay);
addr++;
@@ -488,7 +593,7 @@ static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
}
static int avr910_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int avr910_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes)
{
if (strcmp(m->desc, "flash") == 0) {
@@ -506,11 +611,11 @@ static int avr910_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes)
{
char cmd;
unsigned char cmd;
int rd_size;
unsigned int addr = 0;
unsigned int max_addr;
char buf[2];
unsigned char buf[2];
if (strcmp(m->desc, "flash") == 0) {
cmd = 'R';
@@ -538,7 +643,7 @@ static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
m->buf[addr*2+1] = buf[0]; /* MSB */
}
else {
avr910_recv(pgm, (char *)&m->buf[addr], 1);
avr910_recv(pgm, &m->buf[addr], 1);
}
addr++;
@@ -557,13 +662,15 @@ static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int avr910_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
{
no_show_func_info();
if (m->size < 3) {
fprintf(stderr, "%s: memsize too small for sig byte read", progname);
return -1;
}
avr910_send(pgm, "s", 1);
avr910_recv(pgm, (char *)m->buf, 3);
avr910_recv(pgm, m->buf, 3);
return 3;
}
@@ -571,15 +678,25 @@ static int avr910_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
void avr910_initpgm(PROGRAMMER * pgm)
{
no_show_func_info();
strcpy(pgm->type, "avr910");
/*
* mandatory functions
*/
pgm->rdy_led = avr910_rdy_led;
pgm->err_led = avr910_err_led;
pgm->pgm_led = avr910_pgm_led;
pgm->vfy_led = avr910_vfy_led;
pgm->initialize = avr910_initialize;
pgm->display = avr910_display;
pgm->save = avr910_save;
pgm->restore = avr910_restore;
pgm->enable = avr910_enable;
pgm->disable = avr910_disable;
pgm->powerup = avr910_powerup;
pgm->powerdown = avr910_powerdown;
pgm->program_enable = avr910_program_enable;
pgm->chip_erase = avr910_chip_erase;
pgm->cmd = avr910_cmd;
@@ -590,6 +707,7 @@ void avr910_initpgm(PROGRAMMER * pgm)
* optional functions
*/
pgm->write_setup = avr910_write_setup;
pgm->write_byte = avr910_write_byte;
pgm->read_byte = avr910_read_byte;

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
*
* 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
@@ -22,7 +22,7 @@
#ifndef __avr910_h__
#define __avr910_h__
#include "avrpart.h"
#include "config.h"
void avr910_initpgm (PROGRAMMER * pgm);

View File

@@ -1,6 +1,6 @@
.\"
.\" avrdude - A Downloader/Uploader for AVR device programmers
.\" Copyright (C) 2001, 2002, 2003, 2005 Joerg Wunsch
.\" Copyright (C) 2001, 2002, 2003 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
@@ -19,7 +19,7 @@
.\"
.\" $Id$
.\"
.Dd DATE September 18, 2005
.Dd DATE July 24, 2003
.Os
.Dt AVRDUDE 1
.Sh NAME
@@ -28,8 +28,6 @@
.Sh SYNOPSIS
.Nm
.Fl p Ar partno
.Op Fl b Ar baudrate
.Op Fl B Ar bitclock
.Op Fl c Ar programmer-id
.Op Fl C Ar config-file
.Op Fl D
@@ -37,13 +35,15 @@
.Oo Fl E Ar exitspec Ns
.Op \&, Ns Ar exitspec
.Oc
.Op Fl f Ar format
.Op Fl F
.Op Fl i Ar filename
.Op Fl m Ar memtype
.Op Fl o Ar filename
.Op Fl n
.Op Fl P Ar port
.Op Fl q
.Op Fl s
.Op Fl t
.Op Fl u
.Op Fl U Ar memtype:op:filename:filefmt
.Op Fl v
.Op Fl V
@@ -54,16 +54,10 @@
is a program for downloading code and data to Atmel AVR
microcontrollers.
.Nm Avrdude
supports Atmel's STK500 programmer,
Atmel's JTAG ICE mkII,
programmers complying to AppNote AVR910 and AVR109 (including the Butterfly),
as well as a simple hard-wired
supports Atmel's STK500 programmer as well as a simple hard-wired
programmer connected directly to a
.Xr ppi 4
or
.Xr parport 4
parallel port, or to a standard serial port.
In the simplest case, the hardware consists just of a
parallel port. In the simplest case, the hardware consists just of a
cable connecting the respective AVR signal lines to the parallel port.
.Pp
The MCU is programmed in
@@ -85,27 +79,14 @@ signal is available to control a buffer/driver IC 74LS367 (or
74HCT367). The latter can be useful to decouple the parallel port
from the MCU when in-system programming is used.
.Pp
A number of equally simple bit-bang programming adapters that connect
to a serial port are supported as well, among them the popular
Ponyprog serial adapter, and the DASA and DASA3 adapters that used to
be supported by uisp(1).
Note that these adapters are meant to be attached to a physical serial
port.
Connecting to a serial port emulated on top of USB is likely to not
work at all, or to work abysmally slow.
See the file
.Pa ${PREFIX}/share/doc/avrdude/avrdude.pdf
for a schematic of the
.Xr ppi 4
based programming hardware.
.Pp
Atmel's STK500 programmer is also supported and connects to a serial
port.
Both, firmware versions 1.x and 2.x can be handled, but require a
different programmer type specification (by now).
.Pp
The simple serial programmer described in Atmel's application note
AVR910, and the bootloader described in Atmel's application note
AVR109 (which is also used by the AVR Butterfly evaluation board), are
supported on a serial port.
.Pp
Atmel's JTAG ICE mkII is supported as well to up- or download memory
areas from/to an AVR target (no support for on-chip debugging).
.Pp
Input files can be provided, and output files can be written in
different file formats, such as raw binary files containing the data
@@ -155,9 +136,7 @@ the format. Currently, the following MCU types are understood:
.TS
ll.
\fBOption tag\fP \fBOfficial part name\fP
c128 AT90CAN128
pwm2 AT90PWM2
pwm3 AT90PWM3
t15 ATtiny15
1200 AT90S1200
2313 AT90S2313
2333 AT90S2333
@@ -167,53 +146,17 @@ pwm3 AT90PWM3
4434 AT90S4434
8515 AT90S8515
8535 AT90S8535
m103 ATmega103
m128 ATmega128
m16 ATmega16
m161 ATmega161
m162 ATmega162
m163 ATmega163
m164 ATmega164
m169 ATmega169
m32 ATmega32
m324 ATmega324
m329 ATmega329
m3290 ATmega3290
m48 ATmega48
m64 ATmega64
m644 ATmega644
m649 ATmega649
m6490 ATmega6490
m8 ATmega8
m8515 ATmega8515
m8535 ATmega8535
m88 ATmega88
t12 ATtiny12
t13 ATtiny13
t15 ATtiny15
t2313 ATtiny2313
t25 ATtiny25
t26 ATtiny26
t45 ATtiny45
t85 ATtiny85
m163 ATMEGA163
m169 ATMEGA169
m128 ATMEGA128
m103 ATMEGA103
m16 ATMEGA16
m8 ATMEGA8
.TE
.Bl -tag -width "(*) "
.It "(*)"
The AT90S2323 and ATtiny22 use the same algorithm.
The AT90S2323 uses the same algorithm.
.El
.It Fl b Ar baudrate
Override the RS-232 connection baud rate specified in the respective
programmer's entry of the configuration file.
.It Fl B Ar bitclock
Specify the bit clock period for the JTAG interface (JTAG ICE only).
The value is a floating-point number in microseconds.
The default value of the JTAG ICE results in about 1 microsecond bit
clock period, suitable for target MCUs running at 4 MHz clock and
above.
Unlike certain parameters in the STK500, the JTAG ICE resets all its
parameters to default values when the programming software signs
off from the ICE, so for MCUs running at lower clock speeds, this
parameter must be specified on the command-line.
.It Fl c Ar programmer-id
Use the pin configuration specified by the argument. Pin
configurations are read from the config file (see the
@@ -246,6 +189,11 @@ option with flash memory is specified,
will perform a chip erase before starting any of the programming
operations, since it generally is a mistake to program the flash
without performing an erase first. This option disables that.
However, to remain backward compatible, the
.Fl i ,
and
.Fl m
options automatically disable the auto erase feature.
.It Fl e
Causes a chip erase to be executed. This will reset the contents of the
flash ROM and EEPROM to the value
@@ -309,130 +257,11 @@ pins of the parallel port down at program exit.
Multiple
.Ar exitspec
arguments can be separated with commas.
.It Fl F
Normally,
.Nm
tries to verify that the device signature read from the part is
reasonable before continuing. Since it can happen from time to time
that a device has a broken (erased or overwritten) device signature
but is otherwise operating normally, this options is provided to
override the check.
.It Fl n
No-write - disables actually writing data to the MCU (useful for debugging
.Nm avrdude
).
.It Fl P Ar port
Use
.Ar port
to identify the device to which the programmer is attached. By
default the
.Pa /dev/ppi0
port is used, but if the programmer type normally connects to the
serial port, the
.Pa /dev/cuaa0
port is the default. If you need to use a different parallel or
serial port, use this option to specify the alternate port name.
.Pp
For the JTAG ICE mkII, if
.Nm
has been configured with libusb support,
.Ar port
can alternatively be specified as
.Ar usb Ns Op \&: Ns Ar serialno .
This will cause
.Nm
to search a JTAG ICE mkII on USB.
If
.Ar serialno
is also specified, it will be matched against the serial number read
from any JTAG ICE mkII found on USB.
The match is done after stripping any existing colons from the given
serial number, and right-to-left, so only the least significant bytes
from the serial number need to be given.
.It Fl q
Disable (or quell) output of the progress bar while reading or writing
to the device. Specify it a second time for even quieter operation.
.It Fl s
Disable safemode prompting. When safemode discovers that one or more
fuse bits have unintentionally changed, it will prompt for
confirmation regarding whether or not it should attempt to recover the
fuse bit(s). Specifying this flag disables the prompt and assumes
that the fuse bit(s) should be recovered without asking for
confirmation first.
.It Fl t
Tells
.Nm
to enter the interactive ``terminal'' mode instead of up- or downloading
files. See below for a detailed description of the terminal mode.
.It Fl u
Disable the safemode fuse bit checks. Safemode is enabled by default
and is intended to prevent unintentional fuse bit changes. When
enabled, safemode will issue a warning if the any fuse bits are found
to be different at program exit than they were when
.Nm
was invoked. Safemode won't alter fuse bits itself, but rather will
prompt for instructions, unless the terminal is non-interactive, in
which case safemode is disabled. See the
.Fl s
option to disable safemode prompting.
.It Xo Fl U Ar memtype Ns
.Ar \&: Ns Ar op Ns
.Ar \&: Ns Ar filename Ns
.Op \&: Ns Ar format
.Xc
Perform a memory operation as indicated. The
.Ar memtype
field specifies the memory type to operate on.
The available memory types are device-dependant, the actual
configuration can be viewed with the
.Cm part
command in terminal mode.
Typically, a device's memory configuration at least contains
the memory types
.Ar flash
and
.Ar eeprom .
All memory types currently known are:
.Bl -tag -width "calibration" -compact
.It calibration
One or more bytes of RC oscillator calibration data.
.It eeprom
The EEPROM of the device.
.It efuse
The extended fuse byte.
.It flash
The flash ROM of the device.
.It fuse
The fuse byte in devices that have only a single fuse byte.
.It hfuse
The high fuse byte.
.It lfuse
The low fuse byte.
.It lock
The lock byte.
.It signature
The three device signature bytes (device ID).
.El
.Pp
The
.Ar op
field specifies what operation to perform:
.Bl -tag -width noreset
.It Ar r
read device memory and write to the specified file
.It Ar w
read data from the specified file and write to the device memory
.It Ar v
read data from both the device and the specified file and perform a verify
.El
.Pp
The
.Ar filename
field indicates the name of the file to read or write.
The
.Ar format
field is optional and contains the format of the file to read or
write.
.It Fl f Ar format
(Deprecated, use
.Fl U
instead.) This option specifies the file format for the input or
output files to be processed.
.Ar Format
can be one of:
.Bl -tag -width sss
@@ -454,13 +283,110 @@ provided at
.Pp
The default is to use auto detection for input files, and raw binary
format for output files.
Note that if
.It Fl F
Normally,
.Nm
tries to verify that the device signature read from the part is
reasonable before continuing. Since it can happen from time to time
that a device has a broken (erased or overwritten) device signature
but is otherwise operating normally, this options is provided to
override the check.
.It Fl i Ar filename
(Deprecated, use
.Fl U
instead.) Specifies the input file to be programmed into the MCU.
Can be specified as
.Ql \&-
to use
.Em stdin
as the input.
.It Fl I Ar data
(Deprecated, use
.Fl U
instead.) Same as specifying
.Fl i
and
.Fl f Ar m
together, i.e., this is a shortcut for using immediate file input mode
where the filename field is used as the data itself. Useful for
programming single byte memories such as fuse bytes without having to
use single byte files or enter interactive terminal mode.
.It Fl m Ar memtype
(Deprecated, use
.Fl U
instead.) Specifies which program area of the MCU to read or write;
allowable values depend on the MCU being programmed, but most support
at least
.Em eeprom
for the EEPROM, and
.Em flash
for the flash ROM. Use the
.Fl v
option on the command line or the
.Ar part
command from terminal mode to display all the memory types supported
by a particular device. The default is
.Em flash .
.It Fl n
No-write - disables actually writing data to the MCU (useful for debugging
.Nm avrdude
).
.It Fl o Ar filename
(Deprecated, use
.Fl U
instead.) Specifies the name of the output file to write, and causes
the respective memory area to be read from the MCU. Can be specified
as
.Ql \&-
to write to
.Em stdout .
.It Fl P Ar port
Use
.Ar port
to identify the device to which the programmer is attached. By
default the
.Pa /dev/ppi0
port is used, but if the programmer type normally connects to the
serial port, the
.Pa /dev/cuaa0
port is the default. If you need to use a different parallel or
serial port, use this option to specify the alternate port name.
.It Fl q
Disable (or quell) output of the progress bar while reading or writing
to the device.
.It Fl t
Tells
.Nm
to enter the interactive ``terminal'' mode instead of up- or downloading
files. See below for a detailed description of the terminal mode.
.It Xo Fl U Ar memtype Ns
.Ar \&: Ns Ar op Ns
.Ar \&: Ns Ar filename Ns
.Op \&: Ns Ar format
.Xc
Perform a memory operation as indicated. The
.Ar memtype
field specifies the memory type to operate on. The
.Ar op
field specifies what operation to perform:
.Bl -tag -width noreset
.It Ar r
read device memory and write to the specified file
.It Ar w
read data from the specified file and write to the device memory
.It Ar v
read data from both the device and the specified file and perform a verify
.El
.Pp
The
.Ar filename
contains a colon, the
field indicates the name of the file to read or write.
The
.Ar format
field is no longer optional since the filename part following the colon
would otherwise be misinterpreted as
.Ar format .
field is optional and contains the format of the file to read or
write. See the
.Fl f
option for possible values.
.It Fl v
Enable verbose output.
.It Fl V
@@ -533,9 +459,7 @@ does not implement the command.
.It Ar sig
Display the device signature bytes.
.It Ar part
Display the current part settings and parameters. Includes chip
specific information including all memory types supported by the
device, read/write timing, etc.
Display the current part settings.
.It Ar vtarg voltage
Set the target's supply voltage to
.Ar voltage
@@ -562,25 +486,9 @@ by 1E3.
.It Ar fosc off
Turn the master oscillator off.
.Em Only supported on the STK500 programmer.
.It Ar sck period
.Em STK500 programmer only:
Set the SCK clock period to
.Ar period
microseconds.
.Pp
.Em JTAG ICE only:
Set the JTAG ICE bit clock period to
.Ar period
microseconds.
Note that unlike STK500 settings, this setting will be reverted to
its default value (approximately 1 microsecond) when the programming
software signs off from the JTAG ICE.
.It Ar parms
.Em STK500 programmer only:
Display the current voltage and master oscillator parameters.
.Pp
.Em JTAG ICE only:
Display the current target supply voltage and JTAG bit clock rate/period.
.Em Only supported on the STK500 programmer.
.It Ar \&?
.It Ar help
Give a short on-line summary of the available commands.
@@ -637,17 +545,4 @@ This man page by
.ie t J\(:org Wunsch.
.el Joerg Wunsch.
.Sh BUGS
Please report bugs via
.Dl "http://savannah.nongnu.org/bugs/?group=avrdude" .
.Pp
The JTAGICE mkII programmer currently cannot write to the flash ROM
one byte at a time.
For that reason, updating the flash ROM from terminal mode does not
work.
.Pp
The device IDs used by AVR910 and AVR109 do not match, so the
avr109 (aka. butterfly) programmer might report
.Dl "selected device is not supported by programmer" .
Use the -F option to force
.Nm
to contiue anway.
Please report bugs to avrdude-dev@nongnu.org.

File diff suppressed because it is too large Load Diff

BIN
avrdude/avrdude.pdf Normal file

Binary file not shown.

View File

@@ -1,537 +0,0 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* $Id$ */
#include <stdlib.h>
#include <string.h>
#include "avrpart.h"
#include "pindefs.h"
extern char * progname;
/***
*** Elementary functions dealing with OPCODE structures
***/
OPCODE * avr_new_opcode(void)
{
OPCODE * m;
m = (OPCODE *)malloc(sizeof(*m));
if (m == NULL) {
fprintf(stderr, "avr_new_opcode(): out of memory\n");
exit(1);
}
memset(m, 0, sizeof(*m));
return m;
}
/*
* avr_set_bits()
*
* Set instruction bits in the specified command based on the opcode.
*/
int avr_set_bits(OPCODE * op, unsigned char * cmd)
{
int i, j, bit;
unsigned char mask;
for (i=0; i<32; i++) {
if (op->bit[i].type == AVR_CMDBIT_VALUE) {
j = 3 - i / 8;
bit = i % 8;
mask = 1 << bit;
if (op->bit[i].value)
cmd[j] = cmd[j] | mask;
else
cmd[j] = cmd[j] & ~mask;
}
}
return 0;
}
/*
* avr_set_addr()
*
* Set address bits in the specified command based on the opcode, and
* the address.
*/
int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr)
{
int i, j, bit;
unsigned long value;
unsigned char mask;
for (i=0; i<32; i++) {
if (op->bit[i].type == AVR_CMDBIT_ADDRESS) {
j = 3 - i / 8;
bit = i % 8;
mask = 1 << bit;
value = addr >> op->bit[i].bitno & 0x01;
if (value)
cmd[j] = cmd[j] | mask;
else
cmd[j] = cmd[j] & ~mask;
}
}
return 0;
}
/*
* avr_set_input()
*
* Set input data bits in the specified command based on the opcode,
* and the data byte.
*/
int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data)
{
int i, j, bit;
unsigned char value;
unsigned char mask;
for (i=0; i<32; i++) {
if (op->bit[i].type == AVR_CMDBIT_INPUT) {
j = 3 - i / 8;
bit = i % 8;
mask = 1 << bit;
value = data >> op->bit[i].bitno & 0x01;
if (value)
cmd[j] = cmd[j] | mask;
else
cmd[j] = cmd[j] & ~mask;
}
}
return 0;
}
/*
* avr_get_output()
*
* Retreive output data bits from the command results based on the
* opcode data.
*/
int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data)
{
int i, j, bit;
unsigned char value;
unsigned char mask;
for (i=0; i<32; i++) {
if (op->bit[i].type == AVR_CMDBIT_OUTPUT) {
j = 3 - i / 8;
bit = i % 8;
mask = 1 << bit;
value = ((res[j] & mask) >> bit) & 0x01;
value = value << op->bit[i].bitno;
if (value)
*data = *data | value;
else
*data = *data & ~value;
}
}
return 0;
}
char * avr_op_str(int op)
{
switch (op) {
case AVR_OP_READ : return "READ"; break;
case AVR_OP_WRITE : return "WRITE"; break;
case AVR_OP_READ_LO : return "READ_LO"; break;
case AVR_OP_READ_HI : return "READ_HI"; break;
case AVR_OP_WRITE_LO : return "WRITE_LO"; break;
case AVR_OP_WRITE_HI : return "WRITE_HI"; break;
case AVR_OP_LOADPAGE_LO : return "LOADPAGE_LO"; break;
case AVR_OP_LOADPAGE_HI : return "LOADPAGE_HI"; break;
case AVR_OP_WRITEPAGE : return "WRITEPAGE"; break;
case AVR_OP_CHIP_ERASE : return "CHIP_ERASE"; break;
case AVR_OP_PGM_ENABLE : return "PGM_ENABLE"; break;
default : return "<unknown opcode>"; break;
}
}
char * bittype(int type)
{
switch (type) {
case AVR_CMDBIT_IGNORE : return "IGNORE"; break;
case AVR_CMDBIT_VALUE : return "VALUE"; break;
case AVR_CMDBIT_ADDRESS : return "ADDRESS"; break;
case AVR_CMDBIT_INPUT : return "INPUT"; break;
case AVR_CMDBIT_OUTPUT : return "OUTPUT"; break;
default : return "<unknown bit type>"; break;
}
}
/***
*** Elementary functions dealing with AVRMEM structures
***/
AVRMEM * avr_new_memtype(void)
{
AVRMEM * m;
m = (AVRMEM *)malloc(sizeof(*m));
if (m == NULL) {
fprintf(stderr, "avr_new_memtype(): out of memory\n");
exit(1);
}
memset(m, 0, sizeof(*m));
return m;
}
/*
* Allocate and initialize memory buffers for each of the device's
* defined memory regions.
*/
int avr_initmem(AVRPART * p)
{
LNODEID ln;
AVRMEM * m;
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
m = ldata(ln);
m->buf = (unsigned char *) malloc(m->size);
if (m->buf == NULL) {
fprintf(stderr, "%s: can't alloc buffer for %s size of %d bytes\n",
progname, m->desc, m->size);
return -1;
}
}
return 0;
}
AVRMEM * avr_dup_mem(AVRMEM * m)
{
AVRMEM * n;
n = avr_new_memtype();
*n = *m;
n->buf = (unsigned char *)malloc(n->size);
if (n->buf == NULL) {
fprintf(stderr,
"avr_dup_mem(): out of memory (memsize=%d)\n",
n->size);
exit(1);
}
memset(n->buf, 0, n->size);
return n;
}
AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
{
AVRMEM * m, * match;
LNODEID ln;
int matches;
int l;
l = strlen(desc);
matches = 0;
match = NULL;
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
m = ldata(ln);
if (strncmp(desc, m->desc, l) == 0) {
match = m;
matches++;
}
}
if (matches == 1)
return match;
return NULL;
}
void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
int verbose)
{
int i, j;
char * optr;
if (m == NULL) {
fprintf(f,
"%s Block Poll Page Polled\n"
"%sMemory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack\n"
"%s----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------\n",
prefix, prefix, prefix);
}
else {
if (verbose > 2) {
fprintf(f,
"%s Block Poll Page Polled\n"
"%sMemory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack\n"
"%s----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------\n",
prefix, prefix, prefix);
}
fprintf(f,
"%s%-11s %4d %5d %5d %4d %-6s %6d %4d %6d %5d %5d 0x%02x 0x%02x\n",
prefix, m->desc, m->mode, m->delay, m->blocksize, m->pollindex,
m->paged ? "yes" : "no",
m->size,
m->page_size,
m->num_pages,
m->min_write_delay,
m->max_write_delay,
m->readback[0],
m->readback[1]);
if (verbose > 2) {
fprintf(stderr,
"%s Memory Ops:\n"
"%s Oeration Inst Bit Bit Type Bitno Value\n"
"%s ----------- -------- -------- ----- -----\n",
prefix, prefix, prefix);
for (i=0; i<AVR_OP_MAX; i++) {
if (m->op[i]) {
for (j=31; j>=0; j--) {
if (j==31)
optr = avr_op_str(i);
else
optr = " ";
fprintf(f,
"%s %-11s %8d %8s %5d %5d\n",
prefix, optr, j,
bittype(m->op[i]->bit[j].type),
m->op[i]->bit[j].bitno,
m->op[i]->bit[j].value);
}
}
}
}
}
}
/*
* Elementary functions dealing with AVRPART structures
*/
AVRPART * avr_new_part(void)
{
AVRPART * p;
p = (AVRPART *)malloc(sizeof(AVRPART));
if (p == NULL) {
fprintf(stderr, "new_part(): out of memory\n");
exit(1);
}
memset(p, 0, sizeof(*p));
p->id[0] = 0;
p->desc[0] = 0;
p->reset_disposition = RESET_DEDICATED;
p->retry_pulse = PIN_AVR_SCK;
p->flags = AVRPART_SERIALOK | AVRPART_PARALLELOK | AVRPART_ENABLEPAGEPROGRAMMING;
p->config_file[0] = 0;
p->lineno = 0;
p->mem = lcreat(NULL, 0);
return p;
}
AVRPART * avr_dup_part(AVRPART * d)
{
AVRPART * p;
LISTID save;
LNODEID ln;
p = avr_new_part();
save = p->mem;
*p = *d;
p->mem = save;
for (ln=lfirst(d->mem); ln; ln=lnext(ln)) {
ladd(p->mem, avr_dup_mem(ldata(ln)));
}
return p;
}
AVRPART * locate_part(LISTID parts, char * partdesc)
{
LNODEID ln1;
AVRPART * p = NULL;
int found;
found = 0;
for (ln1=lfirst(parts); ln1 && !found; ln1=lnext(ln1)) {
p = ldata(ln1);
if ((strcasecmp(partdesc, p->id) == 0) ||
(strcasecmp(partdesc, p->desc) == 0))
found = 1;
}
if (found)
return p;
return NULL;
}
AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode)
{
LNODEID ln1;
AVRPART * p = NULL;
for (ln1=lfirst(parts); ln1; ln1=lnext(ln1)) {
p = ldata(ln1);
if (p->avr910_devcode == devcode)
return p;
}
return NULL;
}
void list_parts(FILE * f, char * prefix, LISTID parts)
{
LNODEID ln1;
AVRPART * p;
for (ln1=lfirst(parts); ln1; ln1=lnext(ln1)) {
p = ldata(ln1);
fprintf(f, "%s%-4s = %-15s [%s:%d]\n",
prefix, p->id, p->desc, p->config_file, p->lineno);
}
return;
}
char * reset_disp_str(int r)
{
switch (r) {
case RESET_DEDICATED : return "dedicated";
case RESET_IO : return "possible i/o";
default : return "<invalid>";
}
}
char * pin_name(int pinno)
{
switch (pinno) {
case PIN_AVR_RESET : return "RESET";
case PIN_AVR_MISO : return "MISO";
case PIN_AVR_MOSI : return "MOSI";
case PIN_AVR_SCK : return "SCK";
default : return "<unknown>";
}
}
void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose)
{
int i;
char * buf;
char * px;
LNODEID ln;
AVRMEM * m;
fprintf(f,
"%sAVR Part : %s\n"
"%sChip Erase delay : %d us\n"
"%sPAGEL : P%02X\n"
"%sBS2 : P%02X\n"
"%sRESET disposition : %s\n"
"%sRETRY pulse : %s\n"
"%sserial program mode : %s\n"
"%sparallel program mode : %s\n"
"%sTimeout : %d\n"
"%sStabDelay : %d\n"
"%sCmdexeDelay : %d\n"
"%sSyncLoops : %d\n"
"%sByteDelay : %d\n"
"%sPollIndex : %d\n"
"%sPollValue : 0x%02x\n"
"%sMemory Detail :\n\n",
prefix, p->desc,
prefix, p->chip_erase_delay,
prefix, p->pagel,
prefix, p->bs2,
prefix, reset_disp_str(p->reset_disposition),
prefix, pin_name(p->retry_pulse),
prefix, (p->flags & AVRPART_SERIALOK) ? "yes" : "no",
prefix, (p->flags & AVRPART_PARALLELOK) ?
((p->flags & AVRPART_PSEUDOPARALLEL) ? "psuedo" : "yes") : "no",
prefix, p->timeout,
prefix, p->stabdelay,
prefix, p->cmdexedelay,
prefix, p->synchloops,
prefix, p->bytedelay,
prefix, p->pollindex,
prefix, p->pollvalue,
prefix);
px = prefix;
i = strlen(prefix) + 5;
buf = (char *)malloc(i);
if (buf == NULL) {
/* ugh, this is not important enough to bail, just ignore it */
}
else {
strcpy(buf, prefix);
strcat(buf, " ");
px = buf;
}
if (verbose <= 2) {
avr_mem_display(px, f, NULL, 0, verbose);
}
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
m = ldata(ln);
avr_mem_display(px, f, m, i, verbose);
}
if (buf)
free(buf);
}

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,9 +26,6 @@
#include "lists.h"
extern LISTID part_list;
/*
* AVR serial programming instructions
*/
@@ -78,9 +75,6 @@ typedef struct opcode {
#define AVRPART_SERIALOK 0x0001 /* part supports serial programming */
#define AVRPART_PARALLELOK 0x0002 /* part supports parallel programming */
#define AVRPART_PSEUDOPARALLEL 0x0004 /* part has pseudo parallel support */
#define AVRPART_HAS_JTAG 0x0008 /* part has a JTAG i/f */
#define AVRPART_ALLOWFULLPAGEBITSTREAM 0x0010 /* JTAG ICE mkII param. */
#define AVRPART_ENABLEPAGEPROGRAMMING 0x0020 /* JTAG ICE mkII param. */
#define AVR_DESCLEN 64
#define AVR_IDLEN 32
@@ -97,22 +91,6 @@ typedef struct avrpart {
this pin (PIN_AVR_*) */
unsigned flags; /* see AVRPART_ masks */
int timeout; /* stk500 v2 xml file parameter */
int stabdelay; /* stk500 v2 xml file parameter */
int cmdexedelay; /* stk500 v2 xml file parameter */
int synchloops; /* stk500 v2 xml file parameter */
int bytedelay; /* stk500 v2 xml file parameter */
int pollindex; /* stk500 v2 xml file parameter */
unsigned char pollvalue; /* stk500 v2 xml file parameter */
int predelay; /* stk500 v2 xml file parameter */
int postdelay; /* stk500 v2 xml file parameter */
int pollmethod; /* stk500 v2 xml file parameter */
unsigned char idr; /* JTAG ICE mkII XML file parameter */
unsigned char rampz; /* JTAG ICE mkII XML file parameter */
unsigned char spmcr; /* JTAG ICE mkII XML file parameter */
unsigned short eecr; /* JTAC ICE mkII XML file parameter */
OPCODE * op[AVR_OP_MAX]; /* opcodes */
LISTID mem; /* avr memory definitions */
@@ -134,38 +112,8 @@ typedef struct avrmem {
back on, see errata
http://www.atmel.com/atmel/acrobat/doc1280.pdf */
unsigned char readback[2]; /* polled read-back values */
int mode; /* stk500 v2 xml file parameter */
int delay; /* stk500 v2 xml file parameter */
int blocksize; /* stk500 v2 xml file parameter */
int readsize; /* stk500 v2 xml file parameter */
int pollindex; /* stk500 v2 xml file parameter */
unsigned char * buf; /* pointer to memory buffer */
OPCODE * op[AVR_OP_MAX]; /* opcodes */
} AVRMEM;
/* Functions for OPCODE structures */
OPCODE * avr_new_opcode(void);
int avr_set_bits(OPCODE * op, unsigned char * cmd);
int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr);
int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data);
int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data);
/* Functions for AVRMEM structures */
AVRMEM * avr_new_memtype(void);
int avr_initmem(AVRPART * p);
AVRMEM * avr_dup_mem(AVRMEM * m);
AVRMEM * avr_locate_mem(AVRPART * p, char * desc);
void avr_mem_display(char * prefix, FILE * f, AVRMEM * m, int type,
int verbose);
/* Functions for AVRPART structures */
AVRPART * avr_new_part(void);
AVRPART * avr_dup_part(AVRPART * d);
AVRPART * locate_part(LISTID parts, char * partdesc);
AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode);
void list_parts(FILE * f, char * prefix, LISTID parts);
void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose);
#endif

View File

@@ -1,280 +0,0 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
*
* 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$ */
#include "ac_cfg.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include "avr.h"
#include "pindefs.h"
#include "pgm.h"
#include "par.h"
#include "serbb.h"
#define SLOW_TOGGLE 0
extern char * progname;
extern int do_cycles;
extern int verbose;
static int bitbang_setpin(PROGRAMMER * pgm, int pin, int value)
{
if ( pgm->flag )
serbb_setpin(pgm->fd,pin,value);
else
par_setpin(pgm->fd,pin,value);
return 0;
}
static int bitbang_getpin(PROGRAMMER * pgm, int pin)
{
if ( pgm->flag )
return serbb_getpin(pgm->fd,pin);
else
return par_getpin(pgm->fd,pin);
}
static int bitbang_highpulsepin(PROGRAMMER * pgm, int pin)
{
if ( pgm->flag )
return serbb_highpulsepin(pgm->fd,pin);
else
return par_highpulsepin(pgm->fd,pin);
}
/*
* transmit and receive a byte of data to/from the AVR device
*/
static unsigned char bitbang_txrx(PROGRAMMER * pgm, unsigned char byte)
{
int i;
unsigned char r, b, rbyte;
rbyte = 0;
for (i=7; i>=0; i--) {
/*
* Write and read one bit on SPI.
* Some notes on timing: Let T be the time it takes to do
* one bitbang_setpin()-call resp. par clrpin()-call, then
* - SCK is high for 2T
* - SCK is low for 2T
* - MOSI setuptime is 1T
* - MOSI holdtime is 3T
* - SCK low to MISO read is 2T to 3T
* So we are within programming specs (expect for AT90S1200),
* if and only if T>t_CLCL (t_CLCL=clock period of target system).
*
* Due to the delay introduced by "IN" and "OUT"-commands,
* T is greater than 1us (more like 2us) on x86-architectures.
* So programming works safely down to 1MHz target clock.
*/
b = (byte >> i) & 0x01;
/* set the data input line as desired */
bitbang_setpin(pgm, pgm->pinno[PIN_AVR_MOSI], b);
bitbang_setpin(pgm, pgm->pinno[PIN_AVR_SCK], 1);
/*
* read the result bit (it is either valid from a previous falling
* edge or it is ignored in the current context)
*/
r = bitbang_getpin(pgm, pgm->pinno[PIN_AVR_MISO]);
bitbang_setpin(pgm, pgm->pinno[PIN_AVR_SCK], 0);
rbyte |= r << i;
}
return rbyte;
}
int bitbang_rdy_led(PROGRAMMER * pgm, int value)
{
bitbang_setpin(pgm, pgm->pinno[PIN_LED_RDY], !value);
return 0;
}
int bitbang_err_led(PROGRAMMER * pgm, int value)
{
bitbang_setpin(pgm, pgm->pinno[PIN_LED_ERR], !value);
return 0;
}
int bitbang_pgm_led(PROGRAMMER * pgm, int value)
{
bitbang_setpin(pgm, pgm->pinno[PIN_LED_PGM], !value);
return 0;
}
int bitbang_vfy_led(PROGRAMMER * pgm, int value)
{
bitbang_setpin(pgm, pgm->pinno[PIN_LED_VFY], !value);
return 0;
}
/*
* transmit an AVR device command and return the results; 'cmd' and
* 'res' must point to at least a 4 byte data buffer
*/
int bitbang_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
unsigned char res[4])
{
int i;
for (i=0; i<4; i++) {
res[i] = bitbang_txrx(pgm, cmd[i]);
}
if(verbose >= 2)
{
fprintf(stderr, "bitbang_cmd(): [ ");
for(i = 0; i < 4; i++)
fprintf(stderr, "%02X ", cmd[i]);
fprintf(stderr, "] [ ");
for(i = 0; i < 4; i++)
{
fprintf(stderr, "%02X ", res[i]);
}
fprintf(stderr, "]\n");
}
return 0;
}
/*
* issue the 'chip erase' command to the AVR device
*/
int bitbang_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
unsigned char cmd[4];
unsigned char res[4];
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
fprintf(stderr, "chip erase instruction not defined for part \"%s\"\n",
p->desc);
return -1;
}
pgm->pgm_led(pgm, ON);
memset(cmd, 0, sizeof(cmd));
avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
pgm->cmd(pgm, cmd, res);
usleep(p->chip_erase_delay);
pgm->initialize(pgm, p);
pgm->pgm_led(pgm, OFF);
return 0;
}
/*
* issue the 'program enable' command to the AVR device
*/
int bitbang_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
unsigned char cmd[4];
unsigned char res[4];
if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
fprintf(stderr, "program enable instruction not defined for part \"%s\"\n",
p->desc);
return -1;
}
memset(cmd, 0, sizeof(cmd));
avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd);
pgm->cmd(pgm, cmd, res);
if (res[2] != cmd[1])
return -2;
return 0;
}
/*
* initialize the AVR device and prepare it to accept commands
*/
int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
{
int rc;
int tries;
pgm->powerup(pgm);
usleep(20000);
bitbang_setpin(pgm, pgm->pinno[PIN_AVR_SCK], 0);
bitbang_setpin(pgm, pgm->pinno[PIN_AVR_RESET], 0);
usleep(20000);
bitbang_highpulsepin(pgm, pgm->pinno[PIN_AVR_RESET]);
usleep(20000); /* 20 ms XXX should be a per-chip parameter */
/*
* Enable programming mode. If we are programming an AT90S1200, we
* can only issue the command and hope it worked. If we are using
* one of the other chips, the chip will echo 0x53 when issuing the
* third byte of the command. In this case, try up to 32 times in
* order to possibly get back into sync with the chip if we are out
* of sync.
*/
if (strcmp(p->desc, "AT90S1200")==0) {
pgm->program_enable(pgm, p);
}
else {
tries = 0;
do {
rc = pgm->program_enable(pgm, p);
if ((rc == 0)||(rc == -1))
break;
bitbang_highpulsepin(pgm, pgm->pinno[p->retry_pulse/*PIN_AVR_SCK*/]);
tries++;
} while (tries < 65);
/*
* can't sync with the device, maybe it's not attached?
*/
if (rc) {
fprintf(stderr, "%s: AVR device not responding\n", progname);
return -1;
}
}
return 0;
}

View File

@@ -1,43 +0,0 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
*
* 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 bitbang_h
#define bitbang_h
int bitbang_setpin(int fd, int pin, int value);
int bitbang_getpin(int fd, int pin);
int bitbang_highpulsepin(int fd, int pin);
int bitbang_rdy_led (PROGRAMMER * pgm, int value);
int bitbang_err_led (PROGRAMMER * pgm, int value);
int bitbang_pgm_led (PROGRAMMER * pgm, int value);
int bitbang_vfy_led (PROGRAMMER * pgm, int value);
int bitbang_cmd (PROGRAMMER * pgm, unsigned char cmd[4],
unsigned char res[4]);
int bitbang_chip_erase (PROGRAMMER * pgm, AVRPART * p);
int bitbang_program_enable (PROGRAMMER * pgm, AVRPART * p);
void bitbang_powerup (PROGRAMMER * pgm);
void bitbang_powerdown (PROGRAMMER * pgm);
int bitbang_initialize (PROGRAMMER * pgm, AVRPART * p);
void bitbang_disable (PROGRAMMER * pgm);
void bitbang_enable (PROGRAMMER * pgm);
#endif

View File

@@ -1,11 +1,11 @@
#! /bin/sh
# autoconf-2.59 is required
# autoconf-2.57 is required
: ${AUTOHEADER="autoheader${AC_VER}"}
: ${AUTOCONF="autoconf${AC_VER}"}
# automake-1.9.x is required
# automake-1.7.x is required
: ${ACLOCAL="aclocal${AM_VER}"}
: ${AUTOMAKE="automake${AM_VER}"}
@@ -14,9 +14,9 @@
AUTOCONF_VER=`(${AUTOCONF} --version 2>/dev/null | head -n 1 | \
cut -d ' ' -f 4) 2>/dev/null`
if [ "$AUTOCONF_VER" != "2.59" ]
if [ "$AUTOCONF_VER" != "2.57" ]
then
echo "You need to use autoconf version 2.59."
echo "You need to use autoconf version 2.57."
echo "You are using `${AUTOCONF} --version | head -n 1`."
exit 1
fi
@@ -25,9 +25,9 @@ fi
AUTOMAKE_VER=`(${AUTOMAKE} --version | head -n 1 | \
cut -d ' ' -f 4 | cut -d '.' -f -2) 2>/dev/null`
if [ "$AUTOMAKE_VER" != "1.9" ]
if [ "$AUTOMAKE_VER" != "1.7" ]
then
echo "You need to use automake version 1.9."
echo "You need to use automake version 1.7 (preferrably 1.7.3)."
echo "You are using `${AUTOMAKE} --version | head -n 1`."
exit 1
fi
@@ -38,8 +38,6 @@ export ACLOCAL AUTOHEADER AUTOCONF AUTOMAKE
set -x
rm -rf autom4te.cache
${ACLOCAL}
${AUTOHEADER}
${AUTOCONF}

View File

@@ -1,693 +0,0 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
* Copyright (C) 2005 Joerg Wunsch <j@uriah.heep.sax.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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 the serial programming mode of the Atmel butterfly
* evaluation board. This board features a bootloader which uses a protocol
* very similar, but not identical, to the one described in application note
* avr910.
*
* Actually, the butterfly uses a predecessor of the avr910 protocol
* which is described in application notes avr109 (generic AVR
* bootloader) and avr911 (opensource programmer). This file now
* fully handles the features present in avr109. It should probably
* be renamed to avr109, but we rather stick with the old name inside
* the file. We'll provide aliases for "avr109" and "avr911" in
* avrdude.conf so users could call it by these name as well.
*/
#include "ac_cfg.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "avr.h"
#include "pgm.h"
#include "butterfly.h"
#include "serial.h"
extern char * progname;
extern int do_cycles;
static char has_auto_incr_addr;
static unsigned buffersize = 0;
/* These two defines are only for debugging. Will remove them once it starts
working. */
#define show_func_info() \
fprintf(stderr, "%s: line %d: called %s()\n", \
__FILE__, __LINE__, __FUNCTION__)
#define no_show_func_info()
static int butterfly_send(PROGRAMMER * pgm, char * buf, size_t len)
{
no_show_func_info();
return serial_send(pgm->fd, (unsigned char *)buf, len);
}
static int butterfly_recv(PROGRAMMER * pgm, char * buf, size_t len)
{
int rv;
no_show_func_info();
rv = serial_recv(pgm->fd, (unsigned char *)buf, len);
if (rv < 0) {
fprintf(stderr,
"%s: butterfly_recv(): programmer is not responding\n",
progname);
exit(1);
}
return 0;
}
static int butterfly_drain(PROGRAMMER * pgm, int display)
{
no_show_func_info();
return serial_drain(pgm->fd, display);
}
static void butterfly_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
{
char c;
butterfly_recv(pgm, &c, 1);
if (c != '\r') {
fprintf(stderr, "%s: error: programmer did not respond to command: %s\n",
progname, errmsg);
exit(1);
}
}
static int butterfly_rdy_led(PROGRAMMER * pgm, int value)
{
no_show_func_info();
/* Do nothing. */
return 0;
}
static int butterfly_err_led(PROGRAMMER * pgm, int value)
{
no_show_func_info();
/* Do nothing. */
return 0;
}
static int butterfly_pgm_led(PROGRAMMER * pgm, int value)
{
no_show_func_info();
/* Do nothing. */
return 0;
}
static int butterfly_vfy_led(PROGRAMMER * pgm, int value)
{
no_show_func_info();
/* Do nothing. */
return 0;
}
/*
* issue the 'chip erase' command to the butterfly board
*/
static int butterfly_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
no_show_func_info();
butterfly_send(pgm, "e", 1);
butterfly_vfy_cmd_sent(pgm, "chip erase");
return 0;
}
static void butterfly_enter_prog_mode(PROGRAMMER * pgm)
{
butterfly_send(pgm, "P", 1);
butterfly_vfy_cmd_sent(pgm, "enter prog mode");
}
static void butterfly_leave_prog_mode(PROGRAMMER * pgm)
{
butterfly_send(pgm, "L", 1);
butterfly_vfy_cmd_sent(pgm, "leave prog mode");
}
/*
* issue the 'program enable' command to the AVR device
*/
static int butterfly_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
no_show_func_info();
return -1;
}
/*
* apply power to the AVR processor
*/
static void butterfly_powerup(PROGRAMMER * pgm)
{
no_show_func_info();
/* Do nothing. */
return;
}
/*
* remove power from the AVR processor
*/
static void butterfly_powerdown(PROGRAMMER * pgm)
{
no_show_func_info();
/* Do nothing. */
return;
}
/*
* initialize the AVR device and prepare it to accept commands
*/
static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
{
char id[8];
char sw[2];
char hw[2];
char buf[10];
char type;
char c;
int dev_supported = 0;
no_show_func_info();
/*
* Send some ESC to activate butterfly bootloader. This is not needed
* for plain avr109 bootloaders but does not harm there either.
*/
fprintf(stderr, "Connecting to programmer: ");
do {
putc('.', stderr);
butterfly_send(pgm, "\033", 1);
butterfly_drain(pgm, 0);
butterfly_send(pgm, "S", 1);
butterfly_recv(pgm, &c, 1);
if (c != '?') {
putc('\n', stderr);
/*
* Got a useful response, continue getting the programmer
* identifier. Programmer returns exactly 7 chars _without_
* the null.
*/
id[0] = c;
butterfly_recv(pgm, &id[1], sizeof(id)-2);
id[sizeof(id)-1] = '\0';
}
} while (c == '?');
/* Get the HW and SW versions to see if the programmer is present. */
butterfly_send(pgm, "V", 1);
butterfly_recv(pgm, sw, sizeof(sw));
butterfly_send(pgm, "v", 1);
butterfly_recv(pgm, hw, 1); /* first, read only _one_ byte */
if (hw[0]!='?') {
butterfly_recv(pgm, &hw[1], 1);/* now, read second byte */
};
/* Get the programmer type (serial or parallel). Expect serial. */
butterfly_send(pgm, "p", 1);
butterfly_recv(pgm, &type, 1);
fprintf(stderr, "Found programmer: Id = \"%s\"; type = %c\n", id, type);
fprintf(stderr, " Software Version = %c.%c; ", sw[0], sw[1]);
if (hw[0]=='?') {
fprintf(stderr, "No Hardware Version given.\n");
} else {
fprintf(stderr, "Hardware Version = %c.%c\n", hw[0], hw[1]);
};
/* See if programmer supports autoincrement of address. */
butterfly_send(pgm, "a", 1);
butterfly_recv(pgm, &has_auto_incr_addr, 1);
if (has_auto_incr_addr == 'Y')
fprintf(stderr, "Programmer supports auto addr increment.\n");
/* Check support for buffered memory access, abort if not available */
butterfly_send(pgm, "b", 1);
butterfly_recv(pgm, &c, 1);
if (c != 'Y') {
fprintf(stderr,
"%s: error: buffered memory access not supported. Maybe it isn't\n"\
"a butterfly/AVR109 but a AVR910 device?\n", progname);
exit(1);
};
butterfly_recv(pgm, &c, 1);
buffersize = c<<8;
butterfly_recv(pgm, &c, 1);
buffersize += c;
fprintf(stderr,
"Programmer supports buffered memory access with buffersize=%i bytes.\n",
buffersize);
/* Get list of devices that the programmer supports. */
butterfly_send(pgm, "t", 1);
fprintf(stderr, "\nProgrammer supports the following devices:\n");
while (1) {
butterfly_recv(pgm, &c, 1);
if (c == 0)
break;
fprintf(stderr, " Device code: 0x%02x\n", (unsigned int)(unsigned char)c);
/* FIXME: Need to lookup devcode and report the device. */
if (p->avr910_devcode == (int)(unsigned char)c)
dev_supported = 1;
};
fprintf(stderr,"\n");
if (!dev_supported) {
/* FIXME: if nothing matched, we should rather compare the device
signatures. */
fprintf(stderr,
"%s: error: selected device is not supported by programmer: %s\n",
progname, p->id);
}
/* Tell the programmer which part we selected. */
buf[0] = 'T';
buf[1] = p->avr910_devcode;
butterfly_send(pgm, buf, 2);
butterfly_vfy_cmd_sent(pgm, "select device");
if (dev_supported)
butterfly_enter_prog_mode(pgm);
return dev_supported? 0: -1;
}
static void butterfly_disable(PROGRAMMER * pgm)
{
no_show_func_info();
butterfly_leave_prog_mode(pgm);
return;
}
static void butterfly_enable(PROGRAMMER * pgm)
{
no_show_func_info();
return;
}
static int butterfly_open(PROGRAMMER * pgm, char * port)
{
no_show_func_info();
strcpy(pgm->port, port);
/*
* If baudrate was not specified use 19200 Baud
*/
if(pgm->baudrate == 0) {
pgm->baudrate = 19200;
}
pgm->fd = serial_open(port, pgm->baudrate);
/*
* drain any extraneous input
*/
butterfly_drain (pgm, 0);
return 0;
}
static void butterfly_close(PROGRAMMER * pgm)
{
no_show_func_info();
/* "exit programmer" added by Martin Thomas 2/2004 */
butterfly_send(pgm, "E", 1);
serial_close(pgm->fd);
pgm->fd = -1;
}
static void butterfly_display(PROGRAMMER * pgm, char * p)
{
no_show_func_info();
return;
}
static void butterfly_set_addr(PROGRAMMER * pgm, unsigned long addr)
{
char cmd[3];
cmd[0] = 'A';
cmd[1] = (addr >> 8) & 0xff;
cmd[2] = addr & 0xff;
butterfly_send(pgm, cmd, sizeof(cmd));
butterfly_vfy_cmd_sent(pgm, "set addr");
}
static int butterfly_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned long addr, unsigned char value)
{
char cmd[6];
int size;
no_show_func_info();
if ((strcmp(m->desc, "flash") == 0) || (strcmp(m->desc, "eeprom") == 0))
{
cmd[0] = 'B';
cmd[1] = 0;
if ((cmd[3] = toupper(m->desc[0])) == 'E') { /* write to eeprom */
cmd[2] = 1;
cmd[4] = value;
size = 5;
} else { /* write to flash */
/* @@@ not yet implemented */
cmd[2] = 2;
size = 6;
return -1;
}
butterfly_set_addr(pgm, addr);
}
else if (strcmp(m->desc, "lock") == 0)
{
cmd[0] = 'l';
cmd[1] = value;
size = 2;
}
else
return -1;
butterfly_send(pgm, cmd, size);
butterfly_vfy_cmd_sent(pgm, "write byte");
return 0;
}
static int butterfly_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned long addr, unsigned char * value)
{
static int cached = 0;
static unsigned char cvalue;
static unsigned long caddr;
if (cached && ((caddr + 1) == addr)) {
*value = cvalue;
cached = 0;
}
else {
char buf[2];
butterfly_set_addr(pgm, addr >> 1);
butterfly_send(pgm, "g\000\002F", 4);
/* Read back the program mem word (MSB first) */
butterfly_recv(pgm, buf, sizeof(buf));
if ((addr & 0x01) == 0) {
*value = buf[1];
cached = 1;
cvalue = buf[0];
caddr = addr;
}
else {
*value = buf[0];
}
}
return 0;
}
static int butterfly_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned long addr, unsigned char * value)
{
butterfly_set_addr(pgm, addr);
butterfly_send(pgm, "g\000\001E", 4);
butterfly_recv(pgm, (char *)value, 1);
return 0;
}
static int butterfly_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned long addr, unsigned char * value)
{
char cmd;
no_show_func_info();
if (strcmp(m->desc, "flash") == 0) {
return butterfly_read_byte_flash(pgm, p, m, addr, value);
}
if (strcmp(m->desc, "eeprom") == 0) {
return butterfly_read_byte_eeprom(pgm, p, m, addr, value);
}
if (strcmp(m->desc, "lfuse") == 0) {
cmd = 'F';
}
else if (strcmp(m->desc, "hfuse") == 0) {
cmd = 'N';
}
else if (strcmp(m->desc, "efuse") == 0) {
cmd = 'Q';
}
else if (strcmp(m->desc, "lock") == 0) {
cmd = 'r';
}
else
return -1;
butterfly_send(pgm, &cmd, 1);
butterfly_recv(pgm, (char *)value, 1);
return *value == '?'? -1: 0;
}
static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes)
{
unsigned int addr = 0;
unsigned int max_addr = n_bytes;
char *cmd;
unsigned int blocksize = buffersize;
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
return -2;
if (m->desc[0] == 'e')
blocksize = 1; /* Write to eeprom single bytes only */
butterfly_set_addr(pgm, addr);
#if 0
usleep(1000000);
butterfly_send(pgm, "y", 1);
butterfly_vfy_cmd_sent(pgm, "clear LED");
#endif
cmd = malloc(4+blocksize);
if (!cmd) return -1;
cmd[0] = 'B';
cmd[3] = toupper(m->desc[0]);
while (addr < max_addr) {
if ((max_addr - addr) < blocksize) {
blocksize = max_addr - addr;
};
memcpy(&cmd[4], &m->buf[addr], blocksize);
cmd[1] = (blocksize >> 8) & 0xff;
cmd[2] = blocksize & 0xff;
butterfly_send(pgm, cmd, 4+blocksize);
butterfly_vfy_cmd_sent(pgm, "write block");
addr += blocksize;
report_progress (addr, max_addr, NULL);
} /* while */
free(cmd);
return addr;
}
static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes)
{
unsigned int addr = 0;
unsigned int max_addr = n_bytes;
int rd_size = 1;
/* check parameter syntax: only "flash" or "eeprom" is allowed */
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
return -2;
{ /* use buffered mode */
char cmd[4];
int blocksize = buffersize;
cmd[0] = 'g';
cmd[3] = toupper(m->desc[0]);
butterfly_set_addr(pgm, addr);
while (addr < max_addr) {
if ((max_addr - addr) < blocksize) {
blocksize = max_addr - addr;
};
cmd[1] = (blocksize >> 8) & 0xff;
cmd[2] = blocksize & 0xff;
butterfly_send(pgm, cmd, 4);
butterfly_recv(pgm, (char *)&m->buf[addr], blocksize);
addr += blocksize;
report_progress (addr, max_addr, NULL);
} /* while */
}
return addr * rd_size;
}
/* Signature byte reads are always 3 bytes. */
static int butterfly_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
{
unsigned char tmp;
no_show_func_info();
if (m->size < 3) {
fprintf(stderr, "%s: memsize too small for sig byte read", progname);
return -1;
}
butterfly_send(pgm, "s", 1);
butterfly_recv(pgm, (char *)m->buf, 3);
/* Returned signature has wrong order. */
tmp = m->buf[2];
m->buf[2] = m->buf[0];
m->buf[0] = tmp;
return 3;
}
void butterfly_initpgm(PROGRAMMER * pgm)
{
no_show_func_info();
strcpy(pgm->type, "avr910");
/*
* mandatory functions
*/
pgm->rdy_led = butterfly_rdy_led;
pgm->err_led = butterfly_err_led;
pgm->pgm_led = butterfly_pgm_led;
pgm->vfy_led = butterfly_vfy_led;
pgm->initialize = butterfly_initialize;
pgm->display = butterfly_display;
pgm->enable = butterfly_enable;
pgm->disable = butterfly_disable;
pgm->powerup = butterfly_powerup;
pgm->powerdown = butterfly_powerdown;
pgm->program_enable = butterfly_program_enable;
pgm->chip_erase = butterfly_chip_erase;
/* pgm->cmd not supported, use default error message */
pgm->open = butterfly_open;
pgm->close = butterfly_close;
/*
* optional functions
*/
pgm->write_byte = butterfly_write_byte;
pgm->read_byte = butterfly_read_byte;
pgm->paged_write = butterfly_paged_write;
pgm->paged_load = butterfly_paged_load;
pgm->read_sig_bytes = butterfly_read_sig_bytes;
}

View File

@@ -1,27 +0,0 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
*
* 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 __butterfly_h__
#define __butterfly_h__
void butterfly_initpgm (PROGRAMMER * pgm);
#endif /* __butterfly_h__ */

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -47,6 +47,8 @@ extern FILE * yyin;
extern PROGRAMMER * current_prog;
extern AVRPART * current_part;
extern AVRMEM * current_mem;
extern LISTID programmers;
extern LISTID part_list;
extern int lineno;
extern char * infile;
extern LISTID string_list;

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,28 +29,19 @@
#include "config.h"
#include "lists.h"
#include "par.h"
#include "serbb.h"
#include "pindefs.h"
#include "ppi.h"
#include "pgm.h"
#include "stk500.h"
#include "stk500v2.h"
#include "avr910.h"
#include "butterfly.h"
#include "avr.h"
#include "jtagmkII.h"
#if defined(WIN32NATIVE)
#define strtok_r( _s, _sep, _lasts ) \
( *(_lasts) = strtok( (_s), (_sep) ) )
#endif
extern char * progname;
int yylex(void);
int yyerror(char * errmsg);
static int assign_pin(int pinno, TOKEN * v, int invert);
static int assign_pin(int pinno, TOKEN * v);
static int which_opcode(TOKEN * opcode);
static int parse_cmdbits(OPCODE * op);
@@ -73,7 +64,6 @@ static int parse_cmdbits(OPCODE * op);
%token K_PAGE_SIZE
%token K_PAGED
%token K_BAUDRATE
%token K_BS2
%token K_BUFF
%token K_CHIP_ERASE_DELAY
@@ -90,7 +80,6 @@ static int parse_cmdbits(OPCODE * op);
%token K_FLASH
%token K_ID
%token K_IO
%token K_JTAG_MKII
%token K_LOADPAGE
%token K_MAX_WRITE_DELAY
%token K_MIN_WRITE_DELAY
@@ -111,14 +100,11 @@ static int parse_cmdbits(OPCODE * op);
%token K_READMEM
%token K_RESET
%token K_RETRY_PULSE
%token K_SERBB
%token K_SERIAL
%token K_SCK
%token K_SIZE
%token K_STK500
%token K_STK500V2
%token K_AVR910
%token K_BUTTERFLY
%token K_TYPE
%token K_VCC
%token K_VFYLED
@@ -127,41 +113,9 @@ static int parse_cmdbits(OPCODE * op);
%token K_NO
%token K_YES
/* stk500 v2 xml file parameters */
%token K_TIMEOUT
%token K_STABDELAY
%token K_CMDEXEDELAY
%token K_SYNCHLOOPS
%token K_BYTEDELAY
%token K_POLLVALUE
%token K_POLLINDEX
%token K_PREDELAY
%token K_POSTDELAY
%token K_POLLMETHOD
%token K_MODE
%token K_DELAY
%token K_BLOCKSIZE
%token K_READSIZE
/* JTAG ICE mkII specific parameters */
%token K_ALLOWFULLPAGEBITSTREAM /*
* Internal parameter for the JTAG
* ICE; describes the internal JTAG
* streaming behaviour inside the MCU.
* 1 for all older chips, 0 for newer
* MCUs.
*/
%token K_ENABLEPAGEPROGRAMMING /* ? yes for mega256*, mega406 */
%token K_HAS_JTAG /* MCU has JTAG i/f. */
%token K_IDR /* address of OCD register in IO space */
%token K_RAMPZ /* address of RAMPZ reg. in IO space */
%token K_SPMCR /* address of SPMC[S]R in memory space */
%token K_EECR /* address of EECR in memory space */
%token TKN_COMMA
%token TKN_EQUAL
%token TKN_SEMI
%token TKN_TILDE
%token TKN_NUMBER
%token TKN_STRING
%token TKN_ID
@@ -328,42 +282,18 @@ prog_parm :
}
} |
K_TYPE TKN_EQUAL K_SERBB {
{
serbb_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_STK500 {
{
stk500_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_STK500V2 {
{
stk500v2_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_AVR910 {
{
avr910_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_BUTTERFLY {
{
butterfly_initpgm(current_prog);
}
} |
K_TYPE TKN_EQUAL K_JTAG_MKII {
{
jtagmkII_initpgm(current_prog);
}
} |
K_DESC TKN_EQUAL TKN_STRING {
strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN);
current_prog->desc[PGM_DESCLEN-1] = 0;
@@ -420,33 +350,16 @@ prog_parm :
}
} |
K_BAUDRATE TKN_EQUAL TKN_NUMBER {
{
current_prog->baudrate = $3->value.number;
}
} |
K_RESET TKN_EQUAL TKN_NUMBER { free_token($1);
assign_pin(PIN_AVR_RESET, $3, 0); } |
assign_pin(PIN_AVR_RESET, $3); } |
K_SCK TKN_EQUAL TKN_NUMBER { free_token($1);
assign_pin(PIN_AVR_SCK, $3, 0); } |
K_MOSI TKN_EQUAL TKN_NUMBER { assign_pin(PIN_AVR_MOSI, $3, 0); } |
K_MISO TKN_EQUAL TKN_NUMBER { assign_pin(PIN_AVR_MISO, $3, 0); } |
K_ERRLED TKN_EQUAL TKN_NUMBER { assign_pin(PIN_LED_ERR, $3, 0); } |
K_RDYLED TKN_EQUAL TKN_NUMBER { assign_pin(PIN_LED_RDY, $3, 0); } |
K_PGMLED TKN_EQUAL TKN_NUMBER { assign_pin(PIN_LED_PGM, $3, 0); } |
K_VFYLED TKN_EQUAL TKN_NUMBER { assign_pin(PIN_LED_VFY, $3, 0); } |
K_RESET TKN_EQUAL TKN_TILDE TKN_NUMBER { free_token($1);
assign_pin(PIN_AVR_RESET, $4, 1); } |
K_SCK TKN_EQUAL TKN_TILDE TKN_NUMBER { free_token($1);
assign_pin(PIN_AVR_SCK, $4, 1); } |
K_MOSI TKN_EQUAL TKN_TILDE TKN_NUMBER { assign_pin(PIN_AVR_MOSI, $4, 1); } |
K_MISO TKN_EQUAL TKN_TILDE TKN_NUMBER { assign_pin(PIN_AVR_MISO, $4, 1); } |
K_ERRLED TKN_EQUAL TKN_TILDE TKN_NUMBER { assign_pin(PIN_LED_ERR, $4, 1); } |
K_RDYLED TKN_EQUAL TKN_TILDE TKN_NUMBER { assign_pin(PIN_LED_RDY, $4, 1); } |
K_PGMLED TKN_EQUAL TKN_TILDE TKN_NUMBER { assign_pin(PIN_LED_PGM, $4, 1); } |
K_VFYLED TKN_EQUAL TKN_TILDE TKN_NUMBER { assign_pin(PIN_LED_VFY, $4, 1); }
assign_pin(PIN_AVR_SCK, $3); } |
K_MOSI TKN_EQUAL TKN_NUMBER { assign_pin(PIN_AVR_MOSI, $3); } |
K_MISO TKN_EQUAL TKN_NUMBER { assign_pin(PIN_AVR_MISO, $3); } |
K_ERRLED TKN_EQUAL TKN_NUMBER { assign_pin(PIN_LED_ERR, $3); } |
K_RDYLED TKN_EQUAL TKN_NUMBER { assign_pin(PIN_LED_RDY, $3); } |
K_PGMLED TKN_EQUAL TKN_NUMBER { assign_pin(PIN_LED_PGM, $3); } |
K_VFYLED TKN_EQUAL TKN_NUMBER { assign_pin(PIN_LED_VFY, $3); }
;
@@ -550,120 +463,6 @@ part_parm :
free_tokens(2, $1, $3);
} |
K_TIMEOUT TKN_EQUAL TKN_NUMBER
{
current_part->timeout = $3->value.number;
free_token($3);
} |
K_STABDELAY TKN_EQUAL TKN_NUMBER
{
current_part->stabdelay = $3->value.number;
free_token($3);
} |
K_CMDEXEDELAY TKN_EQUAL TKN_NUMBER
{
current_part->cmdexedelay = $3->value.number;
free_token($3);
} |
K_SYNCHLOOPS TKN_EQUAL TKN_NUMBER
{
current_part->synchloops = $3->value.number;
free_token($3);
} |
K_BYTEDELAY TKN_EQUAL TKN_NUMBER
{
current_part->bytedelay = $3->value.number;
free_token($3);
} |
K_POLLVALUE TKN_EQUAL TKN_NUMBER
{
current_part->pollvalue = $3->value.number;
free_token($3);
} |
K_POLLINDEX TKN_EQUAL TKN_NUMBER
{
current_part->pollindex = $3->value.number;
free_token($3);
} |
K_PREDELAY TKN_EQUAL TKN_NUMBER
{
current_part->predelay = $3->value.number;
free_token($3);
} |
K_POSTDELAY TKN_EQUAL TKN_NUMBER
{
current_part->postdelay = $3->value.number;
free_token($3);
} |
K_POLLMETHOD TKN_EQUAL TKN_NUMBER
{
current_part->pollmethod = $3->value.number;
free_token($3);
} |
K_HAS_JTAG TKN_EQUAL yesno
{
if ($3->primary == K_YES)
current_part->flags |= AVRPART_HAS_JTAG;
else if ($3->primary == K_NO)
current_part->flags &= ~AVRPART_HAS_JTAG;
free_token($3);
} |
K_ALLOWFULLPAGEBITSTREAM TKN_EQUAL yesno
{
if ($3->primary == K_YES)
current_part->flags |= AVRPART_ALLOWFULLPAGEBITSTREAM;
else if ($3->primary == K_NO)
current_part->flags &= ~AVRPART_ALLOWFULLPAGEBITSTREAM;
free_token($3);
} |
K_ENABLEPAGEPROGRAMMING TKN_EQUAL yesno
{
if ($3->primary == K_YES)
current_part->flags |= AVRPART_ENABLEPAGEPROGRAMMING;
else if ($3->primary == K_NO)
current_part->flags &= ~AVRPART_ENABLEPAGEPROGRAMMING;
free_token($3);
} |
K_IDR TKN_EQUAL TKN_NUMBER
{
current_part->idr = $3->value.number;
free_token($3);
} |
K_RAMPZ TKN_EQUAL TKN_NUMBER
{
current_part->rampz = $3->value.number;
free_token($3);
} |
K_SPMCR TKN_EQUAL TKN_NUMBER
{
current_part->spmcr = $3->value.number;
free_token($3);
} |
K_EECR TKN_EQUAL TKN_NUMBER
{
current_part->eecr = $3->value.number;
free_token($3);
} |
K_SERIAL TKN_EQUAL yesno
{
if ($3->primary == K_YES)
@@ -811,38 +610,6 @@ mem_spec :
free_token($3);
} |
K_MODE TKN_EQUAL TKN_NUMBER
{
current_mem->mode = $3->value.number;
free_token($3);
} |
K_DELAY TKN_EQUAL TKN_NUMBER
{
current_mem->delay = $3->value.number;
free_token($3);
} |
K_BLOCKSIZE TKN_EQUAL TKN_NUMBER
{
current_mem->blocksize = $3->value.number;
free_token($3);
} |
K_READSIZE TKN_EQUAL TKN_NUMBER
{
current_mem->readsize = $3->value.number;
free_token($3);
} |
K_POLLINDEX TKN_EQUAL TKN_NUMBER
{
current_mem->pollindex = $3->value.number;
free_token($3);
} |
opcode TKN_EQUAL string_list {
{
int opnum;
@@ -874,7 +641,7 @@ static char * vtypestr(int type)
#endif
static int assign_pin(int pinno, TOKEN * v, int invert)
static int assign_pin(int pinno, TOKEN * v)
{
int value;
@@ -887,8 +654,6 @@ static int assign_pin(int pinno, TOKEN * v, int invert)
progname, lineno, infile);
exit(1);
}
if (invert)
value |= PIN_INVERSE;
current_prog->pinno[pinno] = value;

View File

@@ -1,6 +1,6 @@
#
# avrdude - A Downloader/Uploader for AVR device programmers
# Copyright (C) 2003, 2004 Theodore A. Roth <troth@openavr.org>
# Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
#
# 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
@@ -24,7 +24,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57)
AC_INIT(avrdude, 5.0, avrdude-dev@nongnu.org)
AC_INIT(avrdude, 4.2.0, avrdude-dev@nongnu.org)
AC_CANONICAL_BUILD
AC_CANONICAL_HOST
@@ -44,9 +44,6 @@ AM_PROG_LEX
AC_CHECK_LIB([termcap], [tputs])
AC_CHECK_LIB([ncurses], [tputs])
AC_CHECK_LIB([readline], [readline])
# usb_get_string_simple is only available in recent enough
# versions of libusb, so use that as a decision base.
AC_CHECK_LIB([usb], [usb_get_string_simple])
# Checks for header files.
AC_HEADER_STDC
@@ -81,32 +78,7 @@ else
DOC_INST_DIR='$(DESTDIR)$(datadir)/doc/avrdude'
fi
AC_ARG_ENABLE(
[doc],
AC_HELP_STRING(
[--enable-doc],
[Enable building documents(default)]),
[case "${enableval}" in
yes) enabled_doc=yes ;;
no) enabled_doc=no ;;
*) AC_MSG_ERROR(bad value ${enableval} for disable-doc option) ;;
esac],
[enabled_doc=no])
if test "$enabled_doc" = "yes"; then
SUBDIRS_AC='doc @WINDOWS_DIRS@'
DIST_SUBDIRS_AC='doc windows'
else
SUBDIRS_AC='@WINDOWS_DIRS@'
DIST_SUBDIRS_AC='windows'
fi
AC_SUBST(DOC_INST_DIR, $DOC_INST_DIR)
AC_SUBST(SUBDIRS_AC, $SUBDIRS_AC)
AC_SUBST(DIST_SUBDIRS_AC, $DIST_SUBDIRS_AC)
# Find the parallel serial device files based on target system
# If a system doesn't have a PC style parallel, mark it as unknown.
@@ -149,8 +121,6 @@ AC_SUBST(DEFAULT_SER_PORT, $DEFAULT_SER_PORT)
case $target in
*-*-mingw32* | *-*-cygwin* | *-*-windows*)
WINDOWS_DIRS="windows"
CFLAGS="-mno-cygwin -DWIN32NATIVE"
LDFLAGS="-static"
;;
esac
AC_SUBST(WINDOWS_DIRS,$WINDOWS_DIRS)
@@ -161,16 +131,11 @@ if test "$GCC" = yes; then
fi
AC_SUBST(ENABLE_WARNINGS,$ENABLE_WARNINGS)
if test "$enabled_doc" = "yes"; then
AC_CONFIG_FILES([doc/Makefile])
fi
AC_CONFIG_FILES([
windows/Makefile
avrdude.spec
avrdude.conf
Makefile
doc/Makefile
windows/Makefile
avrdude.spec
avrdude.conf
Makefile
])
AC_OUTPUT

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003-2004 Eric B. Weddington <eric@ecentral.com>
* Copyright (C) 2003 Eric B. Weddington <eric@ecentral.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
#if defined(WIN32NATIVE)
#if defined(__CYGWIN__)
#include <limits.h>
#include <windows.h>

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003-2004 Eric B. Weddington <eric@ecentral.com>
* Copyright (C) 2003 Eric B. Weddington <eric@ecentral.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
#if defined(WIN32NATIVE)
#if defined(__CYGWIN__)
#ifndef __confwin_h__
#define __confwin_h__

View File

@@ -1,83 +0,0 @@
/*
* Derived from CRC algorithm for JTAG ICE mkII, published in Atmel
* Appnote AVR067. Converted from C++ to C.
*/
#include "crc16.h"
/* CRC16 Definitions */
const unsigned short crc_table[256] = {
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};
/* CRC calculation macros */
#define CRC_INIT 0xFFFF
#define CRC(crcval,newchar) crcval = (crcval >> 8) ^ \
crc_table[(crcval ^ newchar) & 0x00ff]
unsigned short
crcsum(const unsigned char* message, unsigned long length,
unsigned short crc)
{
unsigned long i;
for(i = 0; i < length; i++)
{
CRC(crc, message[i]);
}
return crc;
}
int
crcverify(const unsigned char* message, unsigned long length)
{
/*
* Returns true if the last two bytes in a message is the crc of the
* preceding bytes.
*/
unsigned short expected;
expected = crcsum(message, length - 2, CRC_INIT);
return (expected & 0xff) == message[length - 2] &&
((expected >> 8) & 0xff) == message[length - 1];
}
void
crcappend(unsigned char* message, unsigned long length)
{
unsigned long crc;
crc = crcsum(message, length, CRC_INIT);
message[length] = (unsigned char)(crc & 0xff);
message[length+1] = (unsigned char)((crc >> 8) & 0xff);
}

View File

@@ -1,25 +0,0 @@
#ifndef CRC16_H
#define CRC16_H
/*
* Derived from CRC algorithm for JTAG ICE mkII, published in Atmel
* Appnote AVR067. Converted from C++ to C.
*/
extern unsigned short crcsum(const unsigned char* message,
unsigned long length,
unsigned short crc);
/*
* Verify that the last two bytes is a (LSB first) valid CRC of the
* message.
*/
extern int crcverify(const unsigned char* message,
unsigned long length);
/*
* Append a two byte CRC (LSB first) to message. length is size of
* message excluding crc. Space for the CRC bytes must be allocated
* in advance!
*/
extern void crcappend(unsigned char* message,
unsigned long length);
#endif

View File

@@ -29,16 +29,10 @@ info_TEXINFOS = avrdude.texi
all-local: info html ps pdf
html: avrdude-html/avrdude.html
avrdude-html/avrdude.html: $(srcdir)/$(info_TEXINFOS)
html:
mkdir -p avrdude-html
texi2html -split_node $(srcdir)/$(info_TEXINFOS)
if [ -e ./avrdude.html -o -e ./avrdude_1.html ]; then \
mkdir -p avrdude-html ; \
mv -f *.html avrdude-html ; \
else \
mv -f avrdude avrdude-html; \
fi;
mv *.html avrdude-html
clean-local:
rm -rf avrdude-html *.info

View File

@@ -1,26 +1,22 @@
General:
- Man page needs updated for avr910 info.
- avr910 needs a little bit of work to support setting fuse byte (note that it
can only deal with a _single_ fuse byte.
- Website needs to link to docs:
http://savannah.nongnu.org/download/avrdude/doc/avrdude-html/
- Add "skip empty pages" optimization on avr910 paged write. The stk500 has
this optimization already.
- Add avr910 device codes for more devices. Some where posted here:
http://www.avrfreaks.com/phorum/read.php?f=3&i=40925&t=40717#40925
but uisp seems to have a more comprehensive list.
- Fix "overfull \hbox" issues in building documentation.
Windows:
- FIXME: term.c: terminal_get_input(): strip newlines in non-readline input
code.
- FIXME: avr910.c: avr910_cmd(): Insert version check here.
- FIXME: ser_posix.c: serial_close(): Should really restore the terminal to
original state here.
- FIXME: main.c, par.c: exitspecs don't work if RESET-pin is controlled over
PPICTRL.
- transfer ppi-speedtuning to the windows version (CAVEAT: This will make
programming too fast for chips with 500kHz clock)
- make SCK-period configurable for PPI-programmers
- Use Windows API for stk500 serial port communications on Windows port.
This might remove dependency on Cygwin.
- Add ability to find all parallel port names available and base addresses
of available ports.

View File

@@ -5,7 +5,6 @@
@setfilename avrdude.info
@settitle AVRDUDE
@finalout
@include version.texi
@@ -28,7 +27,7 @@ This file documents the avrdude program.
For avrdude version @value{VERSION}, @value{UPDATED}.
Copyright @copyright{} 2003,2005 Brian Dean
Copyright @copyright{} 2003 Brian Dean
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -63,7 +62,7 @@ by the Free Software Foundation.
@vfill
Copyright @copyright{} 2003,2005 Brian S. Dean
Copyright @copyright{} 2003 Brian S. Dean
@sp 2
Permission is granted to make and distribute verbatim copies of
@@ -98,11 +97,10 @@ For avrdude version @value{VERSION}, @value{UPDATED}.
@menu
* Introduction::
* Command Line Options::
* Terminal Mode Operation::
* Command Line Options::
* Terminal Mode Operation::
* Configuration File::
* Platform Dependent Information::
* Troubleshooting::
* Platform Dependent Information::
@end menu
@c
@@ -129,46 +127,24 @@ from the contents of a file, while interactive mode is useful for
exploring memory contents, modifing individual bytes of eeprom,
programming fuse/lock bits, etc.
AVRDUDE supports six basic programmer types: Atmel's STK500,
Atmel's JTAG ICE mkII, appnote
avr910, appnote avr109 (including the AVR Butterfly),
serial bit-bang adapters,
and the PPI (parallel port interface). PPI represents a class
AVRDUDE supports three basic programmer types: Atmel's STK500, appnote
avr910 and the PPI (parallel port interface). PPI represents a class
of simple programmers where the programming lines are directly
connected to the PC parallel port. Several pin configurations exist
for several variations of the PPI programmers, and AVRDUDE can be be
configured to work with them by either specifying the appropriate
programmer on the command line or by creating a new entry in its
configuration file. All that's usually required for a new entry is to
tell AVRDUDE which pins to use for each programming function.
tell AVRDUDE which pins to use for each programming function.
A number of equally simple bit-bang programming adapters that connect
to a serial port are supported as well, among them the popular
Ponyprog serial adapter, and the DASA and DASA3 adapters that used to
be supported by uisp(1). Note that these adapters are meant to be
attached to a physical serial port. Connecting to a serial port
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
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
opposed to being an external device.
The fundamental difference between the two types lies in the
protocol used to control the programmer. The avr910 protocol is very
The STK500 and avr910 use the serial port to communicate with the PC
and contains on-board logic to control the programming of the target
device. The fundamental difference between the two types lies in the
protocol used to control the programmer. The av910 protocol is very
simplistic and can easily be used as the basis for a simple, home made
programer since the firmware is available online. On the other hand,
the STK500 protocol is more robust and complicated and the firmware is
not openly available.
The JTAG ICE also uses a serial communication protocol which is similar
to the STK500 firmware version 2 one. However, as the JTAG ICE is
intented to allow on-chip debugging as well as memory programming, the
protocol is more sophisticated.
(This protocol can also be run on top of USB.)
Only the memory programming functionality of the JTAG ICE is supported
by AVRDUDE.
@menu
* History::
@@ -210,8 +186,8 @@ Roth.
@cindex options
@menu
* Option Descriptions::
* Example Command Line Invocations::
* Option Descriptions::
* Example Command Line Invocations::
@end menu
@c
@@ -235,7 +211,7 @@ following options are recognized:
@item -p @var{partno}
This is the only mandatory option and it tells AVRDUDE what type of part
(MCU) that is connected to the programmer. The @var{partno} parameter
is the part's id listed in the configuration file. Specify -p ? to list
is the part's id listed in the configuration file. Specify -p ? to list
all parts in the configuration file. If a part is unknown
to AVRDUDE, it means that there is no config file entry for that part,
but it can be added to the configuration file if you have the Atmel
@@ -243,15 +219,6 @@ datasheet so that you can enter the programming specifications.
Currently, the following MCU types are understood:
@table @code
@itemx c128
AT90CAN128
@itemx pwm2
AT90PWM2
@itemx pwm3
AT90PWM3
@itemx 1200
AT90S1200
@@ -280,110 +247,41 @@ AT90S8515
AT90S8535
@itemx m103
ATmega103
ATMEGA103
@itemx m128
ATmega128
ATMEGA128
@itemx m16
ATmega16
@itemx m161
ATmega161
@itemx m162
ATmega162
ATMEGA16
@itemx m163
ATmega163
@itemx m164
ATmega164
ATMEGA163
@itemx m169
ATmega169
ATMEGA169
@itemx m32
ATmega32
@itemx m324
ATmega324
@itemx m329
ATmega329
@itemx m3290
ATmega3290
@itemx m48
ATmega48
@itemx m64
ATmega64
@itemx m644
ATmega644
@itemx m649
ATmega649
@itemx m6490
ATmega6490
ATMEGA32
@itemx m8
ATmega8
@itemx m8515
ATmega8515
ATMEGA8
@itemx m8535
ATmega8535
@itemx m88
ATmega88
ATMEGA8535
@itemx t12
ATtiny12
@itemx t13
ATtiny13
@itemx t15
ATtiny15
@itemx t2313
ATtiny2313
@itemx t25
ATtiny25
@itemx t26
ATtiny26
@itemx t45
ATtiny45
@itemx t85
ATtiny85
ATTINY26
@end table
(*) The AT90S2323 and ATtiny22 use the same algorithm.
@item -b @var{baudrate}
Override the RS-232 connection baud rate specified in the respective
programmer's entry of the configuration file.
@item -B @var{bitclock}
Specify the bit clock period for the JTAG interface (JTAG ICE only).
The value is a floating-point number in microseconds.
The default value of the JTAG ICE results in about 1 microsecond bit
clock period, suitable for target MCUs running at 4 MHz clock and
above.
Unlike certain parameters in the STK500, the JTAG ICE resets all its
parameters to default values when the programming software signs
off from the ICE, so for MCUs running at lower clock speeds, this
parameter must be specified on the command-line.
(*) The AT90S2323 uses the same algorithm.
@item -c @var{programmer-id}
Specify the programmer to be used. AVRDUDE knows about several common
@@ -399,23 +297,14 @@ Currently, the following programmer ids are understood and supported:
@table @code
@itemx abcmini
ABCmini Board, aka Dick Smith HOTCHIP
@itemx alf
Nightshade ALF-PgmAVR, http://nightshade.homeip.net/
@itemx avr109
Atmel AppNote AVR109 Boot Loader
@itemx avr910
Atmel Low Cost Serial Programmer
@itemx avr911
Atmel AppNote AVR911 AVROSP (an alias for avr109)
@itemx avrisp
Atmel AVR ISP
Atmel AVR ISP
@itemx bascom
Bascom SAMPLE programming cable
@@ -423,21 +312,8 @@ Bascom SAMPLE programming cable
@itemx bsd
Brian Dean's Programmer, http://www.bsdhome.com/avrdude/
@itemx butterfly
Atmel Butterfly Development Board
@itemx dt006
Dontronics DT006
@item jtagmkII
@itemx jtag2slow
Atmel JTAG ICE mkII (default speed 19200 Bd)
@itemx jtag2fast
Atmel JTAG ICE mkII, running at 115200 Bd
@itemx jtag2
Same as before.
Dontronics DT006
@itemx pavr
Jason Kyle's pAVR Serial Programmer
@@ -445,20 +321,17 @@ Jason Kyle's pAVR Serial Programmer
@itemx picoweb
Picoweb Programming Cable, http://www.picoweb.net/
@itemx pony-stk200
Pony Prog STK200
@itemx pony
stk200 = Pony Prog STK200
@itemx sp12
Steve Bolt's Programmer
Steve Bolt's Programmer
@itemx stk200
STK200
STK200
@itemx stk500
Atmel STK500
@itemx stk500v2
Atmel STK500, running a verrsion 2.x firmware
Atmel STK500
@end table
@@ -474,14 +347,6 @@ specified, AVRDUDE reads the configuration file from
/usr/local/etc/avrdude.conf (FreeBSD and Linux). See Appendix A for
the method of searching for the configuration file for Windows.
@item -D
Disable auto erase for flash. When the -U option with flash memory is
specified, avrdude will perform a chip erase before starting any of the
programming operations, since it generally is a mistake to program the flash
without performing an erase first. This option disables that. However, to
remain backward compatible, the -i, and -m options automatically disable the
auto erase feature.
@item -e
Causes a chip erase to be executed. This will reset the contents of the
flash ROM and EEPROM to the value `0xff', and is basically a
@@ -514,7 +379,7 @@ The `/RESET' line will be deactivated at program exit, thus allowing the
MCU target program to run while the programming hardware remains
connected.
@itemx vcc
@itemx vcc
This option will leave those parallel port pins active (i. e. high) that
can be used to supply `Vcc' power to the MCU.
@@ -527,104 +392,10 @@ program exit.
Multiple @var{exitspec} arguments can be separated with commas.
@item -F
Normally, AVRDUDE tries to verify that the device signature read from
the part is reasonable before continuing. Since it can happen from time
to time that a device has a broken (erased or overwritten) device
signature but is otherwise operating normally, this options is provided
to override the check.
@item -n
No-write - disables actually writing data to the MCU (useful for
debugging AVRDUDE).
@item -P @var{port}
Use port to identify the device to which the programmer is attached.
Normally, the default parallel port is used, but if the programmer type
normally connects to the serial port, the default serial port will be
used. See Appendix A, Platform Dependent Information, to find out the
default port names for your platform. If you need to use a different
parallel or serial port, use this option to specify the alternate port name.
For the JTAG ICE mkII, if AVRDUDE has been built with libusb support,
@var{port} may alternatively be specified as
@var{usb}[:@var{serialno}]. In that case, the JTAG ICE mkII will be
looked up on USB. If @var{serialno} is also specified, it will be
matched against the serial number read from any JTAG ICE mkII found on
USB. The match is done after stripping any existing colons from the
given serial number, and right-to-left, so only the least significant
bytes from the serial number need to be given.
@item -q
Disable (or quell) output of the progress bar while reading or writing
to the device. Specify it a second time for even quieter operation.
@item -u
Disables the default behaviour of reading out the fuses three times before
programming, then verifying at the end of programming that the fuses have not
changed. If you want to change fuses you will need to specify this option,
as avrdude will see the fuses have changed (even though you wanted to) and
will change them back for your "saftey". This option was designed to
prevent cases of fuse bits magically changing (usually called @emph{safemode}).
@item -t
Tells AVRDUDE to enter the interactive ``terminal'' mode instead of up-
or downloading files. See below for a detailed description of the
terminal mode.
@item -U @var{memtype}:@var{op}:@var{filename}[:@var{format}]
Perform a memory operation, equivalent to specifing the @option{-m},
@option{-i} or @option{-o}, and @option{-f} options, except that
multiple @option{-U} optins can be specified in order to operate on
mulitple memories on the same command-line invocation. The
@var{memtype} field specifies the memory type to operate on. Use
the @option{-v} option on the command line or the @code{part} command from
terminal mode to display all the memory types supported by a particular
device.
Typically, a device's memory configuration at least contains
the memory types
@code{flash}
and
@code{eeprom}.
All memory types currently known are:
@table @code
@item calibration
One or more bytes of RC oscillator calibration data.
@item eeprom
The EEPROM of the device.
@item efuse
The extended fuse byte.
@item flash
The flash ROM of the device.
@item fuse
The fuse byte in devices that have only a single fuse byte.
@item hfuse
The high fuse byte.
@item lfuse
The low fuse byte.
@item lock
The lock byte.
@item signature
The three device signature bytes (device ID).
@end table
The @var{op} field specifies what operation to perform:
@table @code
@itemx r
read the specified device memory and write to the specified file
@itemx w
read the specified file and write it to the specified device memory
@itemx v
read the specified device memory and the specified file and perform a verify operation
@end table
The @var{filename} field indicates the name of the file to read or
write. The @var{format} field is optional and contains the format of
the file to read or write. Possible values are:
@item -f @var{format}
This option specifies the file format for the input or output files to
be processed. Format can be one of:
@table @code
@itemx i
@@ -655,9 +426,74 @@ at stdin.
The default is to use auto detection for input files, and raw binary
format for output files.
Note that if @var{filename} contains a colon, the @var{format} field is
no longer optional since the filename part following the colon would
otherwise be misinterpreted as @var{format}.
@item -F
Normally, AVRDUDE tries to verify that the device signature read from
the part is reasonable before continuing. Since it can happen from time
to time that a device has a broken (erased or overwritten) device
signature but is otherwise operating normally, this options is provided
to override the check.
@item -i @var{filename}
Specifies the input file to be programmed into the MCU. Can be
specified as `-' to use stdin as the input.
@item -m @var{memtype}
Specifies which program area of the MCU to read or write; allowable
values depend on the MCU being programmed, but most support at least
@code{eeprom} for the EEPROM, and @code{flash} for the flash ROM. Use
the @option{-v} option on the command line or the @code{part} command from
terminal mode to display all the memory types supported by a particular
device. The default is @code{flash}.
@item -n
No-write - disables actually writing data to the MCU (useful for
debugging AVRDUDE).
@item -o @var{filename}
Specifies the name of the output file to write, and causes the
respective memory area to be read from the MCU. Can be specified as `-'
to write to stdout.
@item -P @var{port}
Use port to identify the device to which the programmer is attached. By
default the @code{/dev/ppi0} port is used, but if the programmer type
normally connects to the serial port, the @code{/dev/cuaa0} port is the
default. If you need to use a different parallel or serial port, use
this option to specify the alternate port name.
@item -q
Disable (or quell) output of the progress bar while reading or writing
to the device.
@item -t
Tells AVRDUDE to enter the interactive ``terminal'' mode instead of up-
or downloading files. See below for a detailed description of the
terminal mode.
@item -U @var{memtype}:@var{op}:@var{filename}[:@var{format}]
Perform a memory operation, equivalent to specifing the @option{-m},
@option{-i} or @option{-o}, and @option{-f} options, except that
multiple @option{-U} optins can be specified in order to operate on
mulitple memories on the same command-line invocation. The
@var{memtype} field specifies the memory type to operate on. The
@var{op} field specifies what operation to perform:
@table @code
@itemx r
read the specified device memory and write to the specified file
@itemx w
read the specified file and write it to the specified device memory
@itemx v
read the specified device memory and the specified file and perform a verify operation
@end table
The @var{filename} field indicates the name of the file to read or
write. The @var{format} field is optional and contains the format of
the file to read or write. See the @option{-f} option for possible
values.
@item -v
Enable verbose output.
@@ -688,7 +524,6 @@ should not be used.
@end table
@page
@c
@c Node
@c
@@ -729,23 +564,20 @@ Reading | ################################################## | 100% 6.83s
avrdude: verifying ...
avrdude: 19278 bytes of flash verified
avrdude: safemode: Fuses OK
avrdude done. Thank you.
%
@end cartouche
@end example
@page
@noindent
Upload the flash memory from the ATmega128 connected to the STK500
programmer and save it in raw binary format in the file named
@code{c:/diag flash.bin}:
@code{diag.flash}:
@example
@cartouche
% avrdude -p m128 -c stk500 -U flash:r:"c:/diag flash.bin":r
% avrdude -p m128 -c stk500 -U flash:r:diag.flash:r
avrdude: AVR device initialized and ready to accept instructions
@@ -756,9 +588,7 @@ avrdude: reading flash memory:
Reading | ################################################## | 100% 46.10s
avrdude: writing output file "c:/diag flash.bin"
avrdude: safemode: Fuses OK
avrdude: writing output file "diag.flash"
avrdude done. Thank you.
@@ -766,7 +596,6 @@ avrdude done. Thank you.
@end cartouche
@end example
@page
@noindent
Using the default programmer, download the file @code{diag.hex} to
flash, @code{eeprom.hex} to EEPROM, and set the Extended, High, and Low
@@ -775,7 +604,7 @@ fuse bytes to 0xff, 0x89, and 0x2e respectively:
@example
@cartouche
% avrdude -p m128 -u -U flash:w:diag.hex \
% avrdude -p m128 -U flash:w:diag.hex \
> -U eeprom:w:eeprom.hex \
> -U efuse:w:0xff:m \
> -U hfuse:w:0x89:m \
@@ -815,29 +644,6 @@ avrdude done. Thank you.
@end cartouche
@end example
@page
@noindent
Connect to the JTAG ICE mkII which serial number ends up in 1C37 via
USB, and enter terminal mode:
@example
@cartouche
% avrdude -c jtag2 -p m649 -P usb:1c:37 -t
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.03s
avrdude: Device signature = 0x1e9603
[ ... terminal mode output skipped for brevity ... ]
avrdude done. Thank you.
@end cartouche
@end example
@c
@@ -895,9 +701,7 @@ command.
Display the device signature bytes.
@item part
Display the current part settings and parameters. Includes chip
specific information including all memory types supported by the
device, read/write timing, etc.
Display the current part settings.
@item ?
@itemx help
@@ -930,23 +734,9 @@ multiplies by 1E6, a trailing letter @var{k} by 1E3.
@item fosc off
Turn the master oscillator off.
@item sck @var{period}
@emph{STK500 only:}
Set the SCK clock period to @var{period} microseconds.
@emph{JTAG ICE only:}
Set the JTAG ICE bit clock period to @var{period} microseconds.
Note that unlike STK500 settings, this setting will be reverted to
its default value (approximately 1 microsecond) when the programming
software signs off from the JTAG ICE.
@item parms
@emph{STK500 only:}
Display the current voltage and master oscillator parameters.
@emph{JTAG ICE only:}
Display the current target supply voltage and JTAG bit clock rate/period.
@end table
@c
@@ -1016,13 +806,11 @@ avrdude>
@noindent
Program the fuse bits of an ATmega128 (disable M103 compatibility,
enable high speed external crystal, enable brown-out detection, slowly
rising power). Note since we are working with fuse bits the -u (unsafe)
option is specified, which allows you to modify the fuse bits. First
display the factory defaults, then reprogram:
rising power). First display the factory defaults, then reprogram:
@example
@cartouche
% avrdude -p m128 -u -c stk500 -t
% avrdude -p m128 -c stk500 -t
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0x1e9702
@@ -1122,18 +910,17 @@ The format of the programmer definition is as follows:
@example
programmer
id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
desc = <description> ; # quoted string
type = par | stk500 ; # programmer type
baudrate = <num> ; # baudrate for serial ports
vcc = <num1> [, <num2> ... ] ; # pin number(s)
reset = <num> ; # pin number
sck = <num> ; # pin number
mosi = <num> ; # pin number
miso = <num> ; # pin number
errled = <num> ; # pin number
rdyled = <num> ; # pin number
pgmled = <num> ; # pin number
vfyled = <num> ; # pin number
desc = <description> ; # quoted string
type = par | stk500 ; # programmer type
vcc = <num1> [, <num2> ... ] ; # pin number(s)
reset = <num> ; # pin number
sck = <num> ; # pin number
mosi = <num> ; # pin number
miso = <num> ; # pin number
errled = <num> ; # pin number
rdyled = <num> ; # pin number
pgmled = <num> ; # pin number
vfyled = <num> ; # pin number
;
@end example
@@ -1180,7 +967,7 @@ part
@end example
@menu
* Instruction Format::
* Instruction Format::
@end menu
@c
@@ -1228,7 +1015,7 @@ instruction for an AT90S2313 AVR part could be encoded as:
@example
read = "1 0 1 0 0 0 0 0 x x x x x x x x",
read = "1 0 1 0 0 0 0 0 x x x x x x x x",
"x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
write = "1 1 0 0 0 0 0 0 x x x x x x x x",
@@ -1248,7 +1035,7 @@ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
@itemize @bullet
@item
The @code{devicecode} parameter is the device code used by the STK500
and is obtained from the software section (@code{avr061.zip}) of
and are obtained from the software section (@code{avr061.zip} of
Atmel's AVR061 application note available from
@url{http://www.atmel.com/atmel/acrobat/doc2525.pdf}.
@@ -1277,36 +1064,18 @@ problem with the at90s4433/2333's; see the at90s4433 errata at:
@url{http://www.atmel.com/atmel/acrobat/doc1280.pdf}
@item
The boot loader from application note AVR109 (and thus also the AVR
Butterfly) does not support writing of fuse bits. Writing lock bits
is supported, but is restricted to the boot lock bits (BLBxx). These
are restrictions imposed by the underlying SPM instruction that is used
to program the device from inside the boot loader. Note that programming
the boot lock bits can result in a ``shoot-into-your-foot'' scenario as
the only way to unprogram these bits is a chip erase, which will also
erase the boot loader code.
The boot loader implements the ``chip erase'' function by erasing the
flash pages of the application section.
Reading fuse and lock bits is fully supported.
Note that due to the unability to write the fuse bits, the safemode
functionality does not make sense for these boot loaders.
@end itemize
@c
@c Node
@c
@node Platform Dependent Information, Troubleshooting, Configuration File, Top
@node Platform Dependent Information, , Configuration File, Top
@appendix Platform Dependent Information
@menu
* Unix::
* Windows::
* Unix::
* Windows::
@end menu
@c
@@ -1742,89 +1511,4 @@ line driven and for writing the batch files.
@end itemize
@c
@c Node
@c
@node Troubleshooting, ,Platform Dependent Information ,Top
@appendix Troubleshooting
@noindent
In general, please report any bugs encountered via
@url{http://savannah.nongnu.org/bugs/?group=avrdude}.
@itemize @bullet
@item
Problem: I'm using a serial programmer under Windows and get the following
error:
@code{avrdude: serial_open(): can't set attributes for device "com1"},
Solution: This problem seems to appear with certain versions of Cygwin. Specifying
@code{"/dev/com1"} instead of @code{"com1"} should help.
@item
Problem: I'm using linux and my AVR910 programmer is really slow.
Solution (short): @code{setserial @var{port} low_latency}
Solution (long):
There are two problems here. First, the system may wait some time before it
passes data from the serial port to the program. Under Linux the following
command works around this (you may need root privileges for this).
@code{setserial @var{port} low_latency}
Secondly, the serial interface chip may delay the interrupt for some time.
This behaviour can be changed by setting the FIFO-threshold to one. Under Linux this
can only be done by changing the kernel source in @code{drivers/char/serial.c}.
Search the file for @code{UART_FCR_TRIGGER_8} and replace it with @code{UART_FCR_TRIGGER_1}. Note that overall performance might suffer if there
is high throughput on serial lines. Also note that you are modifying the kernel at
your own risk.
@item
Problem: I'm not using linux and my AVR910 programmer is really slow.
Solutions: The reasons for this are the same as above.
If you know how to work around this on your OS, please let us know.
@item
Problem: I cannot modify the fuse bits on my AVR!
Solution: You probably forgot to specify the -u option, which allows you to modify fuse bits.
This is done to prevent corrupt data from changing the fuse bits without you knowing about it, and
currently also prevents the user from changing the fuse bits by accident. This patch was added in
response to a number of occasions when an AVR had stopped responding because the fuse bits got changed
by an error caused by the programmer. Programmer of course meaning both the physical device, and the
person sitting at the keyboard.
@item
Problem: AVRDUDE says my device is not supported when using the AVR109 boot loader
Solution: Currently, AVRDUDE uses the AVR910 device codes given in the
@code{avrdude.conf} file, and matches them against the list of supported
devices reported by the programmer. Unfortunately, there are no device
codes at all for some of the newer AVR devices, and even worse, the
device codes listed in @code{preprocessor.xls} of appnote AVR109 do not
match those once specified in AVR910.
Use the -F option to force AVRDUDE to continue anyway.
@item
Problem: Updating the flash ROM from terminal mode does not work with the
JTAG ICE mkII.
Solution: None at this time. Currently, the JTAG ICE mkII code cannot
write to the flash ROM one byte at a time.
@end itemize
@bye

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -48,7 +48,6 @@ struct ihexrec {
extern char * progname;
extern char progbuf[];
extern int quell_progress;
int b2ihex(unsigned char * inbuf, int bufsize,
int recsize, int startaddr,
@@ -911,7 +910,7 @@ int fileio(int op, char * filename, FILEFMT format,
if (rc < 0)
return -1;
#if defined(WIN32NATIVE)
#if defined(__CYGWIN__)
/* Open Raw Binary format in binary mode on Windows.*/
if(format == FMT_RBIN)
{
@@ -971,10 +970,8 @@ int fileio(int op, char * filename, FILEFMT format,
return -1;
}
if (quell_progress < 2) {
fprintf(stderr, "%s: %s file %s auto detected as %s\n",
progname, fio.iodesc, fname, fmtstr(format));
}
fprintf(stderr, "%s: %s file %s auto detected as %s\n",
progname, fio.iodesc, fname, fmtstr(format));
}
if (format != FMT_IMM) {

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

File diff suppressed because it is too large Load Diff

View File

@@ -1,28 +0,0 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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 jtagmkII_h
#define jtagmkII_h
void jtagmkII_initpgm (PROGRAMMER * pgm);
#endif

View File

@@ -1,290 +0,0 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2005 Joerg Wunsch <j@uriah.heep.sax.de>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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$ */
/*
* JTAG ICE mkII definitions
* Taken from Appnote AVR067
*/
/*
* Communication with the JTAG ICE works in frames. The protocol
* somewhat resembles the STK500v2 protocol, yet it is sufficiently
* different to prevent a direct code reuse. :-(
*
* Frame format:
*
* +---------------------------------------------------------------+
* | 0 | 1 . 2 | 3 . 4 . 5 . 6 | 7 | ... | N-1 . N |
* | | | | | | |
* | start | LSB MSB | LSB ....... MSB | token | msg | LSB MSB |
* | 0x1B | sequence# | message size | 0x0E | | CRC16 |
* +---------------------------------------------------------------+
*
* Each request message will be returned by a response with a matching
* sequence #. Sequence # 0xffff is reserved for asynchronous event
* notifications that will be sent by the ICE without a request
* message (e.g. when the target hit a breakpoint).
*
* The message size excludes the framing overhead (10 bytes).
*
* The first byte of the message is always the request or response
* code, which is roughly classified as:
*
* . Messages (commands) use 0x00 through 0x3f. (The documentation
* claims that messages start at 0x01, but actually CMND_SIGN_OFF is
* 0x00.)
* . Internal commands use 0x40 through 0x7f (not documented).
* . Success responses use 0x80 through 0x9f.
* . Failure responses use 0xa0 through 0xbf.
* . Events use 0xe0 through 0xff.
*/
#define MESSAGE_START 0x1b
#define TOKEN 0x0e
/*
* Max message size we are willing to accept. Prevents us from trying
* to allocate too much VM in case we received a nonsensical packet
* length. We have to allocate the buffer as soon as we've got the
* length information (and thus have to trust that information by that
* time at first), as the final CRC check can only be done once the
* entire packet came it.
*/
#define MAX_MESSAGE 100000
/* ICE command codes */
#define CMND_CHIP_ERASE 0x13
#define CMND_CLEAR_EVENTS 0x22
#define CMND_CLR_BREAK 0x1A
#define CMND_ENTER_PROGMODE 0x14
#define CMND_ERASEPAGE_SPM 0x0D
#define CMND_FORCED_STOP 0x0A
#define CMND_GET_BREAK 0x12
#define CMND_GET_PARAMETER 0x03
#define CMND_GET_SIGN_ON 0x01
#define CMND_GET_SYNC 0x0f
#define CMND_GO 0x08
#define CMND_LEAVE_PROGMODE 0x15
#define CMND_READ_MEMORY 0x05
#define CMND_READ_PC 0x07
#define CMND_RESET 0x0B
#define CMND_RESTORE_TARGET 0x23
#define CMND_RUN_TO_ADDR 0x1C
#define CMND_SELFTEST 0x10
#define CMND_SET_BREAK 0x11
#define CMND_SET_DEVICE_DESCRIPTOR 0x0C
#define CMND_SET_N_PARAMETERS 0x16
#define CMND_SET_PARAMETER 0x02
#define CMND_SIGN_OFF 0x00
#define CMND_SINGLE_STEP 0x09
#define CMND_SPI_CMD 0x1D
#define CMND_WRITE_MEMORY 0x04
#define CMND_WRITE_PC 0x06
/* ICE responses */
#define RSP_DEBUGWIRE_SYNC_FAILED 0xAC
#define RSP_FAILED 0xA0
#define RSP_GET_BREAK 0x83
#define RSP_ILLEGAL_BREAKPOINT 0xA8
#define RSP_ILLEGAL_COMMAND 0xAA
#define RSP_ILLEGAL_EMULATOR_MODE 0xA4
#define RSP_ILLEGAL_JTAG_ID 0xA9
#define RSP_ILLEGAL_MCU_STATE 0xA5
#define RSP_ILLEGAL_MEMORY_TYPE 0xA2
#define RSP_ILLEGAL_MEMORY_RANGE 0xA3
#define RSP_ILLEGAL_PARAMETER 0xA1
#define RSP_ILLEGAL_POWER_STATE 0xAD
#define RSP_ILLEGAL_VALUE 0xA6
#define RSP_MEMORY 0x82
#define RSP_NO_TARGET_POWER 0xAB
#define RSP_OK 0x80
#define RSP_PARAMETER 0x81
#define RSP_PC 0x84
#define RSP_SELFTEST 0x85
#define RSP_SET_N_PARAMETERS 0xA7
#define RSP_SIGN_ON 0x86
#define RSP_SPI_DATA 0x88
/* ICE events */
#define EVT_BREAK 0xE0
#define EVT_DEBUG 0xE6
#define EVT_ERROR_PHY_FORCE_BREAK_TIMEOUT 0xE2
#define EVT_ERROR_PHY_MAX_BIT_LENGTH_DIFF 0xED
#define EVT_ERROR_PHY_OPT_RECEIVE_TIMEOUT 0xF9
#define EVT_ERROR_PHY_OPT_RECEIVED_BREAK 0xFA
#define EVT_ERROR_PHY_RECEIVED_BREAK 0xF8
#define EVT_ERROR_PHY_RECEIVE_TIMEOUT 0xF7
#define EVT_ERROR_PHY_RELEASE_BREAK_TIMEOUT 0xE3
#define EVT_ERROR_PHY_SYNC_OUT_OF_RANGE 0xF5
#define EVT_ERROR_PHY_SYNC_TIMEOUT 0xF0
#define EVT_ERROR_PHY_SYNC_TIMEOUT_BAUD 0xF4
#define EVT_ERROR_PHY_SYNC_WAIT_TIMEOUT 0xF6
#define EVT_RESULT_PHY_NO_ACTIVITY 0xFB
#define EVT_EXT_RESET 0xE7
#define EVT_ICE_POWER_ERROR_STATE 0xEA
#define EVT_ICE_POWER_OK 0xEB
#define EVT_IDR_DIRTY 0xEC
#define EVT_NONE 0xEF
#define EVT_PDSB_BREAK 0xF2
#define EVT_PDSMB_BREAK 0xF3
#define EVT_PROGRAM_BREAK 0xF1
#define EVT_RUN 0xE1
#define EVT_TARGET_POWER_OFF 0xE5
#define EVT_TARGET_POWER_ON 0xE4
#define EVT_TARGET_SLEEP 0xE8
#define EVT_TARGET_WAKEUP 0xE9
/* memory types for CMND_{READ,WRITE}_MEMORY */
#define MTYPE_IO_SHADOW 0x30 /* cached IO registers? */
#define MTYPE_SRAM 0x20 /* target's SRAM or [ext.] IO registers */
#define MTYPE_EEPROM 0x22 /* EEPROM, what way? */
#define MTYPE_EVENT 0x60 /* ICE event memory */
#define MTYPE_SPM 0xA0 /* flash through LPM/SPM */
#define MTYPE_FLASH_PAGE 0xB0 /* flash in programming mode */
#define MTYPE_EEPROM_PAGE 0xB1 /* EEPROM in programming mode */
#define MTYPE_FUSE_BITS 0xB2 /* fuse bits in programming mode */
#define MTYPE_LOCK_BITS 0xB3 /* lock bits in programming mode */
#define MTYPE_SIGN_JTAG 0xB4 /* signature in programming mode */
#define MTYPE_OSCCAL_BYTE 0xB5 /* osccal cells in programming mode */
#define MTYPE_CAN 0xB6 /* CAN mailbox */
/* (some) ICE parameters, for CMND_{GET,SET}_PARAMETER */
#define PAR_HW_VERSION 0x01
#define PAR_FW_VERSION 0x02
#define PAR_EMULATOR_MODE 0x03
# define EMULATOR_MODE_DEBUGWIRE 0x00
# define EMULATOR_MODE_JTAG 0x01
# define EMULATOR_MODE_UNKNOWN 0x02
# define EMULATOR_MODE_SPI 0x03
#define PAR_IREG 0x04
#define PAR_BAUD_RATE 0x05
# define PAR_BAUD_2400 0x01
# define PAR_BAUD_4800 0x02
# define PAR_BAUD_9600 0x03
# define PAR_BAUD_19200 0x04 /* default */
# define PAR_BAUD_38400 0x05
# define PAR_BAUD_57600 0x06
# define PAR_BAUD_115200 0x07
# define PAR_BAUD_14400 0x08
#define PAR_OCD_VTARGET 0x06
#define PAR_OCD_JTAG_CLK 0x07
#define PAR_OCD_BREAK_CAUSE 0x08
#define PAR_TIMERS_RUNNING 0x09
#define PAR_BREAK_ON_CHANGE_FLOW 0x0A
#define PAR_BREAK_ADDR1 0x0B
#define PAR_BREAK_ADDR2 0x0C
#define PAR_COMBBREAKCTRL 0x0D
#define PAR_JTAGID 0x0E
#define PAR_UNITS_BEFORE 0x0F
#define PAR_UNITS_AFTER 0x10
#define PAR_BIT_BEFORE 0x11
#define PAR_BIT_ATER 0x12
#define PAR_EXTERNAL_RESET 0x13
#define PAR_FLASH_PAGE_SIZE 0x14
#define PAR_EEPROM_PAGE_SIZE 0x15
#define PAR_UNUSED1 0x16
#define PAR_PSB0 0x17
#define PAR_PSB1 0x18
#define PAR_PROTOCOL_DEBUG_EVENT 0x19
#define PAR_MCU_STATE 0x1A
# define STOPPED 0x00
# define RUNNING 0x01
# define PROGRAMMING 0x02
#define PAR_DAISY_CHAIN_INFO 0x1B
#define PAR_BOOT_ADDRESS 0x1C
#define PAR_TARGET_SIGNATURE 0x1D
#define PAR_DEBUGWIRE_BAUDRATE 0x1E
#define PAR_PROGRAM_ENTRY_POINT 0x1F
#define PAR_PACKET_PARSING_ERRORS 0x40
#define PAR_VALID_PACKETS_RECEIVED 0x41
#define PAR_INTERCOMMUNICATION_TX_FAILURES 0x42
#define PAR_INTERCOMMUNICATION_RX_FAILURES 0x43
#define PAR_CRC_ERRORS 0x44
#define PAR_POWER_SOURCE 0x45
# define POWER_EXTERNAL 0x00
# define POWER_USB 0x01
#define PAR_CAN_FLAG 0x22
# define DONT_READ_CAN_MAILBOX 0x00
# define READ_CAN_MAILBOX 0x01
#define PAR_ENABLE_IDR_IN_RUN_MODE 0x23
# define ACCESS_OSCCAL 0x00
# define ACCESS_IDR 0x01
#define PAR_ALLOW_PAGEPROGRAMMING_IN_SCANCHAIN 0x24
# define PAGEPROG_NOT_ALLOWED 0x00
# define PAGEPROG_ALLOWED 0x01
/*
* In appnote AVR067, struct device_descriptor is written with
* int/long field types. We cannot use them directly, as they were
* neither properly aligned for portability, nor did they care for
* endianess issues. We thus use arrays of unsigned chars, plus
* conversion macros.
*/
struct device_descriptor
{
unsigned char ucReadIO[8]; /*LSB = IOloc 0, MSB = IOloc63 */
unsigned char ucReadIOShadow[8]; /*LSB = IOloc 0, MSB = IOloc63 */
unsigned char ucWriteIO[8]; /*LSB = IOloc 0, MSB = IOloc63 */
unsigned char ucWriteIOShadow[8]; /*LSB = IOloc 0, MSB = IOloc63 */
unsigned char ucReadExtIO[52]; /*LSB = IOloc 96, MSB = IOloc511 */
unsigned char ucReadIOExtShadow[52]; /*LSB = IOloc 96, MSB = IOloc511 */
unsigned char ucWriteExtIO[52]; /*LSB = IOloc 96, MSB = IOloc511 */
unsigned char ucWriteIOExtShadow[52];/*LSB = IOloc 96, MSB = IOloc511 */
unsigned char ucIDRAddress; /*IDR address */
unsigned char ucSPMCRAddress; /*SPMCR Register address and dW BasePC */
unsigned char ucRAMPZAddress; /*RAMPZ Register address in SRAM I/O */
/*space */
unsigned char uiFlashPageSize[2]; /*Device Flash Page Size, Size = */
/*2 exp ucFlashPageSize */
unsigned char ucEepromPageSize; /*Device Eeprom Page Size in bytes */
unsigned char ulBootAddress[4]; /*Device Boot Loader Start Address */
unsigned char uiUpperExtIOLoc[2]; /*Topmost (last) extended I/O */
/*location, 0 if no external I/O */
unsigned char ulFlashSize[4]; /*Device Flash Size */
unsigned char ucEepromInst[20]; /*Instructions for W/R EEPROM */
unsigned char ucFlashInst[3]; /*Instructions for W/R FLASH */
unsigned char ucSPHaddr; /* stack pointer high */
unsigned char ucSPLaddr; /* stack pointer low */
/* new as of 16-02-2004 */
unsigned char uiFlashpages[2]; /* number of pages in flash */
unsigned char ucDWDRAddress; /* DWDR register address */
unsigned char ucDWBasePC; /* base/mask value of the PC */
/* new as of 30-04-2004 */
unsigned char ucAllowFullPageBitstream; /* FALSE on ALL new */
/*parts */
unsigned char uiStartSmallestBootLoaderSection[2]; /* */
/* new as of 18-10-2004 */
unsigned char EnablePageProgramming; /* For JTAG parts only, */
/* default TRUE */
unsigned char ucCacheType; /* CacheType_Normal 0x00, */
/* CacheType_CAN 0x01, */
/* CacheType_HEIMDALL 0x02 */
/* new as of 27-10-2004 */
unsigned char uiSramStartAddr[2]; /* Start of SRAM */
unsigned char ucResetType; /* Selects reset type. ResetNormal = 0x00 */
/* ResetAT76CXXX = 0x01 */
unsigned char ucPCMaskExtended; /* For parts with extended PC */
unsigned char ucPCMaskHigh; /* PC high mask */
unsigned char ucEindAddress; /* Selects reset type. [EIND address...] */
/* new as of early 2005, firmware 4.x */
unsigned char EECRAddress[2]; /* EECR memory-mapped IO address */
};

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -115,30 +115,22 @@ SIGN [+-]
exit(1); }
}
allowfullpagebitstream { yylval=NULL; return K_ALLOWFULLPAGEBITSTREAM; }
avr910 { yylval=NULL; return K_AVR910; }
avr910_devcode { yylval=NULL; return K_AVR910_DEVCODE; }
bank_size { yylval=NULL; return K_PAGE_SIZE; }
banked { yylval=NULL; return K_PAGED; }
baudrate { yylval=NULL; return K_BAUDRATE; }
bs2 { yylval=NULL; return K_BS2; }
buff { yylval=NULL; return K_BUFF; }
butterfly { yylval=NULL; return K_BUTTERFLY; }
chip_erase_delay { yylval=NULL; return K_CHIP_ERASE_DELAY; }
desc { yylval=NULL; return K_DESC; }
default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
devicecode { yylval=NULL; return K_DEVICECODE; }
eecr { yylval=NULL; return K_EECR; }
stk500_devcode { yylval=NULL; return K_STK500_DEVCODE; }
avr910_devcode { yylval=NULL; return K_AVR910_DEVCODE; }
eeprom { yylval=NULL; return K_EEPROM; }
enablepageprogramming { yylval=NULL; return K_ENABLEPAGEPROGRAMMING; }
errled { yylval=NULL; return K_ERRLED; }
flash { yylval=NULL; return K_FLASH; }
has_jtag { yylval=NULL; return K_HAS_JTAG; }
id { yylval=NULL; return K_ID; }
idr { yylval=NULL; return K_IDR; }
jtagmkii { yylval=NULL; return K_JTAG_MKII; }
max_write_delay { yylval=NULL; return K_MAX_WRITE_DELAY; }
memory { yylval=NULL; return K_MEMORY; }
min_write_delay { yylval=NULL; return K_MIN_WRITE_DELAY; }
@@ -155,38 +147,18 @@ part { yylval=NULL; return K_PART; }
pgmled { yylval=NULL; return K_PGMLED; }
programmer { yylval=NULL; return K_PROGRAMMER; }
pwroff_after_write { yylval=NULL; return K_PWROFF_AFTER_WRITE; }
rampz { yylval=NULL; return K_RAMPZ; }
rdyled { yylval=NULL; return K_RDYLED; }
readback_p1 { yylval=NULL; return K_READBACK_P1; }
readback_p2 { yylval=NULL; return K_READBACK_P2; }
retry_pulse { yylval=NULL; return K_RETRY_PULSE; }
serbb { yylval=NULL; return K_SERBB; }
serial { yylval=NULL; return K_SERIAL; }
size { yylval=NULL; return K_SIZE; }
spmcr { yylval=NULL; return K_SPMCR; }
stk500 { yylval=NULL; return K_STK500; }
stk500v2 { yylval=NULL; return K_STK500V2; }
stk500_devcode { yylval=NULL; return K_STK500_DEVCODE; }
avr910 { yylval=NULL; return K_AVR910; }
type { yylval=NULL; return K_TYPE; }
vcc { yylval=NULL; return K_VCC; }
vfyled { yylval=NULL; return K_VFYLED; }
timeout { yylval=NULL; return K_TIMEOUT; }
stabdelay { yylval=NULL; return K_STABDELAY; }
cmdexedelay { yylval=NULL; return K_CMDEXEDELAY; }
synchloops { yylval=NULL; return K_SYNCHLOOPS; }
bytedelay { yylval=NULL; return K_BYTEDELAY; }
pollvalue { yylval=NULL; return K_POLLVALUE; }
pollindex { yylval=NULL; return K_POLLINDEX; }
predelay { yylval=NULL; return K_PREDELAY; }
postdelay { yylval=NULL; return K_POSTDELAY; }
pollmethod { yylval=NULL; return K_POLLMETHOD; }
mode { yylval=NULL; return K_MODE; }
delay { yylval=NULL; return K_DELAY; }
blocksize { yylval=NULL; return K_BLOCKSIZE; }
readsize { yylval=NULL; return K_READSIZE; }
dedicated { yylval=new_token(K_DEDICATED); return K_DEDICATED; }
io { yylval=new_token(K_IO); return K_IO; }
@@ -213,7 +185,6 @@ yes { yylval=new_token(K_YES); return K_YES; }
"," { yylval = NULL; pyytext(); return TKN_COMMA; }
"=" { yylval = NULL; pyytext(); return TKN_EQUAL; }
";" { yylval = NULL; pyytext(); return TKN_SEMI; }
"~" { yylval = NULL; pyytext(); return TKN_TILDE; }
"\n" { lineno++; }
[ \r\t]+ /* ignore whitespace */

View File

@@ -1,6 +1,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 1990-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
* 1998, 1999, 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -412,6 +413,11 @@ lcreat ( void * liststruct, int elements )
{
LIST * l;
if (LISTSZ != sizeof(LIST)) {
printf ( "lcreat(): warning, LISTSZ[%d] != sizeof(LIST)[%d]\n",
LISTSZ, sizeof(LIST) );
}
if (liststruct == NULL) {
/*--------------------------------------------------
allocate memory for the list itself

View File

@@ -1,6 +1,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 1990-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
* 1998, 1999, 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -67,6 +68,9 @@ typedef void * LNODEID;
#define LISTRMV(l,d) lrmv_d(l,d) /* remove from end of the list */
#define LISTSZ 32 /* size of internal private LIST structure */
/* .................... Function Prototypes .................... */
LISTID lcreat ( void * liststruct, int poolsize );

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -37,8 +37,8 @@
#include "avr.h"
#include "pindefs.h"
#include "pgm.h"
#include "par.h"
#include "ppi.h"
#include "bitbang.h"
#define SLOW_TOGGLE 0
@@ -49,7 +49,7 @@ struct ppipins_t {
int inverted;
};
struct ppipins_t ppipins[] = {
static struct ppipins_t pins[] = {
{ 1, PPICTRL, 0x01, 1 },
{ 2, PPIDATA, 0x01, 0 },
{ 3, PPIDATA, 0x02, 0 },
@@ -69,30 +69,70 @@ struct ppipins_t ppipins[] = {
{ 17, PPICTRL, 0x08, 1 }
};
#define NPINS (sizeof(ppipins)/sizeof(struct ppipins_t))
#define NPINS (sizeof(pins)/sizeof(struct ppipins_t))
extern char * progname;
extern int do_cycles;
extern int verbose;
int par_setpin(int fd, int pin, int value)
{
pin &= PIN_MASK;
static int par_setpin (int fd, int pin, int value);
static int par_getpin (int fd, int pin);
static int par_pulsepin (int fd, int pin);
static int par_rdy_led (PROGRAMMER * pgm, int value);
static int par_err_led (PROGRAMMER * pgm, int value);
static int par_pgm_led (PROGRAMMER * pgm, int value);
static int par_vfy_led (PROGRAMMER * pgm, int value);
static int par_cmd (PROGRAMMER * pgm, unsigned char cmd[4],
unsigned char res[4]);
static int par_chip_erase (PROGRAMMER * pgm, AVRPART * p);
static int par_program_enable (PROGRAMMER * pgm, AVRPART * p);
static void par_powerup (PROGRAMMER * pgm);
static void par_powerdown (PROGRAMMER * pgm);
static int par_initialize (PROGRAMMER * pgm, AVRPART * p);
static int par_save (PROGRAMMER * pgm);
static void par_restore (PROGRAMMER * pgm);
static void par_disable (PROGRAMMER * pgm);
static void par_enable (PROGRAMMER * pgm);
static void par_open (PROGRAMMER * pgm, char * port);
static void par_close (PROGRAMMER * pgm);
static int par_setpin(int fd, int pin, int value)
{
if (pin < 1 || pin > 17)
return -1;
pin--;
if (ppipins[pin].inverted)
if (pins[pin].inverted)
value = !value;
if (value)
ppi_set(fd, ppipins[pin].reg, ppipins[pin].bit);
ppi_set(fd, pins[pin].reg, pins[pin].bit);
else
ppi_clr(fd, ppipins[pin].reg, ppipins[pin].bit);
ppi_clr(fd, pins[pin].reg, pins[pin].bit);
#if SLOW_TOGGLE
usleep(1000);
@@ -102,30 +142,28 @@ int par_setpin(int fd, int pin, int value)
}
int par_getpin(int fd, int pin)
static int par_getpin(int fd, int pin)
{
int value;
pin &= PIN_MASK;
if (pin < 1 || pin > 17)
return -1;
pin--;
value = ppi_get(fd, ppipins[pin].reg, ppipins[pin].bit);
value = ppi_get(fd, pins[pin].reg, pins[pin].bit);
if (value)
value = 1;
if (ppipins[pin].inverted)
if (pins[pin].inverted)
value = !value;
return value;
}
int par_highpulsepin(int fd, int pin)
static int par_pulsepin(int fd, int pin)
{
if (pin < 1 || pin > 17)
@@ -133,11 +171,13 @@ int par_highpulsepin(int fd, int pin)
pin--;
ppi_set(fd, ppipins[pin].reg, ppipins[pin].bit);
ppi_toggle(fd, pins[pin].reg, pins[pin].bit);
#if SLOW_TOGGLE
usleep(1000);
#endif
ppi_clr(fd, ppipins[pin].reg, ppipins[pin].bit);
ppi_toggle(fd, pins[pin].reg, pins[pin].bit);
#if SLOW_TOGGLE
usleep(1000);
@@ -148,17 +188,15 @@ int par_highpulsepin(int fd, int pin)
int par_getpinmask(int pin)
{
pin &= PIN_MASK;
if (pin < 1 || pin > 17)
return -1;
return ppipins[pin-1].bit;
return pins[pin-1].bit;
}
char vccpins_buf[64];
char * vccpins_str(unsigned int pmask)
static char vccpins_buf[64];
static char * vccpins_str(unsigned int pmask)
{
unsigned int mask;
int pin;
@@ -180,10 +218,182 @@ char * vccpins_str(unsigned int pmask)
return b;
}
/*
* transmit and receive a byte of data to/from the AVR device
*/
static unsigned char par_txrx(PROGRAMMER * pgm, unsigned char byte)
{
int i;
unsigned char r, b, rbyte;
rbyte = 0;
for (i=0; i<8; i++) {
b = (byte >> (7-i)) & 0x01;
/*
* read the result bit (it is either valid from a previous clock
* pulse or it is ignored in the current context)
*/
r = par_getpin(pgm->fd, pgm->pinno[PIN_AVR_MISO]);
/* set the data input line as desired */
par_setpin(pgm->fd, pgm->pinno[PIN_AVR_MOSI], b);
/*
* pulse the clock line, clocking in the MOSI data, and clocking out
* the next result bit
*/
par_pulsepin(pgm->fd, pgm->pinno[PIN_AVR_SCK]);
rbyte = rbyte | (r << (7-i));
}
return rbyte;
}
static int par_rdy_led(PROGRAMMER * pgm, int value)
{
par_setpin(pgm->fd, pgm->pinno[PIN_LED_RDY], !value);
return 0;
}
static int par_err_led(PROGRAMMER * pgm, int value)
{
par_setpin(pgm->fd, pgm->pinno[PIN_LED_ERR], !value);
return 0;
}
static int par_pgm_led(PROGRAMMER * pgm, int value)
{
par_setpin(pgm->fd, pgm->pinno[PIN_LED_PGM], !value);
return 0;
}
static int par_vfy_led(PROGRAMMER * pgm, int value)
{
par_setpin(pgm->fd, pgm->pinno[PIN_LED_VFY], !value);
return 0;
}
/*
* transmit an AVR device command and return the results; 'cmd' and
* 'res' must point to at least a 4 byte data buffer
*/
static int par_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
unsigned char res[4])
{
int i;
for (i=0; i<4; i++) {
res[i] = par_txrx(pgm, cmd[i]);
}
if(verbose >= 2)
{
fprintf(stderr, "par_cmd(): [ ");
for(i = 0; i < 4; i++)
fprintf(stderr, "%02X ", cmd[i]);
fprintf(stderr, "] [ ");
for(i = 0; i < 4; i++)
{
fprintf(stderr, "%02X ", res[i]);
}
fprintf(stderr, "]\n");
}
return 0;
}
/*
* issue the 'chip erase' command to the AVR device
*/
static int par_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
unsigned char cmd[4];
unsigned char res[4];
int cycles;
int rc;
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
fprintf(stderr, "chip erase instruction not defined for part \"%s\"\n",
p->desc);
return -1;
}
rc = avr_get_cycle_count(pgm, p, &cycles);
/*
* only print out the current cycle count if we aren't going to
* display it below
*/
if (!do_cycles && ((rc >= 0) && (cycles != 0xffffffff))) {
fprintf(stderr,
"%s: current erase-rewrite cycle count is %d%s\n",
progname, cycles,
do_cycles ? "" : " (if being tracked)");
}
pgm->pgm_led(pgm, ON);
memset(cmd, 0, sizeof(cmd));
avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
pgm->cmd(pgm, cmd, res);
usleep(p->chip_erase_delay);
pgm->initialize(pgm, p);
pgm->pgm_led(pgm, OFF);
if (do_cycles && (cycles != -1)) {
if (cycles == 0x00ffff) {
cycles = 0;
}
cycles++;
fprintf(stderr, "%s: erase-rewrite cycle count is now %d\n",
progname, cycles);
avr_put_cycle_count(pgm, p, cycles);
}
return 0;
}
/*
* issue the 'program enable' command to the AVR device
*/
static int par_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
unsigned char cmd[4];
unsigned char res[4];
if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
fprintf(stderr, "program enable instruction not defined for part \"%s\"\n",
p->desc);
return -1;
}
memset(cmd, 0, sizeof(cmd));
avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd);
pgm->cmd(pgm, cmd, res);
if (res[2] != cmd[1])
return -2;
return 0;
}
/*
* apply power to the AVR processor
*/
void par_powerup(PROGRAMMER * pgm)
static void par_powerup(PROGRAMMER * pgm)
{
ppi_set(pgm->fd, PPIDATA, pgm->pinno[PPI_AVR_VCC]); /* power up */
usleep(100000);
@@ -193,17 +403,91 @@ void par_powerup(PROGRAMMER * pgm)
/*
* remove power from the AVR processor
*/
void par_powerdown(PROGRAMMER * pgm)
static void par_powerdown(PROGRAMMER * pgm)
{
ppi_clr(pgm->fd, PPIDATA, pgm->pinno[PPI_AVR_VCC]); /* power down */
}
void par_disable(PROGRAMMER * pgm)
/*
* initialize the AVR device and prepare it to accept commands
*/
static int par_initialize(PROGRAMMER * pgm, AVRPART * p)
{
int rc;
int tries;
pgm->powerup(pgm);
usleep(20000);
par_setpin(pgm->fd, pgm->pinno[PIN_AVR_SCK], 0);
par_setpin(pgm->fd, pgm->pinno[PIN_AVR_RESET], 0);
usleep(20000);
par_pulsepin(pgm->fd, pgm->pinno[PIN_AVR_RESET]);
usleep(20000); /* 20 ms XXX should be a per-chip parameter */
/*
* Enable programming mode. If we are programming an AT90S1200, we
* can only issue the command and hope it worked. If we are using
* one of the other chips, the chip will echo 0x53 when issuing the
* third byte of the command. In this case, try up to 32 times in
* order to possibly get back into sync with the chip if we are out
* of sync.
*/
if (strcmp(p->desc, "AT90S1200")==0) {
pgm->program_enable(pgm, p);
}
else {
tries = 0;
do {
rc = pgm->program_enable(pgm, p);
if ((rc == 0)||(rc == -1))
break;
par_pulsepin(pgm->fd, pgm->pinno[p->retry_pulse/*PIN_AVR_SCK*/]);
tries++;
} while (tries < 65);
/*
* can't sync with the device, maybe it's not attached?
*/
if (rc) {
fprintf(stderr, "%s: AVR device not responding\n", progname);
return -1;
}
}
return 0;
}
static int par_save(PROGRAMMER * pgm)
{
int rc;
rc = ppi_getall(pgm->fd, PPIDATA);
if (rc < 0) {
fprintf(stderr, "%s: error reading status of ppi data port\n", progname);
return -1;
}
pgm->ppidata = rc;
return 0;
}
static void par_restore(PROGRAMMER * pgm)
{
ppi_setall(pgm->fd, PPIDATA, pgm->ppidata);
}
static void par_disable(PROGRAMMER * pgm)
{
ppi_set(pgm->fd, PPIDATA, pgm->pinno[PPI_AVR_BUFF]);
}
void par_enable(PROGRAMMER * pgm)
static void par_enable(PROGRAMMER * pgm)
{
/*
* Prepare to start talking to the connected device - pull reset low
@@ -225,10 +509,9 @@ void par_enable(PROGRAMMER * pgm)
ppi_clr(pgm->fd, PPIDATA, pgm->pinno[PPI_AVR_BUFF]);
}
int par_open(PROGRAMMER * pgm, char * port)
{
int rc;
static void par_open(PROGRAMMER * pgm, char * port)
{
pgm->fd = ppi_open(port);
if (pgm->fd < 0) {
fprintf(stderr, "%s: failed to open parallel port \"%s\"\n\n",
@@ -237,51 +520,25 @@ int par_open(PROGRAMMER * pgm, char * port)
}
ppi_claim(pgm);
/*
* save pin values, so they can be restored when device is closed
*/
rc = ppi_getall(pgm->fd, PPIDATA);
if (rc < 0) {
fprintf(stderr, "%s: error reading status of ppi data port\n", progname);
return -1;
}
pgm->ppidata = rc;
rc = ppi_getall(pgm->fd, PPICTRL);
if (rc < 0) {
fprintf(stderr, "%s: error reading status of ppi ctrl port\n", progname);
return -1;
}
pgm->ppictrl = rc;
return 0;
}
void par_close(PROGRAMMER * pgm)
static void par_close(PROGRAMMER * pgm)
{
/*
* Restore pin values before closing,
* but ensure that buffers are turned off.
*/
pgm->ppidata |= pgm->pinno[PPI_AVR_BUFF];
ppi_setall(pgm->fd, PPIDATA, pgm->ppidata);
ppi_setall(pgm->fd, PPICTRL, pgm->ppictrl);
ppi_release(pgm);
ppi_close(pgm->fd);
pgm->fd = -1;
}
void par_display(PROGRAMMER * pgm, char * p)
static void par_display(PROGRAMMER * pgm, char * p)
{
char vccpins[64];
char buffpins[64];
if (pgm->pinno[PPI_AVR_VCC]) {
snprintf(vccpins, sizeof(vccpins), " = pins %s",
snprintf(vccpins, sizeof(vccpins), " = pins %s",
vccpins_str(pgm->pinno[PPI_AVR_VCC]));
}
else {
@@ -325,22 +582,23 @@ void par_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "PPI");
pgm->rdy_led = bitbang_rdy_led;
pgm->err_led = bitbang_err_led;
pgm->pgm_led = bitbang_pgm_led;
pgm->vfy_led = bitbang_vfy_led;
pgm->initialize = bitbang_initialize;
pgm->rdy_led = par_rdy_led;
pgm->err_led = par_err_led;
pgm->pgm_led = par_pgm_led;
pgm->vfy_led = par_vfy_led;
pgm->initialize = par_initialize;
pgm->display = par_display;
pgm->save = par_save;
pgm->restore = par_restore;
pgm->enable = par_enable;
pgm->disable = par_disable;
pgm->powerup = par_powerup;
pgm->powerdown = par_powerdown;
pgm->program_enable = bitbang_program_enable;
pgm->chip_erase = bitbang_chip_erase;
pgm->cmd = bitbang_cmd;
pgm->program_enable = par_program_enable;
pgm->chip_erase = par_chip_erase;
pgm->cmd = par_cmd;
pgm->open = par_open;
pgm->close = par_close;
/* this is a parallel port bitbang device */
pgm->flag = 0;
}

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,12 +22,11 @@
#ifndef __par_h__
#define __par_h__
#include "config.h"
void par_initpgm (PROGRAMMER * pgm);
int par_getpinmask(int pin);
int par_setpin(int fd, int pin, int value);
int par_getpin(int fd, int pin);
int par_highpulsepin(int fd, int pin);
#endif

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,35 +29,13 @@
extern char * progname;
static int pgm_default_2 (struct programmer_t *, AVRPART *);
static void pgm_default_4 (struct programmer_t *);
static int pgm_default_5 (struct programmer_t *, unsigned char cmd[4],
int pgm_default_1 (struct programmer_t *, int);
int pgm_default_2 (struct programmer_t *, AVRPART *);
int pgm_default_3 (struct programmer_t *);
void pgm_default_4 (struct programmer_t *);
int pgm_default_5 (struct programmer_t *, unsigned char cmd[4],
unsigned char res[4]);
static void pgm_default_6 (struct programmer_t *, char *);
static int pgm_default_open (struct programmer_t *pgm, char * name)
{
fprintf (stderr, "\n%s: Fatal error: Programmer does not support open()",
progname);
exit(1);
}
static int pgm_default_led (struct programmer_t * pgm, int value)
{
/*
* If programmer has no LEDs, just do nothing.
*/
return 0;
}
static void pgm_default_powerup_powerdown (struct programmer_t * pgm)
{
/*
* If programmer does not support powerup/down, just do nothing.
*/
}
void pgm_default_6 (struct programmer_t *, char *);
PROGRAMMER * pgm_new(void)
@@ -79,7 +57,6 @@ PROGRAMMER * pgm_new(void)
pgm->type[0] = 0;
pgm->config_file[0] = 0;
pgm->lineno = 0;
pgm->baudrate = 0;
for (i=0; i<N_PINS; i++)
pgm->pinno[i] = 0;
@@ -88,28 +65,24 @@ PROGRAMMER * pgm_new(void)
* mandatory functions - these are called without checking to see
* whether they are assigned or not
*/
pgm->rdy_led = pgm_default_1;
pgm->err_led = pgm_default_1;
pgm->pgm_led = pgm_default_1;
pgm->vfy_led = pgm_default_1;
pgm->initialize = pgm_default_2;
pgm->display = pgm_default_6;
pgm->save = pgm_default_3;
pgm->restore = pgm_default_4;
pgm->enable = pgm_default_4;
pgm->disable = pgm_default_4;
pgm->powerup = pgm_default_powerup_powerdown;
pgm->powerdown = pgm_default_powerup_powerdown;
pgm->powerup = pgm_default_4;
pgm->powerdown = pgm_default_4;
pgm->program_enable = pgm_default_2;
pgm->chip_erase = pgm_default_2;
pgm->cmd = pgm_default_5;
pgm->open = pgm_default_open;
pgm->open = pgm_default_6;
pgm->close = pgm_default_4;
/*
* predefined functions - these functions have a valid default
* implementation. Hence, they don't need to be defined in
* the programmer.
*/
pgm->rdy_led = pgm_default_led;
pgm->err_led = pgm_default_led;
pgm->pgm_led = pgm_default_led;
pgm->vfy_led = pgm_default_led;
/*
* optional functions - these are checked to make sure they are
* assigned before they are called
@@ -128,31 +101,43 @@ PROGRAMMER * pgm_new(void)
}
static void pgm_default(void)
void pgm_default(void)
{
fprintf(stderr, "%s: programmer operation not supported\n", progname);
}
static int pgm_default_2 (struct programmer_t * pgm, AVRPART * p)
int pgm_default_1 (struct programmer_t * pgm, int value)
{
pgm_default();
return -1;
}
static void pgm_default_4 (struct programmer_t * pgm)
int pgm_default_2 (struct programmer_t * pgm, AVRPART * p)
{
pgm_default();
return -1;
}
int pgm_default_3 (struct programmer_t * pgm)
{
pgm_default();
return -1;
}
void pgm_default_4 (struct programmer_t * pgm)
{
pgm_default();
}
static int pgm_default_5 (struct programmer_t * pgm, unsigned char cmd[4],
int pgm_default_5 (struct programmer_t * pgm, unsigned char cmd[4],
unsigned char res[4])
{
pgm_default();
return -1;
}
static void pgm_default_6 (struct programmer_t * pgm, char * p)
void pgm_default_6 (struct programmer_t * pgm, char * p)
{
pgm_default();
}

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,9 +35,6 @@
#define PGM_DESCLEN 80
#define PGM_PORTLEN PATH_MAX
#define PGM_TYPELEN 32
extern LISTID programmers;
typedef struct programmer_t {
LISTID id;
char desc[PGM_DESCLEN];
@@ -45,9 +42,6 @@ typedef struct programmer_t {
char port[PGM_PORTLEN];
unsigned int pinno[N_PINS];
int ppidata;
int ppictrl;
int baudrate;
double bitclock; /* JTAG ICE clock period in microseconds */
int fd;
int page_size; /* page size if the programmer supports paged write/load */
int (*rdy_led) (struct programmer_t * pgm, int value);
@@ -56,6 +50,8 @@ typedef struct programmer_t {
int (*vfy_led) (struct programmer_t * pgm, int value);
int (*initialize) (struct programmer_t * pgm, AVRPART * p);
void (*display) (struct programmer_t * pgm, char * p);
int (*save) (struct programmer_t * pgm);
void (*restore) (struct programmer_t * pgm);
void (*enable) (struct programmer_t * pgm);
void (*disable) (struct programmer_t * pgm);
void (*powerup) (struct programmer_t * pgm);
@@ -64,7 +60,7 @@ typedef struct programmer_t {
int (*chip_erase) (struct programmer_t * pgm, AVRPART * p);
int (*cmd) (struct programmer_t * pgm, unsigned char cmd[4],
unsigned char res[4]);
int (*open) (struct programmer_t * pgm, char * port);
void (*open) (struct programmer_t * pgm, char * port);
void (*close) (struct programmer_t * pgm);
int (*paged_write) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes);
@@ -80,41 +76,11 @@ typedef struct programmer_t {
int (*set_vtarget) (struct programmer_t * pgm, double v);
int (*set_varef) (struct programmer_t * pgm, double v);
int (*set_fosc) (struct programmer_t * pgm, double v);
int (*set_sck_period) (struct programmer_t * pgm, double v);
char config_file[PATH_MAX]; /* config file where defined */
int lineno; /* config file line number */
char flag; /* for private use of the programmer */
} PROGRAMMER;
PROGRAMMER * pgm_new(void);
#if defined(WIN32NATIVE)
#include <windows.h>
/* usleep replacements */
/* sleep Windows in ms, Unix usleep in us
#define usleep(us) Sleep((us)<20000?20:us/1000)
#define usleep(us) Sleep(us/1000)
#define ANTIWARP 3
#define usleep(us) Sleep(us/1000*ANTIWARP)
*/
void usleep(unsigned long us);
void gettimeofday(struct timeval*, void*z);
#define rindex strrchr
#endif /* __win32native_h */
#if !defined(ppi_claim)
# define ppi_claim(pgm)
#endif
#if !defined(ppi_release)
# define ppi_release(pgm)
#endif
#endif

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,8 +35,6 @@ enum {
PIN_LED_VFY,
N_PINS
};
#define PIN_INVERSE 0x80 /* flag for inverted pin in serbb */
#define PIN_MASK 0x7f
#define LED_ON(fd,pin) ppi_setpin(fd,pin,0)
#define LED_OFF(fd,pin) ppi_setpin(fd,pin,1)

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -43,33 +43,24 @@
extern char * progname;
enum {
PPI_READ,
PPI_WRITE,
PPI_SHADOWREAD
};
int ppi_shadow_access(int fd, int reg, unsigned char *v, unsigned char action)
/*
* set 'get' and 'set' appropriately for subsequent passage to ioctl()
* to get/set the specified PPI registers.
*/
static int ppi_getops(int reg, unsigned long * get, unsigned long * set)
{
static unsigned char shadow[3];
int shadow_num;
unsigned long set, get;
switch (reg) {
case PPIDATA:
set = PPISDATA;
get = PPIGDATA;
shadow_num = 0;
*set = PPISDATA;
*get = PPIGDATA;
break;
case PPICTRL:
set = PPISCTRL;
get = PPIGCTRL;
shadow_num = 1;
*set = PPISCTRL;
*get = PPIGCTRL;
break;
case PPISTATUS:
set = PPISSTATUS;
get = PPIGSTATUS;
shadow_num = 2;
*set = PPISSTATUS;
*get = PPIGSTATUS;
break;
default:
fprintf(stderr, "%s: avr_set(): invalid register=%d\n",
@@ -78,37 +69,27 @@ int ppi_shadow_access(int fd, int reg, unsigned char *v, unsigned char action)
break;
}
switch (action) {
case PPI_SHADOWREAD:
*v = shadow[shadow_num];
break;
case PPI_READ:
ioctl(fd, get, v);
shadow[shadow_num]=*v;
break;
case PPI_WRITE:
shadow[shadow_num]=*v;
ioctl(fd, set, v);
break;
}
return 0;
}
/*
* set the indicated bit of the specified register.
*/
int ppi_set(int fd, int reg, int bit)
{
unsigned char v;
unsigned long get, set;
int rc;
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
v |= bit;
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
rc = ppi_getops(reg, &get, &set);
if (rc)
return -1;
ioctl(fd, get, &v);
v |= bit;
ioctl(fd, set, &v);
return 0;
}
@@ -119,15 +100,17 @@ int ppi_set(int fd, int reg, int bit)
int ppi_clr(int fd, int reg, int bit)
{
unsigned char v;
unsigned long get, set;
int rc;
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
v &= ~bit;
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
rc = ppi_getops(reg, &get, &set);
if (rc)
return -1;
ioctl(fd, get, &v);
v &= ~bit;
ioctl(fd, set, &v);
return 0;
}
@@ -138,14 +121,16 @@ int ppi_clr(int fd, int reg, int bit)
int ppi_get(int fd, int reg, int bit)
{
unsigned char v;
unsigned long get, set;
int rc;
rc = ppi_shadow_access(fd, reg, &v, PPI_READ);
v &= bit;
rc = ppi_getops(reg, &get, &set);
if (rc)
return -1;
ioctl(fd, get, &v);
v &= bit;
return v; /* v == bit */
}
@@ -155,15 +140,17 @@ int ppi_get(int fd, int reg, int bit)
int ppi_toggle(int fd, int reg, int bit)
{
unsigned char v;
unsigned long get, set;
int rc;
rc = ppi_shadow_access(fd, reg, &v, PPI_SHADOWREAD);
v ^= bit;
rc |= ppi_shadow_access(fd, reg, &v, PPI_WRITE);
rc = ppi_getops(reg, &get, &set);
if (rc)
return -1;
ioctl(fd, get, &v);
v ^= bit;
ioctl(fd, set, &v);
return 0;
}
@@ -174,14 +161,16 @@ int ppi_toggle(int fd, int reg, int bit)
int ppi_getall(int fd, int reg)
{
unsigned char v;
unsigned long get, set;
int rc;
rc = ppi_shadow_access(fd, reg, &v, PPI_READ);
rc = ppi_getops(reg, &get, &set);
if (rc)
return -1;
return v; /* v == bit */
ioctl(fd, get, &v);
return (int)v;
}
/*
@@ -190,14 +179,16 @@ int ppi_getall(int fd, int reg)
int ppi_setall(int fd, int reg, int val)
{
unsigned char v;
unsigned long get, set;
int rc;
v = val;
rc = ppi_shadow_access(fd, reg, &v, PPI_WRITE);
rc = ppi_getops(reg, &get, &set);
if (rc)
return -1;
v = val;
ioctl(fd, set, &v);
return 0;
}
@@ -205,7 +196,6 @@ int ppi_setall(int fd, int reg, int val)
int ppi_open(char * port)
{
int fd;
unsigned char v;
fd = open(port, O_RDWR);
if (fd < 0) {
@@ -214,14 +204,6 @@ int ppi_open(char * port)
return -1;
}
/*
* Initialize shadow registers
*/
ppi_shadow_access (fd, PPIDATA, &v, PPI_READ);
ppi_shadow_access (fd, PPICTRL, &v, PPI_READ);
ppi_shadow_access (fd, PPISTATUS, &v, PPI_READ);
return fd;
}
@@ -232,75 +214,4 @@ void ppi_close(int fd)
}
#elif defined(__POWERPC__) && defined(__APPLE__)
int ppi_shadow_access(int fd, int reg, unsigned char *v, unsigned char action)
{
return -1;
}
/*
* set the indicated bit of the specified register.
*/
int ppi_set(int fd, int reg, int bit)
{
return -1;
}
/*
* clear the indicated bit of the specified register.
*/
int ppi_clr(int fd, int reg, int bit)
{
return -1;
}
/*
* get the indicated bit of the specified register.
*/
int ppi_get(int fd, int reg, int bit)
{
return -1;
}
/*
* toggle the indicated bit of the specified register.
*/
int ppi_toggle(int fd, int reg, int bit)
{
return -1;
}
/*
* get all bits of the specified register.
*/
int ppi_getall(int fd, int reg)
{
return -1;
}
/*
* set all bits of the specified register to val.
*/
int ppi_setall(int fd, int reg, int val)
{
return -1;
}
int ppi_open(char * port)
{
return -1;
}
void ppi_close(int fd)
{
}
#endif

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,6 +22,8 @@
#ifndef __ppi_h__
#define __ppi_h__
#include "config.h"
/*
* PPI registers
*/
@@ -32,6 +34,13 @@ enum {
};
#if !defined(ppi_claim)
# define ppi_claim(pgm)
#endif
#if !defined(ppi_release)
# define ppi_release(pgm)
#endif
int ppi_get (int fd, int reg, int bit);

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003, 2004 Eric B. Weddington <ericw@evcohs.com>
* Copyright (C) 2003 Eric B. Weddington <eric@ecentral.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,7 +17,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* $Id$ */
/*
This is the parallel port interface for Windows built using Cygwin.
@@ -31,7 +30,7 @@ reg = register as defined in an enum in ppi.h. This must be converted
#if defined (WIN32NATIVE)
#if defined(__CYGWIN__)
#include <errno.h>
#include <fcntl.h>
@@ -41,9 +40,11 @@ reg = register as defined in an enum in ppi.h. This must be converted
#include <unistd.h>
#include <windows.h>
#include <sys/time.h>
#include <windows.h>
#include <w32api/windows.h>
#include "ppi.h"
extern char *progname;
@@ -316,73 +317,80 @@ static void outb(unsigned char value, unsigned short port)
return;
}
void gettimeofday(struct timeval*tv, void*z){
// i've found only ms resolution, avrdude expects us
/* These two functions usecPerfDelay and usleep are based on code from the
* uisp project and are a replacement for the cygwin usleep library
* function which seems to not delay for the correct time
*/
SYSTEMTIME st;
GetSystemTime(&st);
tv->tv_sec=(long)(st.wSecond+st.wMinute*60+st.wHour*3600);
tv->tv_usec=(long)(st.wMilliseconds*1000);
}
// #define W32USLEEPDBG
#ifdef W32USLEEPDBG
# define DEBUG_QueryPerformanceCounter(arg) QueryPerformanceCounter(arg)
# define DEBUG_DisplayTimingInfo(start, stop, freq, us, has_highperf) \
do { \
unsigned long dt; \
dt = (unsigned long)((stop.QuadPart - start.QuadPart) * 1000 * 1000 \
/ freq.QuadPart); \
fprintf(stderr, \
"hpt:%i usleep usec:%lu sleep msec:%lu timed usec:%lu\n", \
has_highperf, us, ((us + 999) / 1000), dt); \
} while (0)
#else
# define DEBUG_QueryPerformanceCounter(arg)
# define DEBUG_DisplayTimingInfo(start, stop, freq, us, has_highperf)
#endif
void usleep(unsigned long us)
BOOL usecPerfDelay(long t)
{
int has_highperf;
LARGE_INTEGER freq,start,stop,loopend;
static BOOL perf_counter_checked = FALSE;
static BOOL use_perf_counter = FALSE;
static LARGE_INTEGER freq ;
// workaround: although usleep is very precise if using
// high-performance-timers there are sometimes problems with
// verify - increasing the delay helps sometimes but not
// realiably. There must be some other problem. Maybe just
// with my test-hardware maybe in the code-base.
//// us=(unsigned long) (us*1.5);
if (! perf_counter_checked) {
if (QueryPerformanceFrequency(&freq)){
use_perf_counter = TRUE;
}
perf_counter_checked = TRUE;
}
has_highperf=QueryPerformanceFrequency(&freq);
if (! use_perf_counter)
return FALSE;
//has_highperf=0; // debug
else {
LARGE_INTEGER now;
LARGE_INTEGER finish;
QueryPerformanceCounter(&now);
finish.QuadPart = now.QuadPart + (t * freq.QuadPart) / 1000000;
do {
QueryPerformanceCounter(&now);
} while (now.QuadPart < finish.QuadPart);
if (has_highperf) {
QueryPerformanceCounter(&start);
loopend.QuadPart=start.QuadPart+freq.QuadPart*us/(1000*1000);
do {
QueryPerformanceCounter(&stop);
} while (stop.QuadPart<=loopend.QuadPart);
}
else {
DEBUG_QueryPerformanceCounter(&start);
Sleep(1);
Sleep( (DWORD)((us+999)/1000) );
DEBUG_QueryPerformanceCounter(&stop);
}
DEBUG_DisplayTimingInfo(start, stop, freq, us, has_highperf);
return TRUE;
}
}
/*
WARNING WARNING This function replaces the standard usleep() library function
because it doesn't appear to delay for the correct time.
*/
#ifndef MIN_SLEEP_USEC
#define MIN_SLEEP_USEC 20000
#endif
unsigned usleep( unsigned int uSeconds )
{
struct timeval t1, t2;
struct timespec nanoDelay ;
if (usecPerfDelay(uSeconds))
return(0);
gettimeofday(&t1, NULL);
if( uSeconds > MIN_SLEEP_USEC )
{
nanoDelay.tv_sec = uSeconds / 1000000UL;
nanoDelay.tv_nsec = (uSeconds / 1000000UL) * 1000 ;
nanosleep( &nanoDelay, NULL ) ;
}
/* loop for the remaining time */
t2.tv_sec = uSeconds / 1000000UL;
t2.tv_usec = uSeconds % 1000000UL;
timeradd(&t1, &t2, &t1);
do {
gettimeofday(&t2, NULL);
} while (timercmp(&t2, &t1, <));
return(0);
}
#endif

View File

@@ -1,247 +0,0 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* avrdude is Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
*
* This file: Copyright (C) 2005 Colin O'Flynn <coflynn@newae.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include "ac_cfg.h"
#include "avr.h"
#include "pgm.h"
#include "safemode.h"
/* This value from ac_cfg.h */
char * progname = PACKAGE_NAME;
/*
* Writes the specified fuse in fusename (can be "lfuse", "hfuse", or
* "efuse") and verifies it. Will try up to tries amount of times
* before giving up
*/
int safemode_writefuse (unsigned char fuse, char * fusename, PROGRAMMER * pgm,
AVRPART * p, int tries, int verbose)
{
AVRMEM * m;
unsigned char fuseread;
int returnvalue = -1;
m = avr_locate_mem(p, fusename);
if (m == NULL) {
return -1;
}
/* Keep trying to write then read back the fuse values */
while (tries > 0) {
avr_write_byte(pgm, p, m, 0, fuse);
avr_read_byte(pgm, p, m, 0, &fuseread);
/* Report information to user if needed */
if (verbose > 0) {
fprintf(stderr,
"%s: safemode: Wrote %s to %x, read as %x. %d attempts left\n",
progname, fusename, fuse, fuseread, tries-1);
}
/* If fuse wrote OK, no need to keep going */
if (fuse == fuseread) {
tries = 0;
returnvalue = 0;
}
tries--;
}
return returnvalue;
}
/*
* Reads the fuses three times, checking that all readings are the
* same. This will ensure that the before values aren't in error!
*/
int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
unsigned char * efuse, unsigned char * fuse,
PROGRAMMER * pgm, AVRPART * p, int verbose)
{
unsigned char value;
unsigned char fusegood = 0;
unsigned char safemode_lfuse;
unsigned char safemode_hfuse;
unsigned char safemode_efuse;
unsigned char safemode_fuse;
AVRMEM * m;
safemode_lfuse = *lfuse;
safemode_hfuse = *hfuse;
safemode_efuse = *efuse;
safemode_fuse = *fuse;
/* Read fuse three times */
fusegood = 2; /* If AVR device doesn't support this fuse, don't want
to generate a verify error */
m = avr_locate_mem(p, "fuse");
if (m != NULL) {
fusegood = 0; /* By default fuse is a failure */
avr_read_byte(pgm, p, m, 0, &safemode_fuse);
avr_read_byte(pgm, p, m, 0, &value);
if (value == safemode_fuse) {
avr_read_byte(pgm, p, m, 0, &value);
if (value == safemode_fuse){
fusegood = 1; /* Fuse read OK three times */
}
}
}
if (fusegood == 0) {
fprintf(stderr,
"%s: safemode: Verify error - unable to read fuse properly. "
"Programmer may not be reliable.\n", progname);
return -1;
}
else if ((fusegood == 1) && (verbose > 0)) {
printf("%s: safemode: fuse reads as %X\n", progname, safemode_fuse);
}
/* Read lfuse three times */
fusegood = 2; /* If AVR device doesn't support this fuse, don't want
to generate a verify error */
m = avr_locate_mem(p, "lfuse");
if (m != NULL) {
fusegood = 0; /* By default fuse is a failure */
avr_read_byte(pgm, p, m, 0, &safemode_lfuse);
avr_read_byte(pgm, p, m, 0, &value);
if (value == safemode_lfuse) {
avr_read_byte(pgm, p, m, 0, &value);
if (value == safemode_lfuse){
fusegood = 1; /* Fuse read OK three times */
}
}
}
if (fusegood == 0) {
fprintf(stderr,
"%s: safemode: Verify error - unable to read lfuse properly. "
"Programmer may not be reliable.\n", progname);
return -1;
}
else if ((fusegood == 1) && (verbose > 0)) {
printf("%s: safemode: lfuse reads as %X\n", progname, safemode_lfuse);
}
/* Read hfuse three times */
fusegood = 2; /* If AVR device doesn't support this fuse, don't want
to generate a verify error */
m = avr_locate_mem(p, "hfuse");
if (m != NULL) {
fusegood = 0; /* By default fuse is a failure */
avr_read_byte(pgm, p, m, 0, &safemode_hfuse);
avr_read_byte(pgm, p, m, 0, &value);
if (value == safemode_hfuse) {
avr_read_byte(pgm, p, m, 0, &value);
if (value == safemode_hfuse){
fusegood = 1; /* Fuse read OK three times */
}
}
}
if (fusegood == 0) {
fprintf(stderr,
"%s: safemode: Verify error - unable to read hfuse properly. "
"Programmer may not be reliable.\n", progname);
return -2;
}
else if ((fusegood == 1) && (verbose > 0)){
printf("%s: safemode: hfuse reads as %X\n", progname, safemode_hfuse);
}
/* Read efuse three times */
fusegood = 2; /* If AVR device doesn't support this fuse, don't want
to generate a verify error */
m = avr_locate_mem(p, "efuse");
if (m != NULL) {
fusegood = 0; /* By default fuse is a failure */
avr_read_byte(pgm, p, m, 0, &safemode_efuse);
avr_read_byte(pgm, p, m, 0, &value);
if (value == safemode_efuse) {
avr_read_byte(pgm, p, m, 0, &value);
if (value == safemode_efuse){
fusegood = 1; /* Fuse read OK three times */
}
}
}
if (fusegood == 0) {
fprintf(stderr,
"%s: safemode: Verify error - unable to read efuse properly. "
"Programmer may not be reliable.\n", progname);
return -3;
}
else if ((fusegood == 1) && (verbose > 0)) {
printf("%s: safemode: efuse reads as %X\n", progname, safemode_efuse);
}
*lfuse = safemode_lfuse;
*hfuse = safemode_hfuse;
*efuse = safemode_efuse;
*fuse = safemode_fuse;
return 0;
}
/*
* This routine will store the current values pointed to by lfuse,
* hfuse, and efuse into an internal buffer in this routine when save
* is set to 1. When save is 0 (or not 1 really) it will copy the
* values from the internal buffer into the locations pointed to be
* lfuse, hfuse, and efuse. This allows you to change the fuse bits if
* needed from another routine (ie: have it so if user requests fuse
* bits are changed, the requested value is now verified
*/
int safemode_memfuses (int save, unsigned char * lfuse, unsigned char * hfuse,
unsigned char * efuse, unsigned char * fuse)
{
static unsigned char safemode_lfuse = 0xff;
static unsigned char safemode_hfuse = 0xff;
static unsigned char safemode_efuse = 0xff;
static unsigned char safemode_fuse = 0xff;
switch (save) {
/* Save the fuses as safemode setting */
case 1:
safemode_lfuse = *lfuse;
safemode_hfuse = *hfuse;
safemode_efuse = *efuse;
safemode_fuse = *fuse;
break;
/* Read back the fuses */
default:
*lfuse = safemode_lfuse;
*hfuse = safemode_hfuse;
*efuse = safemode_efuse;
*fuse = safemode_fuse;
break;
}
return 0;
}

View File

@@ -1,39 +0,0 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* avrdude is Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
*
* This file: Copyright (C) 2005 Colin O'Flynn <coflynn@newae.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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
*/
#ifndef __safemode_h__
#define __safemode_h__
/* Writes the specified fuse in fusename (can be "lfuse", "hfuse", or "efuse") and verifies it. Will try up to tries
amount of times before giving up */
int safemode_writefuse (unsigned char fuse, char * fusename, PROGRAMMER * pgm, AVRPART * p, int tries, int verbose);
/* Reads the fuses three times, checking that all readings are the same. This will ensure that the before values aren't in error! */
int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse, unsigned char * efuse, unsigned char * fuse, PROGRAMMER * pgm, AVRPART * p, int verbose);
/* This routine will store the current values pointed to by lfuse, hfuse, and efuse into an internal buffer in this routine
when save is set to 1. When save is 0 (or not 1 really) it will copy the values from the internal buffer into the locations
pointed to be lfuse, hfuse, and efuse. This allows you to change the fuse bits if needed from another routine (ie: have it so
if user requests fuse bits are changed, the requested value is now verified */
int safemode_memfuses (int save, unsigned char * lfuse, unsigned char * hfuse, unsigned char * efuse, unsigned char * fuse);
#endif //__safemode_h

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
*
* 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
@@ -23,9 +23,6 @@
* Posix serial interface for avrdude.
*/
#if !defined(WIN32NATIVE)
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
@@ -38,13 +35,9 @@
#include <termios.h>
#include <unistd.h>
#include "serial.h"
extern char *progname;
extern int verbose;
long serial_recv_timeout = 5000; /* ms */
struct baud_mapping {
long baud;
speed_t speed;
@@ -80,7 +73,7 @@ static speed_t serial_baud_lookup(long baud)
exit(1);
}
static int ser_setspeed(int fd, long baud)
static int serial_setattr(int fd, long baud)
{
int rc;
struct termios termios;
@@ -94,7 +87,7 @@ static int ser_setspeed(int fd, long baud)
*/
rc = tcgetattr(fd, &termios);
if (rc < 0) {
fprintf(stderr, "%s: ser_setspeed(): tcgetattr() failed, %s",
fprintf(stderr, "%s: serial_setattr(): tcgetattr() failed, %s",
progname, strerror(errno));
return -errno;
}
@@ -112,24 +105,16 @@ static int ser_setspeed(int fd, long baud)
rc = tcsetattr(fd, TCSANOW, &termios);
if (rc < 0) {
fprintf(stderr, "%s: ser_setspeed(): tcsetattr() failed, %s",
fprintf(stderr, "%s: serial_setattr(): tcsetattr() failed, %s",
progname, strerror(errno));
return -errno;
}
#if 0
/*
* set non blocking mode
*/
rc = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, rc | O_NONBLOCK);
#endif
return 0;
}
static int ser_open(char * port, long baud)
int serial_open(char * port, int baud)
{
int rc;
int fd;
@@ -139,7 +124,7 @@ static int ser_open(char * port, long baud)
*/
fd = open(port, O_RDWR | O_NOCTTY /*| O_NONBLOCK*/);
if (fd < 0) {
fprintf(stderr, "%s: ser_open(): can't open device \"%s\": %s\n",
fprintf(stderr, "%s: serial_open(): can't open device \"%s\": %s\n",
progname, port, strerror(errno));
exit(1);
}
@@ -147,10 +132,10 @@ static int ser_open(char * port, long baud)
/*
* set serial line attributes
*/
rc = ser_setspeed(fd, baud);
rc = serial_setattr(fd, baud);
if (rc) {
fprintf(stderr,
"%s: ser_open(): can't set attributes for device \"%s\"\n",
"%s: serial_open(): can't set attributes for device \"%s\"\n",
progname, port);
exit(1);
}
@@ -159,7 +144,7 @@ static int ser_open(char * port, long baud)
}
static void ser_close(int fd)
void serial_close(int fd)
{
/* FIXME: Should really restore the terminal to original state here. */
@@ -167,13 +152,14 @@ static void ser_close(int fd)
}
static int ser_send(int fd, unsigned char * buf, size_t buflen)
int serial_send(int fd, char * buf, size_t buflen)
{
struct timeval timeout, to2;
struct timeval timeout;
fd_set wfds;
int nfds;
int rc;
unsigned char * p = buf;
char * p = buf;
size_t len = buflen;
if (!len)
@@ -202,94 +188,88 @@ static int ser_send(int fd, unsigned char * buf, size_t buflen)
timeout.tv_sec = 0;
timeout.tv_usec = 500000;
to2 = timeout;
while (len) {
reselect:
FD_ZERO(&wfds);
FD_SET(fd, &wfds);
nfds = select(fd+1, NULL, &wfds, NULL, &to2);
reselect:
nfds = select(fd+1, NULL, &wfds, NULL, &timeout);
if (nfds == 0) {
if (verbose >= 1)
fprintf(stderr,
"%s: ser_send(): programmer is not responding\n",
progname);
fprintf(stderr,
"%s: serial_send(): programmer is not responding\n",
progname);
exit(1);
}
else if (nfds == -1) {
if (errno == EINTR || errno == EAGAIN) {
if (errno == EINTR) {
goto reselect;
}
else {
fprintf(stderr, "%s: ser_send(): select(): %s\n",
fprintf(stderr, "%s: serial_send(): select(): %s\n",
progname, strerror(errno));
exit(1);
}
}
rc = write(fd, p, (len > 1024) ? 1024 : len);
rc = write(fd, p, 1);
if (rc < 0) {
fprintf(stderr, "%s: ser_send(): write error: %s\n",
fprintf(stderr, "%s: serial_send(): write error: %s\n",
progname, strerror(errno));
exit(1);
}
p += rc;
len -= rc;
p++;
len--;
}
return 0;
}
static int ser_recv(int fd, unsigned char * buf, size_t buflen)
int serial_recv(int fd, char * buf, size_t buflen)
{
struct timeval timeout, to2;
struct timeval timeout;
fd_set rfds;
int nfds;
int rc;
unsigned char * p = buf;
char * p = buf;
size_t len = 0;
timeout.tv_sec = serial_recv_timeout / 1000L;
timeout.tv_usec = (serial_recv_timeout % 1000L) * 1000;
to2 = timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
while (len < buflen) {
reselect:
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
nfds = select(fd+1, &rfds, NULL, NULL, &to2);
reselect:
nfds = select(fd+1, &rfds, NULL, NULL, &timeout);
if (nfds == 0) {
if (verbose > 1)
fprintf(stderr,
"%s: ser_recv(): programmer is not responding\n",
progname);
return -1;
fprintf(stderr,
"%s: serial_recv(): programmer is not responding\n",
progname);
exit(1);
}
else if (nfds == -1) {
if (errno == EINTR || errno == EAGAIN) {
fprintf(stderr,
"%s: ser_recv(): programmer is not responding,reselecting\n",
progname);
if (errno == EINTR) {
goto reselect;
}
else {
fprintf(stderr, "%s: ser_recv(): select(): %s\n",
fprintf(stderr, "%s: serial_recv(): select(): %s\n",
progname, strerror(errno));
exit(1);
}
}
rc = read(fd, p, (buflen - len > 1024) ? 1024 : buflen - len);
rc = read(fd, p, 1);
if (rc < 0) {
fprintf(stderr, "%s: ser_recv(): read error: %s\n",
fprintf(stderr, "%s: serial_recv(): read error: %s\n",
progname, strerror(errno));
exit(1);
}
p += rc;
len += rc;
p++;
len++;
}
p = buf;
@@ -318,7 +298,7 @@ static int ser_recv(int fd, unsigned char * buf, size_t buflen)
}
static int ser_drain(int fd, int display)
int serial_drain(int fd, int display)
{
struct timeval timeout;
fd_set rfds;
@@ -351,7 +331,7 @@ static int ser_drain(int fd, int display)
goto reselect;
}
else {
fprintf(stderr, "%s: ser_drain(): select(): %s\n",
fprintf(stderr, "%s: serial_drain(): select(): %s\n",
progname, strerror(errno));
exit(1);
}
@@ -359,7 +339,7 @@ static int ser_drain(int fd, int display)
rc = read(fd, &buf, 1);
if (rc < 0) {
fprintf(stderr, "%s: ser_drain(): read error: %s\n",
fprintf(stderr, "%s: serial_drain(): read error: %s\n",
progname, strerror(errno));
exit(1);
}
@@ -370,17 +350,3 @@ static int ser_drain(int fd, int display)
return 0;
}
struct serial_device serial_serdev =
{
.open = ser_open,
.setspeed = ser_setspeed,
.close = ser_close,
.send = ser_send,
.recv = ser_recv,
.drain = ser_drain,
};
struct serial_device *serdev = &serial_serdev;
#endif /* WIN32NATIVE */

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003, 2004 Martin J. Thomas <mthomas@rhrk.uni-kl.de>
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
*
* 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
@@ -23,333 +23,38 @@
* Native Win32 serial interface for avrdude.
*/
#if defined(WIN32NATIVE)
#include <windows.h>
#include <stdio.h>
#include <ctype.h> /* for isprint */
#include "serial.h"
extern char *progname;
extern int verbose;
long serial_recv_timeout = 5000; /* ms */
#if 0
#define W32SERBUFSIZE 1024
struct baud_mapping {
long baud;
DWORD speed;
};
/* HANDLE hComPort=INVALID_HANDLE_VALUE; */
static struct baud_mapping baud_lookup_table [] = {
{ 1200, CBR_1200 },
{ 2400, CBR_2400 },
{ 4800, CBR_4800 },
{ 9600, CBR_9600 },
{ 19200, CBR_19200 },
{ 38400, CBR_38400 },
{ 57600, CBR_57600 },
{ 115200, CBR_115200 },
{ 0, 0 } /* Terminator. */
};
static DWORD serial_baud_lookup(long baud)
int serial_open(char * port, long baud)
{
struct baud_mapping *map = baud_lookup_table;
while (map->baud) {
if (map->baud == baud)
return map->speed;
map++;
}
fprintf(stderr, "%s: serial_baud_lookup(): unknown baud rate: %ld",
progname, baud);
exit(1);
return fd;
}
static BOOL serial_w32SetTimeOut(HANDLE hComPort, DWORD timeout) // in ms
void serial_close(int fd)
{
COMMTIMEOUTS ctmo;
ZeroMemory (&ctmo, sizeof(COMMTIMEOUTS));
ctmo.ReadIntervalTimeout = timeout;
ctmo.ReadTotalTimeoutMultiplier = timeout;
ctmo.ReadTotalTimeoutConstant = timeout;
return SetCommTimeouts(hComPort, &ctmo);
}
static int ser_setspeed(int fd, long baud)
{
DCB dcb;
HANDLE hComPort = (HANDLE)fd;
ZeroMemory (&dcb, sizeof(DCB));
dcb.DCBlength = sizeof(DCB);
dcb.BaudRate = serial_baud_lookup (baud);
dcb.fBinary = 1;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
if (!SetCommState(hComPort, &dcb))
return -1;
return 0;
}
static int ser_open(char * port, long baud)
int serial_send(int fd, char * buf, size_t buflen)
{
LPVOID lpMsgBuf;
HANDLE hComPort=INVALID_HANDLE_VALUE;
/* if (hComPort!=INVALID_HANDLE_VALUE)
fprintf(stderr, "%s: ser_open(): \"%s\" is already open\n",
progname, port);
*/
hComPort = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hComPort == INVALID_HANDLE_VALUE) {
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL);
fprintf(stderr, "%s: ser_open(): can't open device \"%s\": %s\n",
progname, port, (char*)lpMsgBuf);
LocalFree( lpMsgBuf );
exit(1);
}
if (!SetupComm(hComPort, W32SERBUFSIZE, W32SERBUFSIZE))
{
CloseHandle(hComPort);
fprintf(stderr, "%s: ser_open(): can't set buffers for \"%s\"\n",
progname, port);
exit(1);
}
if (ser_setspeed((int)hComPort, baud) != 0)
{
CloseHandle(hComPort);
fprintf(stderr, "%s: ser_open(): can't set com-state for \"%s\"\n",
progname, port);
exit(1);
}
if (!serial_w32SetTimeOut(hComPort,0))
{
CloseHandle(hComPort);
fprintf(stderr, "%s: ser_open(): can't set initial timeout for \"%s\"\n",
progname, port);
exit(1);
}
return (int)hComPort;
}
static void ser_close(int fd)
{
HANDLE hComPort=(HANDLE)fd;
if (hComPort != INVALID_HANDLE_VALUE)
CloseHandle (hComPort);
hComPort = INVALID_HANDLE_VALUE;
}
static int ser_send(int fd, char * buf, size_t buflen)
{
size_t len = buflen;
unsigned char c='\0';
DWORD written;
HANDLE hComPort=(HANDLE)fd;
if (hComPort == INVALID_HANDLE_VALUE) {
fprintf(stderr, "%s: ser_send(): port not open\n",
progname);
exit(1);
}
if (!len)
return 0;
if (verbose > 3)
{
fprintf(stderr, "%s: Send: ", progname);
while (buflen) {
c = *buf;
if (isprint(c)) {
fprintf(stderr, "%c ", c);
}
else {
fprintf(stderr, ". ");
}
fprintf(stderr, "[%02x] ", c);
buf++;
buflen--;
}
fprintf(stderr, "\n");
}
serial_w32SetTimeOut(hComPort,500);
if (!WriteFile (hComPort, buf, buflen, &written, NULL)) {
fprintf(stderr, "%s: ser_send(): write error: %s\n",
progname, "sorry no info avail"); // TODO
exit(1);
}
if (written != buflen) {
fprintf(stderr, "%s: ser_send(): size/send mismatch\n",
progname);
exit(1);
}
return 0;
}
static int ser_recv(int fd, char * buf, size_t buflen)
{
unsigned char c;
char * p = buf;
size_t len = 0;
DWORD read;
HANDLE hComPort=(HANDLE)fd;
if (hComPort == INVALID_HANDLE_VALUE) {
fprintf(stderr, "%s: ser_read(): port not open\n",
progname);
exit(1);
}
serial_w32SetTimeOut(hComPort, serial_recv_timeout);
if (!ReadFile(hComPort, buf, buflen, &read, NULL)) {
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL );
fprintf(stderr, "%s: ser_recv(): read error: %s\n",
progname, (char*)lpMsgBuf);
LocalFree( lpMsgBuf );
exit(1);
}
p = buf;
if (verbose > 3)
{
fprintf(stderr, "%s: Recv: ", progname);
while (len) {
c = *p;
if (isprint(c)) {
fprintf(stderr, "%c ", c);
}
else {
fprintf(stderr, ". ");
}
fprintf(stderr, "[%02x] ", c);
p++;
len--;
}
fprintf(stderr, "\n");
}
return 0;
}
static int ser_drain(int fd, int display)
int serial_recv(int fd, char * buf, size_t buflen)
{
// int rc;
unsigned char buf[10];
BOOL readres;
DWORD read;
HANDLE hComPort=(HANDLE)fd;
if (hComPort == INVALID_HANDLE_VALUE) {
fprintf(stderr, "%s: ser_drain(): port not open\n",
progname);
exit(1);
}
serial_w32SetTimeOut(hComPort,250);
if (display) {
fprintf(stderr, "drain>");
}
while (1) {
readres=ReadFile(hComPort, buf, 1, &read, NULL);
if (!readres) {
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL );
fprintf(stderr, "%s: ser_drain(): read error: %s\n",
progname, (char*)lpMsgBuf);
LocalFree( lpMsgBuf );
exit(1);
}
if (read) { // data avail
if (display) fprintf(stderr, "%02x ", buf[0]);
}
else { // no more data
if (display) fprintf(stderr, "<drain\n");
break;
}
} // while
return 0;
}
struct serial_device serial_serdev =
int serial_drain(int fd, int display)
{
.open = ser_open,
.setspeed = ser_setspeed,
.close = ser_close,
.send = ser_send,
.recv = ser_recv,
.drain = ser_drain,
};
return 0;
}
struct serial_device *serdev = &serial_serdev;
#endif /* WIN32NATIVE */
#endif

View File

@@ -1,33 +0,0 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
*
* 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 serbb_h
#define serbb_h
void serbb_initpgm (PROGRAMMER * pgm);
int serbb_setpin(int fd, int pin, int value);
int serbb_getpin(int fd, int pin);
int serbb_highpulsepin(int fd, int pin);
#endif

View File

@@ -1,271 +0,0 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
*
* 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$ */
/*
* Posix serial bitbanging interface for avrdude.
*/
#if !defined(WIN32NATIVE)
#include "ac_cfg.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <termios.h>
#include "avr.h"
#include "pindefs.h"
#include "pgm.h"
#include "bitbang.h"
#undef DEBUG
extern char *progname;
struct termios oldmode;
/*
serial port/pin mapping
1 cd <-
2 rxd <-
3 txd ->
4 dtr ->
5 dsr <-
6 rts ->
7 cts <-
*/
int serregbits[] =
{ TIOCM_CD, 0, 0, TIOCM_DTR, TIOCM_DSR, TIOCM_RTS, TIOCM_CTS };
#ifdef DEBUG
char *serpins[7] =
{ "CD", "RXD", "TXD ~RESET", "DTR MOSI", "DSR", "RTS SCK", "CTS MISO" };
#endif
void serbb_setpin(int fd, int pin, int value)
{
unsigned int ctl;
if (pin & PIN_INVERSE)
{
value = !value;
pin &= PIN_MASK;
}
if ( pin < 1 || pin > 7 )
return;
pin--;
#ifdef DEBUG
printf("%s to %d\n",serpins[pin],value);
#endif
switch ( pin )
{
case 2: /* txd */
ioctl(fd, value ? TIOCSBRK : TIOCCBRK, 0);
return;
case 3: /* dtr, rts */
case 5: ioctl(fd, TIOCMGET, &ctl);
if ( value )
ctl |= serregbits[pin];
else
ctl &= ~(serregbits[pin]);
ioctl(fd, TIOCMSET, &ctl);
return;
default: /* impossible */
return;
}
}
int serbb_getpin(int fd, int pin)
{
unsigned int ctl;
unsigned char invert;
if (pin & PIN_INVERSE)
{
invert = 1;
pin &= PIN_MASK;
} else
invert = 0;
if ( pin < 1 || pin > 7 )
return(-1);
pin --;
switch ( pin )
{
case 1: /* rxd, currently not implemented, FIXME */
return(-1);
case 0: /* cd, dsr, dtr, rts, cts */
case 3:
case 4:
case 5:
case 6: ioctl(fd, TIOCMGET, &ctl);
if ( !invert )
{
#ifdef DEBUG
printf("%s is %d\n",serpins[pin],(ctl & serregbits[pin]) ? 1 : 0 );
#endif
return ( (ctl & serregbits[pin]) ? 1 : 0 );
}
else
{
#ifdef DEBUG
printf("%s is %d (~)\n",serpins[pin],(ctl & serregbits[pin]) ? 0 : 1 );
#endif
return (( ctl & serregbits[pin]) ? 0 : 1 );
}
default: /* impossible */
return(-1);
}
}
int serbb_highpulsepin(int fd, int pin)
{
if (pin < 1 || pin > 7)
return -1;
serbb_setpin(fd, pin, 1);
#if SLOW_TOGGLE
usleep(1000);
#endif
serbb_setpin(fd, pin, 0);
#if SLOW_TOGGLE
usleep(1000);
#endif
return 0;
}
void serbb_display(PROGRAMMER *pgm, char *p)
{
/* MAYBE */
}
void serbb_enable(PROGRAMMER *pgm)
{
/* nothing */
}
void serbb_disable(PROGRAMMER *pgm)
{
/* nothing */
}
void serbb_powerup(PROGRAMMER *pgm)
{
/* nothing */
}
void serbb_powerdown(PROGRAMMER *pgm)
{
/* nothing */
}
int serbb_open(PROGRAMMER *pgm, char *port)
{
struct termios mode;
int flags;
/* adapted from uisp code */
pgm->fd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
if ( pgm->fd > 0 )
{
tcgetattr(pgm->fd, &mode);
oldmode = mode;
cfmakeraw(&mode);
mode.c_iflag &= ~(INPCK | IXOFF | IXON);
mode.c_cflag &= ~(HUPCL | CSTOPB | CRTSCTS);
mode.c_cflag |= (CLOCAL | CREAD);
mode.c_cc [VMIN] = 1;
mode.c_cc [VTIME] = 0;
tcsetattr(pgm->fd, TCSANOW, &mode);
/* Clear O_NONBLOCK flag. */
flags = fcntl(pgm->fd, F_GETFL, 0);
if (flags == -1)
{
fprintf(stderr, "%s: Can not get flags\n", progname);
return(-1);
}
flags &= ~O_NONBLOCK;
if (fcntl(pgm->fd, F_SETFL, flags) == -1)
{
fprintf(stderr, "%s: Can not clear nonblock flag\n", progname);
return(-1);
}
}
return(0);
}
void serbb_close(PROGRAMMER *pgm)
{
tcsetattr(pgm->fd, TCSADRAIN, &oldmode);
return;
}
void serbb_initpgm(PROGRAMMER *pgm)
{
strcpy(pgm->type, "SERBB");
pgm->rdy_led = bitbang_rdy_led;
pgm->err_led = bitbang_err_led;
pgm->pgm_led = bitbang_pgm_led;
pgm->vfy_led = bitbang_vfy_led;
pgm->initialize = bitbang_initialize;
pgm->display = serbb_display;
pgm->enable = serbb_enable;
pgm->disable = serbb_disable;
pgm->powerup = serbb_powerup;
pgm->powerdown = serbb_powerdown;
pgm->program_enable = bitbang_program_enable;
pgm->chip_erase = bitbang_chip_erase;
pgm->cmd = bitbang_cmd;
pgm->open = serbb_open;
pgm->close = serbb_close;
/* this is a serial port bitbang device */
pgm->flag = 1;
}
#endif /* WIN32NATIVE */

View File

@@ -1,372 +0,0 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003, 2004 Martin J. Thomas <mthomas@rhrk.uni-kl.de>
* Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
* Copyright (C) 2005 Joerg Wunsch <j@uriah.heep.sax.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* $Id$ */
/*
* Win32 serial bitbanging interface for avrdude.
*/
#if defined(WIN32NATIVE)
#include "ac_cfg.h"
#include <windows.h>
#include <stdio.h>
#include "avr.h"
#include "pindefs.h"
#include "pgm.h"
#include "bitbang.h"
extern char *progname;
extern int verbose;
/* cached status lines */
static int dtr, rts, txd;
#define W32SERBUFSIZE 1024
/*
serial port/pin mapping
1 cd <-
2 rxd <-
3 txd ->
4 dtr ->
5 dsr <-
6 rts ->
7 cts <-
Negative pin # means negated value.
*/
void serbb_setpin(int fd, int pin, int value)
{
HANDLE hComPort = (HANDLE)fd;
LPVOID lpMsgBuf;
DWORD dwFunc;
const char *name;
if (pin & PIN_INVERSE)
{
value = !value;
pin &= PIN_MASK;
}
if (pin < 1 || pin > 7)
return;
pin--;
switch (pin)
{
case 2: /* txd */
dwFunc = value? SETBREAK: CLRBREAK;
name = value? "SETBREAK": "CLRBREAK";
txd = value;
break;
case 3: /* dtr */
dwFunc = value? SETDTR: CLRDTR;
name = value? "SETDTR": "CLRDTR";
dtr = value;
break;
case 5: /* rts */
dwFunc = value? SETRTS: CLRRTS;
name = value? "SETRTS": "CLRRTS";
break;
default:
if (verbose)
fprintf(stderr,
"%s: serbb_setpin(): unknown pin %d\n",
progname, pin + 1);
return;
}
if (verbose > 4)
fprintf(stderr,
"%s: serbb_setpin(): EscapeCommFunction(%s)\n",
progname, name);
if (!EscapeCommFunction(hComPort, dwFunc))
{
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL);
fprintf(stderr,
"%s: serbb_setpin(): SetCommState() failed: %s\n",
progname, (char *)lpMsgBuf);
CloseHandle(hComPort);
LocalFree(lpMsgBuf);
exit(1);
}
return;
}
int serbb_getpin(int fd, int pin)
{
HANDLE hComPort = (HANDLE)fd;
LPVOID lpMsgBuf;
int invert, rv;
const char *name;
DWORD modemstate;
if (pin & PIN_INVERSE)
{
invert = 1;
pin &= PIN_MASK;
} else
invert = 0;
if (pin < 1 || pin > 7)
return -1;
pin --;
if (pin == 0 /* cd */ || pin == 4 /* dsr */ || pin == 6 /* cts */)
{
if (!GetCommModemStatus(hComPort, &modemstate))
{
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL);
fprintf(stderr,
"%s: serbb_setpin(): GetCommModemStatus() failed: %s\n",
progname, (char *)lpMsgBuf);
CloseHandle(hComPort);
LocalFree(lpMsgBuf);
exit(1);
}
if (verbose > 4)
fprintf(stderr,
"%s: serbb_getpin(): GetCommState() => 0x%lx\n",
progname, modemstate);
switch (pin)
{
case 0:
modemstate &= MS_RLSD_ON;
break;
case 4:
modemstate &= MS_DSR_ON;
break;
case 6:
modemstate &= MS_CTS_ON;
break;
}
rv = modemstate != 0;
if (invert)
rv = !rv;
return rv;
}
switch (pin)
{
case 2: /* txd */
rv = txd;
name = "TXD";
break;
case 3: /* dtr */
rv = dtr;
name = "DTR";
break;
case 5: /* rts */
rv = rts;
name = "RTS";
break;
default:
if (verbose)
fprintf(stderr,
"%s: serbb_getpin(): unknown pin %d\n",
progname, pin + 1);
return -1;
}
if (verbose > 4)
fprintf(stderr,
"%s: serbb_getpin(): return cached state for %s\n",
progname, name);
if (invert)
rv = !rv;
return rv;
}
int serbb_highpulsepin(int fd, int pin)
{
if (pin < 1 || pin > 7)
return -1;
serbb_setpin(fd, pin, 1);
#if SLOW_TOGGLE
usleep(1000);
#endif
serbb_setpin(fd, pin, 0);
#if SLOW_TOGGLE
usleep(1000);
#endif
return 0;
}
void serbb_display(PROGRAMMER *pgm, char *p)
{
/* MAYBE */
}
void serbb_enable(PROGRAMMER *pgm)
{
/* nothing */
}
void serbb_disable(PROGRAMMER *pgm)
{
/* nothing */
}
void serbb_powerup(PROGRAMMER *pgm)
{
/* nothing */
}
void serbb_powerdown(PROGRAMMER *pgm)
{
/* nothing */
}
int serbb_open(PROGRAMMER *pgm, char *port)
{
DCB dcb;
LPVOID lpMsgBuf;
HANDLE hComPort = INVALID_HANDLE_VALUE;
hComPort = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hComPort == INVALID_HANDLE_VALUE) {
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL);
fprintf(stderr, "%s: ser_open(): can't open device \"%s\": %s\n",
progname, port, (char*)lpMsgBuf);
LocalFree(lpMsgBuf);
return -1;
}
if (!SetupComm(hComPort, W32SERBUFSIZE, W32SERBUFSIZE))
{
CloseHandle(hComPort);
fprintf(stderr, "%s: ser_open(): can't set buffers for \"%s\"\n",
progname, port);
return -1;
}
ZeroMemory(&dcb, sizeof(DCB));
dcb.DCBlength = sizeof(DCB);
dcb.BaudRate = CBR_9600;
dcb.fBinary = 1;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
if (!SetCommState(hComPort, &dcb))
{
CloseHandle(hComPort);
fprintf(stderr, "%s: ser_open(): can't set com-state for \"%s\"\n",
progname, port);
return -1;
}
if (verbose > 2)
fprintf(stderr,
"%s: ser_open(): opened comm port \"%s\", handle 0x%x\n",
progname, port, (int)hComPort);
pgm->fd = (int)hComPort;
dtr = rts = txd = 0;
return 0;
}
void serbb_close(PROGRAMMER *pgm)
{
HANDLE hComPort=(HANDLE)pgm->fd;
if (hComPort != INVALID_HANDLE_VALUE)
CloseHandle (hComPort);
if (verbose > 2)
fprintf(stderr,
"%s: ser_close(): closed comm port handle 0x%x\n",
progname, (int)hComPort);
hComPort = INVALID_HANDLE_VALUE;
}
void serbb_initpgm(PROGRAMMER *pgm)
{
strcpy(pgm->type, "SERBB");
pgm->rdy_led = bitbang_rdy_led;
pgm->err_led = bitbang_err_led;
pgm->pgm_led = bitbang_pgm_led;
pgm->vfy_led = bitbang_vfy_led;
pgm->initialize = bitbang_initialize;
pgm->display = serbb_display;
pgm->enable = serbb_enable;
pgm->disable = serbb_disable;
pgm->powerup = serbb_powerup;
pgm->powerdown = serbb_powerdown;
pgm->program_enable = bitbang_program_enable;
pgm->chip_erase = bitbang_chip_erase;
pgm->cmd = bitbang_cmd;
pgm->open = serbb_open;
pgm->close = serbb_close;
/* this is a serial port bitbang device */
pgm->flag = 1;
}
#endif /* WIN32NATIVE */

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
* Copyright (C) 2003 Theodore A. Roth <troth@openavr.org>
*
* 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
@@ -30,27 +30,13 @@
#ifndef __serial_h__
#define __serial_h__
extern long serial_recv_timeout;
#include "config.h"
struct serial_device
{
int (*open)(char * port, long baud);
int (*setspeed)(int fd, long baud);
void (*close)(int fd);
extern int serial_open(char * port, long baud);
extern void serial_close(int fd);
int (*send)(int fd, unsigned char * buf, size_t buflen);
int (*recv)(int fd, unsigned char * buf, size_t buflen);
int (*drain)(int fd, int display);
};
extern struct serial_device *serdev;
extern struct serial_device serial_serdev, usb_serdev;
#define serial_open (serdev->open)
#define serial_setspeed (serdev->setspeed)
#define serial_close (serdev->close)
#define serial_send (serdev->send)
#define serial_recv (serdev->recv)
#define serial_drain (serdev->drain)
extern int serial_send(int fd, char * buf, size_t buflen);
extern int serial_recv(int fd, char * buf, size_t buflen);
extern int serial_drain(int fd, int display);
#endif /* __serial_h__ */

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -41,7 +41,6 @@
#include "stk500_private.h"
#include "serial.h"
#define STK500_XTAL 7372800U
extern int verbose;
extern char * progname;
@@ -51,28 +50,16 @@ extern int do_cycles;
static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value);
static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value);
static void stk500_print_parms1(PROGRAMMER * pgm, char * p);
static int stk500_is_page_empty(unsigned int address, int page_size,
const unsigned char *buf);
static int stk500_send(PROGRAMMER * pgm, unsigned char * buf, size_t len)
static int stk500_send(PROGRAMMER * pgm, char * buf, size_t len)
{
return serial_send(pgm->fd, buf, len);
}
static int stk500_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
static int stk500_recv(PROGRAMMER * pgm, char * buf, size_t len)
{
int rv;
rv = serial_recv(pgm->fd, buf, len);
if (rv < 0) {
fprintf(stderr,
"%s: stk500_recv(): programmer is not responding\n",
progname);
exit(1);
}
return 0;
return serial_recv(pgm->fd, buf, len);
}
@@ -113,11 +100,32 @@ static int stk500_getsync(PROGRAMMER * pgm)
}
static int stk500_rdy_led(PROGRAMMER * pgm, int value)
{
return 0;
}
static int stk500_err_led(PROGRAMMER * pgm, int value)
{
return 0;
}
static int stk500_pgm_led(PROGRAMMER * pgm, int value)
{
return 0;
}
static int stk500_vfy_led(PROGRAMMER * pgm, int value)
{
return 0;
}
/*
* transmit an AVR device command and return the results; 'cmd' and
* 'res' must point to at least a 4 byte data buffer
*/
static int stk500_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
static int stk500_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
unsigned char res[4])
{
unsigned char buf[32];
@@ -160,6 +168,8 @@ static int stk500_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
unsigned char cmd[4];
unsigned char res[4];
int cycles;
int rc;
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
fprintf(stderr, "chip erase instruction not defined for part \"%s\"\n",
@@ -167,6 +177,19 @@ static int stk500_chip_erase(PROGRAMMER * pgm, AVRPART * p)
return -1;
}
rc = avr_get_cycle_count(pgm, p, &cycles);
/*
* only print out the current cycle count if we aren't going to
* display it below
*/
if (!do_cycles && ((rc >= 0) && (cycles != 0xffffffff))) {
fprintf(stderr,
"%s: current erase-rewrite cycle count is %d%s\n",
progname, cycles,
do_cycles ? "" : " (if being tracked)");
}
pgm->pgm_led(pgm, ON);
memset(cmd, 0, sizeof(cmd));
@@ -178,6 +201,16 @@ static int stk500_chip_erase(PROGRAMMER * pgm, AVRPART * p)
pgm->pgm_led(pgm, OFF);
if (do_cycles && (cycles != -1)) {
if (cycles == 0x00ffff) {
cycles = 0;
}
cycles++;
fprintf(stderr, "%s: erase-rewrite cycle count is now %d\n",
progname, cycles);
avr_put_cycle_count(pgm, p, cycles);
}
return 0;
}
@@ -241,8 +274,25 @@ static int stk500_program_enable(PROGRAMMER * pgm, AVRPART * p)
}
/*
* apply power to the AVR processor
*/
static void stk500_powerup(PROGRAMMER * pgm)
{
return;
}
static int stk500_set_extended_parms(PROGRAMMER * pgm, int n,
/*
* remove power from the AVR processor
*/
static void stk500_powerdown(PROGRAMMER * pgm)
{
return;
}
static int stk500_set_extended_parms(PROGRAMMER * pgm, int n,
unsigned char * cmd)
{
unsigned char buf[16];
@@ -494,6 +544,16 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
}
static int stk500_save(PROGRAMMER * pgm)
{
return 0;
}
static void stk500_restore(PROGRAMMER * pgm)
{
return;
}
static void stk500_disable(PROGRAMMER * pgm)
{
unsigned char buf[16];
@@ -547,13 +607,10 @@ static void stk500_enable(PROGRAMMER * pgm)
}
static int stk500_open(PROGRAMMER * pgm, char * port)
static void stk500_open(PROGRAMMER * pgm, char * port)
{
strcpy(pgm->port, port);
if (pgm->baudrate)
pgm->fd = serial_open(port, pgm->baudrate);
else
pgm->fd = serial_open(port, 115200);
pgm->fd = serial_open(port, 115200);
/*
* drain any extraneous input
@@ -563,8 +620,6 @@ static int stk500_open(PROGRAMMER * pgm, char * port)
stk500_getsync(pgm);
stk500_drain(pgm, 0);
return 0;
}
@@ -629,10 +684,9 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int memtype;
unsigned int addr;
int a_div;
int block_size;
int i;
int tries;
unsigned int n;
int flash;
if (page_size == 0) {
page_size = 128;
@@ -640,11 +694,9 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
if (strcmp(m->desc, "flash") == 0) {
memtype = 'F';
flash = 1;
}
else if (strcmp(m->desc, "eeprom") == 0) {
memtype = 'E';
flash = 0;
}
else {
return -2;
@@ -679,32 +731,19 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
for (addr = 0; addr < n; addr += page_size) {
report_progress (addr, n_bytes, NULL);
if (addr + page_size > n_bytes) {
block_size = n_bytes % page_size;
}
else {
block_size = page_size;
}
/* Only skip on empty page if programming flash. */
if (flash) {
if (stk500_is_page_empty(addr, block_size, m->buf)) {
continue;
}
}
tries = 0;
retry:
tries++;
stk500_loadaddr(pgm, addr/a_div);
buf[0] = Cmnd_STK_PROG_PAGE;
buf[1] = (block_size >> 8) & 0xff;
buf[2] = block_size & 0xff;
buf[1] = (page_size >> 8) & 0xff;
buf[2] = page_size & 0xff;
buf[3] = memtype;
stk500_send(pgm, buf, 4);
stk500_send(pgm, &m->buf[addr], block_size);
for (i=0; i<page_size; i++) {
buf[0] = m->buf[addr + i];
stk500_send(pgm, buf, 1);
}
buf[0] = Sync_CRC_EOP;
stk500_send(pgm, buf, 1);
@@ -736,23 +775,9 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
}
}
return n_bytes;
return n;
}
static int stk500_is_page_empty(unsigned int address, int page_size,
const unsigned char *buf)
{
int i;
for(i = 0; i < page_size; i++) {
if(buf[address + i] != 0xFF) {
/* Page is not empty. */
return(0);
}
}
/* Page is empty. */
return(1);
}
static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes)
@@ -763,7 +788,6 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int a_div;
int tries;
unsigned int n;
int block_size;
if (strcmp(m->desc, "flash") == 0) {
memtype = 'F';
@@ -795,21 +819,13 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
for (addr = 0; addr < n; addr += page_size) {
report_progress (addr, n_bytes, NULL);
if (addr + page_size > n_bytes) {
block_size = n_bytes % page_size;
}
else {
block_size = page_size;
}
tries = 0;
retry:
tries++;
stk500_loadaddr(pgm, addr/a_div);
buf[0] = Cmnd_STK_READ_PAGE;
buf[1] = (block_size >> 8) & 0xff;
buf[2] = block_size & 0xff;
buf[1] = (page_size >> 8) & 0xff;
buf[2] = page_size & 0xff;
buf[3] = memtype;
buf[4] = Sync_CRC_EOP;
stk500_send(pgm, buf, 5);
@@ -832,7 +848,7 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
return -4;
}
stk500_recv(pgm, &m->buf[addr], block_size);
stk500_recv(pgm, &m->buf[addr], page_size);
stk500_recv(pgm, buf, 1);
if (buf[0] != Resp_STK_OK) {
@@ -844,7 +860,7 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
}
}
return n_bytes;
return n;
}
@@ -899,6 +915,7 @@ static int stk500_set_varef(PROGRAMMER * pgm, double v)
static int stk500_set_fosc(PROGRAMMER * pgm, double v)
{
#define fbase 7372800U
unsigned prescale, cmatch, fosc;
static unsigned ps[] = {
1, 8, 32, 64, 128, 256, 1024
@@ -907,7 +924,7 @@ static int stk500_set_fosc(PROGRAMMER * pgm, double v)
prescale = cmatch = 0;
if (v > 0.0) {
if (v > STK500_XTAL / 2) {
if (v > fbase / 2) {
const char *unit;
if (v > 1e6) {
v /= 1e6;
@@ -919,22 +936,22 @@ static int stk500_set_fosc(PROGRAMMER * pgm, double v)
unit = "Hz";
fprintf(stderr,
"%s: stk500_set_fosc(): f = %.3f %s too high, using %.3f MHz\n",
progname, v, unit, STK500_XTAL / 2e6);
fosc = STK500_XTAL / 2;
progname, v, unit, fbase / 2e6);
fosc = fbase / 2;
} else
fosc = (unsigned)v;
for (idx = 0; idx < sizeof(ps) / sizeof(ps[0]); idx++) {
if (fosc >= STK500_XTAL / (256 * ps[idx] * 2)) {
if (fosc >= fbase / (256 * ps[idx] * 2)) {
/* this prescaler value can handle our frequency */
prescale = idx + 1;
cmatch = (unsigned)(STK500_XTAL / (2 * fosc * ps[idx])) - 1;
cmatch = (unsigned)(fbase / (2 * v * ps[idx]));
break;
}
}
if (idx == sizeof(ps) / sizeof(ps[0])) {
fprintf(stderr, "%s: stk500_set_fosc(): f = %u Hz too low, %u Hz min\n",
progname, fosc, STK500_XTAL / (256 * 1024 * 2));
progname, fosc, fbase / (256 * 1024 * 2));
return -1;
}
}
@@ -947,38 +964,6 @@ static int stk500_set_fosc(PROGRAMMER * pgm, double v)
}
/* This code assumes that each count of the SCK duration parameter
represents 8/f, where f is the clock frequency of the STK500 master
processors (not the target). This number comes from Atmel
application note AVR061. It appears that the STK500 bit bangs SCK.
For small duration values, the actual SCK width is larger than
expected. As the duration value increases, the SCK width error
diminishes. */
static int stk500_set_sck_period(PROGRAMMER * pgm, double v)
{
int dur;
double min, max;
min = 8.0 / STK500_XTAL;
max = 255 * min;
dur = v / min + 0.5;
if (v < min) {
dur = 1;
fprintf(stderr,
"%s: stk500_set_sck_period(): p = %.1f us too small, using %.1f us\n",
progname, v / 1e-6, dur * min / 1e-6);
} else if (v > max) {
dur = 255;
fprintf(stderr,
"%s: stk500_set_sck_period(): p = %.1f us too large, using %.1f us\n",
progname, v / 1e-6, dur * min / 1e-6);
}
return stk500_setparm(pgm, Parm_STK_SCK_DURATION, dur);
}
static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
{
unsigned char buf[16];
@@ -1122,13 +1107,12 @@ static void stk500_display(PROGRAMMER * pgm, char * p)
static void stk500_print_parms1(PROGRAMMER * pgm, char * p)
{
unsigned vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration;
unsigned vtarget, vadjust, osc_pscale, osc_cmatch;
stk500_getparm(pgm, Parm_STK_VTARGET, &vtarget);
stk500_getparm(pgm, Parm_STK_VADJUST, &vadjust);
stk500_getparm(pgm, Parm_STK_OSC_PSCALE, &osc_pscale);
stk500_getparm(pgm, Parm_STK_OSC_CMATCH, &osc_cmatch);
stk500_getparm(pgm, Parm_STK_SCK_DURATION, &sck_duration);
fprintf(stderr, "%sVtarget : %.1f V\n", p, vtarget / 10.0);
fprintf(stderr, "%sVaref : %.1f V\n", p, vadjust / 10.0);
@@ -1137,7 +1121,7 @@ static void stk500_print_parms1(PROGRAMMER * pgm, char * p)
fprintf(stderr, "Off\n");
else {
int prescale = 1;
double f = STK500_XTAL / 2;
double f = 3.6864e6;
const char *unit;
switch (osc_pscale) {
@@ -1160,8 +1144,6 @@ static void stk500_print_parms1(PROGRAMMER * pgm, char * p)
unit = "Hz";
fprintf(stderr, "%.3f %s\n", f, unit);
}
fprintf(stderr, "%sSCK period : %.1f us\n", p,
sck_duration * 8.0e6 / STK500_XTAL + 0.05);
return;
}
@@ -1180,10 +1162,18 @@ void stk500_initpgm(PROGRAMMER * pgm)
/*
* mandatory functions
*/
pgm->rdy_led = stk500_rdy_led;
pgm->err_led = stk500_err_led;
pgm->pgm_led = stk500_pgm_led;
pgm->vfy_led = stk500_vfy_led;
pgm->initialize = stk500_initialize;
pgm->display = stk500_display;
pgm->save = stk500_save;
pgm->restore = stk500_restore;
pgm->enable = stk500_enable;
pgm->disable = stk500_disable;
pgm->powerup = stk500_powerup;
pgm->powerdown = stk500_powerdown;
pgm->program_enable = stk500_program_enable;
pgm->chip_erase = stk500_chip_erase;
pgm->cmd = stk500_cmd;
@@ -1199,6 +1189,5 @@ void stk500_initpgm(PROGRAMMER * pgm)
pgm->set_vtarget = stk500_set_vtarget;
pgm->set_varef = stk500_set_varef;
pgm->set_fosc = stk500_set_fosc;
pgm->set_sck_period = stk500_set_sck_period;
pgm->page_size = 256;
}

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,6 +22,8 @@
#ifndef __stk500_h__
#define __stk500_h__
#include "config.h"
void stk500_initpgm (PROGRAMMER * pgm);
#endif

View File

@@ -1,982 +0,0 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2005 Erik Walthinsen
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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$ */
/* Based on Id: stk500.c,v 1.46 2004/12/22 01:52:45 bdean Exp */
/*
* avrdude interface for Atmel STK500V2 programmer
*
* Note: most commands use the "universal command" feature of the
* programmer in a "pass through" mode, exceptions are "program
* enable", "paged read", and "paged write".
*
*/
#include "ac_cfg.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
#include <time.h>
#include "avr.h"
#include "pgm.h"
#include "stk500_private.h" // temp until all code converted
#include "stk500v2_private.h"
#include "serial.h"
#define STK500V2_XTAL 7372800U
#if 0
#define DEBUG(format,args...) fprintf(stderr, format, ## args)
#else
#define DEBUG(format,args...)
#endif
#if 0
#define DEBUGRECV(format,args...) fprintf(stderr, format, ## args)
#else
#define DEBUGRECV(format,args...)
#endif
extern int verbose;
extern char * progname;
extern int do_cycles;
static unsigned char command_sequence = 1;
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 void stk500v2_print_parms1(PROGRAMMER * pgm, char * p);
static int stk500v2_is_page_empty(unsigned int address, int page_size,
const unsigned char *buf);
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;
buf[0] = MESSAGE_START;
buf[1] = command_sequence;
buf[2] = len / 256;
buf[3] = len % 256;
buf[4] = TOKEN;
memcpy(buf+5, data, len);
// calculate the XOR checksum
buf[5+len] = 0;
for (i=0;i<5+len;i++)
buf[5+len] ^= buf[i];
DEBUG("STK500V2: stk500v2_send(");
for (i=0;i<len+6;i++) DEBUG("0x%02x ",buf[i]);
DEBUG(", %d)\n",len+6);
if (serial_send(pgm->fd, buf, len+6) != 0) {
fprintf(stderr,"%s: stk500_send(): failed to send command to serial port\n",progname);
exit(1);
}
return 0;
}
static int stk500v2_drain(PROGRAMMER * pgm, int display)
{
return serial_drain(pgm->fd, display);
}
static int stk500v2_recv(PROGRAMMER * pgm, unsigned char msg[], size_t maxsize) {
enum states { sINIT, sSTART, sSEQNUM, sSIZE1, sSIZE2, sTOKEN, sDATA, sCSUM, sDONE } state = sSTART;
int msglen = 0;
int curlen = 0;
int timeout = 0;
unsigned char c, checksum = 0;
long timeoutval = 5; // seconds
struct timeval tv;
double tstart, tnow;
DEBUG("STK500V2: stk500v2_recv(): ");
gettimeofday(&tv, NULL);
tstart = tv.tv_sec;
while ( (state != sDONE ) && (!timeout) ) {
if (serial_recv(pgm->fd, &c, 1) < 0)
goto timedout;
DEBUG("0x%02x ",c);
checksum ^= c;
switch (state) {
case sSTART:
DEBUGRECV("hoping for start token...");
if (c == MESSAGE_START) {
DEBUGRECV("got it\n");
checksum = MESSAGE_START;
state = sSEQNUM;
} else
DEBUGRECV("sorry\n");
break;
case sSEQNUM:
DEBUGRECV("hoping for sequence...\n");
if (c == command_sequence) {
DEBUGRECV("got it, incrementing\n");
state = sSIZE1;
command_sequence++;
} else {
DEBUGRECV("sorry\n");
state = sSTART;
}
break;
case sSIZE1:
DEBUGRECV("hoping for size LSB\n");
msglen = c*256;
state = sSIZE2;
break;
case sSIZE2:
DEBUGRECV("hoping for size MSB...");
msglen += c;
DEBUG(" msg is %d bytes\n",msglen);
state = sTOKEN;
break;
case sTOKEN:
if (c == TOKEN) state = sDATA;
else state = sSTART;
break;
case sDATA:
if (curlen < maxsize) {
msg[curlen] = c;
} else {
fprintf(stderr, "%s: stk500v2_recv(): buffer too small, received %d byte into %zd byte buffer\n",
progname,curlen,maxsize);
return -2;
}
if ((curlen == 0) && (msg[0] == ANSWER_CKSUM_ERROR)) {
fprintf(stderr, "%s: stk500v2_recv(): previous packet sent with wrong checksum\n",
progname);
return -3;
}
curlen++;
if (curlen == msglen) state = sCSUM;
break;
case sCSUM:
if (checksum == 0) {
state = sDONE;
} else {
state = sSTART;
fprintf(stderr, "%s: stk500v2_recv(): checksum error\n",
progname);
return -4;
}
break;
default:
fprintf(stderr, "%s: stk500v2_recv(): unknown state\n",
progname);
return -5;
} /* switch */
gettimeofday(&tv, NULL);
tnow = tv.tv_sec;
if (tnow-tstart > timeoutval) { // wuff - signed/unsigned/overflow
timedout:
fprintf(stderr, "%s: stk500_2_ReceiveMessage(): timeout\n",
progname);
return -1;
}
} /* while */
DEBUG("\n");
return msglen+6;
}
static int stk500v2_getsync(PROGRAMMER * pgm) {
int tries = 0;
unsigned char buf[1], resp[32];
int status;
DEBUG("STK500V2: stk500v2_getsync()\n");
retry:
tries++;
// send the sync command and see if we can get there
buf[0] = CMD_SIGN_ON;
stk500v2_send(pgm, buf, 1);
// try to get the response back and see where we got
status = stk500v2_recv(pgm, resp, sizeof(resp));
// if we got bytes returned, check to see what came back
if (status > 0) {
if ((resp[0] == CMD_SIGN_ON) && (resp[1] == STATUS_CMD_OK)) {
// success!
return 0;
} else {
if (tries > 33) {
fprintf(stderr,
"%s: stk500v2_getsync(): can't communicate with device: resp=0x%02x\n",
progname, resp[0]);
return -6;
} else
goto retry;
}
// or if we got a timeout
} else if (status == -1) {
if (tries > 33) {
fprintf(stderr,"%s: stk500v2_getsync(): timeout communicating with programmer\n",
progname);
return -1;
} else
goto retry;
// or any other error
} else {
if (tries > 33) {
fprintf(stderr,"%s: stk500v2_getsync(): error communicating with programmer: (%d)\n",
progname,status);
} else
goto retry;
}
return 0;
}
static int stk500v2_command(PROGRAMMER * pgm, unsigned char * buf, size_t len, size_t maxlen) {
int i;
int tries = 0;
int status;
DEBUG("STK500V2: stk500v2_command(");
for (i=0;i<len;i++) DEBUG("0x%02hhx ",buf[i]);
DEBUG(", %d)\n",len);
retry:
tries++;
// send the command to the programmer
stk500v2_send(pgm,buf,len);
// attempt to read the status back
status = stk500v2_recv(pgm,buf,maxlen);
// if we got a successful readback, return
if (status > 0) {
DEBUG(" = %d\n",status);
return status;
}
// otherwise try to sync up again
status = stk500v2_getsync(pgm);
if (status != 0) {
if (tries > 33) {
fprintf(stderr,"%s: stk500v2_command(): failed miserably to execute command 0x%02x\n",
progname,buf[0]);
return -1;
} else
goto retry;
}
DEBUG(" = 0\n");
return 0;
}
static int stk500v2_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
unsigned char res[4])
{
unsigned char buf[8];
int result;
DEBUG("STK500V2: stk500v2_cmd(%02x,%02x,%02x,%02x)\n",cmd[0],cmd[1],cmd[2],cmd[3]);
buf[0] = CMD_SPI_MULTI;
buf[1] = 4;
buf[2] = 4;
buf[3] = 0;
buf[4] = cmd[0];
buf[5] = cmd[1];
buf[6] = cmd[2];
buf[7] = cmd[3];
result = stk500v2_command(pgm, buf, 8, sizeof(buf));
if (buf[1] != STATUS_CMD_OK) {
fprintf(stderr, "%s: stk500v2_cmd(): failed to send command\n",
progname);
return -1;
}
res[0] = buf[2];
res[1] = buf[3];
res[2] = buf[4];
res[3] = buf[5];
return 0;
}
/*
* issue the 'chip erase' command to the AVR device
*/
static int stk500v2_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
int result;
unsigned char buf[16];
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
fprintf(stderr, "%s: stk500v2_chip_erase: chip erase instruction not defined for part \"%s\"\n",
progname, p->desc);
return -1;
}
pgm->pgm_led(pgm, ON);
buf[0] = CMD_CHIP_ERASE_ISP;
buf[1] = p->chip_erase_delay / 1000;
buf[2] = 0; // use delay (?)
avr_set_bits(p->op[AVR_OP_CHIP_ERASE], buf+3);
result = stk500v2_command(pgm, buf, 7, sizeof(buf));
usleep(p->chip_erase_delay);
pgm->initialize(pgm, p);
pgm->pgm_led(pgm, OFF);
return result;
}
/*
* issue the 'program enable' command to the AVR device
*/
static int stk500v2_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
unsigned char buf[16];
if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
fprintf(stderr, "%s: stk500v2_program_enable(): program enable instruction not defined for part \"%s\"\n",
progname, p->desc);
return -1;
}
buf[0] = CMD_ENTER_PROGMODE_ISP;
buf[1] = p->timeout;
buf[2] = p->stabdelay;
buf[3] = p->cmdexedelay;
buf[4] = p->synchloops;
buf[5] = p->bytedelay;
buf[6] = p->pollvalue;
buf[7] = p->pollindex;
avr_set_bits(p->op[AVR_OP_PGM_ENABLE], buf+8);
return stk500v2_command(pgm, buf, 12, sizeof(buf));
}
/*
* initialize the AVR device and prepare it to accept commands
*/
static int stk500v2_initialize(PROGRAMMER * pgm, AVRPART * p)
{
return pgm->program_enable(pgm, p);
}
static void stk500v2_disable(PROGRAMMER * pgm)
{
unsigned char buf[16];
int result;
buf[0] = CMD_LEAVE_PROGMODE_ISP;
buf[1] = 1; // preDelay;
buf[2] = 1; // postDelay;
result = stk500v2_command(pgm, buf, 3, sizeof(buf));
if (buf[1] != STATUS_CMD_OK) {
fprintf(stderr, "%s: stk500v2_disable(): failed to leave programming mode, got 0x%02x\n",
progname,buf[1]);
exit(1);
}
return;
}
static void stk500v2_enable(PROGRAMMER * pgm)
{
return;
}
static int stk500v2_open(PROGRAMMER * pgm, char * port)
{
DEBUG("STK500V2: stk500v2_open()\n");
strcpy(pgm->port, port);
if (pgm->baudrate)
pgm->fd = serial_open(port, pgm->baudrate);
else
pgm->fd = serial_open(port, 115200);
/*
* drain any extraneous input
*/
stk500v2_drain(pgm, 0);
stk500v2_getsync(pgm);
stk500v2_drain(pgm, 0);
return 0;
}
static void stk500v2_close(PROGRAMMER * pgm)
{
DEBUG("STK500V2: stk500v2_close()\n");
serial_close(pgm->fd);
pgm->fd = -1;
}
static int stk500v2_loadaddr(PROGRAMMER * pgm, unsigned int addr)
{
unsigned char buf[16];
int result;
DEBUG("STK500V2: stk500v2_loadaddr(%d)\n",addr);
buf[0] = CMD_LOAD_ADDRESS;
buf[1] = (addr >> 24) & 0xff;
buf[2] = (addr >> 16) & 0xff;
buf[3] = (addr >> 8) & 0xff;
buf[4] = addr & 0xff;
result = stk500v2_command(pgm, buf, 5, sizeof(buf));
if (buf[1] != STATUS_CMD_OK) {
fprintf(stderr, "%s: stk500v2_loadaddr(): failed to set load address, got 0x%02x\n",
progname,buf[1]);
return -1;
}
return 0;
}
static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes)
{
int addr, block_size, last_addr;
int a_div=1;
unsigned char commandbuf[10];
unsigned char buf[266];
unsigned char cmds[4];
int result;
OPCODE * rop, * wop;
DEBUG("STK500V2: stk500v2_paged_write(..,%s,%d,%d)\n",m->desc,page_size,n_bytes);
if (page_size == 0) page_size = 256;
// determine which command is to be used
if (strcmp(m->desc, "flash") == 0) {
a_div=2;
commandbuf[0] = CMD_PROGRAM_FLASH_ISP;
} else if (strcmp(m->desc, "eeprom") == 0) {
commandbuf[0] = CMD_PROGRAM_EEPROM_ISP;
}
commandbuf[4] = m->delay;
if (a_div == 1) {
wop = m->op[AVR_OP_WRITE];
rop = m->op[AVR_OP_READ];
}
else {
wop = m->op[AVR_OP_WRITE_LO];
rop = m->op[AVR_OP_READ_LO];
}
// if the memory is paged, load the appropriate commands into the buffer
if (m->mode & 0x01) {
commandbuf[3] = m->mode | 0x80; // yes, write the page to flash
if (m->op[AVR_OP_LOADPAGE_LO] == NULL) {
fprintf(stderr, "%s: stk500v2_paged_write: loadpage instruction not defined for part \"%s\"\n",
progname, p->desc);
return -1;
}
avr_set_bits(m->op[AVR_OP_LOADPAGE_LO], cmds);
commandbuf[5] = cmds[0];
if (m->op[AVR_OP_WRITEPAGE] == NULL) {
fprintf(stderr, "%s: stk500v2_paged_write: write page instruction not defined for part \"%s\"\n",
progname, p->desc);
return -1;
}
avr_set_bits(m->op[AVR_OP_WRITEPAGE], cmds);
commandbuf[6] = cmds[0];
// otherwise, we need to load different commands in
}
else {
commandbuf[3] = m->mode | 0x80; // yes, write the words to flash
if (wop == NULL) {
fprintf(stderr, "%s: stk500v2_paged_write: write instruction not defined for part \"%s\"\n",
progname, p->desc);
return -1;
}
avr_set_bits(wop, cmds);
commandbuf[5] = cmds[0];
commandbuf[6] = 0;
}
// the read command is common to both methods
if (rop == NULL) {
fprintf(stderr, "%s: stk500v2_paged_write: read instruction not defined for part \"%s\"\n",
progname, p->desc);
return -1;
}
avr_set_bits(rop, cmds);
commandbuf[7] = cmds[0];
commandbuf[8] = m->readback[0];
commandbuf[9] = m->readback[1];
last_addr=-1;
for (addr=0; addr < n_bytes; addr += page_size) {
report_progress(addr,n_bytes,NULL);
if ((n_bytes-addr) < page_size)
block_size = n_bytes - addr;
else
block_size = page_size;
DEBUG("block_size at addr %d is %d\n",addr,block_size);
if(commandbuf[0] == CMD_PROGRAM_FLASH_ISP){
if (stk500v2_is_page_empty(addr, block_size, m->buf)) {
continue;
}
}
memcpy(buf,commandbuf,sizeof(commandbuf));
buf[1] = block_size >> 8;
buf[2] = block_size & 0xff;
if((last_addr==-1)||(last_addr+block_size != addr)){
stk500v2_loadaddr(pgm, addr/a_div);
}
last_addr=addr;
memcpy(buf+10,m->buf+addr, block_size);
result = stk500v2_command(pgm,buf,block_size+10, sizeof(buf));
if (buf[1] != STATUS_CMD_OK) {
fprintf(stderr,"%s: stk500v2_paged_write: write command failed with %d\n",
progname,buf[1]);
return -1;
}
}
return n_bytes;
}
static int stk500v2_is_page_empty(unsigned int address, int page_size,
const unsigned char *buf)
{
int i;
for(i = 0; i < page_size; i++) {
if(buf[address + i] != 0xFF) {
/* Page is not empty. */
return(0);
}
}
/* Page is empty. */
return(1);
}
static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int page_size, int n_bytes)
{
int addr, block_size;
unsigned char commandbuf[4];
unsigned char buf[275]; // max buffer size for stk500v2 at this point
unsigned char cmds[4];
int result;
OPCODE * rop;
DEBUG("STK500V2: stk500v2_paged_load(..,%s,%d,%d)\n",m->desc,page_size,n_bytes);
page_size = m->readsize;
rop = m->op[AVR_OP_READ];
// determine which command is to be used
if (strcmp(m->desc, "flash") == 0) {
commandbuf[0] = CMD_READ_FLASH_ISP;
rop = m->op[AVR_OP_READ_LO];
}
else if (strcmp(m->desc, "eeprom") == 0) {
commandbuf[0] = CMD_READ_EEPROM_ISP;
}
// the read command is common to both methods
if (rop == NULL) {
fprintf(stderr, "%s: stk500v2_paged_load: read instruction not defined for part \"%s\"\n",
progname, p->desc);
return -1;
}
avr_set_bits(rop, cmds);
commandbuf[3] = cmds[0];
stk500v2_loadaddr(pgm, 0);
for (addr=0; addr < n_bytes; addr += page_size) {
report_progress(addr, n_bytes,NULL);
if ((n_bytes-addr) < page_size)
block_size = n_bytes - addr;
else
block_size = page_size;
DEBUG("block_size at addr %d is %d\n",addr,block_size);
memcpy(buf,commandbuf,sizeof(commandbuf));
buf[1] = block_size >> 8;
buf[2] = block_size & 0xff;
result = stk500v2_command(pgm,buf,4,sizeof(buf));
if (buf[1] != STATUS_CMD_OK) {
fprintf(stderr,"%s: stk500v2_paged_load: read command failed with %d\n",
progname,buf[1]);
return -1;
}
#if 0
for (i=0;i<page_size;i++) {
fprintf(stderr,"%02X",buf[2+i]);
if (i%16 == 15) fprintf(stderr,"\n");
}
#endif
memcpy(&m->buf[addr], &buf[2], block_size);
}
return n_bytes;
}
static int stk500v2_set_vtarget(PROGRAMMER * pgm, double v)
{
unsigned char uaref, utarg;
utarg = (unsigned)((v + 0.049) * 10);
if (stk500v2_getparm(pgm, PARAM_VADJUST, &uaref) != 0) {
fprintf(stderr,
"%s: stk500v2_set_vtarget(): cannot obtain V[aref]\n",
progname);
return -1;
}
if (uaref > utarg) {
fprintf(stderr,
"%s: stk500v2_set_vtarget(): reducing V[aref] from %.1f to %.1f\n",
progname, uaref / 10.0, v);
if (stk500v2_setparm(pgm, PARAM_VADJUST, utarg)
!= 0)
return -1;
}
return stk500v2_setparm(pgm, PARAM_VTARGET, utarg);
}
static int stk500v2_set_varef(PROGRAMMER * pgm, double v)
{
unsigned char uaref, utarg;
uaref = (unsigned)((v + 0.049) * 10);
if (stk500v2_getparm(pgm, PARAM_VTARGET, &utarg) != 0) {
fprintf(stderr,
"%s: stk500v2_set_varef(): cannot obtain V[target]\n",
progname);
return -1;
}
if (uaref > utarg) {
fprintf(stderr,
"%s: stk500v2_set_varef(): V[aref] must not be greater than "
"V[target] = %.1f\n",
progname, utarg / 10.0);
return -1;
}
return stk500v2_setparm(pgm, PARAM_VADJUST, uaref);
}
static int stk500v2_set_fosc(PROGRAMMER * pgm, double v)
{
int fosc;
unsigned char prescale, cmatch;
static unsigned ps[] = {
1, 8, 32, 64, 128, 256, 1024
};
int idx, rc;
prescale = cmatch = 0;
if (v > 0.0) {
if (v > STK500V2_XTAL / 2) {
const char *unit;
if (v > 1e6) {
v /= 1e6;
unit = "MHz";
} else if (v > 1e3) {
v /= 1e3;
unit = "kHz";
} else
unit = "Hz";
fprintf(stderr,
"%s: stk500v2_set_fosc(): f = %.3f %s too high, using %.3f MHz\n",
progname, v, unit, STK500V2_XTAL / 2e6);
fosc = STK500V2_XTAL / 2;
} else
fosc = (unsigned)v;
for (idx = 0; idx < sizeof(ps) / sizeof(ps[0]); idx++) {
if (fosc >= STK500V2_XTAL / (256 * ps[idx] * 2)) {
/* this prescaler value can handle our frequency */
prescale = idx + 1;
cmatch = (unsigned)(STK500V2_XTAL / (2 * fosc * ps[idx])) - 1;
break;
}
}
if (idx == sizeof(ps) / sizeof(ps[0])) {
fprintf(stderr, "%s: stk500v2_set_fosc(): f = %u Hz too low, %u Hz min\n",
progname, fosc, STK500V2_XTAL / (256 * 1024 * 2));
return -1;
}
}
if ((rc = stk500v2_setparm(pgm, PARAM_OSC_PSCALE, prescale)) != 0
|| (rc = stk500v2_setparm(pgm, PARAM_OSC_CMATCH, cmatch)) != 0)
return rc;
return 0;
}
/* This code assumes that each count of the SCK duration parameter
represents 8/f, where f is the clock frequency of the STK500V2 master
processors (not the target). This number comes from Atmel
application note AVR061. It appears that the STK500V2 bit bangs SCK.
For small duration values, the actual SCK width is larger than
expected. As the duration value increases, the SCK width error
diminishes. */
static int stk500v2_set_sck_period(PROGRAMMER * pgm, double v)
{
unsigned char dur;
double min, max;
min = 8.0 / STK500V2_XTAL;
max = 255 * min;
dur = v / min + 0.5;
if (v < min) {
dur = 1;
fprintf(stderr,
"%s: stk500v2_set_sck_period(): p = %.1f us too small, using %.1f us\n",
progname, v / 1e-6, dur * min / 1e-6);
} else if (v > max) {
dur = 255;
fprintf(stderr,
"%s: stk500v2_set_sck_period(): p = %.1f us too large, using %.1f us\n",
progname, v / 1e-6, dur * min / 1e-6);
}
return stk500v2_setparm(pgm, PARAM_SCK_DURATION, dur);
}
static int stk500v2_getparm(PROGRAMMER * pgm, unsigned char parm, unsigned char * 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_getparm(): failed to get parameter 0x%02x\n",
progname, parm);
return -1;
}
*value = buf[2];
return 0;
}
static int stk500v2_setparm(PROGRAMMER * pgm, unsigned char parm, unsigned char value)
{
unsigned char buf[32];
buf[0] = CMD_SET_PARAMETER;
buf[1] = parm;
buf[2] = value;
if (stk500v2_command(pgm, buf, 3, sizeof(buf)) < 0) {
fprintf(stderr, "\n%s: stk500v2_setparm(): failed to set parameter 0x%02x\n",
progname, parm);
return -1;
}
return 0;
}
static void stk500v2_display(PROGRAMMER * pgm, char * p)
{
unsigned char maj, min, hdw, topcard;
const char *topcard_name;
stk500v2_getparm(pgm, PARAM_HW_VER, &hdw);
stk500v2_getparm(pgm, PARAM_SW_MAJOR, &maj);
stk500v2_getparm(pgm, PARAM_SW_MINOR, &min);
stk500v2_getparm(pgm, PARAM_TOPCARD_DETECT, &topcard);
fprintf(stderr, "%sHardware Version: %d\n", p, hdw);
fprintf(stderr, "%sFirmware Version: %d.%d\n", p, maj, min);
if (1) { // should check to see if it's a stk500 first
switch (topcard) {
case 0xAA: topcard_name = "STK501"; break;
case 0x55: topcard_name = "STK502"; break;
case 0xFA: topcard_name = "STK503"; break;
case 0xEE: topcard_name = "STK504"; break;
case 0xE4: topcard_name = "STK505"; break;
case 0xDD: topcard_name = "STK520"; break;
default: topcard_name = "Unknown"; break;
}
fprintf(stderr, "%sTopcard : %s\n", p, topcard_name);
}
stk500v2_print_parms1(pgm, p);
return;
}
static void stk500v2_print_parms1(PROGRAMMER * pgm, char * p)
{
unsigned char vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration;
stk500v2_getparm(pgm, PARAM_VTARGET, &vtarget);
stk500v2_getparm(pgm, PARAM_VADJUST, &vadjust);
stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale);
stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch);
stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration);
fprintf(stderr, "%sVtarget : %.1f V\n", p, vtarget / 10.0);
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;
switch (osc_pscale) {
case 2: prescale = 8; break;
case 3: prescale = 32; break;
case 4: prescale = 64; break;
case 5: prescale = 128; break;
case 6: prescale = 256; break;
case 7: prescale = 1024; break;
}
f /= prescale;
f /= (osc_cmatch + 1);
if (f > 1e6) {
f /= 1e6;
unit = "MHz";
} else if (f > 1e3) {
f /= 1000;
unit = "kHz";
} else
unit = "Hz";
fprintf(stderr, "%.3f %s\n", f, unit);
}
fprintf(stderr, "%sSCK period : %.1f us\n", p,
sck_duration * 8.0e6 / STK500V2_XTAL + 0.05);
return;
}
static void stk500v2_print_parms(PROGRAMMER * pgm)
{
stk500v2_print_parms1(pgm, "");
}
void stk500v2_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "STK500V2");
/*
* 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 = stk500v2_open;
pgm->close = stk500v2_close;
/*
* optional functions
*/
pgm->paged_write = stk500v2_paged_write;
pgm->paged_load = stk500v2_paged_load;
pgm->print_parms = stk500v2_print_parms;
pgm->set_vtarget = stk500v2_set_vtarget;
pgm->set_varef = stk500v2_set_varef;
pgm->set_fosc = stk500v2_set_fosc;
pgm->set_sck_period = stk500v2_set_sck_period;
pgm->page_size = 256;
}

View File

@@ -1,29 +0,0 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2002-2005 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* $Id$ */
#ifndef stk500v2_h__
#define stk500v2_h__
void stk500v2_initpgm (PROGRAMMER * pgm);
#endif

View File

@@ -1,134 +0,0 @@
//**** ATMEL AVR - A P P L I C A T I O N N O T E ************************
//*
//* Title: AVR068 - STK500 Communication Protocol
//* Filename: command.h
//* Version: 1.0
//* Last updated: 10.01.2005
//*
//* Support E-mail: avr@atmel.com
//*
//**************************************************************************
// *****************[ STK message constants ]***************************
#define MESSAGE_START 0x1B //= ESC = 27 decimal
#define TOKEN 0x0E
// *****************[ STK general command constants ]**************************
#define CMD_SIGN_ON 0x01
#define CMD_SET_PARAMETER 0x02
#define CMD_GET_PARAMETER 0x03
#define CMD_SET_DEVICE_PARAMETERS 0x04
#define CMD_OSCCAL 0x05
#define CMD_LOAD_ADDRESS 0x06
#define CMD_FIRMWARE_UPGRADE 0x07
// *****************[ STK ISP command constants ]******************************
#define CMD_ENTER_PROGMODE_ISP 0x10
#define CMD_LEAVE_PROGMODE_ISP 0x11
#define CMD_CHIP_ERASE_ISP 0x12
#define CMD_PROGRAM_FLASH_ISP 0x13
#define CMD_READ_FLASH_ISP 0x14
#define CMD_PROGRAM_EEPROM_ISP 0x15
#define CMD_READ_EEPROM_ISP 0x16
#define CMD_PROGRAM_FUSE_ISP 0x17
#define CMD_READ_FUSE_ISP 0x18
#define CMD_PROGRAM_LOCK_ISP 0x19
#define CMD_READ_LOCK_ISP 0x1A
#define CMD_READ_SIGNATURE_ISP 0x1B
#define CMD_READ_OSCCAL_ISP 0x1C
#define CMD_SPI_MULTI 0x1D
// *****************[ STK PP command constants ]*******************************
#define CMD_ENTER_PROGMODE_PP 0x20
#define CMD_LEAVE_PROGMODE_PP 0x21
#define CMD_CHIP_ERASE_PP 0x22
#define CMD_PROGRAM_FLASH_PP 0x23
#define CMD_READ_FLASH_PP 0x24
#define CMD_PROGRAM_EEPROM_PP 0x25
#define CMD_READ_EEPROM_PP 0x26
#define CMD_PROGRAM_FUSE_PP 0x27
#define CMD_READ_FUSE_PP 0x28
#define CMD_PROGRAM_LOCK_PP 0x29
#define CMD_READ_LOCK_PP 0x2A
#define CMD_READ_SIGNATURE_PP 0x2B
#define CMD_READ_OSCCAL_PP 0x2C
#define CMD_SET_CONTROL_STACK 0x2D
// *****************[ STK HVSP command constants ]*****************************
#define CMD_ENTER_PROGMODE_HVSP 0x30
#define CMD_LEAVE_PROGMODE_HVSP 0x31
#define CMD_CHIP_ERASE_HVSP 0x32
#define CMD_PROGRAM_FLASH_HVSP 0x33
#define CMD_READ_FLASH_HVSP 0x34
#define CMD_PROGRAM_EEPROM_HVSP 0x35
#define CMD_READ_EEPROM_HVSP 0x36
#define CMD_PROGRAM_FUSE_HVSP 0x37
#define CMD_READ_FUSE_HVSP 0x38
#define CMD_PROGRAM_LOCK_HVSP 0x39
#define CMD_READ_LOCK_HVSP 0x3A
#define CMD_READ_SIGNATURE_HVSP 0x3B
#define CMD_READ_OSCCAL_HVSP 0x3C
// *****************[ STK test command constants ]***************************
#define CMD_ENTER_TESTMODE 0x60
#define CMD_LEAVE_TESTMODE 0x61
#define CMD_CHIP_WRITE 0x62
#define CMD_PROGRAM_FLASH_PARTIAL 0x63
#define CMD_PROGRAM_EEPROM_PARTIAL 0x64
#define CMD_PROGRAM_SIGNATURE_ROW 0x65
#define CMD_READ_FLASH_MARGIN 0x66
#define CMD_READ_EEPROM_MARGIN 0x67
#define CMD_READ_SIGNATURE_ROW_MARGIN 0x68
#define CMD_PROGRAM_TEST_FUSE 0x69
#define CMD_READ_TEST_FUSE 0x6A
#define CMD_PROGRAM_HIDDEN_FUSE_LOW 0x6B
#define CMD_READ_HIDDEN_FUSE_LOW 0x6C
#define CMD_PROGRAM_HIDDEN_FUSE_HIGH 0x6D
#define CMD_READ_HIDDEN_FUSE_HIGH 0x6E
#define CMD_PROGRAM_HIDDEN_FUSE_EXT 0x6F
#define CMD_READ_HIDDEN_FUSE_EXT 0x70
// *****************[ STK status constants ]***************************
// Success
#define STATUS_CMD_OK 0x00
// Warnings
#define STATUS_CMD_TOUT 0x80
#define STATUS_RDY_BSY_TOUT 0x81
#define STATUS_SET_PARAM_MISSING 0x82
// Errors
#define STATUS_CMD_FAILED 0xC0
#define STATUS_CKSUM_ERROR 0xC1
#define STATUS_CMD_UNKNOWN 0xC9
// *****************[ STK parameter constants ]***************************
#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_CONTROLLER_INIT 0x9F
// *****************[ STK answer constants ]***************************
#define ANSWER_CKSUM_ERROR 0xB0

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,18 +21,14 @@
#include "ac_cfg.h"
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#if defined(HAVE_LIBREADLINE)
#if !defined(WIN32NATIVE)
# include <readline/readline.h>
# include <readline/history.h>
#endif
#endif
#include "avr.h"
#include "config.h"
@@ -78,8 +74,6 @@ int cmd_varef (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
int cmd_fosc (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
int cmd_sck (PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
struct command cmd[] = {
{ "dump", cmd_dump, "dump memory : %s <memtype> <addr> <N-Bytes>" },
@@ -93,7 +87,6 @@ struct command cmd[] = {
{ "vtarg", cmd_vtarg, "set <V[target]> (STK500 only)" },
{ "varef", cmd_varef, "set <V[aref]> (STK500 only)" },
{ "fosc", cmd_fosc, "set <oscillator frequency> (STK500 only)" },
{ "sck", cmd_sck, "set <SCK period> (STK500 only)" },
{ "help", cmd_help, "help" },
{ "?", cmd_help, "help" },
{ "quit", cmd_quit, "quit" }
@@ -600,38 +593,6 @@ int cmd_fosc(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
}
int cmd_sck(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
{
int rc;
double v;
char *endp;
if (argc != 2) {
fprintf(stderr, "Usage: sck <value>\n");
return -1;
}
v = strtod(argv[1], &endp);
if (endp == argv[1]) {
fprintf(stderr, "%s (sck): can't parse period \"%s\"\n",
progname, argv[1]);
return -1;
}
v *= 1e-6; /* Convert from microseconds to seconds. */
if (pgm->set_sck_period == NULL) {
fprintf(stderr,
"%s (sck): the %s programmer cannot set SCK period\n",
progname, pgm->type);
return -2;
}
if ((rc = pgm->set_sck_period(pgm, v)) != 0) {
fprintf(stderr, "%s (sck): failed to set SCK period (rc = %d)\n",
progname, rc);
return -3;
}
return 0;
}
int cmd_varef(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
{
int rc;
@@ -791,7 +752,7 @@ int do_cmd(PROGRAMMER * pgm, struct avrpart * p, int argc, char * argv[])
char * terminal_get_input(const char *prompt)
{
#if defined(HAVE_LIBREADLINE) && !defined(WIN32NATIVE)
#if defined(HAVE_LIBREADLINE)
char *input;
input = readline(prompt);
if ((input != NULL) && (strlen(input) >= 1))
@@ -804,7 +765,7 @@ char * terminal_get_input(const char *prompt)
if (fgets(input, sizeof(input), stdin))
{
/* FIXME: readline strips the '\n', should this too? */
return strdup(input);
strdup(input);
}
else
return NULL;

View File

@@ -1,6 +1,6 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,6 +26,5 @@
#include "pgm.h"
int terminal_mode(PROGRAMMER * pgm, struct avrpart * p);
char * terminal_get_input(const char *prompt);
#endif

View File

@@ -1,285 +0,0 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2005 Joerg Wunsch
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* $Id$ */
/*
* USB interface via libusb for avrdude.
*/
#include "ac_cfg.h"
#if defined(HAVE_LIBUSB)
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <usb.h>
#include "serial.h"
extern char *progname;
extern int verbose;
#define USB_VENDOR_ATMEL 1003
#define USB_DEVICE_JTAGICEMKII 0x2103
/*
* Should we query the endpoint number and max transfer size from USB?
* After all, the JTAG ICE mkII docs document these values.
*/
#define JTAGICE_BULK_EP 2
#define JTAGICE_MAX_XFER 64
static char usbbuf[JTAGICE_MAX_XFER];
static int buflen = -1, bufptr;
static int usbdev_open(char * port, long baud)
{
char string[256];
struct usb_bus *bus;
struct usb_device *dev;
usb_dev_handle *udev;
char *serno, *cp2;
size_t x;
/*
* The syntax for usb devices is defined as:
*
* -P usb[:serialnumber]
*
* See if we've got a serial number passed here. The serial number
* might contain colons which we remove below, and we compare it
* right-to-left, so only the least significant nibbles need to be
* specified.
*/
if ((serno = strchr(port, ':')) != NULL)
{
/* first, drop all colons there if any */
cp2 = ++serno;
while ((cp2 = strchr(cp2, ':')) != NULL)
{
x = strlen(cp2) - 1;
memmove(cp2, cp2 + 1, x);
cp2[x] = '\0';
}
if (strlen(serno) > 12)
{
fprintf(stderr,
"%s: usbdev_open(): invalid serial number \"%s\"\n",
progname, serno);
exit(1);
}
}
usb_init();
usb_find_busses();
usb_find_devices();
for (bus = usb_busses; bus; bus = bus->next)
{
for (dev = bus->devices; dev; dev = dev->next)
{
udev = usb_open(dev);
if (udev)
{
if (dev->descriptor.idVendor == USB_VENDOR_ATMEL &&
dev->descriptor.idProduct == USB_DEVICE_JTAGICEMKII)
{
/* yeah, we found something */
if (usb_get_string_simple(udev,
dev->descriptor.iSerialNumber,
string, sizeof(string)) < 0)
{
fprintf(stderr,
"%s: usb_open(): cannot read serial number \"%s\"\n",
progname, usb_strerror());
/*
* On some systems, libusb appears to have
* problems sending control messages. Catch the
* benign case where the user did not request a
* particular serial number, so we could
* continue anyway.
*/
if (serno != NULL)
exit(1); /* no chance */
else
strcpy(string, "[unknown]");
}
if (verbose)
fprintf(stderr,
"%s: usb_open(): Found JTAG ICE, serno: %s\n",
progname, string);
if (serno != NULL)
{
/*
* See if the serial number requested by the
* user matches what we found, matching
* right-to-left.
*/
x = strlen(string) - strlen(serno);
if (strcasecmp(string + x, serno) != 0)
{
if (verbose > 2)
fprintf(stderr,
"%s: usbdev_open(): serial number doesn't match\n",
progname);
usb_close(udev);
continue;
}
}
return (int)udev;
}
usb_close(udev);
}
}
}
fprintf(stderr, "%s: usbdev_open(): did not find any%s USB device \"%s\"\n",
progname, serno? " (matching)": "", port);
exit(1);
}
static int usbdev_setspeed(int fd, long baud)
{
return 0;
}
static void usbdev_close(int fd)
{
usb_dev_handle *udev = (usb_dev_handle *)fd;
usb_close(udev);
}
static int usbdev_send(int fd, unsigned char *bp, size_t mlen)
{
usb_dev_handle *udev = (usb_dev_handle *)fd;
return usb_bulk_write(udev, JTAGICE_BULK_EP, (char *)bp, mlen, 5000) != mlen;
}
/*
* As calls to usb_bulk_read() result in exactly one USB request, we
* have to buffer the read results ourselves, so the single-char read
* requests performed by the upper layers will be handled. In order
* to do this, we maintain a private buffer of what we've got so far,
* and transparently issue another USB read request if the buffer is
* empty and more data are requested.
*/
static int
usb_fill_buf(usb_dev_handle *udev)
{
int rv;
rv = usb_bulk_read(udev, JTAGICE_BULK_EP, usbbuf, JTAGICE_MAX_XFER, 5000);
if (rv < 0)
{
if (verbose > 1)
fprintf(stderr, "%s: usb_fill_buf(): usb_bulk_read() error %s\n",
progname, usb_strerror());
return -1;
}
buflen = rv;
bufptr = 0;
return 0;
}
static int usbdev_recv(int fd, unsigned char *buf, size_t nbytes)
{
usb_dev_handle *udev = (usb_dev_handle *)fd;
int i, amnt;
unsigned char * p = buf;
for (i = 0; nbytes > 0;)
{
if (buflen <= bufptr)
{
if (usb_fill_buf(udev) < 0)
return -1;
}
amnt = buflen - bufptr > nbytes? nbytes: buflen - bufptr;
memcpy(buf + i, usbbuf + bufptr, amnt);
bufptr += amnt;
nbytes -= amnt;
i += amnt;
}
if (verbose > 3)
{
fprintf(stderr, "%s: Recv: ", progname);
while (i) {
unsigned char c = *p;
if (isprint(c)) {
fprintf(stderr, "%c ", c);
}
else {
fprintf(stderr, ". ");
}
fprintf(stderr, "[%02x] ", c);
p++;
i--;
}
fprintf(stderr, "\n");
}
return 0;
}
static int usbdev_drain(int fd, int display)
{
usb_dev_handle *udev = (usb_dev_handle *)fd;
int rv;
do {
rv = usb_bulk_read(udev, JTAGICE_BULK_EP, usbbuf, JTAGICE_MAX_XFER, 100);
if (rv > 0 && verbose >= 4)
fprintf(stderr, "%s: usbdev_drain(): flushed %d characters\n",
progname, rv);
} while (rv > 0);
return 0;
}
struct serial_device usb_serdev =
{
.open = usbdev_open,
.setspeed = usbdev_setspeed,
.close = usbdev_close,
.send = usbdev_send,
.recv = usbdev_recv,
.drain = usbdev_drain,
};
#endif /* HAVE_LIBUSB */

View File

@@ -37,7 +37,7 @@ EXTRA_DIST = \
bin_PROGRAMS = loaddrv
loaddrv_LDFLAGS = -mno-cygwin
loaddrv_CFLAGS = -mno-cygwin
loaddrv_SOURCES = \
loaddrv.c \