2003-03-13 03:52:19 +00:00
|
|
|
/*
|
|
|
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
2004-12-22 01:52:45 +00:00
|
|
|
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
|
main.c, pgm.c, pgm.h: Add setup and teardown hooks to the programmer
definition. If present, call the setup hook immediately after finding
the respective programmer object, and schedule the teardown hook to be
called upon exit. This allows the programmer implementation to
dynamically allocate private programmer data.
avr910.c, butterfly.c, jtagmkI.c, jtagmkII.c, stk500v2.c, usbasp.c,
usbtiny.c: Convert static programmer data into dynamically allocated
data.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@764 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-07 20:36:12 +00:00
|
|
|
* Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
|
2008-06-07 20:55:04 +00:00
|
|
|
* Copyright 2008 Klaus Leidinger <klaus@mikrocontroller-projekte.de>
|
2003-03-13 03:52:19 +00:00
|
|
|
*
|
|
|
|
* 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
|
2012-11-20 14:03:50 +00:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2003-03-13 03:52:19 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* $Id$ */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* avrdude interface for Atmel Low Cost Serial programmers which adher to the
|
|
|
|
* protocol described in application note avr910.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "ac_cfg.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
2008-06-07 20:55:04 +00:00
|
|
|
#include <ctype.h>
|
2004-06-24 11:05:07 +00:00
|
|
|
#include <sys/time.h>
|
|
|
|
#include <unistd.h>
|
2003-03-13 03:52:19 +00:00
|
|
|
|
2007-01-24 21:07:54 +00:00
|
|
|
#include "avrdude.h"
|
2014-05-19 10:01:59 +00:00
|
|
|
#include "libavrdude.h"
|
|
|
|
|
2003-03-13 03:52:19 +00:00
|
|
|
#include "avr910.h"
|
|
|
|
|
main.c, pgm.c, pgm.h: Add setup and teardown hooks to the programmer
definition. If present, call the setup hook immediately after finding
the respective programmer object, and schedule the teardown hook to be
called upon exit. This allows the programmer implementation to
dynamically allocate private programmer data.
avr910.c, butterfly.c, jtagmkI.c, jtagmkII.c, stk500v2.c, usbasp.c,
usbtiny.c: Convert static programmer data into dynamically allocated
data.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@764 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-07 20:36:12 +00:00
|
|
|
/*
|
|
|
|
* Private data for this programmer.
|
|
|
|
*/
|
|
|
|
struct pdata
|
|
|
|
{
|
|
|
|
char has_auto_incr_addr;
|
2008-03-24 21:22:04 +00:00
|
|
|
unsigned char devcode;
|
2008-06-07 20:55:04 +00:00
|
|
|
unsigned int buffersize;
|
|
|
|
unsigned char test_blockmode;
|
|
|
|
unsigned char use_blockmode;
|
main.c, pgm.c, pgm.h: Add setup and teardown hooks to the programmer
definition. If present, call the setup hook immediately after finding
the respective programmer object, and schedule the teardown hook to be
called upon exit. This allows the programmer implementation to
dynamically allocate private programmer data.
avr910.c, butterfly.c, jtagmkI.c, jtagmkII.c, stk500v2.c, usbasp.c,
usbtiny.c: Convert static programmer data into dynamically allocated
data.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@764 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-07 20:36:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
|
|
|
|
|
|
|
|
static void avr910_setup(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: avr910_setup(): Out of memory allocating private data\n",
|
2014-05-18 08:41:46 +00:00
|
|
|
progname);
|
main.c, pgm.c, pgm.h: Add setup and teardown hooks to the programmer
definition. If present, call the setup hook immediately after finding
the respective programmer object, and schedule the teardown hook to be
called upon exit. This allows the programmer implementation to
dynamically allocate private programmer data.
avr910.c, butterfly.c, jtagmkI.c, jtagmkII.c, stk500v2.c, usbasp.c,
usbtiny.c: Convert static programmer data into dynamically allocated
data.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@764 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-07 20:36:12 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
memset(pgm->cookie, 0, sizeof(struct pdata));
|
2008-06-07 20:55:04 +00:00
|
|
|
PDATA(pgm)->test_blockmode = 1;
|
main.c, pgm.c, pgm.h: Add setup and teardown hooks to the programmer
definition. If present, call the setup hook immediately after finding
the respective programmer object, and schedule the teardown hook to be
called upon exit. This allows the programmer implementation to
dynamically allocate private programmer data.
avr910.c, butterfly.c, jtagmkI.c, jtagmkII.c, stk500v2.c, usbasp.c,
usbtiny.c: Convert static programmer data into dynamically allocated
data.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@764 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-07 20:36:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void avr910_teardown(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
free(pgm->cookie);
|
|
|
|
}
|
2003-04-06 00:47:16 +00:00
|
|
|
|
2003-03-13 03:52:19 +00:00
|
|
|
|
|
|
|
static int avr910_send(PROGRAMMER * pgm, char * buf, size_t len)
|
|
|
|
{
|
2006-12-11 12:47:35 +00:00
|
|
|
return serial_send(&pgm->fd, (unsigned char *)buf, len);
|
2003-03-13 03:52:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int avr910_recv(PROGRAMMER * pgm, char * buf, size_t len)
|
|
|
|
{
|
2005-05-11 17:09:22 +00:00
|
|
|
int rv;
|
|
|
|
|
2006-12-11 12:47:35 +00:00
|
|
|
rv = serial_recv(&pgm->fd, (unsigned char *)buf, len);
|
2005-05-11 17:09:22 +00:00
|
|
|
if (rv < 0) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: avr910_recv(): programmer is not responding\n",
|
2014-05-18 08:41:46 +00:00
|
|
|
progname);
|
2014-05-16 15:52:25 +00:00
|
|
|
return 1;
|
2005-05-11 17:09:22 +00:00
|
|
|
}
|
|
|
|
return 0;
|
2003-03-13 03:52:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int avr910_drain(PROGRAMMER * pgm, int display)
|
|
|
|
{
|
2006-12-11 12:47:35 +00:00
|
|
|
return serial_drain(&pgm->fd, display);
|
2003-03-13 03:52:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-05-16 15:52:25 +00:00
|
|
|
static int avr910_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
|
2003-03-17 06:20:02 +00:00
|
|
|
{
|
|
|
|
char c;
|
|
|
|
|
|
|
|
avr910_recv(pgm, &c, 1);
|
|
|
|
if (c != '\r') {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: error: programmer did not respond to command: %s\n",
|
2003-03-17 06:20:02 +00:00
|
|
|
progname, errmsg);
|
2014-05-16 15:52:25 +00:00
|
|
|
return 1;
|
2003-03-17 06:20:02 +00:00
|
|
|
}
|
2014-05-16 15:52:25 +00:00
|
|
|
return 0;
|
2003-03-17 06:20:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-03-13 03:52:19 +00:00
|
|
|
/*
|
|
|
|
* issue the 'chip erase' command to the AVR device
|
|
|
|
*/
|
|
|
|
static int avr910_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
|
|
|
{
|
2003-03-17 06:20:02 +00:00
|
|
|
avr910_send(pgm, "e", 1);
|
2014-05-16 15:52:25 +00:00
|
|
|
if (avr910_vfy_cmd_sent(pgm, "chip erase") < 0)
|
|
|
|
return -1;
|
2003-03-16 18:19:37 +00:00
|
|
|
|
2004-04-17 19:37:14 +00:00
|
|
|
/*
|
|
|
|
* avr910 firmware may not delay long enough
|
|
|
|
*/
|
|
|
|
usleep (p->chip_erase_delay);
|
|
|
|
|
2003-03-13 03:52:19 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-03-24 07:09:16 +00:00
|
|
|
|
2014-05-16 15:52:25 +00:00
|
|
|
static int avr910_enter_prog_mode(PROGRAMMER * pgm)
|
2003-03-24 07:09:16 +00:00
|
|
|
{
|
|
|
|
avr910_send(pgm, "P", 1);
|
2014-05-16 15:52:25 +00:00
|
|
|
return avr910_vfy_cmd_sent(pgm, "enter prog mode");
|
2003-03-24 07:09:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-05-16 15:52:25 +00:00
|
|
|
static int avr910_leave_prog_mode(PROGRAMMER * pgm)
|
2003-03-24 07:09:16 +00:00
|
|
|
{
|
|
|
|
avr910_send(pgm, "L", 1);
|
2014-05-16 15:52:25 +00:00
|
|
|
return avr910_vfy_cmd_sent(pgm, "leave prog mode");
|
2003-03-24 07:09:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-03-13 03:52:19 +00:00
|
|
|
/*
|
|
|
|
* issue the 'program enable' command to the AVR device
|
|
|
|
*/
|
|
|
|
static int avr910_program_enable(PROGRAMMER * pgm, AVRPART * p)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* initialize the AVR device and prepare it to accept commands
|
|
|
|
*/
|
|
|
|
static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
|
|
|
|
{
|
2003-03-17 06:20:02 +00:00
|
|
|
char id[8];
|
2003-03-16 18:19:37 +00:00
|
|
|
char sw[2];
|
|
|
|
char hw[2];
|
2003-03-17 06:20:02 +00:00
|
|
|
char buf[10];
|
|
|
|
char type;
|
2012-01-08 17:09:40 +00:00
|
|
|
char c;
|
2004-01-12 22:48:50 +00:00
|
|
|
AVRPART * part;
|
2003-03-16 18:19:37 +00:00
|
|
|
|
2003-03-17 06:20:02 +00:00
|
|
|
/* Get the programmer identifier. Programmer returns exactly 7 chars
|
|
|
|
_without_ the null.*/
|
2003-03-16 18:19:37 +00:00
|
|
|
|
|
|
|
avr910_send(pgm, "S", 1);
|
2003-03-17 06:20:02 +00:00
|
|
|
memset (id, 0, sizeof(id));
|
|
|
|
avr910_recv(pgm, id, sizeof(id)-1);
|
2003-03-16 18:19:37 +00:00
|
|
|
|
|
|
|
/* Get the HW and SW versions to see if the programmer is present. */
|
|
|
|
|
|
|
|
avr910_send(pgm, "V", 1);
|
|
|
|
avr910_recv(pgm, sw, sizeof(sw));
|
|
|
|
|
|
|
|
avr910_send(pgm, "v", 1);
|
|
|
|
avr910_recv(pgm, hw, sizeof(hw));
|
|
|
|
|
2003-03-17 06:20:02 +00:00
|
|
|
/* Get the programmer type (serial or parallel). Expect serial. */
|
|
|
|
|
|
|
|
avr910_send(pgm, "p", 1);
|
|
|
|
avr910_recv(pgm, &type, 1);
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "Found programmer: Id = \"%s\"; type = %c\n", id, type);
|
|
|
|
avrdude_message(MSG_INFO, " Software Version = %c.%c; ", sw[0], sw[1]);
|
|
|
|
avrdude_message(MSG_INFO, "Hardware Version = %c.%c\n", hw[0], hw[1]);
|
2003-04-06 00:47:16 +00:00
|
|
|
|
|
|
|
/* See if programmer supports autoincrement of address. */
|
|
|
|
|
|
|
|
avr910_send(pgm, "a", 1);
|
main.c, pgm.c, pgm.h: Add setup and teardown hooks to the programmer
definition. If present, call the setup hook immediately after finding
the respective programmer object, and schedule the teardown hook to be
called upon exit. This allows the programmer implementation to
dynamically allocate private programmer data.
avr910.c, butterfly.c, jtagmkI.c, jtagmkII.c, stk500v2.c, usbasp.c,
usbtiny.c: Convert static programmer data into dynamically allocated
data.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@764 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-07 20:36:12 +00:00
|
|
|
avr910_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1);
|
|
|
|
if (PDATA(pgm)->has_auto_incr_addr == 'Y')
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "Programmer supports auto addr increment.\n");
|
2003-03-16 18:19:37 +00:00
|
|
|
|
2008-06-07 20:55:04 +00:00
|
|
|
/* Check support for buffered memory access, ignore if not available */
|
|
|
|
|
|
|
|
if (PDATA(pgm)->test_blockmode == 1) {
|
|
|
|
avr910_send(pgm, "b", 1);
|
|
|
|
avr910_recv(pgm, &c, 1);
|
|
|
|
if (c == 'Y') {
|
|
|
|
avr910_recv(pgm, &c, 1);
|
|
|
|
PDATA(pgm)->buffersize = (unsigned int)(unsigned char)c<<8;
|
|
|
|
avr910_recv(pgm, &c, 1);
|
|
|
|
PDATA(pgm)->buffersize += (unsigned int)(unsigned char)c;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "Programmer supports buffered memory access with "
|
2014-05-18 08:41:46 +00:00
|
|
|
"buffersize = %u bytes.\n",
|
|
|
|
PDATA(pgm)->buffersize);
|
2008-06-07 20:55:04 +00:00
|
|
|
PDATA(pgm)->use_blockmode = 1;
|
|
|
|
} else {
|
|
|
|
PDATA(pgm)->use_blockmode = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
PDATA(pgm)->use_blockmode = 0;
|
|
|
|
}
|
|
|
|
|
2008-03-24 21:22:04 +00:00
|
|
|
if (PDATA(pgm)->devcode == 0) {
|
2012-01-08 17:09:40 +00:00
|
|
|
char devtype_1st;
|
|
|
|
int dev_supported = 0;
|
2003-03-16 18:19:37 +00:00
|
|
|
|
2008-03-24 21:22:04 +00:00
|
|
|
/* Get list of devices that the programmer supports. */
|
2004-01-12 22:48:50 +00:00
|
|
|
|
2008-03-24 21:22:04 +00:00
|
|
|
avr910_send(pgm, "t", 1);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "\nProgrammer supports the following devices:\n");
|
2008-03-24 21:22:04 +00:00
|
|
|
devtype_1st = 0;
|
|
|
|
while (1) {
|
|
|
|
avr910_recv(pgm, &c, 1);
|
|
|
|
if (devtype_1st == 0)
|
|
|
|
devtype_1st = c;
|
|
|
|
if (c == 0)
|
|
|
|
break;
|
|
|
|
part = locate_part_by_avr910_devcode(part_list, c);
|
2003-03-17 06:20:02 +00:00
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, " Device code: 0x%02x = %s\n", c, part ? part->desc : "(unknown)");
|
2003-03-17 06:20:02 +00:00
|
|
|
|
2008-03-24 21:22:04 +00:00
|
|
|
/* FIXME: Need to lookup devcode and report the device. */
|
2003-03-17 06:20:02 +00:00
|
|
|
|
2008-03-24 21:22:04 +00:00
|
|
|
if (p->avr910_devcode == c)
|
|
|
|
dev_supported = 1;
|
|
|
|
};
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "\n");
|
2003-03-17 06:20:02 +00:00
|
|
|
|
2008-03-24 21:22:04 +00:00
|
|
|
if (!dev_supported) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: %s: selected device is not supported by programmer: %s\n",
|
2014-05-18 08:41:46 +00:00
|
|
|
progname, ovsigck? "warning": "error", p->id);
|
2008-03-24 21:22:04 +00:00
|
|
|
if (!ovsigck)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2008-03-24 21:22:04 +00:00
|
|
|
}
|
|
|
|
/* If the user forced the selection, use the first device
|
|
|
|
type that is supported by the programmer. */
|
|
|
|
buf[1] = ovsigck? devtype_1st: p->avr910_devcode;
|
|
|
|
} else {
|
|
|
|
/* devcode overridden by -x devcode= option */
|
|
|
|
buf[1] = (char)(PDATA(pgm)->devcode);
|
|
|
|
}
|
2003-03-17 06:20:02 +00:00
|
|
|
|
2008-03-24 21:22:04 +00:00
|
|
|
/* Tell the programmer which part we selected. */
|
2003-03-17 06:20:02 +00:00
|
|
|
buf[0] = 'T';
|
2008-03-24 21:22:04 +00:00
|
|
|
/* buf[1] has been set up above */
|
2003-03-17 06:20:02 +00:00
|
|
|
|
|
|
|
avr910_send(pgm, buf, 2);
|
|
|
|
avr910_vfy_cmd_sent(pgm, "select device");
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE, "%s: avr910_devcode selected: 0x%02x\n",
|
|
|
|
progname, (unsigned)buf[1]);
|
2008-06-07 21:03:41 +00:00
|
|
|
|
2003-03-17 06:20:02 +00:00
|
|
|
avr910_enter_prog_mode(pgm);
|
2003-03-16 18:19:37 +00:00
|
|
|
|
2003-03-13 03:52:19 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void avr910_disable(PROGRAMMER * pgm)
|
|
|
|
{
|
2003-03-17 06:20:02 +00:00
|
|
|
/* Do nothing. */
|
2003-03-16 18:19:37 +00:00
|
|
|
|
2003-03-13 03:52:19 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void avr910_enable(PROGRAMMER * pgm)
|
|
|
|
{
|
2003-03-16 18:19:37 +00:00
|
|
|
/* Do nothing. */
|
|
|
|
|
2003-03-13 03:52:19 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* transmit an AVR device command and return the results; 'cmd' and
|
|
|
|
* 'res' must point to at least a 4 byte data buffer
|
|
|
|
*/
|
2013-09-02 20:22:53 +00:00
|
|
|
static int avr910_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
|
|
|
|
unsigned char *res)
|
2003-03-13 03:52:19 +00:00
|
|
|
{
|
2005-08-30 01:30:05 +00:00
|
|
|
char buf[5];
|
2003-03-17 06:20:02 +00:00
|
|
|
|
2003-09-05 16:40:55 +00:00
|
|
|
/* FIXME: Insert version check here */
|
|
|
|
|
|
|
|
buf[0] = '.'; /* New Universal Command */
|
|
|
|
buf[1] = cmd[0];
|
|
|
|
buf[2] = cmd[1];
|
|
|
|
buf[3] = cmd[2];
|
|
|
|
buf[4] = cmd[3];
|
|
|
|
|
|
|
|
avr910_send (pgm, buf, 5);
|
|
|
|
avr910_recv (pgm, buf, 2);
|
|
|
|
|
|
|
|
res[0] = 0x00; /* Dummy value */
|
|
|
|
res[1] = cmd[0];
|
|
|
|
res[2] = cmd[1];
|
|
|
|
res[3] = buf[0];
|
2003-03-17 06:20:02 +00:00
|
|
|
|
2003-03-16 18:19:37 +00:00
|
|
|
return 0;
|
2003-03-13 03:52:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-24 21:22:04 +00:00
|
|
|
static int avr910_parseextparms(PROGRAMMER * pgm, LISTID extparms)
|
|
|
|
{
|
|
|
|
LNODEID ln;
|
|
|
|
const char *extended_param;
|
|
|
|
int rv = 0;
|
|
|
|
|
|
|
|
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
|
|
|
|
extended_param = ldata(ln);
|
|
|
|
|
|
|
|
if (strncmp(extended_param, "devcode=", strlen("devcode=")) == 0) {
|
|
|
|
int devcode;
|
|
|
|
if (sscanf(extended_param, "devcode=%i", &devcode) != 1 ||
|
|
|
|
devcode <= 0 || devcode > 255) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: avr910_parseextparms(): invalid devcode '%s'\n",
|
2014-05-18 08:41:46 +00:00
|
|
|
progname, extended_param);
|
2008-03-24 21:22:04 +00:00
|
|
|
rv = -1;
|
|
|
|
continue;
|
|
|
|
}
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: avr910_parseextparms(): devcode overwritten as 0x%02x\n",
|
|
|
|
progname, devcode);
|
2008-03-24 21:22:04 +00:00
|
|
|
PDATA(pgm)->devcode = devcode;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
2008-06-07 20:55:04 +00:00
|
|
|
if (strncmp(extended_param, "no_blockmode", strlen("no_blockmode")) == 0) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: avr910_parseextparms(-x): no testing for Blockmode\n",
|
|
|
|
progname);
|
2008-06-07 20:55:04 +00:00
|
|
|
PDATA(pgm)->test_blockmode = 0;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
2008-03-24 21:22:04 +00:00
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: avr910_parseextparms(): invalid extended parameter '%s'\n",
|
2014-05-18 08:41:46 +00:00
|
|
|
progname, extended_param);
|
2008-03-24 21:22:04 +00:00
|
|
|
rv = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-28 20:01:44 +00:00
|
|
|
static int avr910_open(PROGRAMMER * pgm, char * port)
|
2003-03-13 03:52:19 +00:00
|
|
|
{
|
2014-02-21 13:44:11 +00:00
|
|
|
union pinfo pinfo;
|
2004-01-03 18:36:44 +00:00
|
|
|
/*
|
|
|
|
* If baudrate was not specified use 19.200 Baud
|
|
|
|
*/
|
|
|
|
if(pgm->baudrate == 0) {
|
|
|
|
pgm->baudrate = 19200;
|
|
|
|
}
|
|
|
|
|
2003-03-13 03:52:19 +00:00
|
|
|
strcpy(pgm->port, port);
|
2021-12-08 10:09:52 +00:00
|
|
|
pinfo.serialinfo.baud = pgm->baudrate;
|
|
|
|
pinfo.serialinfo.cflags = SERIAL_8N1;
|
2014-02-21 13:44:11 +00:00
|
|
|
if (serial_open(port, pinfo, &pgm->fd)==-1) {
|
2010-10-22 14:29:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2003-03-13 03:52:19 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* drain any extraneous input
|
|
|
|
*/
|
|
|
|
avr910_drain (pgm, 0);
|
2004-06-24 11:05:07 +00:00
|
|
|
|
|
|
|
return 0;
|
2003-03-13 03:52:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void avr910_close(PROGRAMMER * pgm)
|
|
|
|
{
|
2003-03-17 06:20:02 +00:00
|
|
|
avr910_leave_prog_mode(pgm);
|
2003-03-16 18:19:37 +00:00
|
|
|
|
2006-12-11 12:47:35 +00:00
|
|
|
serial_close(&pgm->fd);
|
|
|
|
pgm->fd.ifd = -1;
|
2003-03-13 03:52:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-01-30 13:41:54 +00:00
|
|
|
static void avr910_display(PROGRAMMER * pgm, const char * p)
|
2003-03-13 03:52:19 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-03-24 07:09:16 +00:00
|
|
|
|
|
|
|
static void avr910_set_addr(PROGRAMMER * pgm, unsigned long addr)
|
|
|
|
{
|
2005-08-30 01:30:05 +00:00
|
|
|
char cmd[3];
|
2003-03-24 07:09:16 +00:00
|
|
|
|
|
|
|
cmd[0] = 'A';
|
|
|
|
cmd[1] = (addr >> 8) & 0xff;
|
|
|
|
cmd[2] = addr & 0xff;
|
|
|
|
|
|
|
|
avr910_send(pgm, cmd, sizeof(cmd));
|
|
|
|
avr910_vfy_cmd_sent(pgm, "set addr");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-04-06 07:10:44 +00:00
|
|
|
static int avr910_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|
|
|
unsigned long addr, unsigned char value)
|
|
|
|
{
|
2005-08-30 01:30:05 +00:00
|
|
|
char cmd[2];
|
2003-04-06 07:10:44 +00:00
|
|
|
|
|
|
|
if (strcmp(m->desc, "flash") == 0) {
|
|
|
|
if (addr & 0x01) {
|
|
|
|
cmd[0] = 'C'; /* Write Program Mem high byte */
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
cmd[0] = 'c';
|
|
|
|
}
|
|
|
|
|
|
|
|
addr >>= 1;
|
|
|
|
}
|
|
|
|
else if (strcmp(m->desc, "eeprom") == 0) {
|
|
|
|
cmd[0] = 'D';
|
|
|
|
}
|
|
|
|
else {
|
2007-05-15 22:00:29 +00:00
|
|
|
return avr_write_byte_default(pgm, p, m, addr, value);
|
2003-04-06 07:10:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cmd[1] = value;
|
|
|
|
|
|
|
|
avr910_set_addr(pgm, addr);
|
|
|
|
|
|
|
|
avr910_send(pgm, cmd, sizeof(cmd));
|
|
|
|
avr910_vfy_cmd_sent(pgm, "write byte");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int avr910_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|
|
|
unsigned long addr, unsigned char * value)
|
|
|
|
{
|
2009-02-28 10:07:01 +00:00
|
|
|
char buf[2];
|
2003-04-06 07:10:44 +00:00
|
|
|
|
2009-02-28 10:07:01 +00:00
|
|
|
avr910_set_addr(pgm, addr >> 1);
|
2003-04-06 07:10:44 +00:00
|
|
|
|
2009-02-28 10:07:01 +00:00
|
|
|
avr910_send(pgm, "R", 1);
|
2003-04-06 07:10:44 +00:00
|
|
|
|
2009-02-28 10:07:01 +00:00
|
|
|
/* Read back the program mem word (MSB first) */
|
|
|
|
avr910_recv(pgm, buf, sizeof(buf));
|
2003-04-06 07:10:44 +00:00
|
|
|
|
2009-02-28 10:07:01 +00:00
|
|
|
if ((addr & 0x01) == 0) {
|
|
|
|
*value = buf[1];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*value = buf[0];
|
2003-04-06 07:10:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int avr910_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|
|
|
unsigned long addr, unsigned char * value)
|
|
|
|
{
|
|
|
|
avr910_set_addr(pgm, addr);
|
|
|
|
avr910_send(pgm, "d", 1);
|
2005-08-30 01:30:05 +00:00
|
|
|
avr910_recv(pgm, (char *)value, 1);
|
2003-04-06 07:10:44 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int avr910_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|
|
|
unsigned long addr, unsigned char * value)
|
|
|
|
{
|
|
|
|
if (strcmp(m->desc, "flash") == 0) {
|
|
|
|
return avr910_read_byte_flash(pgm, p, m, addr, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(m->desc, "eeprom") == 0) {
|
|
|
|
return avr910_read_byte_eeprom(pgm, p, m, addr, value);
|
|
|
|
}
|
|
|
|
|
2007-05-15 22:00:29 +00:00
|
|
|
return avr_read_byte_default(pgm, p, m, addr, value);
|
2003-04-06 07:10:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-04-06 00:47:16 +00:00
|
|
|
static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
2011-09-14 21:49:42 +00:00
|
|
|
unsigned int page_size,
|
|
|
|
unsigned int addr, unsigned int n_bytes)
|
2003-03-24 07:09:16 +00:00
|
|
|
{
|
2003-04-06 00:47:16 +00:00
|
|
|
unsigned char cmd[] = {'c', 'C'};
|
2005-08-30 01:30:05 +00:00
|
|
|
char buf[2];
|
2011-09-14 21:49:42 +00:00
|
|
|
unsigned int max_addr = addr + n_bytes;
|
2003-05-14 05:14:32 +00:00
|
|
|
unsigned int page_addr;
|
|
|
|
int page_bytes = page_size;
|
2003-08-28 23:02:25 +00:00
|
|
|
int page_wr_cmd_pending = 0;
|
2003-03-24 07:09:16 +00:00
|
|
|
|
2003-05-14 05:14:32 +00:00
|
|
|
page_addr = addr;
|
2003-04-06 00:47:16 +00:00
|
|
|
avr910_set_addr(pgm, addr>>1);
|
2003-03-24 07:09:16 +00:00
|
|
|
|
2003-04-06 00:47:16 +00:00
|
|
|
while (addr < max_addr) {
|
2003-05-14 05:14:32 +00:00
|
|
|
page_wr_cmd_pending = 1;
|
2003-04-06 00:47:16 +00:00
|
|
|
buf[0] = cmd[addr & 0x01];
|
|
|
|
buf[1] = m->buf[addr];
|
|
|
|
avr910_send(pgm, buf, sizeof(buf));
|
|
|
|
avr910_vfy_cmd_sent(pgm, "write byte");
|
2003-03-24 07:09:16 +00:00
|
|
|
|
2003-04-06 00:47:16 +00:00
|
|
|
addr++;
|
2003-05-14 05:14:32 +00:00
|
|
|
page_bytes--;
|
2003-03-24 07:09:16 +00:00
|
|
|
|
2005-09-18 00:28:19 +00:00
|
|
|
if (m->paged && (page_bytes == 0)) {
|
2003-05-14 05:14:32 +00:00
|
|
|
/* 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");
|
|
|
|
|
2005-09-18 00:28:19 +00:00
|
|
|
page_wr_cmd_pending = 0;
|
|
|
|
usleep(m->max_write_delay);
|
|
|
|
avr910_set_addr(pgm, addr>>1);
|
|
|
|
|
2003-05-14 05:14:32 +00:00
|
|
|
/* Set page address for next page. */
|
|
|
|
|
|
|
|
page_addr = addr;
|
|
|
|
page_bytes = page_size;
|
|
|
|
}
|
main.c, pgm.c, pgm.h: Add setup and teardown hooks to the programmer
definition. If present, call the setup hook immediately after finding
the respective programmer object, and schedule the teardown hook to be
called upon exit. This allows the programmer implementation to
dynamically allocate private programmer data.
avr910.c, butterfly.c, jtagmkI.c, jtagmkII.c, stk500v2.c, usbasp.c,
usbtiny.c: Convert static programmer data into dynamically allocated
data.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@764 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-07 20:36:12 +00:00
|
|
|
else if ((PDATA(pgm)->has_auto_incr_addr != 'Y') && ((addr & 0x01) == 0)) {
|
2005-09-18 00:28:19 +00:00
|
|
|
avr910_set_addr(pgm, addr>>1);
|
|
|
|
}
|
2003-05-14 05:14:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* If we didn't send the page wr cmd after the last byte written in the
|
|
|
|
loop, send it now. */
|
|
|
|
|
|
|
|
if (page_wr_cmd_pending) {
|
|
|
|
avr910_set_addr(pgm, page_addr>>1);
|
|
|
|
avr910_send(pgm, "m", 1);
|
|
|
|
avr910_vfy_cmd_sent(pgm, "flush final page");
|
2005-09-18 00:28:19 +00:00
|
|
|
usleep(m->max_write_delay);
|
2003-03-24 07:09:16 +00:00
|
|
|
}
|
|
|
|
|
2003-04-06 00:47:16 +00:00
|
|
|
return addr;
|
2003-03-24 07:09:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-04-06 00:47:16 +00:00
|
|
|
static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
|
2011-09-14 21:49:42 +00:00
|
|
|
AVRMEM * m,
|
|
|
|
unsigned int page_size,
|
|
|
|
unsigned int addr, unsigned int n_bytes)
|
2003-03-24 07:09:16 +00:00
|
|
|
{
|
2005-08-30 01:30:05 +00:00
|
|
|
char cmd[2];
|
2011-09-14 21:49:42 +00:00
|
|
|
unsigned int max_addr = addr + n_bytes;
|
2003-03-24 07:09:16 +00:00
|
|
|
|
2003-04-06 00:47:16 +00:00
|
|
|
avr910_set_addr(pgm, addr);
|
2003-03-24 07:09:16 +00:00
|
|
|
|
2003-04-06 00:47:16 +00:00
|
|
|
cmd[0] = 'D';
|
2003-03-24 07:09:16 +00:00
|
|
|
|
2003-04-06 00:47:16 +00:00
|
|
|
while (addr < max_addr) {
|
|
|
|
cmd[1] = m->buf[addr];
|
|
|
|
avr910_send(pgm, cmd, sizeof(cmd));
|
|
|
|
avr910_vfy_cmd_sent(pgm, "write byte");
|
2005-09-18 00:28:19 +00:00
|
|
|
usleep(m->max_write_delay);
|
2003-03-24 07:09:16 +00:00
|
|
|
|
2003-04-06 00:47:16 +00:00
|
|
|
addr++;
|
2003-03-24 07:09:16 +00:00
|
|
|
|
main.c, pgm.c, pgm.h: Add setup and teardown hooks to the programmer
definition. If present, call the setup hook immediately after finding
the respective programmer object, and schedule the teardown hook to be
called upon exit. This allows the programmer implementation to
dynamically allocate private programmer data.
avr910.c, butterfly.c, jtagmkI.c, jtagmkII.c, stk500v2.c, usbasp.c,
usbtiny.c: Convert static programmer data into dynamically allocated
data.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@764 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-07 20:36:12 +00:00
|
|
|
if (PDATA(pgm)->has_auto_incr_addr != 'Y') {
|
2003-04-06 00:47:16 +00:00
|
|
|
avr910_set_addr(pgm, addr);
|
2003-03-24 07:09:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-04-06 00:47:16 +00:00
|
|
|
return addr;
|
2003-03-24 07:09:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-04-17 19:37:14 +00:00
|
|
|
static int avr910_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
2011-09-14 21:49:42 +00:00
|
|
|
unsigned int page_size,
|
|
|
|
unsigned int addr, unsigned int n_bytes)
|
2003-03-24 07:09:16 +00:00
|
|
|
{
|
2008-06-07 20:55:04 +00:00
|
|
|
int rval = 0;
|
|
|
|
if (PDATA(pgm)->use_blockmode == 0) {
|
|
|
|
if (strcmp(m->desc, "flash") == 0) {
|
2011-09-14 21:49:42 +00:00
|
|
|
rval = avr910_paged_write_flash(pgm, p, m, page_size, addr, n_bytes);
|
2008-06-07 20:55:04 +00:00
|
|
|
} else if (strcmp(m->desc, "eeprom") == 0) {
|
2011-09-14 21:49:42 +00:00
|
|
|
rval = avr910_paged_write_eeprom(pgm, p, m, page_size, addr, n_bytes);
|
2008-06-07 20:55:04 +00:00
|
|
|
} else {
|
|
|
|
rval = -2;
|
|
|
|
}
|
2003-04-06 00:47:16 +00:00
|
|
|
}
|
2008-06-07 20:55:04 +00:00
|
|
|
|
|
|
|
if (PDATA(pgm)->use_blockmode == 1) {
|
2011-09-14 21:49:42 +00:00
|
|
|
unsigned int max_addr = addr + n_bytes;
|
2008-06-07 20:55:04 +00:00
|
|
|
char *cmd;
|
|
|
|
unsigned int blocksize = PDATA(pgm)->buffersize;
|
2013-09-03 21:43:24 +00:00
|
|
|
int wr_size;
|
2008-06-07 20:55:04 +00:00
|
|
|
|
|
|
|
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
|
2012-01-08 17:09:40 +00:00
|
|
|
return -2;
|
2008-06-07 20:55:04 +00:00
|
|
|
|
2013-09-03 21:43:24 +00:00
|
|
|
if (m->desc[0] == 'e') {
|
2008-06-07 20:55:04 +00:00
|
|
|
blocksize = 1; /* Write to eeprom single bytes only */
|
2013-09-03 21:43:24 +00:00
|
|
|
wr_size = 1;
|
|
|
|
} else {
|
|
|
|
wr_size = 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
avr910_set_addr(pgm, addr / wr_size);
|
2008-06-07 20:55:04 +00:00
|
|
|
|
|
|
|
cmd = malloc(4 + blocksize);
|
2012-01-08 17:09:40 +00:00
|
|
|
if (!cmd) return -1;
|
|
|
|
|
2008-06-07 20:55:04 +00:00
|
|
|
cmd[0] = 'B';
|
2010-01-22 16:40:17 +00:00
|
|
|
cmd[3] = toupper((int)(m->desc[0]));
|
2008-06-07 20:55:04 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
avr910_send(pgm, cmd, 4 + blocksize);
|
|
|
|
avr910_vfy_cmd_sent(pgm, "write block");
|
|
|
|
|
|
|
|
addr += blocksize;
|
|
|
|
} /* while */
|
|
|
|
free(cmd);
|
|
|
|
|
|
|
|
rval = addr;
|
2003-04-06 00:47:16 +00:00
|
|
|
}
|
2008-06-07 20:55:04 +00:00
|
|
|
return rval;
|
2003-03-24 07:09:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-09-14 21:49:42 +00:00
|
|
|
static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|
|
|
unsigned int page_size,
|
|
|
|
unsigned int addr, unsigned int n_bytes)
|
2003-03-24 07:09:16 +00:00
|
|
|
{
|
2011-09-14 21:49:42 +00:00
|
|
|
char cmd[4];
|
|
|
|
int rd_size;
|
2003-04-06 00:47:16 +00:00
|
|
|
unsigned int max_addr;
|
2005-08-30 01:30:05 +00:00
|
|
|
char buf[2];
|
2008-06-07 20:55:04 +00:00
|
|
|
int rval=0;
|
|
|
|
|
2011-09-14 21:49:42 +00:00
|
|
|
max_addr = addr + n_bytes;
|
2003-04-06 00:47:16 +00:00
|
|
|
|
2011-09-14 21:49:42 +00:00
|
|
|
if (strcmp(m->desc, "flash") == 0) {
|
|
|
|
cmd[0] = 'R';
|
|
|
|
rd_size = 2; /* read two bytes per addr */
|
|
|
|
} else if (strcmp(m->desc, "eeprom") == 0) {
|
|
|
|
cmd[0] = 'd';
|
|
|
|
rd_size = 1;
|
|
|
|
} else {
|
|
|
|
return -2;
|
2008-06-07 20:55:04 +00:00
|
|
|
}
|
2003-04-06 00:47:16 +00:00
|
|
|
|
2011-09-14 21:49:42 +00:00
|
|
|
if (PDATA(pgm)->use_blockmode) {
|
|
|
|
/* use buffered mode */
|
2008-06-07 20:55:04 +00:00
|
|
|
int blocksize = PDATA(pgm)->buffersize;
|
|
|
|
|
|
|
|
cmd[0] = 'g';
|
2010-01-22 16:40:17 +00:00
|
|
|
cmd[3] = toupper((int)(m->desc[0]));
|
2008-06-07 20:55:04 +00:00
|
|
|
|
2011-09-14 21:49:42 +00:00
|
|
|
avr910_set_addr(pgm, addr / rd_size);
|
2008-06-07 20:55:04 +00:00
|
|
|
|
|
|
|
while (addr < max_addr) {
|
|
|
|
if ((max_addr - addr) < blocksize) {
|
|
|
|
blocksize = max_addr - addr;
|
2011-09-14 21:49:42 +00:00
|
|
|
}
|
2008-06-07 20:55:04 +00:00
|
|
|
cmd[1] = (blocksize >> 8) & 0xff;
|
|
|
|
cmd[2] = blocksize & 0xff;
|
|
|
|
|
|
|
|
avr910_send(pgm, cmd, 4);
|
|
|
|
avr910_recv(pgm, (char *)&m->buf[addr], blocksize);
|
|
|
|
|
|
|
|
addr += blocksize;
|
2011-09-14 21:49:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
rval = addr;
|
|
|
|
} else {
|
2008-06-07 20:55:04 +00:00
|
|
|
|
2011-09-14 21:49:42 +00:00
|
|
|
avr910_set_addr(pgm, addr / rd_size);
|
|
|
|
|
|
|
|
while (addr < max_addr) {
|
|
|
|
avr910_send(pgm, cmd, 1);
|
|
|
|
if (rd_size == 2) {
|
|
|
|
/* The 'R' command returns two bytes, MSB first, we need to put the data
|
|
|
|
into the memory buffer LSB first. */
|
|
|
|
avr910_recv(pgm, buf, 2);
|
|
|
|
m->buf[addr] = buf[1]; /* LSB */
|
|
|
|
m->buf[addr + 1] = buf[0]; /* MSB */
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
avr910_recv(pgm, (char *)&m->buf[addr], 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
addr += rd_size;
|
|
|
|
|
|
|
|
if (PDATA(pgm)->has_auto_incr_addr != 'Y') {
|
|
|
|
avr910_set_addr(pgm, addr / rd_size);
|
|
|
|
}
|
2003-04-06 00:47:16 +00:00
|
|
|
}
|
2003-07-29 22:08:21 +00:00
|
|
|
|
2011-09-14 21:49:42 +00:00
|
|
|
rval = addr;
|
2003-03-24 07:09:16 +00:00
|
|
|
}
|
|
|
|
|
2008-06-07 20:55:04 +00:00
|
|
|
return rval;
|
2003-03-24 07:09:16 +00:00
|
|
|
}
|
|
|
|
|
2003-03-17 06:20:02 +00:00
|
|
|
/* Signature byte reads are always 3 bytes. */
|
|
|
|
|
|
|
|
static int avr910_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
|
|
|
|
{
|
2006-09-01 10:03:12 +00:00
|
|
|
unsigned char tmp;
|
|
|
|
|
2003-03-17 06:20:02 +00:00
|
|
|
if (m->size < 3) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: memsize too small for sig byte read", progname);
|
2003-03-17 06:20:02 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
avr910_send(pgm, "s", 1);
|
2005-08-30 01:30:05 +00:00
|
|
|
avr910_recv(pgm, (char *)m->buf, 3);
|
2006-09-01 10:03:12 +00:00
|
|
|
/* Returned signature has wrong order. */
|
|
|
|
tmp = m->buf[2];
|
|
|
|
m->buf[2] = m->buf[0];
|
|
|
|
m->buf[0] = tmp;
|
2003-03-17 06:20:02 +00:00
|
|
|
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
|
2012-01-31 17:03:43 +00:00
|
|
|
const char avr910_desc[] = "Serial programmers using protocol described in application note AVR910";
|
2003-03-13 03:52:19 +00:00
|
|
|
|
|
|
|
void avr910_initpgm(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
strcpy(pgm->type, "avr910");
|
|
|
|
|
|
|
|
/*
|
|
|
|
* mandatory functions
|
|
|
|
*/
|
|
|
|
pgm->initialize = avr910_initialize;
|
|
|
|
pgm->display = avr910_display;
|
|
|
|
pgm->enable = avr910_enable;
|
|
|
|
pgm->disable = avr910_disable;
|
|
|
|
pgm->program_enable = avr910_program_enable;
|
|
|
|
pgm->chip_erase = avr910_chip_erase;
|
|
|
|
pgm->cmd = avr910_cmd;
|
|
|
|
pgm->open = avr910_open;
|
|
|
|
pgm->close = avr910_close;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* optional functions
|
|
|
|
*/
|
2003-03-17 06:20:02 +00:00
|
|
|
|
2003-04-06 07:10:44 +00:00
|
|
|
pgm->write_byte = avr910_write_byte;
|
|
|
|
pgm->read_byte = avr910_read_byte;
|
|
|
|
|
2003-04-06 00:47:16 +00:00
|
|
|
pgm->paged_write = avr910_paged_write;
|
|
|
|
pgm->paged_load = avr910_paged_load;
|
2003-04-06 07:10:44 +00:00
|
|
|
|
2003-03-17 06:20:02 +00:00
|
|
|
pgm->read_sig_bytes = avr910_read_sig_bytes;
|
main.c, pgm.c, pgm.h: Add setup and teardown hooks to the programmer
definition. If present, call the setup hook immediately after finding
the respective programmer object, and schedule the teardown hook to be
called upon exit. This allows the programmer implementation to
dynamically allocate private programmer data.
avr910.c, butterfly.c, jtagmkI.c, jtagmkII.c, stk500v2.c, usbasp.c,
usbtiny.c: Convert static programmer data into dynamically allocated
data.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@764 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-07 20:36:12 +00:00
|
|
|
|
2008-03-24 21:22:04 +00:00
|
|
|
pgm->parseextparams = avr910_parseextparms;
|
main.c, pgm.c, pgm.h: Add setup and teardown hooks to the programmer
definition. If present, call the setup hook immediately after finding
the respective programmer object, and schedule the teardown hook to be
called upon exit. This allows the programmer implementation to
dynamically allocate private programmer data.
avr910.c, butterfly.c, jtagmkI.c, jtagmkII.c, stk500v2.c, usbasp.c,
usbtiny.c: Convert static programmer data into dynamically allocated
data.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@764 81a1dc3b-b13d-400b-aceb-764788c761c2
2007-11-07 20:36:12 +00:00
|
|
|
pgm->setup = avr910_setup;
|
|
|
|
pgm->teardown = avr910_teardown;
|
2003-03-13 03:52:19 +00:00
|
|
|
}
|