2005-05-10 19:53:56 +00:00
|
|
|
/*
|
|
|
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
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 (C) 2005-2007 Joerg Wunsch <j@uriah.heep.sax.de>
|
2005-05-10 19:53:56 +00:00
|
|
|
*
|
|
|
|
* Derived from stk500 code which is:
|
|
|
|
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
|
|
|
|
* Copyright (C) 2005 Erik Walthinsen
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 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/>.
|
2005-05-10 19:53:56 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* $Id$ */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* avrdude interface for Atmel JTAG ICE mkII programmer
|
2006-10-26 21:14:10 +00:00
|
|
|
*
|
|
|
|
* The AVR Dragon also uses the same protocol, so it is handled here
|
|
|
|
* as well.
|
2005-05-10 19:53:56 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "ac_cfg.h"
|
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
#include <ctype.h>
|
2012-03-30 16:19:13 +00:00
|
|
|
#include <limits.h>
|
2005-05-10 19:53:56 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
2007-01-24 21:07:54 +00:00
|
|
|
#include "avrdude.h"
|
2014-05-19 10:01:59 +00:00
|
|
|
#include "libavrdude.h"
|
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
#include "crc16.h"
|
2006-09-06 22:37:30 +00:00
|
|
|
#include "jtagmkII.h"
|
2005-05-10 19:53:56 +00:00
|
|
|
#include "jtagmkII_private.h"
|
2006-01-12 23:13:50 +00:00
|
|
|
#include "usbdevs.h"
|
2005-05-10 19:53:56 +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
|
|
|
* Private data for this programmer.
|
2005-05-10 19:53:56 +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
|
|
|
struct pdata
|
|
|
|
{
|
|
|
|
unsigned short command_sequence; /* Next cmd seqno to issue. */
|
2005-05-10 19:53:56 +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
|
|
|
/*
|
|
|
|
* See jtagmkII_read_byte() for an explanation of the flash and
|
|
|
|
* EEPROM page caches.
|
|
|
|
*/
|
|
|
|
unsigned char *flash_pagecache;
|
|
|
|
unsigned long flash_pageaddr;
|
|
|
|
unsigned int flash_pagesize;
|
2005-05-10 19:53:56 +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
|
|
|
unsigned char *eeprom_pagecache;
|
|
|
|
unsigned long eeprom_pageaddr;
|
|
|
|
unsigned int eeprom_pagesize;
|
2005-05-10 19:53:56 +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
|
|
|
int prog_enabled; /* Cached value of PROGRAMMING status. */
|
|
|
|
unsigned char serno[6]; /* JTAG ICE serial number. */
|
2007-11-06 19:42: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
|
|
|
/* JTAG chain stuff */
|
|
|
|
unsigned char jtagchain[4];
|
|
|
|
|
|
|
|
/* The length of the device descriptor is firmware-dependent. */
|
|
|
|
size_t device_descriptor_length;
|
2012-03-30 16:19:13 +00:00
|
|
|
|
|
|
|
/* Start address of Xmega boot area */
|
|
|
|
unsigned long boot_start;
|
2012-04-13 15:25:41 +00:00
|
|
|
|
|
|
|
/* Major firmware version (needed for Xmega programming) */
|
|
|
|
unsigned int fwver;
|
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))
|
2007-11-06 19:42:16 +00:00
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
/*
|
|
|
|
* The OCDEN fuse is bit 7 of the high fuse (hfuse). In order to
|
Quite some cleanup of the JTAG ICE mkII stuff.
. Implement the new EECRAddress field in the device descriptor that is
required by the 4.x firmware; make an uneducated guess about what
firmware requires what length of device descriptor -- perhaps Atmel
can be convinced to publish an official matrix for that.
. Specify EECR in the config file where required. Obviously, only
locations that differ from the 0x3c default are mentioned in the
XML files, so by now, this only affects the AT90CAN128 for us.
. After clarification with Atmel, EnablePageProgramming should really
default to 1, and only cleared if specified by an XML parameter. So
far, only the XML files for the ATmega256x and ATmega406 do specify
it at all, and they specify a 1, too.
. Drop the entire OCDEN fuse heuristic. If OCDEN is unprogrammed at
startup, issue a warning that single-byte EEPROM updates won't be
possible. Leave it to the user to program the fuse if desired.
That way, we won't run into any issue of prematurely wearing out the
hfuse EEPROM cell. Interestingly enough, this also solved the
problem of the target not restarting from scratch upon sign-off.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@461 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-11 20:06:23 +00:00
|
|
|
* perform memory operations on MTYPE_SPM and MTYPE_EEPROM, OCDEN
|
|
|
|
* needs to be programmed.
|
2005-05-10 19:53:56 +00:00
|
|
|
*
|
|
|
|
* OCDEN should probably rather be defined via the configuration, but
|
|
|
|
* if this ever changes to a different fuse byte for one MCU, quite
|
|
|
|
* some code here needs to be generalized anyway.
|
|
|
|
*/
|
|
|
|
#define OCDEN (1 << 7)
|
Quite some cleanup of the JTAG ICE mkII stuff.
. Implement the new EECRAddress field in the device descriptor that is
required by the 4.x firmware; make an uneducated guess about what
firmware requires what length of device descriptor -- perhaps Atmel
can be convinced to publish an official matrix for that.
. Specify EECR in the config file where required. Obviously, only
locations that differ from the 0x3c default are mentioned in the
XML files, so by now, this only affects the AT90CAN128 for us.
. After clarification with Atmel, EnablePageProgramming should really
default to 1, and only cleared if specified by an XML parameter. So
far, only the XML files for the ATmega256x and ATmega406 do specify
it at all, and they specify a 1, too.
. Drop the entire OCDEN fuse heuristic. If OCDEN is unprogrammed at
startup, issue a warning that single-byte EEPROM updates won't be
possible. Leave it to the user to program the fuse if desired.
That way, we won't run into any issue of prematurely wearing out the
hfuse EEPROM cell. Interestingly enough, this also solved the
problem of the target not restarting from scratch upon sign-off.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@461 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-11 20:06:23 +00:00
|
|
|
|
2006-09-07 19:57:59 +00:00
|
|
|
#define RC(x) { x, #x },
|
|
|
|
static struct {
|
|
|
|
unsigned int code;
|
|
|
|
const char *descr;
|
|
|
|
} jtagresults[] = {
|
|
|
|
RC(RSP_DEBUGWIRE_SYNC_FAILED)
|
|
|
|
RC(RSP_FAILED)
|
|
|
|
RC(RSP_ILLEGAL_BREAKPOINT)
|
|
|
|
RC(RSP_ILLEGAL_COMMAND)
|
|
|
|
RC(RSP_ILLEGAL_EMULATOR_MODE)
|
|
|
|
RC(RSP_ILLEGAL_JTAG_ID)
|
|
|
|
RC(RSP_ILLEGAL_MCU_STATE)
|
|
|
|
RC(RSP_ILLEGAL_MEMORY_TYPE)
|
|
|
|
RC(RSP_ILLEGAL_MEMORY_RANGE)
|
|
|
|
RC(RSP_ILLEGAL_PARAMETER)
|
|
|
|
RC(RSP_ILLEGAL_POWER_STATE)
|
|
|
|
RC(RSP_ILLEGAL_VALUE)
|
|
|
|
RC(RSP_NO_TARGET_POWER)
|
|
|
|
RC(RSP_SET_N_PARAMETERS)
|
|
|
|
};
|
|
|
|
|
2006-11-20 23:23:37 +00:00
|
|
|
/*
|
|
|
|
* pgm->flag is marked as "for private use of the programmer".
|
|
|
|
* The following defines this programmer's use of that field.
|
|
|
|
*/
|
|
|
|
#define PGM_FL_IS_DW (0x0001)
|
2010-01-13 17:34:18 +00:00
|
|
|
#define PGM_FL_IS_PDI (0x0002)
|
|
|
|
#define PGM_FL_IS_JTAG (0x0004)
|
2006-09-07 19:57:59 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
static int jtagmkII_open(PROGRAMMER * pgm, char * port);
|
|
|
|
|
|
|
|
static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p);
|
|
|
|
static int jtagmkII_chip_erase(PROGRAMMER * pgm, AVRPART * p);
|
2005-05-10 19:53:56 +00:00
|
|
|
static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
2009-10-10 20:09:53 +00:00
|
|
|
unsigned long addr, unsigned char * value);
|
2005-05-10 19:53:56 +00:00
|
|
|
static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
2009-10-10 20:09:53 +00:00
|
|
|
unsigned long addr, unsigned char data);
|
2006-09-06 22:37:30 +00:00
|
|
|
static int jtagmkII_reset(PROGRAMMER * pgm, unsigned char flags);
|
2005-05-10 19:53:56 +00:00
|
|
|
static int jtagmkII_set_sck_period(PROGRAMMER * pgm, double v);
|
|
|
|
static int jtagmkII_setparm(PROGRAMMER * pgm, unsigned char parm,
|
2009-10-10 20:09:53 +00:00
|
|
|
unsigned char * value);
|
2008-07-25 21:14:43 +00:00
|
|
|
static void jtagmkII_print_parms1(PROGRAMMER * pgm, const char * p);
|
2009-10-10 20:09:53 +00:00
|
|
|
static int jtagmkII_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);
|
2012-03-30 16:19:13 +00:00
|
|
|
static unsigned char jtagmkII_memtype(PROGRAMMER * pgm, AVRPART * p, unsigned long addr);
|
2012-04-13 15:25:41 +00:00
|
|
|
static unsigned int jtagmkII_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr);
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
// AVR32
|
|
|
|
#define ERROR_SAB 0xFFFFFFFF
|
|
|
|
|
|
|
|
static int jtagmkII_open32(PROGRAMMER * pgm, char * port);
|
|
|
|
static void jtagmkII_close32(PROGRAMMER * pgm);
|
|
|
|
static int jtagmkII_reset32(PROGRAMMER * pgm, unsigned short flags);
|
|
|
|
static int jtagmkII_initialize32(PROGRAMMER * pgm, AVRPART * p);
|
|
|
|
static int jtagmkII_chip_erase32(PROGRAMMER * pgm, AVRPART * p);
|
|
|
|
static unsigned long jtagmkII_read_SABaddr(PROGRAMMER * pgm, unsigned long addr,
|
|
|
|
unsigned int prefix); // ERROR_SAB illegal
|
|
|
|
static int jtagmkII_write_SABaddr(PROGRAMMER * pgm, unsigned long addr,
|
|
|
|
unsigned int prefix, unsigned long val);
|
|
|
|
static int jtagmkII_avr32_reset(PROGRAMMER * pgm, unsigned char val,
|
|
|
|
unsigned char ret1, unsigned char ret2);
|
|
|
|
static int jtagmkII_smc_init32(PROGRAMMER * pgm);
|
|
|
|
static int jtagmkII_paged_write32(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);
|
2009-10-10 20:09:53 +00:00
|
|
|
static int jtagmkII_flash_lock32(PROGRAMMER * pgm, unsigned char lock,
|
|
|
|
unsigned int page);
|
|
|
|
static int jtagmkII_flash_erase32(PROGRAMMER * pgm, unsigned int page);
|
|
|
|
static int jtagmkII_flash_write_page32(PROGRAMMER * pgm, unsigned int page);
|
|
|
|
static int jtagmkII_flash_clear_pagebuffer32(PROGRAMMER * pgm);
|
|
|
|
static int jtagmkII_paged_load32(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);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
2008-10-31 21:26:06 +00:00
|
|
|
void jtagmkII_setup(PROGRAMMER * pgm)
|
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 ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_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-10-31 21:26:06 +00:00
|
|
|
void jtagmkII_teardown(PROGRAMMER * pgm)
|
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
|
|
|
{
|
|
|
|
free(pgm->cookie);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
static unsigned long
|
|
|
|
b4_to_u32(unsigned char *b)
|
|
|
|
{
|
|
|
|
unsigned long l;
|
|
|
|
l = b[0];
|
2005-05-27 12:15:28 +00:00
|
|
|
l += (unsigned)b[1] << 8;
|
|
|
|
l += (unsigned)b[2] << 16;
|
|
|
|
l += (unsigned)b[3] << 24;
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
return l;
|
|
|
|
}
|
2009-10-10 20:09:53 +00:00
|
|
|
static unsigned long
|
|
|
|
b4_to_u32r(unsigned char *b)
|
|
|
|
{
|
|
|
|
unsigned long l;
|
|
|
|
l = b[3];
|
|
|
|
l += (unsigned)b[2] << 8;
|
|
|
|
l += (unsigned)b[1] << 16;
|
|
|
|
l += (unsigned)b[0] << 24;
|
|
|
|
|
|
|
|
return l;
|
|
|
|
}
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
u32_to_b4(unsigned char *b, unsigned long l)
|
|
|
|
{
|
|
|
|
b[0] = l & 0xff;
|
|
|
|
b[1] = (l >> 8) & 0xff;
|
|
|
|
b[2] = (l >> 16) & 0xff;
|
|
|
|
b[3] = (l >> 24) & 0xff;
|
|
|
|
}
|
2009-10-10 20:09:53 +00:00
|
|
|
static void
|
|
|
|
u32_to_b4r(unsigned char *b, unsigned long l)
|
|
|
|
{
|
|
|
|
b[3] = l & 0xff;
|
|
|
|
b[2] = (l >> 8) & 0xff;
|
|
|
|
b[1] = (l >> 16) & 0xff;
|
|
|
|
b[0] = (l >> 24) & 0xff;
|
|
|
|
}
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
static unsigned short
|
|
|
|
b2_to_u16(unsigned char *b)
|
|
|
|
{
|
|
|
|
unsigned short l;
|
|
|
|
l = b[0];
|
2005-05-27 12:15:28 +00:00
|
|
|
l += (unsigned)b[1] << 8;
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
return l;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
u16_to_b2(unsigned char *b, unsigned short l)
|
|
|
|
{
|
|
|
|
b[0] = l & 0xff;
|
|
|
|
b[1] = (l >> 8) & 0xff;
|
|
|
|
}
|
|
|
|
|
2006-09-07 19:57:59 +00:00
|
|
|
static const char *
|
|
|
|
jtagmkII_get_rc(unsigned int rc)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
static char msg[50];
|
|
|
|
|
|
|
|
for (i = 0; i < sizeof jtagresults / sizeof jtagresults[0]; i++)
|
|
|
|
if (jtagresults[i].code == rc)
|
|
|
|
return jtagresults[i].descr;
|
|
|
|
|
|
|
|
sprintf(msg, "Unknown JTAG ICE mkII result code 0x%02x", rc);
|
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
static void jtagmkII_print_memory(unsigned char *b, size_t s)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (s < 2)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < s - 1; i++) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "0x%02x ", b[i + 1]);
|
2005-05-10 19:53:56 +00:00
|
|
|
if (i % 16 == 15)
|
|
|
|
putc('\n', stderr);
|
|
|
|
else
|
|
|
|
putc(' ', stderr);
|
|
|
|
}
|
|
|
|
if (i % 16 != 0)
|
|
|
|
putc('\n', stderr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void jtagmkII_prmsg(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (verbose >= 4) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_TRACE, "Raw message:\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
for (i = 0; i < len; i++) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_TRACE, "0x%02x", data[i]);
|
2005-05-10 19:53:56 +00:00
|
|
|
if (i % 16 == 15)
|
|
|
|
putc('\n', stderr);
|
|
|
|
else
|
2013-01-08 21:02:01 +00:00
|
|
|
putc(' ', stderr);
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
if (i % 16 != 0)
|
|
|
|
putc('\n', stderr);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (data[0]) {
|
|
|
|
case RSP_OK:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "OK\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_FAILED:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "FAILED\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_BREAKPOINT:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "Illegal breakpoint\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_COMMAND:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "Illegal command\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_EMULATOR_MODE:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "Illegal emulator mode");
|
2005-05-10 19:53:56 +00:00
|
|
|
if (len > 1)
|
|
|
|
switch (data[1]) {
|
2014-06-13 20:07:40 +00:00
|
|
|
case EMULATOR_MODE_DEBUGWIRE: avrdude_message(MSG_INFO, ": DebugWire"); break;
|
|
|
|
case EMULATOR_MODE_JTAG: avrdude_message(MSG_INFO, ": JTAG"); break;
|
|
|
|
case EMULATOR_MODE_HV: avrdude_message(MSG_INFO, ": HVSP/PP"); break;
|
|
|
|
case EMULATOR_MODE_SPI: avrdude_message(MSG_INFO, ": SPI"); break;
|
|
|
|
case EMULATOR_MODE_JTAG_XMEGA: avrdude_message(MSG_INFO, ": JTAG/Xmega"); break;
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
putc('\n', stderr);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_JTAG_ID:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "Illegal JTAG ID\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_MCU_STATE:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "Illegal MCU state");
|
2005-05-10 19:53:56 +00:00
|
|
|
if (len > 1)
|
|
|
|
switch (data[1]) {
|
2014-06-13 20:07:40 +00:00
|
|
|
case STOPPED: avrdude_message(MSG_INFO, ": Stopped"); break;
|
|
|
|
case RUNNING: avrdude_message(MSG_INFO, ": Running"); break;
|
|
|
|
case PROGRAMMING: avrdude_message(MSG_INFO, ": Programming"); break;
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
putc('\n', stderr);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_MEMORY_TYPE:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "Illegal memory type\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_MEMORY_RANGE:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "Illegal memory range\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_PARAMETER:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "Illegal parameter\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_POWER_STATE:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "Illegal power state\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_VALUE:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "Illegal value\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_NO_TARGET_POWER:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "No target power\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_SIGN_ON:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "Sign-on succeeded\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
/* Sign-on data will be printed below anyway. */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_MEMORY:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "memory contents:\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_print_memory(data, len);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_PARAMETER:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "parameter values:\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_print_memory(data, len);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_SPI_DATA:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "SPI data returned:\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
for (i = 1; i < len; i++)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "0x%02x ", data[i]);
|
2005-05-10 19:53:56 +00:00
|
|
|
putc('\n', stderr);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EVT_BREAK:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "BREAK event");
|
2005-05-10 19:53:56 +00:00
|
|
|
if (len >= 6) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, ", PC = 0x%lx, reason ", b4_to_u32(data + 1));
|
2005-05-10 19:53:56 +00:00
|
|
|
switch (data[5]) {
|
|
|
|
case 0x00:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "unspecified");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
case 0x01:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "program break");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
case 0x02:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "data break PDSB");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
case 0x03:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "data break PDMSB");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
default:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "unknown: 0x%02x", data[5]);
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
putc('\n', stderr);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "unknown message 0x%02x\n", data[0]);
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
putc('\n', stderr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-06 20:06:07 +00:00
|
|
|
int jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
2005-05-10 19:53:56 +00:00
|
|
|
{
|
|
|
|
unsigned char *buf;
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_DEBUG, "\n%s: jtagmkII_send(): sending %lu bytes\n",
|
2009-10-10 20:09:53 +00:00
|
|
|
progname, (unsigned long)len);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
if ((buf = malloc(len + 10)) == NULL)
|
|
|
|
{
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_send(): out of memory",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
buf[0] = MESSAGE_START;
|
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
|
|
|
u16_to_b2(buf + 1, PDATA(pgm)->command_sequence);
|
2005-05-10 19:53:56 +00:00
|
|
|
u32_to_b4(buf + 3, len);
|
|
|
|
buf[7] = TOKEN;
|
|
|
|
memcpy(buf + 8, data, len);
|
|
|
|
|
|
|
|
crcappend(buf, len + 8);
|
|
|
|
|
2006-12-11 12:47:35 +00:00
|
|
|
if (serial_send(&pgm->fd, buf, len + 10) != 0) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_send(): failed to send command to serial port\n",
|
2014-05-18 08:41:46 +00:00
|
|
|
progname);
|
2014-06-17 20:08:28 +00:00
|
|
|
free(buf);
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
free(buf);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int jtagmkII_drain(PROGRAMMER * pgm, int display)
|
|
|
|
{
|
2006-12-11 12:47:35 +00:00
|
|
|
return serial_drain(&pgm->fd, display);
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Receive one frame, return it in *msg. Received sequence number is
|
|
|
|
* returned in seqno. Any valid frame will be returned, regardless
|
|
|
|
* whether it matches the expected sequence number, including event
|
|
|
|
* notification frames (seqno == 0xffff).
|
|
|
|
*
|
|
|
|
* Caller must eventually free the buffer.
|
|
|
|
*/
|
|
|
|
static int jtagmkII_recv_frame(PROGRAMMER * pgm, unsigned char **msg,
|
|
|
|
unsigned short * seqno) {
|
|
|
|
enum states { sSTART,
|
|
|
|
/* NB: do NOT change the sequence of the following: */
|
|
|
|
sSEQNUM1, sSEQNUM2,
|
|
|
|
sSIZE1, sSIZE2, sSIZE3, sSIZE4,
|
|
|
|
sTOKEN,
|
|
|
|
sDATA,
|
|
|
|
sCSUM1, sCSUM2,
|
|
|
|
/* end NB */
|
|
|
|
sDONE
|
|
|
|
} state = sSTART;
|
|
|
|
unsigned long msglen = 0, l = 0;
|
|
|
|
int headeridx = 0;
|
|
|
|
int timeout = 0;
|
|
|
|
int ignorpkt = 0;
|
|
|
|
int rv;
|
|
|
|
unsigned char c, *buf = NULL, header[8];
|
|
|
|
unsigned short r_seqno = 0;
|
|
|
|
unsigned short checksum = 0;
|
|
|
|
|
|
|
|
struct timeval tv;
|
2011-05-11 20:42:27 +00:00
|
|
|
double timeoutval = 100; /* seconds */
|
2005-05-10 19:53:56 +00:00
|
|
|
double tstart, tnow;
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_TRACE, "%s: jtagmkII_recv():\n", progname);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
gettimeofday(&tv, NULL);
|
|
|
|
tstart = tv.tv_sec;
|
|
|
|
|
|
|
|
while ( (state != sDONE ) && (!timeout) ) {
|
|
|
|
if (state == sDATA) {
|
|
|
|
rv = 0;
|
|
|
|
if (ignorpkt) {
|
|
|
|
/* skip packet's contents */
|
|
|
|
for(l = 0; l < msglen; l++)
|
2006-12-11 12:47:35 +00:00
|
|
|
rv += serial_recv(&pgm->fd, &c, 1);
|
2005-05-10 19:53:56 +00:00
|
|
|
} else {
|
2006-12-11 12:47:35 +00:00
|
|
|
rv += serial_recv(&pgm->fd, buf + 8, msglen);
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
if (rv != 0) {
|
|
|
|
timedout:
|
|
|
|
/* timeout in receive */
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_recv(): Timeout receiving packet\n",
|
2014-05-18 08:41:46 +00:00
|
|
|
progname);
|
2005-05-10 19:53:56 +00:00
|
|
|
free(buf);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
2006-12-11 12:47:35 +00:00
|
|
|
if (serial_recv(&pgm->fd, &c, 1) != 0)
|
2005-05-10 19:53:56 +00:00
|
|
|
goto timedout;
|
|
|
|
}
|
|
|
|
checksum ^= c;
|
|
|
|
|
|
|
|
if (state < sDATA)
|
|
|
|
header[headeridx++] = c;
|
|
|
|
|
|
|
|
switch (state) {
|
|
|
|
case sSTART:
|
|
|
|
if (c == MESSAGE_START) {
|
|
|
|
state = sSEQNUM1;
|
|
|
|
} else {
|
|
|
|
headeridx = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case sSEQNUM1:
|
|
|
|
case sSEQNUM2:
|
|
|
|
r_seqno >>= 8;
|
2005-05-27 12:15:28 +00:00
|
|
|
r_seqno |= ((unsigned)c << 8);
|
2005-05-10 19:53:56 +00:00
|
|
|
state++;
|
|
|
|
break;
|
|
|
|
case sSIZE1:
|
|
|
|
case sSIZE2:
|
|
|
|
case sSIZE3:
|
|
|
|
case sSIZE4:
|
|
|
|
msglen >>= 8;
|
2005-05-27 12:15:28 +00:00
|
|
|
msglen |= ((unsigned)c << 24);
|
2005-05-10 19:53:56 +00:00
|
|
|
state++;
|
|
|
|
break;
|
|
|
|
case sTOKEN:
|
|
|
|
if (c == TOKEN) {
|
|
|
|
state = sDATA;
|
|
|
|
if (msglen > MAX_MESSAGE) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_recv(): msglen %lu exceeds max message "
|
2014-05-18 08:41:46 +00:00
|
|
|
"size %u, ignoring message\n",
|
|
|
|
progname, msglen, MAX_MESSAGE);
|
2005-05-27 12:15:28 +00:00
|
|
|
state = sSTART;
|
|
|
|
headeridx = 0;
|
2005-05-10 19:53:56 +00:00
|
|
|
} else if ((buf = malloc(msglen + 10)) == NULL) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_recv(): out of memory\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname);
|
|
|
|
ignorpkt++;
|
|
|
|
} else {
|
|
|
|
memcpy(buf, header, 8);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
state = sSTART;
|
|
|
|
headeridx = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case sDATA:
|
|
|
|
/* The entire payload has been read above. */
|
|
|
|
l = msglen + 8;
|
|
|
|
state = sCSUM1;
|
|
|
|
break;
|
|
|
|
case sCSUM1:
|
|
|
|
case sCSUM2:
|
|
|
|
buf[l++] = c;
|
|
|
|
if (state == sCSUM2) {
|
|
|
|
if (crcverify(buf, msglen + 10)) {
|
2009-10-10 20:09:53 +00:00
|
|
|
if (verbose >= 9)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_TRACE2, "%s: jtagmkII_recv(): CRC OK",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname);
|
|
|
|
state = sDONE;
|
|
|
|
} else {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_recv(): checksum error\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname);
|
|
|
|
free(buf);
|
|
|
|
return -4;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
state++;
|
|
|
|
break;
|
|
|
|
default:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_recv(): unknown state\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname);
|
|
|
|
free(buf);
|
|
|
|
return -5;
|
|
|
|
}
|
|
|
|
|
|
|
|
gettimeofday(&tv, NULL);
|
|
|
|
tnow = tv.tv_sec;
|
|
|
|
if (tnow - tstart > timeoutval) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_recv_frame(): timeout\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname);
|
2020-03-14 22:34:45 +00:00
|
|
|
free(buf);
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_DEBUG, "\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
*seqno = r_seqno;
|
|
|
|
*msg = buf;
|
|
|
|
|
|
|
|
return msglen;
|
|
|
|
}
|
|
|
|
|
2006-09-06 20:06:07 +00:00
|
|
|
int jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg) {
|
2005-05-10 19:53:56 +00:00
|
|
|
unsigned short r_seqno;
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
if ((rv = jtagmkII_recv_frame(pgm, msg, &r_seqno)) <= 0)
|
|
|
|
return rv;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_DEBUG, "%s: jtagmkII_recv(): "
|
2005-05-10 19:53:56 +00:00
|
|
|
"Got message seqno %d (command_sequence == %d)\n",
|
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
|
|
|
progname, r_seqno, PDATA(pgm)->command_sequence);
|
|
|
|
if (r_seqno == PDATA(pgm)->command_sequence) {
|
|
|
|
if (++(PDATA(pgm)->command_sequence) == 0xffff)
|
|
|
|
PDATA(pgm)->command_sequence = 0;
|
2005-05-10 19:53:56 +00:00
|
|
|
/*
|
|
|
|
* We move the payload to the beginning of the buffer, to make
|
|
|
|
* the job easier for the caller. We have to return the
|
|
|
|
* original pointer though, as the caller must free() it.
|
|
|
|
*/
|
|
|
|
memmove(*msg, *msg + 8, rv);
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
if (verbose == 4)
|
|
|
|
{
|
|
|
|
int i = rv;
|
|
|
|
unsigned char *p = *msg;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_TRACE, "%s: Recv: ", progname);
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
while (i) {
|
|
|
|
unsigned char c = *p;
|
|
|
|
if (isprint(c)) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_TRACE, "%c ", c);
|
2009-10-10 20:09:53 +00:00
|
|
|
}
|
|
|
|
else {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_TRACE, ". ");
|
2009-10-10 20:09:53 +00:00
|
|
|
}
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_TRACE, "[%02x] ", c);
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
p++;
|
|
|
|
i--;
|
|
|
|
}
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_TRACE, "\n");
|
2009-10-10 20:09:53 +00:00
|
|
|
}
|
2005-05-10 19:53:56 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
if (r_seqno == 0xffff) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_DEBUG, "%s: jtagmkII_recv(): got asynchronous event\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname);
|
|
|
|
} else {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_recv(): "
|
2005-05-10 19:53:56 +00:00
|
|
|
"got wrong sequence number, %u != %u\n",
|
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
|
|
|
progname, r_seqno, PDATA(pgm)->command_sequence);
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
free(*msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-06 20:06:07 +00:00
|
|
|
int jtagmkII_getsync(PROGRAMMER * pgm, int mode) {
|
2005-05-10 19:53:56 +00:00
|
|
|
int tries;
|
|
|
|
#define MAXTRIES 33
|
|
|
|
unsigned char buf[3], *resp, c = 0xff;
|
|
|
|
int status;
|
2006-10-26 21:14:10 +00:00
|
|
|
unsigned int fwver, hwver;
|
2010-01-14 13:46:02 +00:00
|
|
|
int is_dragon;
|
2005-05-10 19:53:56 +00:00
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_DEBUG, "%s: jtagmkII_getsync()\n", progname);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
2010-01-14 13:46:02 +00:00
|
|
|
if (strncmp(pgm->type, "JTAG", strlen("JTAG")) == 0) {
|
|
|
|
is_dragon = 0;
|
|
|
|
} else if (strncmp(pgm->type, "DRAGON", strlen("DRAGON")) == 0) {
|
|
|
|
is_dragon = 1;
|
|
|
|
} else {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: Programmer is neither JTAG ICE mkII nor AVR Dragon\n",
|
2014-05-18 08:41:46 +00:00
|
|
|
progname);
|
2010-01-14 13:46:02 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2005-05-10 19:53:56 +00:00
|
|
|
for (tries = 0; tries < MAXTRIES; tries++) {
|
|
|
|
|
|
|
|
/* Get the sign-on information. */
|
|
|
|
buf[0] = CMND_GET_SIGN_ON;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_getsync(): Sending sign-on command: ",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname);
|
|
|
|
jtagmkII_send(pgm, buf, 1);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): sign-on command: "
|
2005-05-10 19:53:56 +00:00
|
|
|
"status %d\n",
|
|
|
|
progname, status);
|
|
|
|
} else if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
if (status > 0) {
|
|
|
|
if ((c = resp[0]) == RSP_SIGN_ON) {
|
Quite some cleanup of the JTAG ICE mkII stuff.
. Implement the new EECRAddress field in the device descriptor that is
required by the 4.x firmware; make an uneducated guess about what
firmware requires what length of device descriptor -- perhaps Atmel
can be convinced to publish an official matrix for that.
. Specify EECR in the config file where required. Obviously, only
locations that differ from the 0x3c default are mentioned in the
XML files, so by now, this only affects the AT90CAN128 for us.
. After clarification with Atmel, EnablePageProgramming should really
default to 1, and only cleared if specified by an XML parameter. So
far, only the XML files for the ATmega256x and ATmega406 do specify
it at all, and they specify a 1, too.
. Drop the entire OCDEN fuse heuristic. If OCDEN is unprogrammed at
startup, issue a warning that single-byte EEPROM updates won't be
possible. Leave it to the user to program the fuse if desired.
That way, we won't run into any issue of prematurely wearing out the
hfuse EEPROM cell. Interestingly enough, this also solved the
problem of the target not restarting from scratch upon sign-off.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@461 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-11 20:06:23 +00:00
|
|
|
fwver = ((unsigned)resp[8] << 8) | (unsigned)resp[7];
|
2012-04-13 15:25:41 +00:00
|
|
|
PDATA(pgm)->fwver = fwver;
|
2006-10-26 21:14:10 +00:00
|
|
|
hwver = (unsigned)resp[9];
|
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
|
|
|
memcpy(PDATA(pgm)->serno, resp + 10, 6);
|
2014-06-13 20:07:40 +00:00
|
|
|
if (status > 17) {
|
|
|
|
avrdude_message(MSG_NOTICE, "JTAG ICE mkII sign-on message:\n");
|
|
|
|
avrdude_message(MSG_NOTICE, "Communications protocol version: %u\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
(unsigned)resp[1]);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE, "M_MCU:\n");
|
|
|
|
avrdude_message(MSG_NOTICE, " boot-loader FW version: %u\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
(unsigned)resp[2]);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE, " firmware version: %u.%02u\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
(unsigned)resp[4], (unsigned)resp[3]);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE, " hardware version: %u\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
(unsigned)resp[5]);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE, "S_MCU:\n");
|
|
|
|
avrdude_message(MSG_NOTICE, " boot-loader FW version: %u\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
(unsigned)resp[6]);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE, " firmware version: %u.%02u\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
(unsigned)resp[8], (unsigned)resp[7]);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE, " hardware version: %u\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
(unsigned)resp[9]);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE, "Serial number: "
|
2005-05-10 19:53:56 +00:00
|
|
|
"%02x:%02x:%02x:%02x:%02x:%02x\n",
|
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
|
|
|
PDATA(pgm)->serno[0], PDATA(pgm)->serno[1], PDATA(pgm)->serno[2], PDATA(pgm)->serno[3], PDATA(pgm)->serno[4], PDATA(pgm)->serno[5]);
|
2005-05-10 19:53:56 +00:00
|
|
|
resp[status - 1] = '\0';
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE, "Device ID: %s\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
resp + 16);
|
|
|
|
}
|
2020-03-14 22:34:45 +00:00
|
|
|
free(resp);
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
free(resp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (tries >= MAXTRIES) {
|
|
|
|
if (status <= 0)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
2005-05-10 19:53:56 +00:00
|
|
|
else
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"bad response to sign-on command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(c));
|
2005-05-10 19:53:56 +00:00
|
|
|
return -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
|
|
|
PDATA(pgm)->device_descriptor_length = sizeof(struct device_descriptor);
|
Quite some cleanup of the JTAG ICE mkII stuff.
. Implement the new EECRAddress field in the device descriptor that is
required by the 4.x firmware; make an uneducated guess about what
firmware requires what length of device descriptor -- perhaps Atmel
can be convinced to publish an official matrix for that.
. Specify EECR in the config file where required. Obviously, only
locations that differ from the 0x3c default are mentioned in the
XML files, so by now, this only affects the AT90CAN128 for us.
. After clarification with Atmel, EnablePageProgramming should really
default to 1, and only cleared if specified by an XML parameter. So
far, only the XML files for the ATmega256x and ATmega406 do specify
it at all, and they specify a 1, too.
. Drop the entire OCDEN fuse heuristic. If OCDEN is unprogrammed at
startup, issue a warning that single-byte EEPROM updates won't be
possible. Leave it to the user to program the fuse if desired.
That way, we won't run into any issue of prematurely wearing out the
hfuse EEPROM cell. Interestingly enough, this also solved the
problem of the target not restarting from scratch upon sign-off.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@461 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-11 20:06:23 +00:00
|
|
|
/*
|
|
|
|
* There's no official documentation from Atmel about what firmware
|
|
|
|
* revision matches what device descriptor length. The algorithm
|
|
|
|
* below has been found empirically.
|
|
|
|
*/
|
|
|
|
#define FWVER(maj, min) ((maj << 8) | (min))
|
2010-01-14 13:46:02 +00:00
|
|
|
if (!is_dragon && fwver < FWVER(3, 16)) {
|
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
|
|
|
PDATA(pgm)->device_descriptor_length -= 2;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"S_MCU firmware version might be too old to work correctly\n",
|
|
|
|
progname);
|
2010-01-14 13:46:02 +00:00
|
|
|
} else if (!is_dragon && fwver < FWVER(4, 0)) {
|
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
|
|
|
PDATA(pgm)->device_descriptor_length -= 2;
|
Quite some cleanup of the JTAG ICE mkII stuff.
. Implement the new EECRAddress field in the device descriptor that is
required by the 4.x firmware; make an uneducated guess about what
firmware requires what length of device descriptor -- perhaps Atmel
can be convinced to publish an official matrix for that.
. Specify EECR in the config file where required. Obviously, only
locations that differ from the 0x3c default are mentioned in the
XML files, so by now, this only affects the AT90CAN128 for us.
. After clarification with Atmel, EnablePageProgramming should really
default to 1, and only cleared if specified by an XML parameter. So
far, only the XML files for the ATmega256x and ATmega406 do specify
it at all, and they specify a 1, too.
. Drop the entire OCDEN fuse heuristic. If OCDEN is unprogrammed at
startup, issue a warning that single-byte EEPROM updates won't be
possible. Leave it to the user to program the fuse if desired.
That way, we won't run into any issue of prematurely wearing out the
hfuse EEPROM cell. Interestingly enough, this also solved the
problem of the target not restarting from scratch upon sign-off.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@461 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-11 20:06:23 +00:00
|
|
|
}
|
2014-06-13 20:07:40 +00:00
|
|
|
if (mode != EMULATOR_MODE_SPI)
|
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_getsync(): Using a %u-byte device descriptor\n",
|
2014-05-18 08:41:46 +00:00
|
|
|
progname, (unsigned)PDATA(pgm)->device_descriptor_length);
|
2010-01-14 13:46:02 +00:00
|
|
|
if (mode == EMULATOR_MODE_SPI) {
|
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
|
|
|
PDATA(pgm)->device_descriptor_length = 0;
|
2010-01-14 13:46:02 +00:00
|
|
|
if (!is_dragon && fwver < FWVER(4, 14)) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): ISP functionality requires firmware "
|
2014-05-18 08:41:46 +00:00
|
|
|
"version >= 4.14\n",
|
|
|
|
progname);
|
2006-09-06 20:06:07 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2010-01-14 13:46:02 +00:00
|
|
|
if (mode == EMULATOR_MODE_PDI || mode == EMULATOR_MODE_JTAG_XMEGA) {
|
|
|
|
if (!is_dragon && mode == EMULATOR_MODE_PDI && hwver < 1) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): Xmega PDI support requires hardware "
|
2014-05-18 08:41:46 +00:00
|
|
|
"revision >= 1\n",
|
|
|
|
progname);
|
2010-01-14 13:46:02 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (!is_dragon && fwver < FWVER(5, 37)) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): Xmega support requires firmware "
|
2014-05-18 08:41:46 +00:00
|
|
|
"version >= 5.37\n",
|
|
|
|
progname);
|
2010-01-14 13:46:02 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (is_dragon && fwver < FWVER(6, 11)) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): Xmega support requires firmware "
|
2014-05-18 08:41:46 +00:00
|
|
|
"version >= 6.11\n",
|
|
|
|
progname);
|
2010-01-14 13:46:02 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2006-09-06 20:06:07 +00:00
|
|
|
#undef FWVER
|
Quite some cleanup of the JTAG ICE mkII stuff.
. Implement the new EECRAddress field in the device descriptor that is
required by the 4.x firmware; make an uneducated guess about what
firmware requires what length of device descriptor -- perhaps Atmel
can be convinced to publish an official matrix for that.
. Specify EECR in the config file where required. Obviously, only
locations that differ from the 0x3c default are mentioned in the
XML files, so by now, this only affects the AT90CAN128 for us.
. After clarification with Atmel, EnablePageProgramming should really
default to 1, and only cleared if specified by an XML parameter. So
far, only the XML files for the ATmega256x and ATmega406 do specify
it at all, and they specify a 1, too.
. Drop the entire OCDEN fuse heuristic. If OCDEN is unprogrammed at
startup, issue a warning that single-byte EEPROM updates won't be
possible. Leave it to the user to program the fuse if desired.
That way, we won't run into any issue of prematurely wearing out the
hfuse EEPROM cell. Interestingly enough, this also solved the
problem of the target not restarting from scratch upon sign-off.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@461 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-11 20:06:23 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
if(mode < 0) return 0; // for AVR32
|
|
|
|
|
2013-05-17 16:23:55 +00:00
|
|
|
tries = 0;
|
|
|
|
retry:
|
2006-09-06 20:06:07 +00:00
|
|
|
/* Turn the ICE into JTAG or ISP mode as requested. */
|
|
|
|
buf[0] = mode;
|
2006-09-06 22:37:30 +00:00
|
|
|
if (jtagmkII_setparm(pgm, PAR_EMULATOR_MODE, buf) < 0) {
|
|
|
|
if (mode == EMULATOR_MODE_SPI) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"ISP activation failed, trying debugWire\n",
|
|
|
|
progname);
|
2006-09-06 22:37:30 +00:00
|
|
|
buf[0] = EMULATOR_MODE_DEBUGWIRE;
|
|
|
|
if (jtagmkII_setparm(pgm, PAR_EMULATOR_MODE, buf) < 0)
|
|
|
|
return -1;
|
|
|
|
else {
|
|
|
|
/*
|
|
|
|
* We are supposed to send a CMND_RESET with the
|
|
|
|
* MONCOM_DISABLE flag set right now, and then
|
|
|
|
* restart from scratch.
|
|
|
|
*
|
|
|
|
* As this will make the ICE sign off from USB, so
|
|
|
|
* we risk losing our USB connection, it's easier
|
|
|
|
* to instruct the user to restart AVRDUDE rather
|
|
|
|
* than trying to cope with all this inside the
|
|
|
|
* program.
|
|
|
|
*/
|
|
|
|
(void)jtagmkII_reset(pgm, 0x04);
|
2013-05-17 16:23:55 +00:00
|
|
|
if (tries++ > 3) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: Failed to return from debugWIRE to ISP.\n",
|
2014-05-18 08:41:46 +00:00
|
|
|
progname);
|
2013-05-17 16:23:55 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: Target prepared for ISP, signed off.\n"
|
2014-05-18 08:41:46 +00:00
|
|
|
"%s: Now retrying without power-cycling the target.\n",
|
|
|
|
progname, progname);
|
2013-05-17 16:23:55 +00:00
|
|
|
goto retry;
|
2006-09-06 22:37:30 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
/* GET SYNC forces the target into STOPPED mode */
|
|
|
|
buf[0] = CMND_GET_SYNC;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_getsync(): Sending get sync command: ",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname);
|
|
|
|
jtagmkII_send(pgm, buf, 1);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2005-05-10 19:53:56 +00:00
|
|
|
c = resp[0];
|
|
|
|
free(resp);
|
|
|
|
if (c != RSP_OK) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"bad response to set parameter command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(c));
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* issue the 'chip erase' command to the AVR device
|
|
|
|
*/
|
|
|
|
static int jtagmkII_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
|
|
|
{
|
2010-01-11 15:27:44 +00:00
|
|
|
int status, len;
|
|
|
|
unsigned char buf[6], *resp, c;
|
|
|
|
|
|
|
|
if (p->flags & AVRPART_HAS_PDI) {
|
|
|
|
buf[0] = CMND_XMEGA_ERASE;
|
|
|
|
buf[1] = XMEGA_ERASE_CHIP;
|
|
|
|
memset(buf + 2, 0, 4); /* address of area to be erased */
|
|
|
|
len = 6;
|
|
|
|
} else {
|
|
|
|
buf[0] = CMND_CHIP_ERASE;
|
|
|
|
len = 1;
|
|
|
|
}
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_chip_erase(): Sending %schip erase command: ",
|
2014-05-18 08:41:46 +00:00
|
|
|
progname,
|
|
|
|
(p->flags & AVRPART_HAS_PDI)? "Xmega ": "");
|
2010-01-11 15:27:44 +00:00
|
|
|
jtagmkII_send(pgm, buf, len);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_chip_erase(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2005-05-10 19:53:56 +00:00
|
|
|
c = resp[0];
|
|
|
|
free(resp);
|
|
|
|
if (c != RSP_OK) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_chip_erase(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"bad response to chip erase command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(c));
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2010-01-11 16:04:29 +00:00
|
|
|
if (!(p->flags & AVRPART_HAS_PDI))
|
|
|
|
pgm->initialize(pgm, p);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-11-20 23:23:37 +00:00
|
|
|
/*
|
|
|
|
* There is no chip erase functionality in debugWire mode.
|
|
|
|
*/
|
|
|
|
static int jtagmkII_chip_erase_dw(PROGRAMMER * pgm, AVRPART * p)
|
|
|
|
{
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: Chip erase not supported in debugWire mode\n",
|
2006-11-20 23:23:37 +00:00
|
|
|
progname);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
static void jtagmkII_set_devdescr(PROGRAMMER * pgm, AVRPART * p)
|
|
|
|
{
|
|
|
|
int status;
|
|
|
|
unsigned char *resp, c;
|
|
|
|
LNODEID ln;
|
|
|
|
AVRMEM * m;
|
|
|
|
struct {
|
|
|
|
unsigned char cmd;
|
|
|
|
struct device_descriptor dd;
|
|
|
|
} sendbuf;
|
|
|
|
|
|
|
|
memset(&sendbuf, 0, sizeof sendbuf);
|
|
|
|
sendbuf.cmd = CMND_SET_DEVICE_DESCRIPTOR;
|
|
|
|
sendbuf.dd.ucSPMCRAddress = p->spmcr;
|
|
|
|
sendbuf.dd.ucRAMPZAddress = p->rampz;
|
|
|
|
sendbuf.dd.ucIDRAddress = p->idr;
|
Quite some cleanup of the JTAG ICE mkII stuff.
. Implement the new EECRAddress field in the device descriptor that is
required by the 4.x firmware; make an uneducated guess about what
firmware requires what length of device descriptor -- perhaps Atmel
can be convinced to publish an official matrix for that.
. Specify EECR in the config file where required. Obviously, only
locations that differ from the 0x3c default are mentioned in the
XML files, so by now, this only affects the AT90CAN128 for us.
. After clarification with Atmel, EnablePageProgramming should really
default to 1, and only cleared if specified by an XML parameter. So
far, only the XML files for the ATmega256x and ATmega406 do specify
it at all, and they specify a 1, too.
. Drop the entire OCDEN fuse heuristic. If OCDEN is unprogrammed at
startup, issue a warning that single-byte EEPROM updates won't be
possible. Leave it to the user to program the fuse if desired.
That way, we won't run into any issue of prematurely wearing out the
hfuse EEPROM cell. Interestingly enough, this also solved the
problem of the target not restarting from scratch upon sign-off.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@461 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-11 20:06:23 +00:00
|
|
|
u16_to_b2(sendbuf.dd.EECRAddress, p->eecr);
|
2005-05-10 19:53:56 +00:00
|
|
|
sendbuf.dd.ucAllowFullPageBitstream =
|
|
|
|
(p->flags & AVRPART_ALLOWFULLPAGEBITSTREAM) != 0;
|
|
|
|
sendbuf.dd.EnablePageProgramming =
|
|
|
|
(p->flags & AVRPART_ENABLEPAGEPROGRAMMING) != 0;
|
|
|
|
for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
|
|
|
|
m = ldata(ln);
|
|
|
|
if (strcmp(m->desc, "flash") == 0) {
|
2012-05-04 10:02:30 +00:00
|
|
|
if (m->page_size > 256)
|
|
|
|
PDATA(pgm)->flash_pagesize = 256;
|
|
|
|
else
|
|
|
|
PDATA(pgm)->flash_pagesize = m->page_size;
|
2005-05-10 19:53:56 +00:00
|
|
|
u32_to_b4(sendbuf.dd.ulFlashSize, m->size);
|
2012-05-04 10:02:30 +00:00
|
|
|
u16_to_b2(sendbuf.dd.uiFlashPageSize, m->page_size);
|
|
|
|
u16_to_b2(sendbuf.dd.uiFlashpages, m->size / m->page_size);
|
2006-11-23 07:07:06 +00:00
|
|
|
if (p->flags & AVRPART_HAS_DW) {
|
2006-11-20 23:23:37 +00:00
|
|
|
memcpy(sendbuf.dd.ucFlashInst, p->flash_instr, FLASH_INSTR_SIZE);
|
2006-11-23 07:07:06 +00:00
|
|
|
memcpy(sendbuf.dd.ucEepromInst, p->eeprom_instr, EEPROM_INSTR_SIZE);
|
|
|
|
}
|
2005-05-10 19:53:56 +00:00
|
|
|
} else if (strcmp(m->desc, "eeprom") == 0) {
|
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
|
|
|
sendbuf.dd.ucEepromPageSize = PDATA(pgm)->eeprom_pagesize = m->page_size;
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
}
|
2008-10-31 21:16:46 +00:00
|
|
|
sendbuf.dd.ucCacheType =
|
|
|
|
(p->flags & AVRPART_HAS_PDI)? 0x02 /* ATxmega */: 0x00;
|
2005-05-10 19:53:56 +00:00
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_set_devdescr(): "
|
2005-05-10 19:53:56 +00:00
|
|
|
"Sending set device descriptor command: ",
|
|
|
|
progname);
|
Quite some cleanup of the JTAG ICE mkII stuff.
. Implement the new EECRAddress field in the device descriptor that is
required by the 4.x firmware; make an uneducated guess about what
firmware requires what length of device descriptor -- perhaps Atmel
can be convinced to publish an official matrix for that.
. Specify EECR in the config file where required. Obviously, only
locations that differ from the 0x3c default are mentioned in the
XML files, so by now, this only affects the AT90CAN128 for us.
. After clarification with Atmel, EnablePageProgramming should really
default to 1, and only cleared if specified by an XML parameter. So
far, only the XML files for the ATmega256x and ATmega406 do specify
it at all, and they specify a 1, too.
. Drop the entire OCDEN fuse heuristic. If OCDEN is unprogrammed at
startup, issue a warning that single-byte EEPROM updates won't be
possible. Leave it to the user to program the fuse if desired.
That way, we won't run into any issue of prematurely wearing out the
hfuse EEPROM cell. Interestingly enough, this also solved the
problem of the target not restarting from scratch upon sign-off.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@461 81a1dc3b-b13d-400b-aceb-764788c761c2
2005-05-11 20:06:23 +00:00
|
|
|
jtagmkII_send(pgm, (unsigned char *)&sendbuf,
|
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
|
|
|
PDATA(pgm)->device_descriptor_length + sizeof(unsigned char));
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_set_devdescr(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
2005-05-10 19:53:56 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2005-05-10 19:53:56 +00:00
|
|
|
c = resp[0];
|
|
|
|
free(resp);
|
|
|
|
if (c != RSP_OK) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_set_devdescr(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"bad response to set device descriptor command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(c));
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-13 15:25:41 +00:00
|
|
|
static void jtagmkII_set_xmega_params(PROGRAMMER * pgm, AVRPART * p)
|
|
|
|
{
|
|
|
|
int status;
|
|
|
|
unsigned char *resp, c;
|
|
|
|
LNODEID ln;
|
|
|
|
AVRMEM * m;
|
|
|
|
struct {
|
|
|
|
unsigned char cmd;
|
|
|
|
struct xmega_device_desc dd;
|
|
|
|
} sendbuf;
|
|
|
|
|
|
|
|
memset(&sendbuf, 0, sizeof sendbuf);
|
|
|
|
sendbuf.cmd = CMND_SET_XMEGA_PARAMS;
|
|
|
|
u16_to_b2(sendbuf.dd.whatever, 0x0002);
|
|
|
|
sendbuf.dd.datalen = 47;
|
|
|
|
u16_to_b2(sendbuf.dd.nvm_base_addr, p->nvm_base);
|
|
|
|
u16_to_b2(sendbuf.dd.mcu_base_addr, p->mcu_base);
|
|
|
|
|
|
|
|
for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
|
|
|
|
m = ldata(ln);
|
|
|
|
if (strcmp(m->desc, "flash") == 0) {
|
2012-05-04 10:02:30 +00:00
|
|
|
if (m->page_size > 256)
|
|
|
|
PDATA(pgm)->flash_pagesize = 256;
|
|
|
|
else
|
|
|
|
PDATA(pgm)->flash_pagesize = m->page_size;
|
|
|
|
u16_to_b2(sendbuf.dd.flash_page_size, m->page_size);
|
2012-04-13 15:25:41 +00:00
|
|
|
} else if (strcmp(m->desc, "eeprom") == 0) {
|
|
|
|
sendbuf.dd.eeprom_page_size = m->page_size;
|
|
|
|
u16_to_b2(sendbuf.dd.eeprom_size, m->size);
|
|
|
|
u32_to_b4(sendbuf.dd.nvm_eeprom_offset, m->offset);
|
|
|
|
} else if (strcmp(m->desc, "application") == 0) {
|
|
|
|
u32_to_b4(sendbuf.dd.app_size, m->size);
|
|
|
|
u32_to_b4(sendbuf.dd.nvm_app_offset, m->offset);
|
|
|
|
} else if (strcmp(m->desc, "boot") == 0) {
|
|
|
|
u16_to_b2(sendbuf.dd.boot_size, m->size);
|
|
|
|
u32_to_b4(sendbuf.dd.nvm_boot_offset, m->offset);
|
2012-11-29 13:31:11 +00:00
|
|
|
} else if (strcmp(m->desc, "fuse1") == 0) {
|
|
|
|
u32_to_b4(sendbuf.dd.nvm_fuse_offset, m->offset & ~7);
|
2014-10-15 20:01:12 +00:00
|
|
|
} else if (strncmp(m->desc, "lock", 4) == 0) {
|
2012-04-13 15:25:41 +00:00
|
|
|
u32_to_b4(sendbuf.dd.nvm_lock_offset, m->offset);
|
|
|
|
} else if (strcmp(m->desc, "usersig") == 0) {
|
|
|
|
u32_to_b4(sendbuf.dd.nvm_user_sig_offset, m->offset);
|
|
|
|
} else if (strcmp(m->desc, "prodsig") == 0) {
|
|
|
|
u32_to_b4(sendbuf.dd.nvm_prod_sig_offset, m->offset);
|
|
|
|
} else if (strcmp(m->desc, "data") == 0) {
|
|
|
|
u32_to_b4(sendbuf.dd.nvm_data_offset, m->offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_set_xmega_params(): "
|
2012-04-13 15:25:41 +00:00
|
|
|
"Sending set Xmega params command: ",
|
|
|
|
progname);
|
|
|
|
jtagmkII_send(pgm, (unsigned char *)&sendbuf, sizeof sendbuf);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_set_xmega_params(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
2012-04-13 15:25:41 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2012-04-13 15:25:41 +00:00
|
|
|
c = resp[0];
|
|
|
|
free(resp);
|
|
|
|
if (c != RSP_OK) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_set_xmega_params(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"bad response to set device descriptor command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(c));
|
2012-04-13 15:25:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
/*
|
|
|
|
* Reset the target.
|
|
|
|
*/
|
2006-09-06 22:37:30 +00:00
|
|
|
static int jtagmkII_reset(PROGRAMMER * pgm, unsigned char flags)
|
2005-05-10 19:53:56 +00:00
|
|
|
{
|
|
|
|
int status;
|
2006-09-06 22:37:30 +00:00
|
|
|
unsigned char buf[2], *resp, c;
|
2005-05-10 19:53:56 +00:00
|
|
|
|
2006-11-20 23:23:37 +00:00
|
|
|
/*
|
|
|
|
* In debugWire mode, don't reset. Do a forced stop, and tell the
|
|
|
|
* ICE to stop any timers, too.
|
|
|
|
*/
|
|
|
|
if (pgm->flag & PGM_FL_IS_DW) {
|
|
|
|
unsigned char parm[] = { 0 };
|
|
|
|
|
|
|
|
(void)jtagmkII_setparm(pgm, PAR_TIMERS_RUNNING, parm);
|
|
|
|
}
|
|
|
|
|
|
|
|
buf[0] = (pgm->flag & PGM_FL_IS_DW)? CMND_FORCED_STOP: CMND_RESET;
|
|
|
|
buf[1] = (pgm->flag & PGM_FL_IS_DW)? 1: flags;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_reset(): Sending %s command: ",
|
2006-11-20 23:23:37 +00:00
|
|
|
progname, (pgm->flag & PGM_FL_IS_DW)? "stop": "reset");
|
2006-09-06 22:37:30 +00:00
|
|
|
jtagmkII_send(pgm, buf, 2);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_reset(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2005-05-10 19:53:56 +00:00
|
|
|
c = resp[0];
|
|
|
|
free(resp);
|
|
|
|
if (c != RSP_OK) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_reset(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"bad response to reset command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(c));
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
static int jtagmkII_program_enable_INFO(PROGRAMMER * pgm, AVRPART * p)
|
2005-05-10 19:53:56 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int jtagmkII_program_enable(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
int status;
|
|
|
|
unsigned char buf[1], *resp, c;
|
2010-01-17 17:31:10 +00:00
|
|
|
int use_ext_reset;
|
2005-05-10 19:53:56 +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)->prog_enabled)
|
2005-05-10 19:53:56 +00:00
|
|
|
return 0;
|
|
|
|
|
2010-01-17 17:31:10 +00:00
|
|
|
for (use_ext_reset = 0; use_ext_reset <= 1; use_ext_reset++) {
|
|
|
|
buf[0] = CMND_ENTER_PROGMODE;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_program_enable(): "
|
2010-01-17 17:31:10 +00:00
|
|
|
"Sending enter progmode command: ",
|
|
|
|
progname);
|
|
|
|
jtagmkII_send(pgm, buf, 1);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_program_enable(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
2010-01-17 17:31:10 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
2005-05-10 19:53:56 +00:00
|
|
|
putc('\n', stderr);
|
2010-01-17 17:31:10 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2010-01-17 17:31:10 +00:00
|
|
|
c = resp[0];
|
|
|
|
free(resp);
|
|
|
|
if (c != RSP_OK) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_program_enable(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"bad response to enter progmode command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(c));
|
2010-01-17 17:31:10 +00:00
|
|
|
if (c == RSP_ILLEGAL_JTAG_ID) {
|
|
|
|
if (use_ext_reset == 0) {
|
|
|
|
unsigned char parm[] = { 1};
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: retrying with external reset applied\n",
|
2014-05-18 08:41:46 +00:00
|
|
|
progname);
|
2010-01-17 17:31:10 +00:00
|
|
|
|
|
|
|
(void)jtagmkII_setparm(pgm, PAR_EXTERNAL_RESET, parm);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: JTAGEN fuse disabled?\n", progname);
|
2010-01-17 17:31:10 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2005-05-10 19:53:56 +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
|
|
|
PDATA(pgm)->prog_enabled = 1;
|
2005-05-10 19:53:56 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int jtagmkII_program_disable(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
int status;
|
|
|
|
unsigned char buf[1], *resp, c;
|
|
|
|
|
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)->prog_enabled)
|
2005-05-10 19:53:56 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
buf[0] = CMND_LEAVE_PROGMODE;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_program_disable(): "
|
2005-05-10 19:53:56 +00:00
|
|
|
"Sending leave progmode command: ",
|
|
|
|
progname);
|
|
|
|
jtagmkII_send(pgm, buf, 1);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_program_disable(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2005-05-10 19:53:56 +00:00
|
|
|
c = resp[0];
|
|
|
|
free(resp);
|
|
|
|
if (c != RSP_OK) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_program_disable(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"bad response to leave progmode command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(c));
|
2005-05-10 19:53:56 +00:00
|
|
|
return -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
|
|
|
PDATA(pgm)->prog_enabled = 0;
|
2006-09-06 22:37:30 +00:00
|
|
|
(void)jtagmkII_reset(pgm, 0x01);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned char jtagmkII_get_baud(long baud)
|
|
|
|
{
|
|
|
|
static struct {
|
|
|
|
long baud;
|
|
|
|
unsigned char val;
|
|
|
|
} baudtab[] = {
|
2021-12-21 22:22:06 +00:00
|
|
|
{ 2400L, PAR_BAUD_2400 },
|
|
|
|
{ 4800L, PAR_BAUD_4800 },
|
|
|
|
{ 9600L, PAR_BAUD_9600 },
|
|
|
|
{ 19200L, PAR_BAUD_19200 },
|
|
|
|
{ 38400L, PAR_BAUD_38400 },
|
|
|
|
{ 57600L, PAR_BAUD_57600 },
|
|
|
|
{ 115200L, PAR_BAUD_115200 },
|
|
|
|
{ 14400L, PAR_BAUD_14400 },
|
|
|
|
/* Extension to jtagmkII protocol: extra baud rates, standard series. */
|
|
|
|
{ 153600L, PAR_BAUD_153600 },
|
|
|
|
{ 230400L, PAR_BAUD_230400 },
|
|
|
|
{ 460800L, PAR_BAUD_460800 },
|
|
|
|
{ 921600L, PAR_BAUD_921600 },
|
|
|
|
/* Extension to jtagmkII protocol: extra baud rates, binary series. */
|
|
|
|
{ 128000L, PAR_BAUD_128000 },
|
|
|
|
{ 256000L, PAR_BAUD_256000 },
|
|
|
|
{ 512000L, PAR_BAUD_512000 },
|
|
|
|
{ 1024000L, PAR_BAUD_1024000 },
|
|
|
|
/* Extension to jtagmkII protocol: extra baud rates, decimal series. */
|
|
|
|
{ 150000L, PAR_BAUD_150000 },
|
|
|
|
{ 200000L, PAR_BAUD_200000 },
|
|
|
|
{ 250000L, PAR_BAUD_250000 },
|
|
|
|
{ 300000L, PAR_BAUD_300000 },
|
|
|
|
{ 400000L, PAR_BAUD_400000 },
|
|
|
|
{ 500000L, PAR_BAUD_500000 },
|
|
|
|
{ 600000L, PAR_BAUD_600000 },
|
|
|
|
{ 666666L, PAR_BAUD_666666 },
|
|
|
|
{ 1000000L, PAR_BAUD_1000000 },
|
|
|
|
{ 1500000L, PAR_BAUD_1500000 },
|
|
|
|
{ 2000000L, PAR_BAUD_2000000 },
|
|
|
|
{ 3000000L, PAR_BAUD_3000000 },
|
|
|
|
};
|
2005-05-10 19:53:56 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < sizeof baudtab / sizeof baudtab[0]; i++)
|
|
|
|
if (baud == baudtab[i].baud)
|
|
|
|
return baudtab[i].val;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* initialize the AVR device and prepare it to accept commands
|
|
|
|
*/
|
|
|
|
static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
|
|
|
|
{
|
|
|
|
AVRMEM hfuse;
|
|
|
|
unsigned char b;
|
2006-11-20 23:23:37 +00:00
|
|
|
int ok;
|
|
|
|
const char *ifname;
|
|
|
|
|
|
|
|
ok = 0;
|
|
|
|
if (pgm->flag & PGM_FL_IS_DW) {
|
|
|
|
ifname = "debugWire";
|
|
|
|
if (p->flags & AVRPART_HAS_DW)
|
|
|
|
ok = 1;
|
2010-01-13 17:34:18 +00:00
|
|
|
} else if (pgm->flag & PGM_FL_IS_PDI) {
|
|
|
|
ifname = "PDI";
|
|
|
|
if (p->flags & AVRPART_HAS_PDI)
|
|
|
|
ok = 1;
|
2006-11-20 23:23:37 +00:00
|
|
|
} else {
|
|
|
|
ifname = "JTAG";
|
|
|
|
if (p->flags & AVRPART_HAS_JTAG)
|
|
|
|
ok = 1;
|
|
|
|
}
|
2005-05-10 19:53:56 +00:00
|
|
|
|
2006-11-20 23:23:37 +00:00
|
|
|
if (!ok) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): part %s has no %s interface\n",
|
2006-11-20 23:23:37 +00:00
|
|
|
progname, p->desc, ifname);
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2006-10-27 08:45:47 +00:00
|
|
|
if ((serdev->flags & SERDEV_FL_CANSETSPEED) && pgm->baudrate && pgm->baudrate != 19200) {
|
2005-05-10 19:53:56 +00:00
|
|
|
if ((b = jtagmkII_get_baud(pgm->baudrate)) == 0) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): unsupported baudrate %d\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname, pgm->baudrate);
|
|
|
|
} else {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_initialize(): "
|
2005-05-10 19:53:56 +00:00
|
|
|
"trying to set baudrate to %d\n",
|
|
|
|
progname, pgm->baudrate);
|
|
|
|
if (jtagmkII_setparm(pgm, PAR_BAUD_RATE, &b) == 0)
|
2021-12-08 10:09:52 +00:00
|
|
|
serial_setparams(&pgm->fd, pgm->baudrate, SERIAL_8N1);
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
}
|
2010-01-13 17:34:18 +00:00
|
|
|
if ((pgm->flag & PGM_FL_IS_JTAG) && pgm->bitclock != 0.0) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_initialize(): "
|
2005-05-10 19:53:56 +00:00
|
|
|
"trying to set JTAG clock period to %.1f us\n",
|
|
|
|
progname, pgm->bitclock);
|
|
|
|
if (jtagmkII_set_sck_period(pgm, pgm->bitclock) != 0)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2011-08-16 18:47:52 +00:00
|
|
|
if ((pgm->flag & PGM_FL_IS_JTAG) &&
|
|
|
|
jtagmkII_setparm(pgm, PAR_DAISY_CHAIN_INFO, PDATA(pgm)->jtagchain) < 0) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Failed to setup JTAG chain\n",
|
2007-11-06 19:42:16 +00:00
|
|
|
progname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2012-05-04 10:02:30 +00:00
|
|
|
/*
|
|
|
|
* If this is an ATxmega device in JTAG mode, change the emulator
|
|
|
|
* mode from JTAG to JTAG_XMEGA.
|
|
|
|
*/
|
|
|
|
if ((pgm->flag & PGM_FL_IS_JTAG) &&
|
|
|
|
(p->flags & AVRPART_HAS_PDI)) {
|
|
|
|
if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG_XMEGA) < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
2005-05-10 19:53:56 +00:00
|
|
|
/*
|
|
|
|
* Must set the device descriptor before entering programming mode.
|
|
|
|
*/
|
2012-04-13 15:25:41 +00:00
|
|
|
if (PDATA(pgm)->fwver >= 0x700 && (p->flags & AVRPART_HAS_PDI) != 0)
|
|
|
|
jtagmkII_set_xmega_params(pgm, p);
|
|
|
|
else
|
|
|
|
jtagmkII_set_devdescr(pgm, p);
|
2009-10-10 20:09:53 +00:00
|
|
|
|
2012-03-30 16:19:13 +00:00
|
|
|
PDATA(pgm)->boot_start = ULONG_MAX;
|
2018-01-16 22:01:36 +00:00
|
|
|
if ((p->flags & AVRPART_HAS_PDI)) {
|
2012-03-30 16:19:13 +00:00
|
|
|
/*
|
|
|
|
* Find out where the border between application and boot area
|
|
|
|
* is.
|
|
|
|
*/
|
|
|
|
AVRMEM *bootmem = avr_locate_mem(p, "boot");
|
|
|
|
AVRMEM *flashmem = avr_locate_mem(p, "flash");
|
|
|
|
if (bootmem == NULL || flashmem == NULL) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Cannot locate \"flash\" and \"boot\" memories in description\n",
|
2014-05-18 08:41:46 +00:00
|
|
|
progname);
|
2012-03-30 16:19:13 +00:00
|
|
|
} else {
|
2012-05-04 10:02:30 +00:00
|
|
|
if (PDATA(pgm)->fwver < 0x700) {
|
|
|
|
/* V7+ firmware does not need this anymore */
|
|
|
|
unsigned char par[4];
|
|
|
|
|
|
|
|
u32_to_b4(par, flashmem->offset);
|
|
|
|
(void) jtagmkII_setparm(pgm, PAR_PDI_OFFSET_START, par);
|
|
|
|
u32_to_b4(par, bootmem->offset);
|
|
|
|
(void) jtagmkII_setparm(pgm, PAR_PDI_OFFSET_END, par);
|
|
|
|
}
|
|
|
|
|
2012-03-30 16:19:13 +00:00
|
|
|
PDATA(pgm)->boot_start = bootmem->offset - flashmem->offset;
|
|
|
|
}
|
2010-01-14 13:46:02 +00:00
|
|
|
}
|
2005-05-10 19:53:56 +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
|
|
|
free(PDATA(pgm)->flash_pagecache);
|
|
|
|
free(PDATA(pgm)->eeprom_pagecache);
|
|
|
|
if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Out of memory\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname);
|
|
|
|
return -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
|
|
|
if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Out of memory\n",
|
2005-05-10 19:53:56 +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
|
|
|
free(PDATA(pgm)->flash_pagecache);
|
2005-05-10 19:53:56 +00:00
|
|
|
return -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
|
|
|
PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
|
2005-05-10 19:53:56 +00:00
|
|
|
|
2012-12-18 09:20:06 +00:00
|
|
|
if (PDATA(pgm)->fwver >= 0x700 && (p->flags & AVRPART_HAS_PDI)) {
|
|
|
|
/*
|
|
|
|
* Work around for
|
|
|
|
* https://savannah.nongnu.org/bugs/index.php?37942
|
|
|
|
*
|
|
|
|
* Firmware version 7.24 (at least) on the Dragon behaves very
|
|
|
|
* strange when it gets a RESET request here. All subsequent
|
|
|
|
* responses are completely off, so the emulator becomes unusable.
|
|
|
|
* This appears to be a firmware bug (earlier versions, at least
|
|
|
|
* 7.14, didn't experience this), but by omitting the RESET for
|
|
|
|
* Xmega devices, we can work around it.
|
|
|
|
*/
|
|
|
|
} else {
|
|
|
|
if (jtagmkII_reset(pgm, 0x01) < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
2005-05-10 19:53:56 +00:00
|
|
|
|
2010-01-13 17:34:18 +00:00
|
|
|
if ((pgm->flag & PGM_FL_IS_JTAG) && !(p->flags & AVRPART_HAS_PDI)) {
|
2006-11-20 23:23:37 +00:00
|
|
|
strcpy(hfuse.desc, "hfuse");
|
|
|
|
if (jtagmkII_read_byte(pgm, p, &hfuse, 1, &b) < 0)
|
|
|
|
return -1;
|
|
|
|
if ((b & OCDEN) != 0)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): warning: OCDEN fuse not programmed, "
|
2014-05-18 08:41:46 +00:00
|
|
|
"single-byte EEPROM updates not possible\n",
|
|
|
|
progname);
|
2006-11-20 23:23:37 +00:00
|
|
|
}
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void jtagmkII_disable(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
|
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
|
|
|
free(PDATA(pgm)->flash_pagecache);
|
|
|
|
PDATA(pgm)->flash_pagecache = NULL;
|
|
|
|
free(PDATA(pgm)->eeprom_pagecache);
|
|
|
|
PDATA(pgm)->eeprom_pagecache = NULL;
|
2005-05-10 19:53:56 +00:00
|
|
|
|
2010-01-13 17:34:18 +00:00
|
|
|
/*
|
|
|
|
* jtagmkII_program_disable() doesn't do anything if the
|
|
|
|
* device is currently not in programming mode, so just
|
|
|
|
* call it unconditionally here.
|
|
|
|
*/
|
|
|
|
(void)jtagmkII_program_disable(pgm);
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void jtagmkII_enable(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-11-06 19:42:16 +00:00
|
|
|
static int jtagmkII_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, "jtagchain=", strlen("jtagchain=")) == 0) {
|
|
|
|
unsigned int ub, ua, bb, ba;
|
|
|
|
if (sscanf(extended_param, "jtagchain=%u,%u,%u,%u", &ub, &ua, &bb, &ba)
|
|
|
|
!= 4) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_parseextparms(): invalid JTAG chain '%s'\n",
|
2014-05-18 08:41:46 +00:00
|
|
|
progname, extended_param);
|
2007-11-06 19:42:16 +00:00
|
|
|
rv = -1;
|
|
|
|
continue;
|
|
|
|
}
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_parseextparms(): JTAG chain parsed as:\n"
|
2014-05-18 08:41:46 +00:00
|
|
|
"%s %u units before, %u units after, %u bits before, %u bits after\n",
|
|
|
|
progname,
|
|
|
|
progbuf, ub, ua, bb, ba);
|
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
|
|
|
PDATA(pgm)->jtagchain[0] = ub;
|
|
|
|
PDATA(pgm)->jtagchain[1] = ua;
|
|
|
|
PDATA(pgm)->jtagchain[2] = bb;
|
|
|
|
PDATA(pgm)->jtagchain[3] = ba;
|
2007-11-06 19:42:16 +00:00
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_parseextparms(): invalid extended parameter '%s'\n",
|
2014-05-18 08:41:46 +00:00
|
|
|
progname, extended_param);
|
2007-11-06 19:42:16 +00:00
|
|
|
rv = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
static int jtagmkII_open(PROGRAMMER * pgm, char * port)
|
|
|
|
{
|
2014-02-21 13:44:11 +00:00
|
|
|
union pinfo pinfo;
|
2006-01-12 23:13:50 +00:00
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_open()\n", progname);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
2006-01-12 23:13:50 +00:00
|
|
|
/*
|
|
|
|
* The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
|
|
|
|
* attaching. If the config file or command-line parameters specify
|
|
|
|
* a higher baud rate, we switch to it later on, after establishing
|
|
|
|
* the connection with the ICE.
|
|
|
|
*/
|
2021-12-08 10:09:52 +00:00
|
|
|
pinfo.serialinfo.baud = 19200;
|
|
|
|
pinfo.serialinfo.cflags = SERIAL_8N1;
|
2006-01-12 23:13:50 +00:00
|
|
|
|
2005-06-19 21:38:03 +00:00
|
|
|
/*
|
|
|
|
* If the port name starts with "usb", divert the serial routines
|
2006-01-12 23:13:50 +00:00
|
|
|
* to the USB ones. The serial_open() function for USB overrides
|
|
|
|
* the meaning of the "baud" parameter to be the USB device ID to
|
|
|
|
* search for.
|
2005-06-19 21:38:03 +00:00
|
|
|
*/
|
2006-01-12 23:13:50 +00:00
|
|
|
if (strncmp(port, "usb", 3) == 0) {
|
2006-09-06 20:06:07 +00:00
|
|
|
#if defined(HAVE_LIBUSB)
|
2005-06-19 21:38:03 +00:00
|
|
|
serdev = &usb_serdev;
|
2014-02-21 13:44:11 +00:00
|
|
|
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
|
|
|
|
pinfo.usbinfo.flags = 0;
|
|
|
|
pinfo.usbinfo.pid = USB_DEVICE_JTAGICEMKII;
|
2012-11-26 16:24:56 +00:00
|
|
|
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
|
|
|
|
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
|
|
|
|
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
|
|
|
|
pgm->fd.usb.eep = 0; /* no seperate EP for events */
|
2006-09-06 20:06:07 +00:00
|
|
|
#else
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
|
2006-09-06 20:06:07 +00:00
|
|
|
return -1;
|
2005-06-19 21:38:03 +00:00
|
|
|
#endif
|
2006-09-06 20:06:07 +00:00
|
|
|
}
|
2005-06-19 21:38:03 +00:00
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
strcpy(pgm->port, port);
|
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;
|
|
|
|
}
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* drain any extraneous input
|
|
|
|
*/
|
|
|
|
jtagmkII_drain(pgm, 0);
|
|
|
|
|
2010-01-14 13:46:02 +00:00
|
|
|
if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG) < 0)
|
|
|
|
return -1;
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-11-20 23:23:37 +00:00
|
|
|
static int jtagmkII_open_dw(PROGRAMMER * pgm, char * port)
|
|
|
|
{
|
2014-02-21 13:44:11 +00:00
|
|
|
union pinfo pinfo;
|
2006-11-20 23:23:37 +00:00
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_open_dw()\n", progname);
|
2006-11-20 23:23:37 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
|
|
|
|
* attaching. If the config file or command-line parameters specify
|
|
|
|
* a higher baud rate, we switch to it later on, after establishing
|
|
|
|
* the connection with the ICE.
|
|
|
|
*/
|
2021-12-08 10:09:52 +00:00
|
|
|
pinfo.serialinfo.baud = 19200;
|
|
|
|
pinfo.serialinfo.cflags = SERIAL_8N1;
|
2006-11-20 23:23:37 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If the port name starts with "usb", divert the serial routines
|
|
|
|
* to the USB ones. The serial_open() function for USB overrides
|
|
|
|
* the meaning of the "baud" parameter to be the USB device ID to
|
|
|
|
* search for.
|
|
|
|
*/
|
|
|
|
if (strncmp(port, "usb", 3) == 0) {
|
|
|
|
#if defined(HAVE_LIBUSB)
|
|
|
|
serdev = &usb_serdev;
|
2014-02-21 13:44:11 +00:00
|
|
|
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
|
|
|
|
pinfo.usbinfo.flags = 0;
|
|
|
|
pinfo.usbinfo.pid = USB_DEVICE_JTAGICEMKII;
|
2012-11-26 16:24:56 +00:00
|
|
|
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
|
|
|
|
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
|
|
|
|
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
|
|
|
|
pgm->fd.usb.eep = 0; /* no seperate EP for events */
|
2006-11-20 23:23:37 +00:00
|
|
|
#else
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
|
2006-11-20 23:23:37 +00:00
|
|
|
return -1;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy(pgm->port, port);
|
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;
|
|
|
|
}
|
2006-11-20 23:23:37 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* drain any extraneous input
|
|
|
|
*/
|
|
|
|
jtagmkII_drain(pgm, 0);
|
|
|
|
|
2010-01-14 13:46:02 +00:00
|
|
|
if (jtagmkII_getsync(pgm, EMULATOR_MODE_DEBUGWIRE) < 0)
|
|
|
|
return -1;
|
2006-11-20 23:23:37 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-01-13 17:34:18 +00:00
|
|
|
static int jtagmkII_open_pdi(PROGRAMMER * pgm, char * port)
|
|
|
|
{
|
2014-02-21 13:44:11 +00:00
|
|
|
union pinfo pinfo;
|
2010-01-13 17:34:18 +00:00
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_open_pdi()\n", progname);
|
2010-01-13 17:34:18 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
|
|
|
|
* attaching. If the config file or command-line parameters specify
|
|
|
|
* a higher baud rate, we switch to it later on, after establishing
|
|
|
|
* the connection with the ICE.
|
|
|
|
*/
|
2021-12-08 10:09:52 +00:00
|
|
|
pinfo.serialinfo.baud = 19200;
|
|
|
|
pinfo.serialinfo.cflags = SERIAL_8N1;
|
2010-01-13 17:34:18 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If the port name starts with "usb", divert the serial routines
|
|
|
|
* to the USB ones. The serial_open() function for USB overrides
|
|
|
|
* the meaning of the "baud" parameter to be the USB device ID to
|
|
|
|
* search for.
|
|
|
|
*/
|
|
|
|
if (strncmp(port, "usb", 3) == 0) {
|
|
|
|
#if defined(HAVE_LIBUSB)
|
|
|
|
serdev = &usb_serdev;
|
2014-02-21 13:44:11 +00:00
|
|
|
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
|
|
|
|
pinfo.usbinfo.flags = 0;
|
|
|
|
pinfo.usbinfo.pid = USB_DEVICE_JTAGICEMKII;
|
2012-11-26 16:24:56 +00:00
|
|
|
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
|
|
|
|
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
|
|
|
|
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
|
|
|
|
pgm->fd.usb.eep = 0; /* no seperate EP for events */
|
2010-01-13 17:34:18 +00:00
|
|
|
#else
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
|
2010-01-13 17:34:18 +00:00
|
|
|
return -1;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy(pgm->port, port);
|
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;
|
|
|
|
}
|
2010-01-13 17:34:18 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* drain any extraneous input
|
|
|
|
*/
|
|
|
|
jtagmkII_drain(pgm, 0);
|
|
|
|
|
2010-01-14 13:46:02 +00:00
|
|
|
if (jtagmkII_getsync(pgm, EMULATOR_MODE_PDI) < 0)
|
|
|
|
return -1;
|
2010-01-13 17:34:18 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-11-20 23:23:37 +00:00
|
|
|
|
2006-10-26 21:14:10 +00:00
|
|
|
static int jtagmkII_dragon_open(PROGRAMMER * pgm, char * port)
|
|
|
|
{
|
2014-02-21 13:44:11 +00:00
|
|
|
union pinfo pinfo;
|
2006-10-26 21:14:10 +00:00
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_dragon_open()\n", progname);
|
2006-10-26 21:14:10 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
|
|
|
|
* attaching. If the config file or command-line parameters specify
|
|
|
|
* a higher baud rate, we switch to it later on, after establishing
|
|
|
|
* the connection with the ICE.
|
|
|
|
*/
|
2021-12-08 10:09:52 +00:00
|
|
|
pinfo.serialinfo.baud = 19200;
|
|
|
|
pinfo.serialinfo.cflags = SERIAL_8N1;
|
2006-10-26 21:14:10 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If the port name starts with "usb", divert the serial routines
|
|
|
|
* to the USB ones. The serial_open() function for USB overrides
|
|
|
|
* the meaning of the "baud" parameter to be the USB device ID to
|
|
|
|
* search for.
|
|
|
|
*/
|
|
|
|
if (strncmp(port, "usb", 3) == 0) {
|
|
|
|
#if defined(HAVE_LIBUSB)
|
|
|
|
serdev = &usb_serdev;
|
2014-02-21 13:44:11 +00:00
|
|
|
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
|
|
|
|
pinfo.usbinfo.flags = 0;
|
|
|
|
pinfo.usbinfo.pid = USB_DEVICE_AVRDRAGON;
|
2012-11-26 16:24:56 +00:00
|
|
|
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
|
|
|
|
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
|
|
|
|
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
|
|
|
|
pgm->fd.usb.eep = 0; /* no seperate EP for events */
|
2006-10-26 21:14:10 +00:00
|
|
|
#else
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
|
2006-10-26 21:14:10 +00:00
|
|
|
return -1;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy(pgm->port, port);
|
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;
|
|
|
|
}
|
2006-10-26 21:14:10 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* drain any extraneous input
|
|
|
|
*/
|
|
|
|
jtagmkII_drain(pgm, 0);
|
|
|
|
|
2010-01-14 13:46:02 +00:00
|
|
|
if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG) < 0)
|
|
|
|
return -1;
|
2006-10-26 21:14:10 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-20 23:23:37 +00:00
|
|
|
static int jtagmkII_dragon_open_dw(PROGRAMMER * pgm, char * port)
|
|
|
|
{
|
2014-02-21 13:44:11 +00:00
|
|
|
union pinfo pinfo;
|
2006-11-20 23:23:37 +00:00
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_dragon_open_dw()\n", progname);
|
2006-11-20 23:23:37 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
|
|
|
|
* attaching. If the config file or command-line parameters specify
|
|
|
|
* a higher baud rate, we switch to it later on, after establishing
|
|
|
|
* the connection with the ICE.
|
|
|
|
*/
|
2021-12-08 10:09:52 +00:00
|
|
|
pinfo.serialinfo.baud = 19200;
|
|
|
|
pinfo.serialinfo.cflags = SERIAL_8N1;
|
2006-11-20 23:23:37 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If the port name starts with "usb", divert the serial routines
|
|
|
|
* to the USB ones. The serial_open() function for USB overrides
|
|
|
|
* the meaning of the "baud" parameter to be the USB device ID to
|
|
|
|
* search for.
|
|
|
|
*/
|
|
|
|
if (strncmp(port, "usb", 3) == 0) {
|
|
|
|
#if defined(HAVE_LIBUSB)
|
|
|
|
serdev = &usb_serdev;
|
2014-02-21 13:44:11 +00:00
|
|
|
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
|
|
|
|
pinfo.usbinfo.flags = 0;
|
|
|
|
pinfo.usbinfo.pid = USB_DEVICE_AVRDRAGON;
|
2012-11-26 16:24:56 +00:00
|
|
|
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
|
|
|
|
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
|
|
|
|
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
|
|
|
|
pgm->fd.usb.eep = 0; /* no seperate EP for events */
|
2006-11-20 23:23:37 +00:00
|
|
|
#else
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
|
2006-11-20 23:23:37 +00:00
|
|
|
return -1;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy(pgm->port, port);
|
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;
|
|
|
|
}
|
2006-11-20 23:23:37 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* drain any extraneous input
|
|
|
|
*/
|
|
|
|
jtagmkII_drain(pgm, 0);
|
|
|
|
|
2010-01-14 13:46:02 +00:00
|
|
|
if (jtagmkII_getsync(pgm, EMULATOR_MODE_DEBUGWIRE) < 0)
|
|
|
|
return -1;
|
2006-11-20 23:23:37 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-13 17:34:18 +00:00
|
|
|
static int jtagmkII_dragon_open_pdi(PROGRAMMER * pgm, char * port)
|
|
|
|
{
|
2014-02-21 13:44:11 +00:00
|
|
|
union pinfo pinfo;
|
2010-01-13 17:34:18 +00:00
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_dragon_open_pdi()\n", progname);
|
2010-01-13 17:34:18 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
|
|
|
|
* attaching. If the config file or command-line parameters specify
|
|
|
|
* a higher baud rate, we switch to it later on, after establishing
|
|
|
|
* the connection with the ICE.
|
|
|
|
*/
|
2021-12-08 10:09:52 +00:00
|
|
|
pinfo.serialinfo.baud = 19200;
|
|
|
|
pinfo.serialinfo.cflags = SERIAL_8N1;
|
2010-01-13 17:34:18 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If the port name starts with "usb", divert the serial routines
|
|
|
|
* to the USB ones. The serial_open() function for USB overrides
|
|
|
|
* the meaning of the "baud" parameter to be the USB device ID to
|
|
|
|
* search for.
|
|
|
|
*/
|
|
|
|
if (strncmp(port, "usb", 3) == 0) {
|
|
|
|
#if defined(HAVE_LIBUSB)
|
|
|
|
serdev = &usb_serdev;
|
2014-02-21 13:44:11 +00:00
|
|
|
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
|
|
|
|
pinfo.usbinfo.flags = 0;
|
|
|
|
pinfo.usbinfo.pid = USB_DEVICE_AVRDRAGON;
|
2012-11-26 16:24:56 +00:00
|
|
|
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
|
|
|
|
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
|
|
|
|
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
|
|
|
|
pgm->fd.usb.eep = 0; /* no seperate EP for events */
|
2010-01-13 17:34:18 +00:00
|
|
|
#else
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
|
2010-01-13 17:34:18 +00:00
|
|
|
return -1;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy(pgm->port, port);
|
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;
|
|
|
|
}
|
2010-01-13 17:34:18 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* drain any extraneous input
|
|
|
|
*/
|
|
|
|
jtagmkII_drain(pgm, 0);
|
|
|
|
|
2010-01-14 13:46:02 +00:00
|
|
|
if (jtagmkII_getsync(pgm, EMULATOR_MODE_PDI) < 0)
|
|
|
|
return -1;
|
2010-01-13 17:34:18 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-06 20:06:07 +00:00
|
|
|
void jtagmkII_close(PROGRAMMER * pgm)
|
2005-05-10 19:53:56 +00:00
|
|
|
{
|
|
|
|
int status;
|
|
|
|
unsigned char buf[1], *resp, c;
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_close()\n", progname);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
2012-03-20 14:42:20 +00:00
|
|
|
if (pgm->flag & PGM_FL_IS_PDI) {
|
|
|
|
/* When in PDI mode, restart target. */
|
|
|
|
buf[0] = CMND_GO;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_close(): Sending GO command: ",
|
2012-03-20 14:42:20 +00:00
|
|
|
progname);
|
|
|
|
jtagmkII_send(pgm, buf, 1);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
2012-03-20 14:42:20 +00:00
|
|
|
} else {
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2012-03-20 14:42:20 +00:00
|
|
|
c = resp[0];
|
|
|
|
free(resp);
|
|
|
|
if (c != RSP_OK) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"bad response to GO command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(c));
|
2012-03-20 14:42:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
buf[0] = CMND_SIGN_OFF;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_close(): Sending sign-off command: ",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname);
|
|
|
|
jtagmkII_send(pgm, buf, 1);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
2005-05-10 19:53:56 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2005-05-10 19:53:56 +00:00
|
|
|
c = resp[0];
|
|
|
|
free(resp);
|
|
|
|
if (c != RSP_OK) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"bad response to sign-off command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(c));
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
2006-12-11 12:47:35 +00:00
|
|
|
serial_close(&pgm->fd);
|
|
|
|
pgm->fd.ifd = -1;
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
2012-05-04 10:02:30 +00:00
|
|
|
static int jtagmkII_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|
|
|
unsigned int addr)
|
|
|
|
{
|
|
|
|
unsigned char cmd[6];
|
|
|
|
unsigned char *resp;
|
|
|
|
int status, tries;
|
|
|
|
long otimeout = serial_recv_timeout;
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_page_erase(.., %s, 0x%x)\n",
|
2012-05-04 10:02:30 +00:00
|
|
|
progname, m->desc, addr);
|
|
|
|
|
|
|
|
if (!(p->flags & AVRPART_HAS_PDI)) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase: not an Xmega device\n",
|
2012-05-04 10:02:30 +00:00
|
|
|
progname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if ((pgm->flag & PGM_FL_IS_DW)) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase: not applicable to debugWIRE\n",
|
2012-05-04 10:02:30 +00:00
|
|
|
progname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (jtagmkII_program_enable(pgm) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
cmd[0] = CMND_XMEGA_ERASE;
|
|
|
|
if (strcmp(m->desc, "flash") == 0) {
|
|
|
|
if (jtagmkII_memtype(pgm, p, addr) == MTYPE_FLASH)
|
|
|
|
cmd[1] = XMEGA_ERASE_APP_PAGE;
|
|
|
|
else
|
|
|
|
cmd[1] = XMEGA_ERASE_BOOT_PAGE;
|
|
|
|
} else if (strcmp(m->desc, "eeprom") == 0) {
|
|
|
|
cmd[1] = XMEGA_ERASE_EEPROM_PAGE;
|
|
|
|
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
|
|
|
|
cmd[1] = XMEGA_ERASE_USERSIG;
|
|
|
|
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
|
|
|
|
cmd[1] = XMEGA_ERASE_BOOT_PAGE;
|
|
|
|
} else {
|
|
|
|
cmd[1] = XMEGA_ERASE_APP_PAGE;
|
|
|
|
}
|
|
|
|
serial_recv_timeout = 100;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Don't use jtagmkII_memaddr() here. While with all other
|
|
|
|
* commands, firmware 7+ doesn't require the NVM offsets being
|
|
|
|
* applied, the erase page commands make an exception, and do
|
|
|
|
* require the NVM offsets as part of the (page) address.
|
|
|
|
*/
|
|
|
|
u32_to_b4(cmd + 2, addr + m->offset);
|
|
|
|
|
|
|
|
tries = 0;
|
|
|
|
|
|
|
|
retry:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_page_erase(): "
|
2020-09-16 21:31:19 +00:00
|
|
|
"Sending Xmega erase command: ",
|
2012-05-04 10:02:30 +00:00
|
|
|
progname);
|
|
|
|
jtagmkII_send(pgm, cmd, sizeof cmd);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
2012-05-04 10:02:30 +00:00
|
|
|
if (tries++ < 4) {
|
|
|
|
serial_recv_timeout *= 2;
|
|
|
|
goto retry;
|
|
|
|
}
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase(): fatal timeout/"
|
2014-05-18 08:41:46 +00:00
|
|
|
"error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
2012-05-04 10:02:30 +00:00
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2012-05-04 10:02:30 +00:00
|
|
|
if (resp[0] != RSP_OK) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"bad response to xmega erase command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(resp[0]));
|
2012-05-04 10:02:30 +00:00
|
|
|
free(resp);
|
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
free(resp);
|
|
|
|
|
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
static int jtagmkII_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)
|
2005-05-10 19:53:56 +00:00
|
|
|
{
|
2011-09-14 21:49:42 +00:00
|
|
|
unsigned int block_size;
|
|
|
|
unsigned int maxaddr = addr + n_bytes;
|
2005-05-10 19:53:56 +00:00
|
|
|
unsigned char *cmd;
|
|
|
|
unsigned char *resp;
|
2012-03-30 16:19:13 +00:00
|
|
|
int status, tries, dynamic_memtype = 0;
|
2005-05-10 19:53:56 +00:00
|
|
|
long otimeout = serial_recv_timeout;
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_paged_write(.., %s, %d, %d)\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname, m->desc, page_size, n_bytes);
|
|
|
|
|
2006-11-20 23:23:37 +00:00
|
|
|
if (!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0)
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
|
2005-09-26 12:16:45 +00:00
|
|
|
if (page_size == 0) page_size = 256;
|
2012-05-04 10:02:30 +00:00
|
|
|
else if (page_size > 256) page_size = 256;
|
2005-09-26 12:16:45 +00:00
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
if ((cmd = malloc(page_size + 10)) == NULL) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write(): Out of memory\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmd[0] = CMND_WRITE_MEMORY;
|
|
|
|
if (strcmp(m->desc, "flash") == 0) {
|
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
|
|
|
PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
|
2012-04-26 11:01:19 +00:00
|
|
|
cmd[1] = jtagmkII_memtype(pgm, p, addr);
|
2012-03-30 16:19:13 +00:00
|
|
|
if (p->flags & AVRPART_HAS_PDI)
|
|
|
|
/* dynamically decide between flash/boot memtype */
|
|
|
|
dynamic_memtype = 1;
|
2005-05-10 19:53:56 +00:00
|
|
|
} else if (strcmp(m->desc, "eeprom") == 0) {
|
2006-11-20 23:23:37 +00:00
|
|
|
if (pgm->flag & PGM_FL_IS_DW) {
|
2009-02-16 12:26:44 +00:00
|
|
|
/*
|
|
|
|
* jtagmkII_paged_write() to EEPROM attempted while in
|
|
|
|
* DW mode. Use jtagmkII_write_byte() instead.
|
|
|
|
*/
|
2011-09-14 21:49:42 +00:00
|
|
|
for (; addr < maxaddr; addr++) {
|
2009-02-16 12:26:44 +00:00
|
|
|
status = jtagmkII_write_byte(pgm, p, m, addr, m->buf[addr]);
|
|
|
|
if (status < 0) {
|
|
|
|
free(cmd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2006-11-20 23:23:37 +00:00
|
|
|
free(cmd);
|
2009-02-16 12:26:44 +00:00
|
|
|
return n_bytes;
|
2006-11-20 23:23:37 +00:00
|
|
|
}
|
Contributed by Zoltan Laday:
patch #6825: xmega problems with JTAGICEmkII
* jtagmkII.c: Many fixes for Xmega devices.
* jtagmkII_private.h: Add various new constants required for
Xmega devices.
* avrdude.conf.in: New devices: ATXMEGA64A1, ATXMEGA192A1,
ATXMEGA256A1, ATXMEGA64A3, ATXMEGA128A3, ATXMEGA192A3,
ATXMEGA256A3, ATXMEGA256A3B, ATXMEGA16A4, ATXMEGA32A4,
ATXMEGA64A4, ATXMEGA128A4
* avr.c (avr_read, avr_write): Add more names for (Xmega)
memory areas that require paged operation.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@821 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-06-24 21:32:12 +00:00
|
|
|
cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
|
2009-02-16 12:26:44 +00:00
|
|
|
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
|
2012-03-30 16:19:13 +00:00
|
|
|
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
|
|
|
|
cmd[1] = MTYPE_USERSIG;
|
2012-04-26 10:57:09 +00:00
|
|
|
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
|
|
|
|
cmd[1] = MTYPE_BOOT_FLASH;
|
|
|
|
} else if ( p->flags & AVRPART_HAS_PDI ) {
|
|
|
|
cmd[1] = MTYPE_FLASH;
|
|
|
|
} else {
|
|
|
|
cmd[1] = MTYPE_SPM;
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
serial_recv_timeout = 100;
|
2011-09-14 21:49:42 +00:00
|
|
|
for (; addr < maxaddr; addr += page_size) {
|
|
|
|
if ((maxaddr - addr) < page_size)
|
|
|
|
block_size = maxaddr - addr;
|
2005-05-10 19:53:56 +00:00
|
|
|
else
|
|
|
|
block_size = page_size;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_DEBUG, "%s: jtagmkII_paged_write(): "
|
2005-05-10 19:53:56 +00:00
|
|
|
"block_size at addr %d is %d\n",
|
|
|
|
progname, addr, block_size);
|
|
|
|
|
2012-03-30 16:19:13 +00:00
|
|
|
if (dynamic_memtype)
|
|
|
|
cmd[1] = jtagmkII_memtype(pgm, p, addr);
|
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
u32_to_b4(cmd + 2, page_size);
|
2012-04-13 15:25:41 +00:00
|
|
|
u32_to_b4(cmd + 6, jtagmkII_memaddr(pgm, p, m, addr));
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The JTAG ICE will refuse to write anything but a full page, at
|
|
|
|
* least for the flash ROM. If a partial page has been requested,
|
|
|
|
* set the remainder to 0xff. (Maybe we should rather read back
|
|
|
|
* the existing contents instead before? Doesn't matter much, as
|
|
|
|
* bits cannot be written to 1 anyway.)
|
|
|
|
*/
|
|
|
|
memset(cmd + 10, 0xff, page_size);
|
|
|
|
memcpy(cmd + 10, m->buf + addr, block_size);
|
|
|
|
|
|
|
|
tries = 0;
|
|
|
|
|
|
|
|
retry:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_paged_write(): "
|
2005-05-10 19:53:56 +00:00
|
|
|
"Sending write memory command: ",
|
|
|
|
progname);
|
|
|
|
jtagmkII_send(pgm, cmd, page_size + 10);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
2005-05-11 16:58:12 +00:00
|
|
|
if (tries++ < 4) {
|
|
|
|
serial_recv_timeout *= 2;
|
2005-05-10 19:53:56 +00:00
|
|
|
goto retry;
|
2005-05-11 16:58:12 +00:00
|
|
|
}
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write(): fatal timeout/"
|
2014-05-18 08:41:46 +00:00
|
|
|
"error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
2005-05-10 19:53:56 +00:00
|
|
|
free(cmd);
|
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2005-05-10 19:53:56 +00:00
|
|
|
if (resp[0] != RSP_OK) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"bad response to write memory command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(resp[0]));
|
2005-05-10 19:53:56 +00:00
|
|
|
free(resp);
|
|
|
|
free(cmd);
|
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
free(resp);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(cmd);
|
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
|
|
|
|
return n_bytes;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int jtagmkII_paged_load(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)
|
2005-05-10 19:53:56 +00:00
|
|
|
{
|
2011-09-14 21:49:42 +00:00
|
|
|
unsigned int block_size;
|
|
|
|
unsigned int maxaddr = addr + n_bytes;
|
2005-05-10 19:53:56 +00:00
|
|
|
unsigned char cmd[10];
|
|
|
|
unsigned char *resp;
|
2012-04-13 15:25:41 +00:00
|
|
|
int status, tries, dynamic_memtype = 0;
|
2005-05-10 19:53:56 +00:00
|
|
|
long otimeout = serial_recv_timeout;
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_paged_load(.., %s, %d, %d)\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname, m->desc, page_size, n_bytes);
|
|
|
|
|
2006-11-20 23:23:37 +00:00
|
|
|
if (!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0)
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
page_size = m->readsize;
|
|
|
|
|
|
|
|
cmd[0] = CMND_READ_MEMORY;
|
2012-04-13 15:25:41 +00:00
|
|
|
if (strcmp(m->desc, "flash") == 0) {
|
2012-04-26 11:01:19 +00:00
|
|
|
cmd[1] = jtagmkII_memtype(pgm, p, addr);
|
2012-04-13 15:25:41 +00:00
|
|
|
if (p->flags & AVRPART_HAS_PDI)
|
|
|
|
/* dynamically decide between flash/boot memtype */
|
|
|
|
dynamic_memtype = 1;
|
|
|
|
} else if (strcmp(m->desc, "eeprom") == 0) {
|
Contributed by Zoltan Laday:
patch #6825: xmega problems with JTAGICEmkII
* jtagmkII.c: Many fixes for Xmega devices.
* jtagmkII_private.h: Add various new constants required for
Xmega devices.
* avrdude.conf.in: New devices: ATXMEGA64A1, ATXMEGA192A1,
ATXMEGA256A1, ATXMEGA64A3, ATXMEGA128A3, ATXMEGA192A3,
ATXMEGA256A3, ATXMEGA256A3B, ATXMEGA16A4, ATXMEGA32A4,
ATXMEGA64A4, ATXMEGA128A4
* avr.c (avr_read, avr_write): Add more names for (Xmega)
memory areas that require paged operation.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@821 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-06-24 21:32:12 +00:00
|
|
|
cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
|
2006-11-20 23:23:37 +00:00
|
|
|
if (pgm->flag & PGM_FL_IS_DW)
|
|
|
|
return -1;
|
Contributed by Zoltan Laday:
patch #6825: xmega problems with JTAGICEmkII
* jtagmkII.c: Many fixes for Xmega devices.
* jtagmkII_private.h: Add various new constants required for
Xmega devices.
* avrdude.conf.in: New devices: ATXMEGA64A1, ATXMEGA192A1,
ATXMEGA256A1, ATXMEGA64A3, ATXMEGA128A3, ATXMEGA192A3,
ATXMEGA256A3, ATXMEGA256A3B, ATXMEGA16A4, ATXMEGA32A4,
ATXMEGA64A4, ATXMEGA128A4
* avr.c (avr_read, avr_write): Add more names for (Xmega)
memory areas that require paged operation.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@821 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-06-24 21:32:12 +00:00
|
|
|
} else if ( ( strcmp(m->desc, "prodsig") == 0 ) ) {
|
|
|
|
cmd[1] = MTYPE_PRODSIG;
|
|
|
|
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
|
|
|
|
cmd[1] = MTYPE_USERSIG;
|
2012-04-26 10:57:09 +00:00
|
|
|
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
|
|
|
|
cmd[1] = MTYPE_BOOT_FLASH;
|
|
|
|
} else if ( p->flags & AVRPART_HAS_PDI ) {
|
|
|
|
cmd[1] = MTYPE_FLASH;
|
|
|
|
} else {
|
|
|
|
cmd[1] = MTYPE_SPM;
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
serial_recv_timeout = 100;
|
2011-09-14 21:49:42 +00:00
|
|
|
for (; addr < maxaddr; addr += page_size) {
|
|
|
|
if ((maxaddr - addr) < page_size)
|
|
|
|
block_size = maxaddr - addr;
|
2005-05-10 19:53:56 +00:00
|
|
|
else
|
|
|
|
block_size = page_size;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_DEBUG, "%s: jtagmkII_paged_load(): "
|
2005-05-10 19:53:56 +00:00
|
|
|
"block_size at addr %d is %d\n",
|
|
|
|
progname, addr, block_size);
|
|
|
|
|
2012-04-13 15:25:41 +00:00
|
|
|
if (dynamic_memtype)
|
|
|
|
cmd[1] = jtagmkII_memtype(pgm, p, addr);
|
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
u32_to_b4(cmd + 2, block_size);
|
2012-04-13 15:25:41 +00:00
|
|
|
u32_to_b4(cmd + 6, jtagmkII_memaddr(pgm, p, m, addr));
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
tries = 0;
|
|
|
|
|
|
|
|
retry:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_paged_load(): Sending read memory command: ",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname);
|
|
|
|
jtagmkII_send(pgm, cmd, 10);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_load(): "
|
2014-05-18 08:41:46 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
2005-05-11 16:58:12 +00:00
|
|
|
if (tries++ < 4) {
|
|
|
|
serial_recv_timeout *= 2;
|
2005-05-10 19:53:56 +00:00
|
|
|
goto retry;
|
2005-05-11 16:58:12 +00:00
|
|
|
}
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_load(): fatal timeout/"
|
2014-05-18 08:41:46 +00:00
|
|
|
"error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
2005-05-10 19:53:56 +00:00
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2005-05-10 19:53:56 +00:00
|
|
|
if (resp[0] != RSP_MEMORY) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_load(): "
|
2006-09-07 19:57:59 +00:00
|
|
|
"bad response to read memory command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(resp[0]));
|
2005-05-10 19:53:56 +00:00
|
|
|
free(resp);
|
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
return -1;
|
|
|
|
}
|
Contributed by Zoltan Laday:
patch #6825: xmega problems with JTAGICEmkII
* jtagmkII.c: Many fixes for Xmega devices.
* jtagmkII_private.h: Add various new constants required for
Xmega devices.
* avrdude.conf.in: New devices: ATXMEGA64A1, ATXMEGA192A1,
ATXMEGA256A1, ATXMEGA64A3, ATXMEGA128A3, ATXMEGA192A3,
ATXMEGA256A3, ATXMEGA256A3B, ATXMEGA16A4, ATXMEGA32A4,
ATXMEGA64A4, ATXMEGA128A4
* avr.c (avr_read, avr_write): Add more names for (Xmega)
memory areas that require paged operation.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@821 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-06-24 21:32:12 +00:00
|
|
|
memcpy(m->buf + addr, resp + 1, status-1);
|
2005-05-10 19:53:56 +00:00
|
|
|
free(resp);
|
|
|
|
}
|
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
|
2005-09-16 15:52:28 +00:00
|
|
|
return n_bytes;
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|
|
|
unsigned long addr, unsigned char * value)
|
|
|
|
{
|
|
|
|
unsigned char cmd[10];
|
|
|
|
unsigned char *resp = NULL, *cache_ptr = NULL;
|
2006-11-20 23:23:37 +00:00
|
|
|
int status, tries, unsupp;
|
2005-05-10 19:53:56 +00:00
|
|
|
unsigned long paddr = 0UL, *paddr_ptr = NULL;
|
|
|
|
unsigned int pagesize = 0;
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_read_byte(.., %s, 0x%lx, ...)\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname, mem->desc, addr);
|
|
|
|
|
2006-11-20 23:23:37 +00:00
|
|
|
if (!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0)
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
cmd[0] = CMND_READ_MEMORY;
|
2006-11-20 23:23:37 +00:00
|
|
|
unsupp = 0;
|
2005-05-10 19:53:56 +00:00
|
|
|
|
Contributed by Zoltan Laday:
patch #6825: xmega problems with JTAGICEmkII
* jtagmkII.c: Many fixes for Xmega devices.
* jtagmkII_private.h: Add various new constants required for
Xmega devices.
* avrdude.conf.in: New devices: ATXMEGA64A1, ATXMEGA192A1,
ATXMEGA256A1, ATXMEGA64A3, ATXMEGA128A3, ATXMEGA192A3,
ATXMEGA256A3, ATXMEGA256A3B, ATXMEGA16A4, ATXMEGA32A4,
ATXMEGA64A4, ATXMEGA128A4
* avr.c (avr_read, avr_write): Add more names for (Xmega)
memory areas that require paged operation.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@821 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-06-24 21:32:12 +00:00
|
|
|
addr += mem->offset;
|
|
|
|
cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_FLASH_PAGE;
|
2012-05-04 10:02:30 +00:00
|
|
|
if (strcmp(mem->desc, "flash") == 0 ||
|
|
|
|
strcmp(mem->desc, "application") == 0 ||
|
|
|
|
strcmp(mem->desc, "apptable") == 0 ||
|
|
|
|
strcmp(mem->desc, "boot") == 0) {
|
|
|
|
pagesize = PDATA(pgm)->flash_pagesize;
|
2005-05-10 19:53:56 +00:00
|
|
|
paddr = addr & ~(pagesize - 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
|
|
|
paddr_ptr = &PDATA(pgm)->flash_pageaddr;
|
|
|
|
cache_ptr = PDATA(pgm)->flash_pagecache;
|
2005-05-10 19:53:56 +00:00
|
|
|
} else if (strcmp(mem->desc, "eeprom") == 0) {
|
Contributed by Zoltan Laday:
patch #6825: xmega problems with JTAGICEmkII
* jtagmkII.c: Many fixes for Xmega devices.
* jtagmkII_private.h: Add various new constants required for
Xmega devices.
* avrdude.conf.in: New devices: ATXMEGA64A1, ATXMEGA192A1,
ATXMEGA256A1, ATXMEGA64A3, ATXMEGA128A3, ATXMEGA192A3,
ATXMEGA256A3, ATXMEGA256A3B, ATXMEGA16A4, ATXMEGA32A4,
ATXMEGA64A4, ATXMEGA128A4
* avr.c (avr_read, avr_write): Add more names for (Xmega)
memory areas that require paged operation.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@821 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-06-24 21:32:12 +00:00
|
|
|
if ( (pgm->flag & PGM_FL_IS_DW) || ( p->flags & AVRPART_HAS_PDI ) ) {
|
2006-11-23 07:07:06 +00:00
|
|
|
/* debugWire cannot use page access for EEPROM */
|
|
|
|
cmd[1] = MTYPE_EEPROM;
|
|
|
|
} else {
|
|
|
|
cmd[1] = MTYPE_EEPROM_PAGE;
|
|
|
|
pagesize = mem->page_size;
|
|
|
|
paddr = addr & ~(pagesize - 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
|
|
|
paddr_ptr = &PDATA(pgm)->eeprom_pageaddr;
|
|
|
|
cache_ptr = PDATA(pgm)->eeprom_pagecache;
|
2006-11-23 07:07:06 +00:00
|
|
|
}
|
2005-05-10 19:53:56 +00:00
|
|
|
} else if (strcmp(mem->desc, "lfuse") == 0) {
|
|
|
|
cmd[1] = MTYPE_FUSE_BITS;
|
|
|
|
addr = 0;
|
2006-11-20 23:23:37 +00:00
|
|
|
if (pgm->flag & PGM_FL_IS_DW)
|
|
|
|
unsupp = 1;
|
2005-05-10 19:53:56 +00:00
|
|
|
} else if (strcmp(mem->desc, "hfuse") == 0) {
|
|
|
|
cmd[1] = MTYPE_FUSE_BITS;
|
|
|
|
addr = 1;
|
2006-11-20 23:23:37 +00:00
|
|
|
if (pgm->flag & PGM_FL_IS_DW)
|
|
|
|
unsupp = 1;
|
2005-05-10 19:53:56 +00:00
|
|
|
} else if (strcmp(mem->desc, "efuse") == 0) {
|
|
|
|
cmd[1] = MTYPE_FUSE_BITS;
|
|
|
|
addr = 2;
|
2006-11-20 23:23:37 +00:00
|
|
|
if (pgm->flag & PGM_FL_IS_DW)
|
|
|
|
unsupp = 1;
|
2014-10-15 20:01:12 +00:00
|
|
|
} else if (strncmp(mem->desc, "lock", 4) == 0) {
|
2005-05-10 19:53:56 +00:00
|
|
|
cmd[1] = MTYPE_LOCK_BITS;
|
2006-11-20 23:23:37 +00:00
|
|
|
if (pgm->flag & PGM_FL_IS_DW)
|
|
|
|
unsupp = 1;
|
Contributed by Zoltan Laday:
patch #6825: xmega problems with JTAGICEmkII
* jtagmkII.c: Many fixes for Xmega devices.
* jtagmkII_private.h: Add various new constants required for
Xmega devices.
* avrdude.conf.in: New devices: ATXMEGA64A1, ATXMEGA192A1,
ATXMEGA256A1, ATXMEGA64A3, ATXMEGA128A3, ATXMEGA192A3,
ATXMEGA256A3, ATXMEGA256A3B, ATXMEGA16A4, ATXMEGA32A4,
ATXMEGA64A4, ATXMEGA128A4
* avr.c (avr_read, avr_write): Add more names for (Xmega)
memory areas that require paged operation.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@821 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-06-24 21:32:12 +00:00
|
|
|
} else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
|
|
|
|
cmd[1] = MTYPE_FUSE_BITS;
|
|
|
|
} else if (strcmp(mem->desc, "usersig") == 0) {
|
|
|
|
cmd[1] = MTYPE_USERSIG;
|
|
|
|
} else if (strcmp(mem->desc, "prodsig") == 0) {
|
|
|
|
cmd[1] = MTYPE_PRODSIG;
|
2005-05-10 19:53:56 +00:00
|
|
|
} else if (strcmp(mem->desc, "calibration") == 0) {
|
|
|
|
cmd[1] = MTYPE_OSCCAL_BYTE;
|
2006-11-20 23:23:37 +00:00
|
|
|
if (pgm->flag & PGM_FL_IS_DW)
|
|
|
|
unsupp = 1;
|
2005-05-10 19:53:56 +00:00
|
|
|
} else if (strcmp(mem->desc, "signature") == 0) {
|
|
|
|
cmd[1] = MTYPE_SIGN_JTAG;
|
2006-11-20 23:23:37 +00:00
|
|
|
|
|
|
|
if (pgm->flag & PGM_FL_IS_DW) {
|
|
|
|
/*
|
|
|
|
* In debugWire mode, there is no accessible memory area to read
|
|
|
|
* the signature from, but the essential two bytes can be read
|
|
|
|
* as a parameter from the ICE.
|
|
|
|
*/
|
|
|
|
unsigned char parm[4];
|
|
|
|
|
|
|
|
switch (addr) {
|
|
|
|
case 0:
|
|
|
|
*value = 0x1E; /* Atmel vendor ID */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
if (jtagmkII_getparm(pgm, PAR_TARGET_SIGNATURE, parm) < 0)
|
|
|
|
return -1;
|
|
|
|
*value = parm[2 - addr];
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: illegal address %lu for signature memory\n",
|
2006-11-20 23:23:37 +00:00
|
|
|
progname, addr);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2009-02-27 08:29:30 +00:00
|
|
|
|
2006-11-20 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the respective memory area is not supported under debugWire,
|
|
|
|
* leave here.
|
|
|
|
*/
|
|
|
|
if (unsupp) {
|
|
|
|
*value = 42;
|
|
|
|
return -1;
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* To improve the read speed, we used paged reads for flash and
|
|
|
|
* EEPROM, and cache the results in a page cache.
|
|
|
|
*
|
|
|
|
* Page cache validation is based on "{flash,eeprom}_pageaddr"
|
|
|
|
* (holding the base address of the most recent cache fill
|
|
|
|
* operation). This variable is set to (unsigned long)-1L when the
|
|
|
|
* cache needs to be invalidated.
|
|
|
|
*/
|
|
|
|
if (pagesize && paddr == *paddr_ptr) {
|
|
|
|
*value = cache_ptr[addr & (pagesize - 1)];
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pagesize) {
|
|
|
|
u32_to_b4(cmd + 2, pagesize);
|
|
|
|
u32_to_b4(cmd + 6, paddr);
|
|
|
|
} else {
|
|
|
|
u32_to_b4(cmd + 2, 1);
|
|
|
|
u32_to_b4(cmd + 6, addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
tries = 0;
|
|
|
|
retry:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_read_byte(): Sending read memory command: ",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname);
|
|
|
|
jtagmkII_send(pgm, cmd, 10);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_read_byte(): "
|
2005-05-10 19:53:56 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
|
|
|
if (tries++ < 3)
|
|
|
|
goto retry;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_read_byte(): "
|
2005-05-10 19:53:56 +00:00
|
|
|
"fatal timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
2006-11-23 07:07:06 +00:00
|
|
|
if (status < 0)
|
|
|
|
resp = 0;
|
2005-05-10 19:53:56 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2005-05-10 19:53:56 +00:00
|
|
|
if (resp[0] != RSP_MEMORY) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_read_byte(): "
|
2006-09-07 19:57:59 +00:00
|
|
|
"bad response to read memory command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(resp[0]));
|
2005-05-10 19:53:56 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pagesize) {
|
|
|
|
*paddr_ptr = paddr;
|
|
|
|
memcpy(cache_ptr, resp + 1, pagesize);
|
|
|
|
*value = cache_ptr[addr & (pagesize - 1)];
|
|
|
|
} else
|
|
|
|
*value = resp[1];
|
|
|
|
|
|
|
|
free(resp);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
fail:
|
|
|
|
free(resp);
|
2006-11-21 16:13:08 +00:00
|
|
|
return -1;
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|
|
|
unsigned long addr, unsigned char data)
|
|
|
|
{
|
2013-09-08 19:57:58 +00:00
|
|
|
unsigned char cmd[12];
|
|
|
|
unsigned char *resp = NULL, writedata, writedata2 = 0xFF;
|
|
|
|
int status, tries, need_progmode = 1, unsupp = 0, writesize = 1;
|
2005-05-10 19:53:56 +00:00
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_write_byte(.., %s, 0x%lx, ...)\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname, mem->desc, addr);
|
|
|
|
|
Contributed by Zoltan Laday:
patch #6825: xmega problems with JTAGICEmkII
* jtagmkII.c: Many fixes for Xmega devices.
* jtagmkII_private.h: Add various new constants required for
Xmega devices.
* avrdude.conf.in: New devices: ATXMEGA64A1, ATXMEGA192A1,
ATXMEGA256A1, ATXMEGA64A3, ATXMEGA128A3, ATXMEGA192A3,
ATXMEGA256A3, ATXMEGA256A3B, ATXMEGA16A4, ATXMEGA32A4,
ATXMEGA64A4, ATXMEGA128A4
* avr.c (avr_read, avr_write): Add more names for (Xmega)
memory areas that require paged operation.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@821 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-06-24 21:32:12 +00:00
|
|
|
addr += mem->offset;
|
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
writedata = data;
|
|
|
|
cmd[0] = CMND_WRITE_MEMORY;
|
Contributed by Zoltan Laday:
patch #6825: xmega problems with JTAGICEmkII
* jtagmkII.c: Many fixes for Xmega devices.
* jtagmkII_private.h: Add various new constants required for
Xmega devices.
* avrdude.conf.in: New devices: ATXMEGA64A1, ATXMEGA192A1,
ATXMEGA256A1, ATXMEGA64A3, ATXMEGA128A3, ATXMEGA192A3,
ATXMEGA256A3, ATXMEGA256A3B, ATXMEGA16A4, ATXMEGA32A4,
ATXMEGA64A4, ATXMEGA128A4
* avr.c (avr_read, avr_write): Add more names for (Xmega)
memory areas that require paged operation.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@821 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-06-24 21:32:12 +00:00
|
|
|
cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_SPM;
|
2005-05-10 19:53:56 +00:00
|
|
|
if (strcmp(mem->desc, "flash") == 0) {
|
2013-09-08 19:57:58 +00:00
|
|
|
if ((addr & 1) == 1) {
|
|
|
|
/* odd address = high byte */
|
|
|
|
writedata = 0xFF; /* don't modify the low byte */
|
|
|
|
writedata2 = data;
|
|
|
|
addr &= ~1L;
|
|
|
|
}
|
|
|
|
writesize = 2;
|
Contributed by Zoltan Laday:
patch #6825: xmega problems with JTAGICEmkII
* jtagmkII.c: Many fixes for Xmega devices.
* jtagmkII_private.h: Add various new constants required for
Xmega devices.
* avrdude.conf.in: New devices: ATXMEGA64A1, ATXMEGA192A1,
ATXMEGA256A1, ATXMEGA64A3, ATXMEGA128A3, ATXMEGA192A3,
ATXMEGA256A3, ATXMEGA256A3B, ATXMEGA16A4, ATXMEGA32A4,
ATXMEGA64A4, ATXMEGA128A4
* avr.c (avr_read, avr_write): Add more names for (Xmega)
memory areas that require paged operation.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@821 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-06-24 21:32:12 +00:00
|
|
|
need_progmode = 0;
|
|
|
|
PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
|
|
|
|
if (pgm->flag & PGM_FL_IS_DW)
|
|
|
|
unsupp = 1;
|
2005-05-10 19:53:56 +00:00
|
|
|
} else if (strcmp(mem->desc, "eeprom") == 0) {
|
2013-09-08 19:57:58 +00:00
|
|
|
cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM_XMEGA: MTYPE_EEPROM;
|
2005-05-10 19:53:56 +00:00
|
|
|
need_progmode = 0;
|
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
|
|
|
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
|
2005-05-10 19:53:56 +00:00
|
|
|
} else if (strcmp(mem->desc, "lfuse") == 0) {
|
|
|
|
cmd[1] = MTYPE_FUSE_BITS;
|
|
|
|
addr = 0;
|
2006-11-23 07:07:06 +00:00
|
|
|
if (pgm->flag & PGM_FL_IS_DW)
|
|
|
|
unsupp = 1;
|
2005-05-10 19:53:56 +00:00
|
|
|
} else if (strcmp(mem->desc, "hfuse") == 0) {
|
|
|
|
cmd[1] = MTYPE_FUSE_BITS;
|
|
|
|
addr = 1;
|
2006-11-23 07:07:06 +00:00
|
|
|
if (pgm->flag & PGM_FL_IS_DW)
|
|
|
|
unsupp = 1;
|
2005-05-10 19:53:56 +00:00
|
|
|
} else if (strcmp(mem->desc, "efuse") == 0) {
|
|
|
|
cmd[1] = MTYPE_FUSE_BITS;
|
|
|
|
addr = 2;
|
2006-11-23 07:07:06 +00:00
|
|
|
if (pgm->flag & PGM_FL_IS_DW)
|
|
|
|
unsupp = 1;
|
Contributed by Zoltan Laday:
patch #6825: xmega problems with JTAGICEmkII
* jtagmkII.c: Many fixes for Xmega devices.
* jtagmkII_private.h: Add various new constants required for
Xmega devices.
* avrdude.conf.in: New devices: ATXMEGA64A1, ATXMEGA192A1,
ATXMEGA256A1, ATXMEGA64A3, ATXMEGA128A3, ATXMEGA192A3,
ATXMEGA256A3, ATXMEGA256A3B, ATXMEGA16A4, ATXMEGA32A4,
ATXMEGA64A4, ATXMEGA128A4
* avr.c (avr_read, avr_write): Add more names for (Xmega)
memory areas that require paged operation.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@821 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-06-24 21:32:12 +00:00
|
|
|
} else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
|
|
|
|
cmd[1] = MTYPE_FUSE_BITS;
|
|
|
|
} else if (strcmp(mem->desc, "usersig") == 0) {
|
|
|
|
cmd[1] = MTYPE_USERSIG;
|
|
|
|
} else if (strcmp(mem->desc, "prodsig") == 0) {
|
|
|
|
cmd[1] = MTYPE_PRODSIG;
|
2014-10-15 20:01:12 +00:00
|
|
|
} else if (strncmp(mem->desc, "lock", 4) == 0) {
|
2005-05-10 19:53:56 +00:00
|
|
|
cmd[1] = MTYPE_LOCK_BITS;
|
2006-11-23 07:07:06 +00:00
|
|
|
if (pgm->flag & PGM_FL_IS_DW)
|
|
|
|
unsupp = 1;
|
2005-05-10 19:53:56 +00:00
|
|
|
} else if (strcmp(mem->desc, "calibration") == 0) {
|
|
|
|
cmd[1] = MTYPE_OSCCAL_BYTE;
|
2006-11-23 07:07:06 +00:00
|
|
|
if (pgm->flag & PGM_FL_IS_DW)
|
|
|
|
unsupp = 1;
|
2005-05-10 19:53:56 +00:00
|
|
|
} else if (strcmp(mem->desc, "signature") == 0) {
|
|
|
|
cmd[1] = MTYPE_SIGN_JTAG;
|
2006-11-23 07:07:06 +00:00
|
|
|
if (pgm->flag & PGM_FL_IS_DW)
|
|
|
|
unsupp = 1;
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
2006-11-23 07:07:06 +00:00
|
|
|
if (unsupp)
|
|
|
|
return -1;
|
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
if (need_progmode) {
|
|
|
|
if (jtagmkII_program_enable(pgm) < 0)
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
if (jtagmkII_program_disable(pgm) < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-09-08 19:57:58 +00:00
|
|
|
u32_to_b4(cmd + 2, writesize);
|
2005-05-10 19:53:56 +00:00
|
|
|
u32_to_b4(cmd + 6, addr);
|
|
|
|
cmd[10] = writedata;
|
2013-09-08 19:57:58 +00:00
|
|
|
cmd[11] = writedata2;
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
tries = 0;
|
|
|
|
retry:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_write_byte(): Sending write memory command: ",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname);
|
2013-09-08 19:57:58 +00:00
|
|
|
jtagmkII_send(pgm, cmd, 10 + writesize);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_write_byte(): "
|
2005-05-10 19:53:56 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
|
|
|
if (tries++ < 3)
|
|
|
|
goto retry;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_write_byte(): "
|
2005-05-10 19:53:56 +00:00
|
|
|
"fatal timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2005-05-10 19:53:56 +00:00
|
|
|
if (resp[0] != RSP_OK) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_write_byte(): "
|
2006-09-07 19:57:59 +00:00
|
|
|
"bad response to write memory command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(resp[0]));
|
2005-05-10 19:53:56 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(resp);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
fail:
|
|
|
|
free(resp);
|
2006-11-21 16:13:08 +00:00
|
|
|
return -1;
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set the JTAG clock. The actual frequency is quite a bit of
|
|
|
|
* guesswork, based on the values claimed by AVR Studio. Inside the
|
|
|
|
* JTAG ICE, the value is the delay count of a delay loop between the
|
|
|
|
* JTAG clock edges. A count of 0 bypasses the delay loop.
|
|
|
|
*
|
|
|
|
* As the STK500 expresses it as a period length (and we actualy do
|
|
|
|
* program a period length as well), we rather call it by that name.
|
|
|
|
*/
|
|
|
|
static int jtagmkII_set_sck_period(PROGRAMMER * pgm, double v)
|
|
|
|
{
|
|
|
|
unsigned char dur;
|
|
|
|
|
|
|
|
v = 1 / v; /* convert to frequency */
|
|
|
|
if (v >= 6.4e6)
|
|
|
|
dur = 0;
|
|
|
|
else if (v >= 2.8e6)
|
|
|
|
dur = 1;
|
|
|
|
else if (v >= 20.9e3)
|
|
|
|
dur = (unsigned char)(5.35e6 / v);
|
|
|
|
else
|
|
|
|
dur = 255;
|
|
|
|
|
|
|
|
return jtagmkII_setparm(pgm, PAR_OCD_JTAG_CLK, &dur);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Read an emulator parameter. As the maximal parameter length is 4
|
|
|
|
* bytes by now, we always copy out 4 bytes to *value, so the caller
|
|
|
|
* must have allocated sufficient space.
|
|
|
|
*/
|
2006-09-06 20:06:07 +00:00
|
|
|
int jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm,
|
|
|
|
unsigned char * value)
|
2005-05-10 19:53:56 +00:00
|
|
|
{
|
|
|
|
int status;
|
|
|
|
unsigned char buf[2], *resp, c;
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_getparm()\n", progname);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
buf[0] = CMND_GET_PARAMETER;
|
|
|
|
buf[1] = parm;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_getparm(): "
|
2005-05-10 19:53:56 +00:00
|
|
|
"Sending get parameter command (parm 0x%02x): ",
|
|
|
|
progname, parm);
|
|
|
|
jtagmkII_send(pgm, buf, 2);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_getparm(): "
|
2005-05-10 19:53:56 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2005-05-10 19:53:56 +00:00
|
|
|
c = resp[0];
|
|
|
|
if (c != RSP_PARAMETER) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_getparm(): "
|
2006-09-07 19:57:59 +00:00
|
|
|
"bad response to get parameter command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(c));
|
2005-05-10 19:53:56 +00:00
|
|
|
free(resp);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(value, resp + 1, 4);
|
|
|
|
free(resp);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Write an emulator parameter.
|
|
|
|
*/
|
|
|
|
static int jtagmkII_setparm(PROGRAMMER * pgm, unsigned char parm,
|
|
|
|
unsigned char * value)
|
|
|
|
{
|
|
|
|
int status;
|
|
|
|
/*
|
|
|
|
* As the maximal parameter length is 4 bytes, we use a fixed-length
|
|
|
|
* buffer, as opposed to malloc()ing it.
|
|
|
|
*/
|
|
|
|
unsigned char buf[2 + 4], *resp, c;
|
|
|
|
size_t size;
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_setparm()\n", progname);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
switch (parm) {
|
|
|
|
case PAR_HW_VERSION: size = 2; break;
|
|
|
|
case PAR_FW_VERSION: size = 4; break;
|
|
|
|
case PAR_EMULATOR_MODE: size = 1; break;
|
|
|
|
case PAR_BAUD_RATE: size = 1; break;
|
|
|
|
case PAR_OCD_VTARGET: size = 2; break;
|
|
|
|
case PAR_OCD_JTAG_CLK: size = 1; break;
|
2006-11-20 23:23:37 +00:00
|
|
|
case PAR_TIMERS_RUNNING: size = 1; break;
|
2010-01-17 17:31:10 +00:00
|
|
|
case PAR_EXTERNAL_RESET: size = 1; break;
|
2007-11-06 19:42:16 +00:00
|
|
|
case PAR_DAISY_CHAIN_INFO: size = 4; break;
|
Contributed by Zoltan Laday:
patch #6825: xmega problems with JTAGICEmkII
* jtagmkII.c: Many fixes for Xmega devices.
* jtagmkII_private.h: Add various new constants required for
Xmega devices.
* avrdude.conf.in: New devices: ATXMEGA64A1, ATXMEGA192A1,
ATXMEGA256A1, ATXMEGA64A3, ATXMEGA128A3, ATXMEGA192A3,
ATXMEGA256A3, ATXMEGA256A3B, ATXMEGA16A4, ATXMEGA32A4,
ATXMEGA64A4, ATXMEGA128A4
* avr.c (avr_read, avr_write): Add more names for (Xmega)
memory areas that require paged operation.
git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@821 81a1dc3b-b13d-400b-aceb-764788c761c2
2009-06-24 21:32:12 +00:00
|
|
|
case PAR_PDI_OFFSET_START:
|
|
|
|
case PAR_PDI_OFFSET_END: size = 4; break;
|
2005-05-10 19:53:56 +00:00
|
|
|
default:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_setparm(): unknown parameter 0x%02x\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
progname, parm);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
buf[0] = CMND_SET_PARAMETER;
|
|
|
|
buf[1] = parm;
|
|
|
|
memcpy(buf + 2, value, size);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_setparm(): "
|
2010-01-14 13:46:02 +00:00
|
|
|
"Sending set parameter command (parm 0x%02x, %u bytes): ",
|
|
|
|
progname, parm, (unsigned)size);
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_send(pgm, buf, size + 2);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_setparm(): "
|
2005-05-10 19:53:56 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2005-05-10 19:53:56 +00:00
|
|
|
c = resp[0];
|
|
|
|
free(resp);
|
|
|
|
if (c != RSP_OK) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_setparm(): "
|
2006-09-07 19:57:59 +00:00
|
|
|
"bad response to set parameter command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(c));
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-01-30 13:41:54 +00:00
|
|
|
static void jtagmkII_display(PROGRAMMER * pgm, const char * p)
|
2005-05-10 19:53:56 +00:00
|
|
|
{
|
|
|
|
unsigned char hw[4], fw[4];
|
|
|
|
|
|
|
|
if (jtagmkII_getparm(pgm, PAR_HW_VERSION, hw) < 0 ||
|
|
|
|
jtagmkII_getparm(pgm, PAR_FW_VERSION, fw) < 0)
|
|
|
|
return;
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%sM_MCU hardware version: %d\n", p, hw[0]);
|
|
|
|
avrdude_message(MSG_INFO, "%sM_MCU firmware version: %d.%02d\n", p, fw[1], fw[0]);
|
|
|
|
avrdude_message(MSG_INFO, "%sS_MCU hardware version: %d\n", p, hw[1]);
|
|
|
|
avrdude_message(MSG_INFO, "%sS_MCU firmware version: %d.%02d\n", p, fw[3], fw[2]);
|
|
|
|
avrdude_message(MSG_INFO, "%sSerial number: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
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
|
|
|
p, PDATA(pgm)->serno[0], PDATA(pgm)->serno[1], PDATA(pgm)->serno[2], PDATA(pgm)->serno[3], PDATA(pgm)->serno[4], PDATA(pgm)->serno[5]);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
jtagmkII_print_parms1(pgm, p);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-07-25 21:14:43 +00:00
|
|
|
static void jtagmkII_print_parms1(PROGRAMMER * pgm, const char * p)
|
2005-05-10 19:53:56 +00:00
|
|
|
{
|
|
|
|
unsigned char vtarget[4], jtag_clock[4];
|
|
|
|
char clkbuf[20];
|
|
|
|
double clk;
|
|
|
|
|
2006-11-20 23:23:37 +00:00
|
|
|
if (jtagmkII_getparm(pgm, PAR_OCD_VTARGET, vtarget) < 0)
|
2005-05-10 19:53:56 +00:00
|
|
|
return;
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%sVtarget : %.1f V\n", p,
|
2005-05-10 19:53:56 +00:00
|
|
|
b2_to_u16(vtarget) / 1000.0);
|
2006-11-20 23:23:37 +00:00
|
|
|
|
2010-01-13 17:34:18 +00:00
|
|
|
if ((pgm->flag & PGM_FL_IS_JTAG)) {
|
2006-11-20 23:23:37 +00:00
|
|
|
if (jtagmkII_getparm(pgm, PAR_OCD_JTAG_CLK, jtag_clock) < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (jtag_clock[0] == 0) {
|
|
|
|
strcpy(clkbuf, "6.4 MHz");
|
|
|
|
clk = 6.4e6;
|
|
|
|
} else if (jtag_clock[0] == 1) {
|
|
|
|
strcpy(clkbuf, "2.8 MHz");
|
|
|
|
clk = 2.8e6;
|
|
|
|
} else if (jtag_clock[0] <= 5) {
|
|
|
|
sprintf(clkbuf, "%.1f MHz", 5.35 / (double)jtag_clock[0]);
|
|
|
|
clk = 5.35e6 / (double)jtag_clock[0];
|
|
|
|
} else {
|
|
|
|
sprintf(clkbuf, "%.1f kHz", 5.35e3 / (double)jtag_clock[0]);
|
|
|
|
clk = 5.35e6 / (double)jtag_clock[0];
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%sJTAG clock : %s (%.1f us)\n", p, clkbuf,
|
2006-11-20 23:23:37 +00:00
|
|
|
1.0e6 / clk);
|
|
|
|
}
|
|
|
|
}
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void jtagmkII_print_parms(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
jtagmkII_print_parms1(pgm, "");
|
|
|
|
}
|
|
|
|
|
2012-03-30 16:19:13 +00:00
|
|
|
static unsigned char jtagmkII_memtype(PROGRAMMER * pgm, AVRPART * p, unsigned long addr)
|
|
|
|
{
|
|
|
|
if ( p->flags & AVRPART_HAS_PDI ) {
|
|
|
|
if (addr >= PDATA(pgm)->boot_start)
|
|
|
|
return MTYPE_BOOT_FLASH;
|
|
|
|
else
|
|
|
|
return MTYPE_FLASH;
|
|
|
|
} else {
|
2012-07-25 14:56:39 +00:00
|
|
|
return MTYPE_FLASH_PAGE;
|
2012-03-30 16:19:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-13 15:25:41 +00:00
|
|
|
static unsigned int jtagmkII_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Xmega devices handled by V7+ firmware don't want to be told their
|
|
|
|
* m->offset within the write memory command.
|
|
|
|
*/
|
|
|
|
if (PDATA(pgm)->fwver >= 0x700 && (p->flags & AVRPART_HAS_PDI) != 0) {
|
|
|
|
if (addr >= PDATA(pgm)->boot_start)
|
|
|
|
/*
|
|
|
|
* all memories but "flash" are smaller than boot_start anyway, so
|
|
|
|
* no need for an extra check we are operating on "flash"
|
|
|
|
*/
|
|
|
|
return addr - PDATA(pgm)->boot_start;
|
|
|
|
else
|
|
|
|
/* normal flash, or anything else */
|
|
|
|
return addr;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Old firmware, or non-Xmega device. Non-Xmega (and non-AVR32)
|
|
|
|
* devices always have an m->offset of 0, so we don't have to
|
|
|
|
* distinguish them here.
|
|
|
|
*/
|
|
|
|
return addr + m->offset;
|
|
|
|
}
|
|
|
|
|
2012-03-30 16:19:13 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
#ifdef __OBJC__
|
|
|
|
#pragma mark -
|
|
|
|
#endif
|
2005-05-10 19:53:56 +00:00
|
|
|
|
2010-01-13 08:37:57 +00:00
|
|
|
static int jtagmkII_avr32_reset(PROGRAMMER * pgm, unsigned char val,
|
|
|
|
unsigned char ret1, unsigned char ret2)
|
2009-10-10 20:09:53 +00:00
|
|
|
{
|
|
|
|
int status;
|
|
|
|
unsigned char buf[3], *resp;
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE, "%s: jtagmkII_avr32_reset(%2.2x)\n",
|
2009-10-12 16:44:30 +00:00
|
|
|
progname, val);
|
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
buf[0] = CMND_GET_IR;
|
|
|
|
buf[1] = 0x0C;
|
|
|
|
status = jtagmkII_send(pgm, buf, 2);
|
|
|
|
if(status < 0) return -1;
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status != 2 || resp[0] != 0x87 || resp[1] != ret1) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE, "%s: jtagmkII_avr32_reset(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"Get_IR, expecting %2.2x but got %2.2x\n",
|
|
|
|
progname, ret1, resp[1]);
|
|
|
|
|
|
|
|
//return -1;
|
|
|
|
}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
buf[0] = CMND_GET_xxx;
|
|
|
|
buf[1] = 5;
|
|
|
|
buf[2] = val;
|
|
|
|
status = jtagmkII_send(pgm, buf, 3);
|
|
|
|
if(status < 0) return -1;
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status != 2 || resp[0] != 0x87 || resp[1] != ret2) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE, "%s: jtagmkII_avr32_reset(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"Get_XXX, expecting %2.2x but got %2.2x\n",
|
|
|
|
progname, ret2, resp[1]);
|
|
|
|
//return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// At init: AVR32_RESET_READ_IR | AVR32_RESET_READ_READ_CHIPINFO
|
|
|
|
static int jtagmkII_reset32(PROGRAMMER * pgm, unsigned short flags)
|
|
|
|
{
|
|
|
|
int status, j, lineno;
|
|
|
|
unsigned char *resp, buf[3];
|
|
|
|
unsigned long val=0;
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE, "%s: jtagmkII_reset32(%2.2x)\n",
|
2009-10-12 16:44:30 +00:00
|
|
|
progname, flags);
|
|
|
|
|
2010-01-07 13:13:02 +00:00
|
|
|
status = -1;
|
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
// Happens at the start of a programming operation
|
2009-10-12 16:44:30 +00:00
|
|
|
if(flags & AVR32_RESET_READ) {
|
2009-10-10 20:09:53 +00:00
|
|
|
buf[0] = CMND_GET_IR;
|
|
|
|
buf[1] = 0x11;
|
|
|
|
status = jtagmkII_send(pgm, buf, 2);
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status != 2 || resp[0] != 0x87 || resp[1] != 01)
|
|
|
|
{lineno = __LINE__; goto eRR;};
|
|
|
|
}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
if(flags & (AVR32_RESET_WRITE | AVR32_SET4RUNNING)) {
|
|
|
|
// AVR_RESET(0x1F)
|
|
|
|
status = jtagmkII_avr32_reset(pgm, 0x1F, 0x01, 0x00);
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
// AVR_RESET(0x07)
|
|
|
|
status = jtagmkII_avr32_reset(pgm, 0x07, 0x11, 0x1F);
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
2009-10-10 20:09:53 +00:00
|
|
|
}
|
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
//if(flags & AVR32_RESET_COMMON)
|
|
|
|
{
|
2009-10-10 20:09:53 +00:00
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
|
2009-10-12 16:44:30 +00:00
|
|
|
if(val != 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DC, 0x01);
|
|
|
|
if(val != 0) {lineno = __LINE__; goto eRR;}
|
2009-10-10 20:09:53 +00:00
|
|
|
}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
if(flags & (AVR32_RESET_READ | AVR32_RESET_CHIP_ERASE)) {
|
2010-01-13 08:37:57 +00:00
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DC, 0x01,
|
|
|
|
AVR32_DC_DBE | AVR32_DC_DBR);
|
2009-10-12 16:44:30 +00:00
|
|
|
if(status < 0) return -1;
|
|
|
|
}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
if(flags & (AVR32_RESET_WRITE | AVR32_SET4RUNNING)) {
|
2010-01-13 08:37:57 +00:00
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DC, 0x01,
|
|
|
|
AVR32_DC_ABORT | AVR32_DC_RESET | AVR32_DC_DBE | AVR32_DC_DBR);
|
2009-10-12 16:44:30 +00:00
|
|
|
if(status < 0) return -1;
|
|
|
|
for(j=0; j<21; ++j) {
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
|
|
|
|
}
|
|
|
|
if(val != 0x04000000) {lineno = __LINE__; goto eRR;}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
// AVR_RESET(0x00)
|
|
|
|
status = jtagmkII_avr32_reset(pgm, 0x00, 0x01, 0x07);
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
}
|
|
|
|
// if(flags & (AVR32_RESET_READ | AVR32_RESET_WRITE))
|
|
|
|
{
|
|
|
|
for(j=0; j<2; ++j) {
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
|
|
|
|
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
|
|
|
|
if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;}
|
|
|
|
}
|
|
|
|
}
|
2009-10-10 20:09:53 +00:00
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
//if(flags & (AVR32_RESET_READ | AVR32_RESET_WRITE | AVR32_RESET_CHIP_ERASE))
|
|
|
|
{
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
2009-10-10 20:09:53 +00:00
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
|
|
|
|
if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
|
|
|
|
if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
|
|
|
|
}
|
2009-10-10 20:09:53 +00:00
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
// Read chip configuration - common for all
|
|
|
|
if(flags & (AVR32_RESET_READ | AVR32_RESET_WRITE | AVR32_RESET_CHIP_ERASE)) {
|
2009-10-10 20:09:53 +00:00
|
|
|
for(j=0; j<2; ++j) {
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
|
|
|
|
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
|
|
|
|
if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;}
|
|
|
|
}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
|
|
|
|
if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
|
|
|
|
if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00040); // mfsr R0, 256
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
|
|
|
|
if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
|
|
|
|
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DCEMU, 0x01, 0x00000000);
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045); // mtdr R0, 276
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
|
|
|
|
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
|
|
|
|
if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
|
|
|
|
if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
|
|
|
|
if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00041); // mfsr R0, 260
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
|
|
|
|
if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
|
|
|
|
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DCEMU, 0x01, 0x00000000);
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045); // mtdr R0, 276
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
val = jtagmkII_read_SABaddr(pgm, 0x00000010, 0x06); // need to recheck who does this...
|
2009-10-10 20:09:53 +00:00
|
|
|
if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
|
|
|
|
}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
if(flags & AVR32_RESET_CHIP_ERASE) {
|
|
|
|
status = jtagmkII_avr32_reset(pgm, 0x1f, 0x01, 0x00);
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_avr32_reset(pgm, 0x01, 0x11, 0x1f);
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
}
|
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
if(flags & AVR32_SET4RUNNING) {
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00014); // mfsr R0, 80
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
|
|
|
|
if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
|
|
|
|
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DCEMU, 0x01, 0x00000000);
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045); // mfdr R0, 276
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
|
|
|
|
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
|
|
|
|
if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xd623d703); // retd
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
return 0;
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
eRR:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_reset32(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"failed at line %d (status=%x val=%lx)\n",
|
|
|
|
progname, lineno, status, val);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int jtagmkII_smc_init32(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
int status, lineno;
|
|
|
|
unsigned long val;
|
|
|
|
|
|
|
|
// HMATRIX 0xFFFF1000
|
2010-01-13 08:37:57 +00:00
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x04000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x04000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x04000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x04000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x04000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x08000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x08000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x08000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x08000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x08000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x10000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x10000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x10000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x10000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x10000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x00020000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x00020000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x00020000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x00020000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x00020000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x02000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x02000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x02000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x02000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x02000000);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xfffe1c00, 0x05, 0x00010001);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xfffe1c04, 0x05, 0x05070a0b);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xfffe1c08, 0x05, 0x000b000c);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xfffe1c0c, 0x05, 0x00031103);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
// switchToClockSource
|
2010-01-13 08:37:57 +00:00
|
|
|
val = jtagmkII_read_SABaddr(pgm, 0xffff0c28, 0x05);
|
|
|
|
if (val != 0x00000000) {lineno = __LINE__; goto eRR;} // OSC 0
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff0c28, 0x05, 0x0000607);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, 0xffff0c00, 0x05);
|
|
|
|
if (val != 0x00000000) {lineno = __LINE__; goto eRR;} // PLL 0
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff0c00, 0x05, 0x0000004);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;} // Power Manager
|
|
|
|
status = jtagmkII_write_SABaddr(pgm, 0xffff0c00, 0x05, 0x0000005);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
2009-10-10 20:09:53 +00:00
|
|
|
|
2010-01-01 08:55:33 +00:00
|
|
|
usleep(1000000);
|
2010-01-13 08:37:57 +00:00
|
|
|
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, 0xfffe1408, 0x05);
|
|
|
|
if (val != 0x0000a001) {lineno = __LINE__; goto eRR;} // PLL 0
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
// need a small delay to let clock stabliize
|
2010-01-13 08:37:57 +00:00
|
|
|
usleep(50*1000);
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
return 0;
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
eRR:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_smc_init32(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"failed at line %d\n",
|
|
|
|
progname, lineno);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* initialize the AVR device and prepare it to accept commands
|
|
|
|
*/
|
|
|
|
static int jtagmkII_initialize32(PROGRAMMER * pgm, AVRPART * p)
|
|
|
|
{
|
2009-10-12 16:44:30 +00:00
|
|
|
int status, j;
|
2009-10-10 20:09:53 +00:00
|
|
|
unsigned char buf[6], *resp;
|
|
|
|
|
|
|
|
if (jtagmkII_setparm(pgm, PAR_DAISY_CHAIN_INFO, PDATA(pgm)->jtagchain) < 0) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Failed to setup JTAG chain\n",
|
2009-10-10 20:09:53 +00:00
|
|
|
progname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(PDATA(pgm)->flash_pagecache);
|
|
|
|
free(PDATA(pgm)->eeprom_pagecache);
|
|
|
|
if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Out of memory\n",
|
2009-10-10 20:09:53 +00:00
|
|
|
progname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize32(): Out of memory\n",
|
2009-10-10 20:09:53 +00:00
|
|
|
progname);
|
|
|
|
free(PDATA(pgm)->flash_pagecache);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
|
|
|
|
|
|
|
|
for(j=0; j<2; ++j) {
|
|
|
|
buf[0] = CMND_GET_IR;
|
|
|
|
buf[1] = 0x1;
|
|
|
|
if(jtagmkII_send(pgm, buf, 2) < 0)
|
|
|
|
return -1;
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if(status <= 0 || resp[0] != 0x87) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize32(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
free(resp);
|
|
|
|
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
buf[0] = CMND_GET_xxx;
|
|
|
|
buf[1] = 0x20;
|
|
|
|
if(jtagmkII_send(pgm, buf, 6) < 0)
|
|
|
|
return -1;
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if(status <= 0 || resp[0] != 0x87) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_initialize32(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status != 5 ||
|
|
|
|
resp[2] != p->signature[0] ||
|
|
|
|
resp[3] != p->signature[1] ||
|
|
|
|
resp[4] != p->signature[2]) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: Expected signature for %s is %02X %02X %02X\n",
|
2009-10-10 20:09:53 +00:00
|
|
|
progname, p->desc,
|
|
|
|
p->signature[0], p->signature[1], p->signature[2]);
|
|
|
|
if (!ovsigck) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%sDouble check chip, "
|
2009-10-10 20:09:53 +00:00
|
|
|
"or use -F to override this check.\n",
|
|
|
|
progbuf);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(resp);
|
|
|
|
}
|
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
return 0;
|
2009-10-10 20:09:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int jtagmkII_chip_erase32(PROGRAMMER * pgm, AVRPART * p)
|
|
|
|
{
|
2009-10-12 16:44:30 +00:00
|
|
|
int status=0, loops;
|
|
|
|
unsigned char *resp, buf[3], x, ret[4], *retP;
|
2009-10-12 22:33:49 +00:00
|
|
|
unsigned long val=0;
|
2009-10-10 20:09:53 +00:00
|
|
|
unsigned int lineno;
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE, "%s: jtagmkII_chip_erase32()\n",
|
2009-10-12 16:44:30 +00:00
|
|
|
progname);
|
2009-10-10 20:09:53 +00:00
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
status = jtagmkII_reset32(pgm, AVR32_RESET_CHIP_ERASE);
|
2009-10-12 22:33:49 +00:00
|
|
|
if(status != 0) {lineno = __LINE__; goto eRR;}
|
2009-10-10 20:09:53 +00:00
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
// sequence of IR transitions
|
|
|
|
ret[0] = 0x01;
|
|
|
|
ret[1] = 0x05;
|
|
|
|
ret[2] = 0x01;
|
|
|
|
ret[3] = 0x00;
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
retP = ret;
|
|
|
|
for(loops=0; loops<1000; ++loops) {
|
2009-10-10 20:09:53 +00:00
|
|
|
buf[0] = CMND_GET_IR;
|
|
|
|
buf[1] = 0x0F;
|
|
|
|
status = jtagmkII_send(pgm, buf, 2);
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status != 2 || resp[0] != 0x87) {
|
|
|
|
{lineno = __LINE__; goto eRR;}
|
|
|
|
}
|
|
|
|
x = resp[1];
|
|
|
|
free(resp);
|
2009-10-12 16:44:30 +00:00
|
|
|
if(x == *retP) ++retP;
|
|
|
|
if(*retP == 0x00) break;
|
2009-10-10 20:09:53 +00:00
|
|
|
}
|
2009-10-12 16:44:30 +00:00
|
|
|
if(loops == 1000) {lineno = __LINE__; goto eRR;}
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
status = jtagmkII_avr32_reset(pgm, 0x00, 0x01, 0x01);
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, 0x00000010, 0x06);
|
|
|
|
if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
// AVR32 "special"
|
2010-01-13 08:37:57 +00:00
|
|
|
buf[0] = CMND_SET_PARAMETER;
|
2009-10-10 20:09:53 +00:00
|
|
|
buf[1] = 0x03;
|
|
|
|
buf[2] = 0x02;
|
|
|
|
jtagmkII_send(pgm, buf, 3);
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if(status < 0 || resp[0] != RSP_OK) {lineno = __LINE__; goto eRR;}
|
|
|
|
free(resp);
|
|
|
|
|
|
|
|
return 0;
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
eRR:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_reset32(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"failed at line %d (status=%x val=%lx)\n",
|
|
|
|
progname, lineno, status, val);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2010-01-13 08:37:57 +00:00
|
|
|
static unsigned long jtagmkII_read_SABaddr(PROGRAMMER * pgm, unsigned long addr,
|
|
|
|
unsigned int prefix)
|
2009-10-10 20:09:53 +00:00
|
|
|
{
|
|
|
|
unsigned char buf[6], *resp;
|
|
|
|
int status;
|
|
|
|
unsigned long val;
|
|
|
|
unsigned long otimeout = serial_recv_timeout;
|
|
|
|
|
|
|
|
serial_recv_timeout = 256;
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
buf[0] = CMND_READ_SAB;
|
|
|
|
buf[1] = prefix;
|
|
|
|
u32_to_b4r(&buf[2], addr);
|
|
|
|
|
|
|
|
if(jtagmkII_send(pgm, buf, 6) < 0)
|
|
|
|
return ERROR_SAB;
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if(status <= 0 || resp[0] != 0x87) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_read_SABaddr(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"timeout/error communicating with programmer (status %d) resp=%x\n",
|
|
|
|
progname, status, resp[0]);
|
|
|
|
serial_recv_timeout = otimeout;
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
if(status > 0) {
|
|
|
|
int i;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "Cmd: ");
|
|
|
|
for(i=0; i<6; ++i) avrdude_message(MSG_INFO, "%2.2x ", buf[i]);
|
|
|
|
avrdude_message(MSG_INFO, "\n");
|
|
|
|
avrdude_message(MSG_INFO, "Data: ");
|
|
|
|
for(i=0; i<status; ++i) avrdude_message(MSG_INFO, "%2.2x ", resp[i]);
|
|
|
|
avrdude_message(MSG_INFO, "\n");
|
2009-10-10 20:09:53 +00:00
|
|
|
}
|
|
|
|
return ERROR_SAB;
|
|
|
|
}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
if(status != 5) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_read_SABaddr(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"wrong number of bytes (status %d)\n",
|
|
|
|
progname, status);
|
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
return ERROR_SAB;
|
|
|
|
}
|
|
|
|
|
|
|
|
val = b4_to_u32r(&resp[1]);
|
|
|
|
free(resp);
|
|
|
|
|
|
|
|
if (verbose) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_read_SABaddr(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"OCD Register %lx -> %4.4lx\n",
|
|
|
|
progname, addr, val);
|
|
|
|
}
|
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2010-01-13 08:37:57 +00:00
|
|
|
static int jtagmkII_write_SABaddr(PROGRAMMER * pgm, unsigned long addr,
|
|
|
|
unsigned int prefix, unsigned long val)
|
2009-10-10 20:09:53 +00:00
|
|
|
{
|
|
|
|
unsigned char buf[10], *resp;
|
|
|
|
int status;
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
buf[0] = CMND_WRITE_SAB;
|
|
|
|
buf[1] = prefix;
|
|
|
|
u32_to_b4r(&buf[2], addr);
|
|
|
|
u32_to_b4r(&buf[6], val);
|
|
|
|
|
|
|
|
if(jtagmkII_send(pgm, buf, 10) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if(status <= 0 || resp[0] != RSP_OK) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_write_SABaddr(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
|
|
|
return -1;
|
|
|
|
}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
if (verbose) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_write_SABaddr(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"OCD Register %lx -> %4.4lx\n",
|
|
|
|
progname, addr, val);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int jtagmkII_open32(PROGRAMMER * pgm, char * port)
|
|
|
|
{
|
|
|
|
int status;
|
|
|
|
unsigned char buf[6], *resp;
|
2014-02-21 13:44:11 +00:00
|
|
|
union pinfo pinfo;
|
2009-10-10 20:09:53 +00:00
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_open32()\n", progname);
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
|
|
|
|
* attaching. If the config file or command-line parameters specify
|
|
|
|
* a higher baud rate, we switch to it later on, after establishing
|
|
|
|
* the connection with the ICE.
|
|
|
|
*/
|
2021-12-08 10:09:52 +00:00
|
|
|
pinfo.serialinfo.baud = 19200;
|
|
|
|
pinfo.serialinfo.cflags = SERIAL_8N1;
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If the port name starts with "usb", divert the serial routines
|
|
|
|
* to the USB ones. The serial_open() function for USB overrides
|
|
|
|
* the meaning of the "baud" parameter to be the USB device ID to
|
|
|
|
* search for.
|
|
|
|
*/
|
|
|
|
if (strncmp(port, "usb", 3) == 0) {
|
|
|
|
#if defined(HAVE_LIBUSB)
|
|
|
|
serdev = &usb_serdev;
|
2014-02-21 13:44:11 +00:00
|
|
|
pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
|
|
|
|
pinfo.usbinfo.flags = 0;
|
|
|
|
pinfo.usbinfo.pid = USB_DEVICE_JTAGICEMKII;
|
2012-11-26 16:24:56 +00:00
|
|
|
pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
|
|
|
|
pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
|
|
|
|
pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
|
|
|
|
pgm->fd.usb.eep = 0; /* no seperate EP for events */
|
2009-10-10 20:09:53 +00:00
|
|
|
#else
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
|
2009-10-10 20:09:53 +00:00
|
|
|
return -1;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy(pgm->port, port);
|
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;
|
|
|
|
}
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* drain any extraneous input
|
|
|
|
*/
|
|
|
|
jtagmkII_drain(pgm, 0);
|
|
|
|
|
|
|
|
status = jtagmkII_getsync(pgm, -1);
|
|
|
|
if(status < 0) return -1;
|
|
|
|
|
|
|
|
// AVR32 "special"
|
|
|
|
buf[0] = CMND_SET_PARAMETER;
|
|
|
|
buf[1] = 0x2D;
|
|
|
|
buf[2] = 0x03;
|
|
|
|
jtagmkII_send(pgm, buf, 3);
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if(status < 0 || resp[0] != RSP_OK)
|
|
|
|
return -1;
|
|
|
|
free(resp);
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
buf[1] = 0x03;
|
|
|
|
buf[2] = 0x02;
|
|
|
|
jtagmkII_send(pgm, buf, 3);
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if(status < 0 || resp[0] != RSP_OK)
|
|
|
|
return -1;
|
|
|
|
free(resp);
|
|
|
|
|
|
|
|
buf[1] = 0x03;
|
|
|
|
buf[2] = 0x04;
|
|
|
|
jtagmkII_send(pgm, buf, 3);
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if(status < 0 || resp[0] != RSP_OK)
|
|
|
|
return -1;
|
|
|
|
free(resp);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void jtagmkII_close32(PROGRAMMER * pgm)
|
|
|
|
{
|
2009-10-10 23:34:03 +00:00
|
|
|
int status, lineno;
|
|
|
|
unsigned char *resp, buf[3], c;
|
|
|
|
unsigned long val=0;
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_close32()\n", progname);
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 23:34:03 +00:00
|
|
|
// AVR32 "special"
|
2010-01-13 08:37:57 +00:00
|
|
|
buf[0] = CMND_SET_PARAMETER;
|
2009-10-10 23:34:03 +00:00
|
|
|
buf[1] = 0x03;
|
|
|
|
buf[2] = 0x02;
|
|
|
|
jtagmkII_send(pgm, buf, 3);
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if(status < 0 || resp[0] != RSP_OK) {lineno = __LINE__; goto eRR;}
|
|
|
|
free(resp);
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
buf[0] = CMND_SIGN_OFF;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_close(): Sending sign-off command: ",
|
2009-10-10 20:09:53 +00:00
|
|
|
progname);
|
|
|
|
jtagmkII_send(pgm, buf, 1);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
|
|
|
if (verbose >= 2)
|
|
|
|
putc('\n', stderr);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"timeout/error communicating with programmer (status %d)\n",
|
|
|
|
progname, status);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2009-10-10 20:09:53 +00:00
|
|
|
c = resp[0];
|
|
|
|
free(resp);
|
|
|
|
if (c != RSP_OK) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"bad response to sign-off command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(c));
|
|
|
|
}
|
|
|
|
|
2009-10-10 23:34:03 +00:00
|
|
|
ret:
|
|
|
|
serial_close(&pgm->fd);
|
|
|
|
pgm->fd.ifd = -1;
|
|
|
|
return;
|
|
|
|
|
|
|
|
eRR:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_reset32(): "
|
2009-10-10 23:34:03 +00:00
|
|
|
"failed at line %d (status=%x val=%lx)\n",
|
|
|
|
progname, lineno, status, val);
|
|
|
|
goto ret;
|
2009-10-10 20:09:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int jtagmkII_paged_load32(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)
|
2009-10-10 20:09:53 +00:00
|
|
|
{
|
2011-09-14 21:49:42 +00:00
|
|
|
unsigned int block_size;
|
|
|
|
unsigned int maxaddr = addr + n_bytes;
|
2009-10-10 23:34:03 +00:00
|
|
|
unsigned char cmd[7];
|
|
|
|
unsigned char *resp;
|
|
|
|
int lineno, status;
|
|
|
|
unsigned long val=0;
|
|
|
|
long otimeout = serial_recv_timeout;
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "%s: jtagmkII_paged_load32(.., %s, %d, %d)\n",
|
2009-10-10 23:34:03 +00:00
|
|
|
progname, m->desc, page_size, n_bytes);
|
|
|
|
|
|
|
|
serial_recv_timeout = 256;
|
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
if(!(p->flags & AVRPART_WRITE)) {
|
|
|
|
status = jtagmkII_reset32(pgm, AVR32_RESET_READ);
|
2009-10-12 22:33:49 +00:00
|
|
|
if(status != 0) {lineno = __LINE__; goto eRR;}
|
2009-10-12 16:44:30 +00:00
|
|
|
}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
// Init SMC and set clocks
|
|
|
|
if(!(p->flags & AVRPART_INIT_SMC)) {
|
|
|
|
status = jtagmkII_smc_init32(pgm);
|
|
|
|
if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
|
|
|
|
p->flags |= AVRPART_INIT_SMC;
|
|
|
|
}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
// Init SMC and set clocks
|
|
|
|
if(!(p->flags & AVRPART_INIT_SMC)) {
|
|
|
|
status = jtagmkII_smc_init32(pgm);
|
|
|
|
if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
|
|
|
|
p->flags |= AVRPART_INIT_SMC;
|
|
|
|
}
|
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
//avrdude_message(MSG_INFO, "\n pageSize=%d bytes=%d pages=%d m->offset=0x%x pgm->page_size %d\n",
|
2010-01-13 08:37:57 +00:00
|
|
|
// page_size, n_bytes, pages, m->offset, pgm->page_size);
|
2009-10-10 23:34:03 +00:00
|
|
|
|
|
|
|
cmd[0] = CMND_READ_MEMORY32;
|
|
|
|
cmd[1] = 0x40;
|
|
|
|
cmd[2] = 0x05;
|
|
|
|
|
2011-09-14 21:49:42 +00:00
|
|
|
for (; addr < maxaddr; addr += block_size) {
|
|
|
|
block_size = ((maxaddr-addr) < pgm->page_size) ? (maxaddr - addr) : pgm->page_size;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_DEBUG, "%s: jtagmkII_paged_load32(): "
|
2009-10-10 23:34:03 +00:00
|
|
|
"block_size at addr %d is %d\n",
|
|
|
|
progname, addr, block_size);
|
|
|
|
|
|
|
|
u32_to_b4r(cmd + 3, m->offset + addr);
|
|
|
|
|
2010-01-13 08:37:57 +00:00
|
|
|
status = jtagmkII_send(pgm, cmd, 7);
|
|
|
|
if(status<0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if(status<0) {lineno = __LINE__; goto eRR;}
|
2009-10-10 23:34:03 +00:00
|
|
|
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2009-10-10 23:34:03 +00:00
|
|
|
if (resp[0] != 0x87) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_load32(): "
|
2009-10-10 23:34:03 +00:00
|
|
|
"bad response to write memory command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(resp[0]));
|
|
|
|
free(resp);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
memcpy(m->buf + addr, resp + 1, block_size);
|
|
|
|
free(resp);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
|
2010-01-13 08:37:57 +00:00
|
|
|
status = jtagmkII_reset32(pgm, AVR32_SET4RUNNING);
|
2009-10-10 23:34:03 +00:00
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
return addr;
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 23:34:03 +00:00
|
|
|
eRR:
|
|
|
|
serial_recv_timeout = otimeout;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_load32(): "
|
2009-10-10 23:34:03 +00:00
|
|
|
"failed at line %d (status=%x val=%lx)\n",
|
|
|
|
progname, lineno, status, val);
|
|
|
|
return -1;
|
2009-10-10 20:09:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int jtagmkII_paged_write32(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)
|
2009-10-10 20:09:53 +00:00
|
|
|
{
|
2011-09-14 21:49:42 +00:00
|
|
|
unsigned int block_size;
|
2009-10-10 20:09:53 +00:00
|
|
|
unsigned char *cmd=NULL;
|
|
|
|
unsigned char *resp;
|
2011-09-14 21:49:42 +00:00
|
|
|
int lineno, status, pages, sPageNum, pageNum, blocks;
|
2009-10-10 20:09:53 +00:00
|
|
|
unsigned long val=0;
|
|
|
|
unsigned long otimeout = serial_recv_timeout;
|
2011-09-14 21:49:42 +00:00
|
|
|
unsigned int maxaddr = addr + n_bytes;
|
2009-10-10 20:09:53 +00:00
|
|
|
|
2009-10-10 23:34:03 +00:00
|
|
|
serial_recv_timeout = 256;
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
if(n_bytes == 0) return -1;
|
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
status = jtagmkII_reset32(pgm, AVR32_RESET_WRITE);
|
2009-10-12 22:33:49 +00:00
|
|
|
if(status != 0) {lineno = __LINE__; goto eRR;}
|
2009-10-12 16:44:30 +00:00
|
|
|
p->flags |= AVRPART_WRITE;
|
|
|
|
|
2011-09-14 21:49:42 +00:00
|
|
|
pages = (n_bytes - addr - 1)/page_size + 1;
|
|
|
|
sPageNum = addr/page_size;
|
2014-06-13 20:07:40 +00:00
|
|
|
//avrdude_message(MSG_INFO, "\n pageSize=%d bytes=%d pages=%d m->offset=0x%x pgm->page_size %d\n",
|
2010-01-13 08:37:57 +00:00
|
|
|
// page_size, n_bytes, pages, m->offset, pgm->page_size);
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
// Before any errors can happen
|
|
|
|
if ((cmd = malloc(pgm->page_size + 10)) == NULL) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write32(): Out of memory\n", progname);
|
2009-10-10 20:09:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Init SMC and set clocks
|
2009-10-12 16:44:30 +00:00
|
|
|
if(!(p->flags & AVRPART_INIT_SMC)) {
|
|
|
|
status = jtagmkII_smc_init32(pgm);
|
|
|
|
if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
|
|
|
|
p->flags |= AVRPART_INIT_SMC;
|
|
|
|
}
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
// First unlock the pages
|
2011-09-14 21:49:42 +00:00
|
|
|
for(pageNum=sPageNum; pageNum < pages; ++pageNum) {
|
2009-10-10 20:09:53 +00:00
|
|
|
status =jtagmkII_flash_lock32(pgm, 0, pageNum);
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Then erase them (guess could do this in the same loop above?)
|
2011-09-14 21:49:42 +00:00
|
|
|
for(pageNum=sPageNum; pageNum < pages; ++pageNum) {
|
2009-10-10 20:09:53 +00:00
|
|
|
status =jtagmkII_flash_erase32(pgm, pageNum);
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
}
|
|
|
|
|
|
|
|
cmd[0] = CMND_WRITE_MEMORY32;
|
|
|
|
u32_to_b4r(&cmd[1], 0x40000000); // who knows
|
|
|
|
cmd[5] = 0x5;
|
|
|
|
|
2011-09-14 21:49:42 +00:00
|
|
|
for(pageNum=sPageNum; pageNum < pages; ++pageNum) {
|
2009-10-12 16:44:30 +00:00
|
|
|
|
2010-01-13 08:37:57 +00:00
|
|
|
status = jtagmkII_flash_clear_pagebuffer32(pgm);
|
|
|
|
if(status != 0) {lineno = __LINE__; goto eRR;}
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
for(blocks=0; blocks<2; ++blocks) {
|
2011-09-14 21:49:42 +00:00
|
|
|
block_size = ((maxaddr-addr) < pgm->page_size) ? (maxaddr - addr) : pgm->page_size;
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_DEBUG, "%s: jtagmkII_paged_write32(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"block_size at addr %d is %d\n",
|
|
|
|
progname, addr, block_size);
|
|
|
|
|
|
|
|
u32_to_b4r(cmd + 6, m->offset + addr);
|
|
|
|
memset(cmd + 10, 0xff, pgm->page_size);
|
|
|
|
memcpy(cmd + 10, m->buf + addr, block_size);
|
|
|
|
|
2010-01-13 08:37:57 +00:00
|
|
|
status = jtagmkII_send(pgm, cmd, pgm->page_size + 10);
|
|
|
|
if(status<0) {lineno = __LINE__; goto eRR;}
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status<0) {lineno = __LINE__; goto eRR;}
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
if (verbose >= 3) {
|
|
|
|
putc('\n', stderr);
|
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
|
|
|
} else if (verbose == 2)
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
|
2009-10-10 20:09:53 +00:00
|
|
|
if (resp[0] != RSP_OK) {
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write32(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"bad response to write memory command: %s\n",
|
|
|
|
progname, jtagmkII_get_rc(resp[0]));
|
|
|
|
free(resp);
|
|
|
|
free(cmd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
free(resp);
|
|
|
|
|
|
|
|
addr += block_size;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
status = jtagmkII_flash_write_page32(pgm, pageNum);
|
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
}
|
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
|
2009-10-10 23:34:03 +00:00
|
|
|
status = jtagmkII_reset32(pgm, AVR32_SET4RUNNING); // AVR32_SET4RUNNING | AVR32_RELEASE_JTAG
|
2009-10-10 20:09:53 +00:00
|
|
|
if(status < 0) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
2020-03-14 22:34:45 +00:00
|
|
|
free(cmd);
|
2009-10-10 23:34:03 +00:00
|
|
|
return addr;
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
eRR:
|
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
free(cmd);
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write32(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"failed at line %d (status=%x val=%lx)\n",
|
|
|
|
progname, lineno, status, val);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int jtagmkII_flash_lock32(PROGRAMMER * pgm, unsigned char lock, unsigned int page)
|
|
|
|
{
|
|
|
|
int status, lineno, i;
|
|
|
|
unsigned long val, cmd=0;
|
|
|
|
|
|
|
|
for(i=0; i<256; ++i) {
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05);
|
|
|
|
if(val == ERROR_SAB) continue;
|
|
|
|
if(val & AVR32_FLASHC_FSR_RDY) break;
|
|
|
|
}
|
|
|
|
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
|
|
|
|
if(!(val&AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;} // Flash better be ready
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
page <<= 8;
|
|
|
|
cmd = AVR32_FLASHC_FCMD_KEY | page | (lock ? AVR32_FLASHC_FCMD_LOCK : AVR32_FLASHC_FCMD_UNLOCK);
|
2010-01-13 08:37:57 +00:00
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_FLASHC_FCMD, 0x05, cmd);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
return 0;
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
eRR:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_flash_lock32(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"failed at line %d page %d cmd %8.8lx\n",
|
|
|
|
progname, lineno, page, cmd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int jtagmkII_flash_erase32(PROGRAMMER * pgm, unsigned int page)
|
|
|
|
{
|
|
|
|
int status, lineno, i;
|
|
|
|
unsigned long val=0, cmd=0, err=0;
|
|
|
|
|
|
|
|
for(i=0; i<256; ++i) {
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05);
|
|
|
|
if(val == ERROR_SAB) continue;
|
|
|
|
if(val & AVR32_FLASHC_FSR_RDY) break;
|
|
|
|
}
|
|
|
|
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
|
|
|
|
if(!(val&AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;} // Flash better be ready
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
page <<= 8;
|
|
|
|
cmd = AVR32_FLASHC_FCMD_KEY | page | AVR32_FLASHC_FCMD_ERASE_PAGE;
|
2010-01-13 08:37:57 +00:00
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_FLASHC_FCMD, 0x05, cmd);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
2009-10-10 20:09:53 +00:00
|
|
|
|
2014-06-13 20:07:40 +00:00
|
|
|
//avrdude_message(MSG_INFO, "ERASE %x -> %x\n", cmd, AVR32_FLASHC_FCMD);
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
err = 0;
|
|
|
|
for(i=0; i<256; ++i) {
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05);
|
|
|
|
if(val == ERROR_SAB) continue;
|
|
|
|
err |= val;
|
|
|
|
if(val & AVR32_FLASHC_FSR_RDY) break;
|
|
|
|
}
|
|
|
|
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
|
|
|
|
if(!(val & AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;}
|
|
|
|
if(err & AVR32_FLASHC_FSR_ERR) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
return 0;
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
eRR:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_flash_erase32(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"failed at line %d page %d cmd %8.8lx val %lx\n",
|
|
|
|
progname, lineno, page, cmd, val);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int jtagmkII_flash_write_page32(PROGRAMMER * pgm, unsigned int page)
|
|
|
|
{
|
|
|
|
int status, lineno, i;
|
|
|
|
unsigned long val=0, cmd, err;
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
page <<= 8;
|
|
|
|
cmd = AVR32_FLASHC_FCMD_KEY | page | AVR32_FLASHC_FCMD_WRITE_PAGE;
|
2010-01-13 08:37:57 +00:00
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_FLASHC_FCMD, 0x05, cmd);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
err = 0;
|
|
|
|
for(i=0; i<256; ++i) {
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05);
|
|
|
|
if(val == ERROR_SAB) continue;
|
|
|
|
err |= val;
|
|
|
|
if(val & AVR32_FLASHC_FSR_RDY) break;
|
|
|
|
}
|
|
|
|
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
|
|
|
|
if(!(val & AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;}
|
|
|
|
if(err & AVR32_FLASHC_FSR_ERR) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
return 0;
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
eRR:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_flash_write_page32(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"failed at line %d page %d cmd %8.8lx val %lx\n",
|
|
|
|
progname, lineno, page, cmd, val);
|
|
|
|
return -1;
|
|
|
|
}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
static int jtagmkII_flash_clear_pagebuffer32(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
int status, lineno, i;
|
|
|
|
unsigned long val=0, cmd, err;
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
cmd = AVR32_FLASHC_FCMD_KEY | AVR32_FLASHC_FCMD_CLEAR_PAGE_BUFFER;
|
2010-01-13 08:37:57 +00:00
|
|
|
status = jtagmkII_write_SABaddr(pgm, AVR32_FLASHC_FCMD, 0x05, cmd);
|
|
|
|
if (status < 0) {lineno = __LINE__; goto eRR;}
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
err = 0;
|
|
|
|
for(i=0; i<256; ++i) {
|
|
|
|
val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05);
|
|
|
|
if(val == ERROR_SAB) continue;
|
|
|
|
err |= val;
|
|
|
|
if(val & AVR32_FLASHC_FSR_RDY) break;
|
|
|
|
}
|
|
|
|
if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
|
|
|
|
if(!(val & AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;}
|
|
|
|
if(err & AVR32_FLASHC_FSR_ERR) {lineno = __LINE__; goto eRR;}
|
|
|
|
|
|
|
|
return 0;
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2009-10-10 20:09:53 +00:00
|
|
|
eRR:
|
2014-06-13 20:07:40 +00:00
|
|
|
avrdude_message(MSG_INFO, "%s: jtagmkII_flash_clear_pagebuffer32(): "
|
2009-10-10 20:09:53 +00:00
|
|
|
"failed at line %d cmd %8.8lx val %lx\n",
|
|
|
|
progname, lineno, cmd, val);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2010-01-13 08:37:57 +00:00
|
|
|
#ifdef __OBJC__
|
|
|
|
#pragma mark -
|
|
|
|
#endif
|
2009-10-10 20:09:53 +00:00
|
|
|
|
2012-01-31 17:03:43 +00:00
|
|
|
const char jtagmkII_desc[] = "Atmel JTAG ICE mkII";
|
|
|
|
|
2010-01-13 08:37:57 +00:00
|
|
|
void jtagmkII_initpgm(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
strcpy(pgm->type, "JTAGMKII");
|
|
|
|
|
|
|
|
/*
|
|
|
|
* mandatory functions
|
|
|
|
*/
|
|
|
|
pgm->initialize = jtagmkII_initialize;
|
|
|
|
pgm->display = jtagmkII_display;
|
|
|
|
pgm->enable = jtagmkII_enable;
|
|
|
|
pgm->disable = jtagmkII_disable;
|
2014-06-13 20:07:40 +00:00
|
|
|
pgm->program_enable = jtagmkII_program_enable_INFO;
|
2010-01-13 08:37:57 +00:00
|
|
|
pgm->chip_erase = jtagmkII_chip_erase;
|
|
|
|
pgm->open = jtagmkII_open;
|
|
|
|
pgm->close = jtagmkII_close;
|
|
|
|
pgm->read_byte = jtagmkII_read_byte;
|
|
|
|
pgm->write_byte = jtagmkII_write_byte;
|
2009-10-10 20:09:53 +00:00
|
|
|
|
2010-01-13 08:37:57 +00:00
|
|
|
/*
|
|
|
|
* optional functions
|
|
|
|
*/
|
|
|
|
pgm->paged_write = jtagmkII_paged_write;
|
|
|
|
pgm->paged_load = jtagmkII_paged_load;
|
2012-05-04 10:02:30 +00:00
|
|
|
pgm->page_erase = jtagmkII_page_erase;
|
2010-01-13 08:37:57 +00:00
|
|
|
pgm->print_parms = jtagmkII_print_parms;
|
|
|
|
pgm->set_sck_period = jtagmkII_set_sck_period;
|
|
|
|
pgm->parseextparams = jtagmkII_parseextparms;
|
|
|
|
pgm->setup = jtagmkII_setup;
|
|
|
|
pgm->teardown = jtagmkII_teardown;
|
|
|
|
pgm->page_size = 256;
|
2010-01-13 17:34:18 +00:00
|
|
|
pgm->flag = PGM_FL_IS_JTAG;
|
2010-01-13 08:37:57 +00:00
|
|
|
}
|
2009-10-10 20:09:53 +00:00
|
|
|
|
2012-01-31 17:03:43 +00:00
|
|
|
const char jtagmkII_dw_desc[] = "Atmel JTAG ICE mkII in debugWire mode";
|
|
|
|
|
2010-01-13 08:37:57 +00:00
|
|
|
void jtagmkII_dw_initpgm(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
strcpy(pgm->type, "JTAGMKII_DW");
|
2009-10-10 20:09:53 +00:00
|
|
|
|
2010-01-13 08:37:57 +00:00
|
|
|
/*
|
|
|
|
* mandatory functions
|
|
|
|
*/
|
|
|
|
pgm->initialize = jtagmkII_initialize;
|
|
|
|
pgm->display = jtagmkII_display;
|
|
|
|
pgm->enable = jtagmkII_enable;
|
|
|
|
pgm->disable = jtagmkII_disable;
|
2014-06-13 20:07:40 +00:00
|
|
|
pgm->program_enable = jtagmkII_program_enable_INFO;
|
2010-01-13 08:37:57 +00:00
|
|
|
pgm->chip_erase = jtagmkII_chip_erase_dw;
|
|
|
|
pgm->open = jtagmkII_open_dw;
|
|
|
|
pgm->close = jtagmkII_close;
|
|
|
|
pgm->read_byte = jtagmkII_read_byte;
|
|
|
|
pgm->write_byte = jtagmkII_write_byte;
|
2009-10-10 20:09:53 +00:00
|
|
|
|
2010-01-13 08:37:57 +00:00
|
|
|
/*
|
|
|
|
* optional functions
|
|
|
|
*/
|
|
|
|
pgm->paged_write = jtagmkII_paged_write;
|
|
|
|
pgm->paged_load = jtagmkII_paged_load;
|
|
|
|
pgm->print_parms = jtagmkII_print_parms;
|
|
|
|
pgm->setup = jtagmkII_setup;
|
|
|
|
pgm->teardown = jtagmkII_teardown;
|
|
|
|
pgm->page_size = 256;
|
|
|
|
pgm->flag = PGM_FL_IS_DW;
|
|
|
|
}
|
|
|
|
|
2012-01-31 17:03:43 +00:00
|
|
|
const char jtagmkII_pdi_desc[] = "Atmel JTAG ICE mkII in PDI mode";
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2010-01-13 17:34:18 +00:00
|
|
|
void jtagmkII_pdi_initpgm(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
strcpy(pgm->type, "JTAGMKII_PDI");
|
|
|
|
|
|
|
|
/*
|
|
|
|
* mandatory functions
|
|
|
|
*/
|
|
|
|
pgm->initialize = jtagmkII_initialize;
|
|
|
|
pgm->display = jtagmkII_display;
|
|
|
|
pgm->enable = jtagmkII_enable;
|
|
|
|
pgm->disable = jtagmkII_disable;
|
2014-06-13 20:07:40 +00:00
|
|
|
pgm->program_enable = jtagmkII_program_enable_INFO;
|
2010-01-13 17:34:18 +00:00
|
|
|
pgm->chip_erase = jtagmkII_chip_erase;
|
|
|
|
pgm->open = jtagmkII_open_pdi;
|
|
|
|
pgm->close = jtagmkII_close;
|
|
|
|
pgm->read_byte = jtagmkII_read_byte;
|
|
|
|
pgm->write_byte = jtagmkII_write_byte;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* optional functions
|
|
|
|
*/
|
|
|
|
pgm->paged_write = jtagmkII_paged_write;
|
|
|
|
pgm->paged_load = jtagmkII_paged_load;
|
2012-05-04 10:02:30 +00:00
|
|
|
pgm->page_erase = jtagmkII_page_erase;
|
2010-01-13 17:34:18 +00:00
|
|
|
pgm->print_parms = jtagmkII_print_parms;
|
|
|
|
pgm->setup = jtagmkII_setup;
|
|
|
|
pgm->teardown = jtagmkII_teardown;
|
|
|
|
pgm->page_size = 256;
|
|
|
|
pgm->flag = PGM_FL_IS_PDI;
|
|
|
|
}
|
|
|
|
|
2012-01-31 17:03:43 +00:00
|
|
|
const char jtagmkII_dragon_desc[] = "Atmel AVR Dragon in JTAG mode";
|
2010-01-13 17:34:18 +00:00
|
|
|
|
2010-01-13 08:37:57 +00:00
|
|
|
void jtagmkII_dragon_initpgm(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
strcpy(pgm->type, "DRAGON_JTAG");
|
|
|
|
|
|
|
|
/*
|
|
|
|
* mandatory functions
|
|
|
|
*/
|
|
|
|
pgm->initialize = jtagmkII_initialize;
|
|
|
|
pgm->display = jtagmkII_display;
|
|
|
|
pgm->enable = jtagmkII_enable;
|
|
|
|
pgm->disable = jtagmkII_disable;
|
2014-06-13 20:07:40 +00:00
|
|
|
pgm->program_enable = jtagmkII_program_enable_INFO;
|
2010-01-13 08:37:57 +00:00
|
|
|
pgm->chip_erase = jtagmkII_chip_erase;
|
|
|
|
pgm->open = jtagmkII_dragon_open;
|
|
|
|
pgm->close = jtagmkII_close;
|
|
|
|
pgm->read_byte = jtagmkII_read_byte;
|
|
|
|
pgm->write_byte = jtagmkII_write_byte;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* optional functions
|
|
|
|
*/
|
|
|
|
pgm->paged_write = jtagmkII_paged_write;
|
|
|
|
pgm->paged_load = jtagmkII_paged_load;
|
2012-05-04 10:02:30 +00:00
|
|
|
pgm->page_erase = jtagmkII_page_erase;
|
2010-01-13 08:37:57 +00:00
|
|
|
pgm->print_parms = jtagmkII_print_parms;
|
|
|
|
pgm->set_sck_period = jtagmkII_set_sck_period;
|
|
|
|
pgm->parseextparams = jtagmkII_parseextparms;
|
|
|
|
pgm->setup = jtagmkII_setup;
|
|
|
|
pgm->teardown = jtagmkII_teardown;
|
|
|
|
pgm->page_size = 256;
|
2010-01-13 17:34:18 +00:00
|
|
|
pgm->flag = PGM_FL_IS_JTAG;
|
2010-01-13 08:37:57 +00:00
|
|
|
}
|
|
|
|
|
2012-01-31 17:03:43 +00:00
|
|
|
const char jtagmkII_dragon_dw_desc[] = "Atmel AVR Dragon in debugWire mode";
|
2010-01-13 08:37:57 +00:00
|
|
|
|
|
|
|
void jtagmkII_dragon_dw_initpgm(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
strcpy(pgm->type, "DRAGON_DW");
|
|
|
|
|
|
|
|
/*
|
|
|
|
* mandatory functions
|
|
|
|
*/
|
|
|
|
pgm->initialize = jtagmkII_initialize;
|
|
|
|
pgm->display = jtagmkII_display;
|
|
|
|
pgm->enable = jtagmkII_enable;
|
|
|
|
pgm->disable = jtagmkII_disable;
|
2014-06-13 20:07:40 +00:00
|
|
|
pgm->program_enable = jtagmkII_program_enable_INFO;
|
2010-01-13 08:37:57 +00:00
|
|
|
pgm->chip_erase = jtagmkII_chip_erase_dw;
|
|
|
|
pgm->open = jtagmkII_dragon_open_dw;
|
|
|
|
pgm->close = jtagmkII_close;
|
|
|
|
pgm->read_byte = jtagmkII_read_byte;
|
|
|
|
pgm->write_byte = jtagmkII_write_byte;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* optional functions
|
|
|
|
*/
|
|
|
|
pgm->paged_write = jtagmkII_paged_write;
|
|
|
|
pgm->paged_load = jtagmkII_paged_load;
|
|
|
|
pgm->print_parms = jtagmkII_print_parms;
|
|
|
|
pgm->setup = jtagmkII_setup;
|
|
|
|
pgm->teardown = jtagmkII_teardown;
|
|
|
|
pgm->page_size = 256;
|
|
|
|
pgm->flag = PGM_FL_IS_DW;
|
|
|
|
}
|
|
|
|
|
2012-01-31 17:03:43 +00:00
|
|
|
const char jtagmkII_avr32_desc[] = "Atmel JTAG ICE mkII in AVR32 mode";
|
|
|
|
|
2010-01-13 08:37:57 +00:00
|
|
|
void jtagmkII_avr32_initpgm(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
strcpy(pgm->type, "JTAGMKII_AVR32");
|
|
|
|
|
|
|
|
/*
|
|
|
|
* mandatory functions
|
|
|
|
*/
|
|
|
|
pgm->initialize = jtagmkII_initialize32;
|
|
|
|
pgm->display = jtagmkII_display;
|
|
|
|
pgm->enable = jtagmkII_enable;
|
|
|
|
pgm->disable = jtagmkII_disable;
|
2014-06-13 20:07:40 +00:00
|
|
|
pgm->program_enable = jtagmkII_program_enable_INFO;
|
2010-01-13 08:37:57 +00:00
|
|
|
pgm->chip_erase = jtagmkII_chip_erase32;
|
|
|
|
pgm->open = jtagmkII_open32;
|
|
|
|
pgm->close = jtagmkII_close32;
|
|
|
|
pgm->read_byte = jtagmkII_read_byte;
|
|
|
|
pgm->write_byte = jtagmkII_write_byte;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* optional functions
|
|
|
|
*/
|
|
|
|
pgm->paged_write = jtagmkII_paged_write32;
|
|
|
|
pgm->paged_load = jtagmkII_paged_load32;
|
|
|
|
pgm->print_parms = jtagmkII_print_parms;
|
|
|
|
//pgm->set_sck_period = jtagmkII_set_sck_period;
|
|
|
|
//pgm->parseextparams = jtagmkII_parseextparms;
|
|
|
|
pgm->setup = jtagmkII_setup;
|
|
|
|
pgm->teardown = jtagmkII_teardown;
|
|
|
|
pgm->page_size = 256;
|
2010-01-13 17:34:18 +00:00
|
|
|
pgm->flag = PGM_FL_IS_JTAG;
|
|
|
|
}
|
|
|
|
|
2012-01-31 17:03:43 +00:00
|
|
|
const char jtagmkII_dragon_pdi_desc[] = "Atmel AVR Dragon in PDI mode";
|
|
|
|
|
2010-01-13 17:34:18 +00:00
|
|
|
void jtagmkII_dragon_pdi_initpgm(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
strcpy(pgm->type, "DRAGON_PDI");
|
|
|
|
|
|
|
|
/*
|
|
|
|
* mandatory functions
|
|
|
|
*/
|
|
|
|
pgm->initialize = jtagmkII_initialize;
|
|
|
|
pgm->display = jtagmkII_display;
|
|
|
|
pgm->enable = jtagmkII_enable;
|
|
|
|
pgm->disable = jtagmkII_disable;
|
2014-06-13 20:07:40 +00:00
|
|
|
pgm->program_enable = jtagmkII_program_enable_INFO;
|
2010-01-13 17:34:18 +00:00
|
|
|
pgm->chip_erase = jtagmkII_chip_erase;
|
|
|
|
pgm->open = jtagmkII_dragon_open_pdi;
|
|
|
|
pgm->close = jtagmkII_close;
|
|
|
|
pgm->read_byte = jtagmkII_read_byte;
|
|
|
|
pgm->write_byte = jtagmkII_write_byte;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* optional functions
|
|
|
|
*/
|
|
|
|
pgm->paged_write = jtagmkII_paged_write;
|
|
|
|
pgm->paged_load = jtagmkII_paged_load;
|
2012-05-04 10:02:30 +00:00
|
|
|
pgm->page_erase = jtagmkII_page_erase;
|
2010-01-13 17:34:18 +00:00
|
|
|
pgm->print_parms = jtagmkII_print_parms;
|
|
|
|
pgm->setup = jtagmkII_setup;
|
|
|
|
pgm->teardown = jtagmkII_teardown;
|
|
|
|
pgm->page_size = 256;
|
|
|
|
pgm->flag = PGM_FL_IS_PDI;
|
2010-01-13 08:37:57 +00:00
|
|
|
}
|
2009-10-10 20:09:53 +00:00
|
|
|
|