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;
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
|
|
|
|
#define FLAGS32_INIT_SMC 1 // Part will undergo chip erase
|
|
|
|
#define FLAGS32_WRITE 2 // At least one write operation specified
|
|
|
|
// Couple of flag bits for AVR32 programming
|
|
|
|
int flags32;
|
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
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_open(PROGRAMMER *pgm, const char *port);
|
2009-10-10 20:09:53 +00:00
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p);
|
|
|
|
static int jtagmkII_chip_erase(const PROGRAMMER *pgm, const AVRPART *p);
|
|
|
|
static int jtagmkII_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
|
2009-10-10 20:09:53 +00:00
|
|
|
unsigned long addr, unsigned char * value);
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
|
2009-10-10 20:09:53 +00:00
|
|
|
unsigned long addr, unsigned char data);
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_reset(const PROGRAMMER *pgm, unsigned char flags);
|
|
|
|
static int jtagmkII_set_sck_period(const PROGRAMMER *pgm, double v);
|
|
|
|
static int jtagmkII_setparm(const PROGRAMMER *pgm, unsigned char parm,
|
2009-10-10 20:09:53 +00:00
|
|
|
unsigned char * value);
|
2022-10-23 20:56:45 +00:00
|
|
|
static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp);
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
|
2011-09-14 21:49:42 +00:00
|
|
|
unsigned int page_size,
|
|
|
|
unsigned int addr, unsigned int n_bytes);
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static unsigned char jtagmkII_memtype(const PROGRAMMER *pgm, const AVRPART *p, unsigned long addr);
|
|
|
|
static unsigned int jtagmkII_memaddr(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr);
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
// AVR32
|
|
|
|
#define ERROR_SAB 0xFFFFFFFF
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_open32(PROGRAMMER *pgm, const char *port);
|
2009-10-10 20:09:53 +00:00
|
|
|
static void jtagmkII_close32(PROGRAMMER * pgm);
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_reset32(const PROGRAMMER *pgm, unsigned short flags);
|
|
|
|
static int jtagmkII_initialize32(const PROGRAMMER *pgm, const AVRPART *p);
|
|
|
|
static int jtagmkII_chip_erase32(const PROGRAMMER *pgm, const AVRPART *p);
|
|
|
|
static unsigned long jtagmkII_read_SABaddr(const PROGRAMMER *pgm, unsigned long addr,
|
2009-10-10 20:09:53 +00:00
|
|
|
unsigned int prefix); // ERROR_SAB illegal
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_write_SABaddr(const PROGRAMMER *pgm, unsigned long addr,
|
2009-10-10 20:09:53 +00:00
|
|
|
unsigned int prefix, unsigned long val);
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_avr32_reset(const PROGRAMMER *pgm, unsigned char val,
|
2009-10-10 20:09:53 +00:00
|
|
|
unsigned char ret1, unsigned char ret2);
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_smc_init32(const PROGRAMMER *pgm);
|
|
|
|
static int jtagmkII_paged_write32(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
|
2011-09-14 21:49:42 +00:00
|
|
|
unsigned int page_size,
|
|
|
|
unsigned int addr, unsigned int n_bytes);
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_flash_lock32(const PROGRAMMER *pgm, unsigned char lock,
|
2009-10-10 20:09:53 +00:00
|
|
|
unsigned int page);
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_flash_erase32(const PROGRAMMER *pgm, unsigned int page);
|
|
|
|
static int jtagmkII_flash_write_page32(const PROGRAMMER *pgm, unsigned int page);
|
|
|
|
static int jtagmkII_flash_clear_pagebuffer32(const PROGRAMMER *pgm);
|
|
|
|
static int jtagmkII_paged_load32(const PROGRAMMER *pgm, const AVRPART *p, const 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
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
void jtagmkII_setup(PROGRAMMER *pgm) {
|
|
|
|
pgm->cookie = cfg_malloc("jtagmkII_setup()", sizeof(struct pdata));
|
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
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +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;
|
2022-10-17 14:44:55 +00:00
|
|
|
static char msg[64];
|
2006-09-07 19:57:59 +00:00
|
|
|
|
|
|
|
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++) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("0x%02x ", b[i + 1]);
|
2005-05-10 19:53:56 +00:00
|
|
|
if (i % 16 == 15)
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
else
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info(" ");
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
if (i % 16 != 0)
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static void jtagmkII_prmsg(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
|
2005-05-10 19:53:56 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
if (verbose >= 4) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_trace("Raw message:\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
for (i = 0; i < len; i++) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_trace("0x%02x", data[i]);
|
2005-05-10 19:53:56 +00:00
|
|
|
if (i % 16 == 15)
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_trace("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
else
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_trace(" ");
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
if (i % 16 != 0)
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_trace("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (data[0]) {
|
|
|
|
case RSP_OK:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("OK\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_FAILED:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("FAILED\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_BREAKPOINT:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("Illegal breakpoint\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_COMMAND:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("Illegal command\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_EMULATOR_MODE:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("Illegal emulator mode");
|
2005-05-10 19:53:56 +00:00
|
|
|
if (len > 1)
|
|
|
|
switch (data[1]) {
|
2022-10-17 14:44:55 +00:00
|
|
|
case EMULATOR_MODE_DEBUGWIRE: msg_info(": DebugWire"); break;
|
|
|
|
case EMULATOR_MODE_JTAG: msg_info(": JTAG"); break;
|
|
|
|
case EMULATOR_MODE_HV: msg_info(": HVSP/PP"); break;
|
|
|
|
case EMULATOR_MODE_SPI: msg_info(": SPI"); break;
|
|
|
|
case EMULATOR_MODE_JTAG_XMEGA: msg_info(": JTAG/Xmega"); break;
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_JTAG_ID:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("Illegal JTAG ID\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_MCU_STATE:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("Illegal MCU state");
|
2005-05-10 19:53:56 +00:00
|
|
|
if (len > 1)
|
|
|
|
switch (data[1]) {
|
2022-10-17 14:44:55 +00:00
|
|
|
case STOPPED: msg_info(": Stopped"); break;
|
|
|
|
case RUNNING: msg_info(": Running"); break;
|
|
|
|
case PROGRAMMING: msg_info(": Programming"); break;
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_MEMORY_TYPE:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("Illegal memory type\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_MEMORY_RANGE:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("Illegal memory range\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_PARAMETER:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("Illegal parameter\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_POWER_STATE:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("Illegal power state\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_ILLEGAL_VALUE:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("Illegal value\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_NO_TARGET_POWER:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("No target power\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_SIGN_ON:
|
2022-10-17 14:44:55 +00:00
|
|
|
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:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("memory contents:\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_print_memory(data, len);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_PARAMETER:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("parameter values:\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_print_memory(data, len);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RSP_SPI_DATA:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("SPI data returned:\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
for (i = 1; i < len; i++)
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("0x%02x ", data[i]);
|
|
|
|
msg_info("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case EVT_BREAK:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("BREAK event");
|
2005-05-10 19:53:56 +00:00
|
|
|
if (len >= 6) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info(", PC = 0x%lx, reason ", b4_to_u32(data + 1));
|
2005-05-10 19:53:56 +00:00
|
|
|
switch (data[5]) {
|
|
|
|
case 0x00:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("unspecified");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
case 0x01:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("program break");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
case 0x02:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("data break PDSB");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
case 0x03:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("data break PDMSB");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
default:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("unknown: 0x%02x", data[5]);
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("unknown message 0x%02x\n", data[0]);
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
int jtagmkII_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) {
|
2005-05-10 19:53:56 +00:00
|
|
|
unsigned char *buf;
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
|
|
|
pmsg_debug("jtagmkII_send(): sending %lu bytes\n", (unsigned long) len);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
if ((buf = malloc(len + 10)) == NULL)
|
|
|
|
{
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("out of memory");
|
2005-05-10 19:53:56 +00:00
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("unable to send command to serial port\n");
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_drain(const 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.
|
|
|
|
*/
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_recv_frame(const PROGRAMMER *pgm, unsigned char **msg,
|
2005-05-10 19:53:56 +00:00
|
|
|
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;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_trace("jtagmkII_recv():\n");
|
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 */
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_recv(): timeout receiving packet\n");
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("msglen %lu exceeds max message size %u, ignoring message\n",
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("out of memory\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
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)
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_trace2("jtagmkII_recv(): CRC OK");
|
2005-05-10 19:53:56 +00:00
|
|
|
state = sDONE;
|
|
|
|
} else {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("wrong checksum\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
free(buf);
|
|
|
|
return -4;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
state++;
|
|
|
|
break;
|
|
|
|
default:
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("unknown state\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
free(buf);
|
|
|
|
return -5;
|
|
|
|
}
|
|
|
|
|
|
|
|
gettimeofday(&tv, NULL);
|
|
|
|
tnow = tv.tv_sec;
|
|
|
|
if (tnow - tstart > timeoutval) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("timeout\n");
|
2020-03-14 22:34:45 +00:00
|
|
|
free(buf);
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
*seqno = r_seqno;
|
|
|
|
*msg = buf;
|
|
|
|
|
|
|
|
return msglen;
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
int jtagmkII_recv(const 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;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_debug("jtagmkII_recv(): got message seqno %d (command_sequence == %d)\n",
|
|
|
|
r_seqno, PDATA(pgm)->command_sequence);
|
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 (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;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_trace("recv: ");
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
while (i) {
|
|
|
|
unsigned char c = *p;
|
|
|
|
if (isprint(c)) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_trace("%c ", c);
|
2009-10-10 20:09:53 +00:00
|
|
|
}
|
|
|
|
else {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_trace(". ");
|
2009-10-10 20:09:53 +00:00
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_trace("[%02x] ", c);
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
p++;
|
|
|
|
i--;
|
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_debug("jtagmkII_recv(): got asynchronous event\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
} else {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_recv(): got wrong sequence number, %u != %u\n",
|
|
|
|
r_seqno, PDATA(pgm)->command_sequence);
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
free(*msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
int jtagmkII_getsync(const PROGRAMMER *pgm, int mode) {
|
2005-05-10 19:53:56 +00:00
|
|
|
int tries;
|
2022-01-19 21:55:11 +00:00
|
|
|
#define MAXTRIES 10
|
2005-05-10 19:53:56 +00:00
|
|
|
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
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_debug("jtagmkII_getsync()\n");
|
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 {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("programmer is neither JTAG ICE mkII nor AVR Dragon\n");
|
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;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_getsync() attempt %d of %d: sending sign-on command: ",
|
|
|
|
tries + 1, MAXTRIES);
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_send(pgm, buf, 1);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("attempt %d of %d: sign-on command: status %d\n",
|
|
|
|
tries + 1, MAXTRIES, status);
|
2005-05-10 19:53:56 +00:00
|
|
|
} else if (verbose >= 3) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice("JTAG ICE mkII sign-on message:\n");
|
|
|
|
msg_notice("Communications protocol version: %u\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
(unsigned)resp[1]);
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice("M_MCU:\n");
|
|
|
|
msg_notice(" boot-loader FW version: %u\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
(unsigned)resp[2]);
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice(" firmware version: %u.%02u\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
(unsigned)resp[4], (unsigned)resp[3]);
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice(" hardware version: %u\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
(unsigned)resp[5]);
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice("S_MCU:\n");
|
|
|
|
msg_notice(" boot-loader FW version: %u\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
(unsigned)resp[6]);
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice(" firmware version: %u.%02u\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
(unsigned)resp[8], (unsigned)resp[7]);
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice(" hardware version: %u\n",
|
2005-05-10 19:53:56 +00:00
|
|
|
(unsigned)resp[9]);
|
2022-10-17 14:44:55 +00:00
|
|
|
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';
|
2022-10-17 14:44:55 +00:00
|
|
|
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)
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2005-05-10 19:53:56 +00:00
|
|
|
else
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to sign-on command: %s\n", 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;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("S_MCU firmware version might be too old to work correctly\n");
|
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)
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_getsync(): using a %u-byte device descriptor\n",
|
|
|
|
(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)) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("ISP functionality requires firmware version >= 4.14\n");
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("Xmega PDI support requires hardware revision >= 1\n");
|
2010-01-14 13:46:02 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (!is_dragon && fwver < FWVER(5, 37)) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("Xmega support requires firmware version >= 5.37\n");
|
2010-01-14 13:46:02 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (is_dragon && fwver < FWVER(6, 11)) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("Xmega support requires firmware version >= 6.11\n");
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("ISP activation failed, trying debugWire\n");
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("unable to return from debugWIRE to ISP\n");
|
2013-05-17 16:23:55 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("target prepared for ISP, signed off\n");
|
|
|
|
imsg_warning("now retrying without power-cycling the target\n");
|
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;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_getsync(): sending get sync command: ");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_send(pgm, buf, 1);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to set parameter command: %s\n", 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
|
|
|
|
*/
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
|
2010-01-11 15:27:44 +00:00
|
|
|
int status, len;
|
|
|
|
unsigned char buf[6], *resp, c;
|
|
|
|
|
2022-08-30 15:33:42 +00:00
|
|
|
if (p->prog_modes & (PM_PDI | PM_UPDI)) {
|
2010-01-11 15:27:44 +00:00
|
|
|
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;
|
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_chip_erase(): sending %schip erase command: ",
|
|
|
|
p->prog_modes & (PM_PDI | PM_UPDI)? "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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to chip erase command: %s\n", jtagmkII_get_rc(c));
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-08-30 15:33:42 +00:00
|
|
|
if (!(p->prog_modes & (PM_PDI | PM_UPDI)))
|
2010-01-11 16:04:29 +00:00
|
|
|
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.
|
|
|
|
*/
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_chip_erase_dw(const PROGRAMMER *pgm, const AVRPART *p) {
|
2006-11-20 23:23:37 +00:00
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_info("chip erase not supported in debugWire mode\n");
|
2006-11-20 23:23:37 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static void jtagmkII_set_devdescr(const PROGRAMMER *pgm, const AVRPART *p) {
|
2005-05-10 19:53:56 +00:00
|
|
|
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;
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
u16_to_b2(sendbuf.dd.EECRAddress, p->eecr? p->eecr: 0x3f); // Unset eecr means 0x3f
|
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);
|
2022-08-30 15:33:42 +00:00
|
|
|
if (p->prog_modes & PM_debugWIRE) {
|
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 =
|
2022-08-30 15:33:42 +00:00
|
|
|
p->prog_modes & (PM_PDI | PM_UPDI)? 0x02 /* ATxmega */: 0x00;
|
2005-05-10 19:53:56 +00:00
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_set_devdescr(): "
|
|
|
|
"Sending set device descriptor command: ");
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2005-05-10 19:53:56 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to set device descriptor command: %s\n", jtagmkII_get_rc(c));
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static void jtagmkII_set_xmega_params(const PROGRAMMER *pgm, const AVRPART *p) {
|
2012-04-13 15:25:41 +00:00
|
|
|
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);
|
2022-02-28 18:46:47 +00:00
|
|
|
} else if (strcmp(m->desc, "usersig") == 0 ||
|
|
|
|
strcmp(m->desc, "userrow") == 0) {
|
2012-04-13 15:25:41 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_set_xmega_params(): "
|
|
|
|
"Sending set Xmega params command: ");
|
2012-04-13 15:25:41 +00:00
|
|
|
jtagmkII_send(pgm, (unsigned char *)&sendbuf, sizeof sendbuf);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2012-04-13 15:25:41 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2012-04-13 15:25:41 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to set device descriptor command: %s\n", jtagmkII_get_rc(c));
|
2012-04-13 15:25:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
/*
|
|
|
|
* Reset the target.
|
|
|
|
*/
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_reset(const 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;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_reset(): sending %s command: ",
|
|
|
|
(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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to reset command: %s\n", jtagmkII_get_rc(c));
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_program_enable_INFO(const PROGRAMMER *pgm, const AVRPART *p) {
|
2005-05-10 19:53:56 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_program_enable(const PROGRAMMER *pgm) {
|
2005-05-10 19:53:56 +00:00
|
|
|
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;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_program_enable(): "
|
|
|
|
"Sending enter progmode command: ");
|
2010-01-17 17:31:10 +00:00
|
|
|
jtagmkII_send(pgm, buf, 1);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2010-01-17 17:31:10 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2010-01-17 17:31:10 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("bad response to enter progmode command: %s\n", 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};
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("retrying with external reset applied\n");
|
2010-01-17 17:31:10 +00:00
|
|
|
|
|
|
|
(void)jtagmkII_setparm(pgm, PAR_EXTERNAL_RESET, parm);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("JTAGEN fuse disabled?\n");
|
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;
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_program_disable(const PROGRAMMER *pgm) {
|
2005-05-10 19:53:56 +00:00
|
|
|
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;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_program_disable(): "
|
|
|
|
"Sending leave progmode command: ");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_send(pgm, buf, 1);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to leave progmode command: %s\n", 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
|
|
|
|
*/
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
|
2005-05-10 19:53:56 +00:00
|
|
|
AVRMEM hfuse;
|
|
|
|
unsigned char b;
|
2006-11-20 23:23:37 +00:00
|
|
|
int ok;
|
|
|
|
const char *ifname;
|
|
|
|
|
2022-01-02 11:57:42 +00:00
|
|
|
/* Abort and print error if programmer does not support the target microcontroller */
|
2022-08-30 15:33:42 +00:00
|
|
|
if ((strncmp(pgm->type, "JTAGMKII_UPDI", strlen("JTAGMKII_UPDI")) == 0 && !(p->prog_modes & PM_UPDI)) ||
|
|
|
|
(strncmp(ldata(lfirst(pgm->id)), "jtagmkII", strlen("jtagmkII")) == 0 && (p->prog_modes & PM_UPDI))) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("programmer %s does not support target %s\n\n",
|
|
|
|
(char *) ldata(lfirst(pgm->id)), p->desc);
|
2022-01-02 11:57:42 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2006-11-20 23:23:37 +00:00
|
|
|
ok = 0;
|
|
|
|
if (pgm->flag & PGM_FL_IS_DW) {
|
|
|
|
ifname = "debugWire";
|
2022-08-30 15:33:42 +00:00
|
|
|
if (p->prog_modes & PM_debugWIRE)
|
2006-11-20 23:23:37 +00:00
|
|
|
ok = 1;
|
2010-01-13 17:34:18 +00:00
|
|
|
} else if (pgm->flag & PGM_FL_IS_PDI) {
|
|
|
|
ifname = "PDI";
|
2022-08-30 15:33:42 +00:00
|
|
|
if (p->prog_modes & (PM_PDI | PM_UPDI))
|
2010-01-13 17:34:18 +00:00
|
|
|
ok = 1;
|
2006-11-20 23:23:37 +00:00
|
|
|
} else {
|
|
|
|
ifname = "JTAG";
|
2022-09-20 17:36:46 +00:00
|
|
|
if (p->prog_modes & (PM_JTAG | PM_JTAGmkI | PM_XMEGAJTAG | PM_AVR32JTAG))
|
2006-11-20 23:23:37 +00:00
|
|
|
ok = 1;
|
|
|
|
}
|
2005-05-10 19:53:56 +00:00
|
|
|
|
2006-11-20 23:23:37 +00:00
|
|
|
if (!ok) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("part %s has no %s interface\n", 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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("unsupported baudrate %d\n", pgm->baudrate);
|
2005-05-10 19:53:56 +00:00
|
|
|
} else {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_initialize(): "
|
|
|
|
"trying to set baudrate to %d\n", pgm->baudrate);
|
2005-05-10 19:53:56 +00:00
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_initialize(): "
|
|
|
|
"trying to set JTAG clock period to %.1f us\n", pgm->bitclock);
|
2005-05-10 19:53:56 +00:00
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("unable to setup JTAG chain\n");
|
2007-11-06 19:42:16 +00:00
|
|
|
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) &&
|
2022-08-30 15:33:42 +00:00
|
|
|
(p->prog_modes & (PM_PDI | PM_UPDI))) {
|
2012-05-04 10:02:30 +00:00
|
|
|
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.
|
|
|
|
*/
|
2022-08-30 15:33:42 +00:00
|
|
|
if (PDATA(pgm)->fwver >= 0x700 && (p->prog_modes & (PM_PDI | PM_UPDI)) != 0)
|
2012-04-13 15:25:41 +00:00
|
|
|
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;
|
2022-08-30 15:33:42 +00:00
|
|
|
if ((p->prog_modes & (PM_PDI | PM_UPDI))) {
|
|
|
|
// Find the border between application and boot area
|
2012-03-30 16:19:13 +00:00
|
|
|
AVRMEM *bootmem = avr_locate_mem(p, "boot");
|
|
|
|
AVRMEM *flashmem = avr_locate_mem(p, "flash");
|
|
|
|
if (bootmem == NULL || flashmem == NULL) {
|
2022-01-02 18:20:05 +00:00
|
|
|
if (strncmp(ldata(lfirst(pgm->id)), "jtagmkII", strlen("jtagmkII")) == 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("cannot locate flash or boot memories in description\n");
|
2022-01-02 18:20:05 +00:00
|
|
|
}
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("out of memory\n");
|
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
|
|
|
if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("out of memory\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
|
|
|
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
|
|
|
|
2022-08-30 15:33:42 +00:00
|
|
|
if (PDATA(pgm)->fwver >= 0x700 && (p->prog_modes & (PM_PDI | PM_UPDI))) {
|
2012-12-18 09:20:06 +00:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
2022-08-30 15:33:42 +00:00
|
|
|
if ((pgm->flag & PGM_FL_IS_JTAG) && !(p->prog_modes & (PM_PDI | PM_UPDI))) {
|
Replace string arrays with const char * and allocated space (part 2)
This commit replaces fixed-string buffers in PROGRAMMER, AVRPART and AVRMEM
that are dealt with by the parser and grammar. Now, string assignments are
always to const char *, ie, these are read-only strings with arbitrary
length.
config_gram.y now only needs to consider one type of string assignment.
This commit also
- Replaces the simple linear-search cache_string() function with faster
hashed cache_string(). Either way, the returned value is likely to be
shared, so should never be free()'d.
- Duplicates hvupdi_support list in pgm_dup() and frees it in pgm_free()
- Adds const qualifier to some function args in avrpart.c and pgm.c
- Hardens some functions against being called with NULL pointers
- Ensures _new() and _dup() functions for parts, programmers and memory
return a suitable memory. Out of memory triggers exit in one of three
functions, cfg_malloc(), cfg_realloc() and cfg_strdup(); there is
rarely anything useful that AVRDUDE or, for that matter, any
application compiled against libavrdude can do once you run out of
memory as AVRDUDE/libavrdude rely heavily on allocation of memory.
2022-08-10 15:14:56 +00:00
|
|
|
hfuse.desc = cache_string("hfuse");
|
2006-11-20 23:23:37 +00:00
|
|
|
if (jtagmkII_read_byte(pgm, p, &hfuse, 1, &b) < 0)
|
|
|
|
return -1;
|
|
|
|
if ((b & OCDEN) != 0)
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("OCDEN fuse not programmed, "
|
|
|
|
"single-byte EEPROM updates not possible\n");
|
2006-11-20 23:23:37 +00:00
|
|
|
}
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static void jtagmkII_disable(const PROGRAMMER *pgm) {
|
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);
|
|
|
|
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
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static void jtagmkII_enable(PROGRAMMER * pgm, const AVRPART *p) {
|
2005-05-10 19:53:56 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
|
2007-11-06 19:42:16 +00:00
|
|
|
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;
|
2022-10-17 14:44:55 +00:00
|
|
|
if (sscanf(extended_param, "jtagchain=%u,%u,%u,%u", &ub, &ua, &bb, &ba) != 4) {
|
|
|
|
pmsg_error("invalid JTAG chain '%s'\n", extended_param);
|
2007-11-06 19:42:16 +00:00
|
|
|
rv = -1;
|
|
|
|
continue;
|
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_parseextparms(): JTAG chain parsed as:\n");
|
|
|
|
imsg_notice2("%u units before, %u units after, %u bits before, %u bits after\n",
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("invalid extended parameter '%s'\n", extended_param);
|
2007-11-06 19:42:16 +00:00
|
|
|
rv = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_open(PROGRAMMER *pgm, const char *port) {
|
2014-02-21 13:44:11 +00:00
|
|
|
union pinfo pinfo;
|
2006-01-12 23:13:50 +00:00
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_open()\n");
|
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
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("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;
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_open_dw(PROGRAMMER *pgm, const char *port) {
|
2014-02-21 13:44:11 +00:00
|
|
|
union pinfo pinfo;
|
2006-11-20 23:23:37 +00:00
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_open_dw()\n");
|
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
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("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;
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_open_pdi(PROGRAMMER *pgm, const char *port) {
|
2014-02-21 13:44:11 +00:00
|
|
|
union pinfo pinfo;
|
2010-01-13 17:34:18 +00:00
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_open_pdi()\n");
|
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
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("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
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_dragon_open(PROGRAMMER *pgm, const char *port) {
|
2014-02-21 13:44:11 +00:00
|
|
|
union pinfo pinfo;
|
2006-10-26 21:14:10 +00:00
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_dragon_open()\n");
|
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
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_dragon_open_dw(PROGRAMMER *pgm, const char *port) {
|
2014-02-21 13:44:11 +00:00
|
|
|
union pinfo pinfo;
|
2006-11-20 23:23:37 +00:00
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_dragon_open_dw()\n");
|
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
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_dragon_open_pdi(PROGRAMMER *pgm, const char *port) {
|
2014-02-21 13:44:11 +00:00
|
|
|
union pinfo pinfo;
|
2010-01-13 17:34:18 +00:00
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_dragon_open_pdi()\n");
|
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
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("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;
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_close()\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
|
2022-05-29 11:12:50 +00:00
|
|
|
if (pgm->flag & (PGM_FL_IS_PDI | PGM_FL_IS_JTAG)) {
|
|
|
|
/* When in PDI or JTAG mode, restart target. */
|
2012-03-20 14:42:20 +00:00
|
|
|
buf[0] = CMND_GO;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_close(): sending GO command: ");
|
2012-03-20 14:42:20 +00:00
|
|
|
jtagmkII_send(pgm, buf, 1);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2012-03-20 14:42:20 +00:00
|
|
|
} else {
|
|
|
|
if (verbose >= 3) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2012-03-20 14:42:20 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to GO command: %s\n", 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;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_close(): sending sign-off command: ");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_send(pgm, buf, 1);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2005-05-10 19:53:56 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to sign-off command: %s\n", 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
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
|
2012-05-04 10:02:30 +00:00
|
|
|
unsigned int addr)
|
|
|
|
{
|
|
|
|
unsigned char cmd[6];
|
|
|
|
unsigned char *resp;
|
|
|
|
int status, tries;
|
|
|
|
long otimeout = serial_recv_timeout;
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_page_erase(.., %s, 0x%x)\n", m->desc, addr);
|
2012-05-04 10:02:30 +00:00
|
|
|
|
2022-08-30 15:33:42 +00:00
|
|
|
if (!(p->prog_modes & (PM_PDI | PM_UPDI))) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("not an Xmega nor a UPDI device\n");
|
2012-05-04 10:02:30 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if ((pgm->flag & PGM_FL_IS_DW)) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("not applicable to debugWIRE\n");
|
2012-05-04 10:02:30 +00:00
|
|
|
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;
|
2022-02-28 18:46:47 +00:00
|
|
|
} else if (strcmp(m->desc, "usersig") == 0 ||
|
|
|
|
strcmp(m->desc, "userrow") == 0) {
|
2012-05-04 10:02:30 +00:00
|
|
|
cmd[1] = XMEGA_ERASE_USERSIG;
|
2022-02-28 18:46:47 +00:00
|
|
|
} else if (strcmp(m->desc, "boot") == 0) {
|
2012-05-04 10:02:30 +00:00
|
|
|
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:
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_page_erase(): "
|
|
|
|
"Sending Xmega erase command: ");
|
2012-05-04 10:02:30 +00:00
|
|
|
jtagmkII_send(pgm, cmd, sizeof cmd);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_warning("timeout/error communicating with programmer (status %d)\n", status);
|
2012-05-04 10:02:30 +00:00
|
|
|
if (tries++ < 4) {
|
|
|
|
serial_recv_timeout *= 2;
|
|
|
|
goto retry;
|
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2012-05-04 10:02:30 +00:00
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2012-05-04 10:02:30 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status);
|
2012-05-04 10:02:30 +00:00
|
|
|
if (resp[0] != RSP_OK) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to xmega erase command: %s\n", 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;
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const 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;
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_paged_write(.., %s, %d, %d)\n", m->desc, page_size, n_bytes);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("out of memory\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
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);
|
2022-08-30 15:33:42 +00:00
|
|
|
if (p->prog_modes & (PM_PDI | PM_UPDI))
|
2012-03-30 16:19:13 +00:00
|
|
|
/* 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
|
|
|
}
|
2022-08-30 15:33:42 +00:00
|
|
|
cmd[1] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_EEPROM: MTYPE_EEPROM_PAGE;
|
2009-02-16 12:26:44 +00:00
|
|
|
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
|
2022-02-28 18:46:47 +00:00
|
|
|
} else if (strcmp(m->desc, "usersig") == 0 ||
|
|
|
|
strcmp(m->desc, "userrow") == 0) {
|
2012-03-30 16:19:13 +00:00
|
|
|
cmd[1] = MTYPE_USERSIG;
|
2022-02-28 18:46:47 +00:00
|
|
|
} else if (strcmp(m->desc, "boot") == 0) {
|
2012-04-26 10:57:09 +00:00
|
|
|
cmd[1] = MTYPE_BOOT_FLASH;
|
2022-08-30 15:33:42 +00:00
|
|
|
} else if (p->prog_modes & (PM_PDI | PM_UPDI)) {
|
2012-04-26 10:57:09 +00:00
|
|
|
cmd[1] = MTYPE_FLASH;
|
|
|
|
} else {
|
|
|
|
cmd[1] = MTYPE_SPM;
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
2021-12-29 12:32:56 +00:00
|
|
|
serial_recv_timeout = 200;
|
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;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_debug("jtagmkII_paged_write(): "
|
|
|
|
"block_size at addr %d is %d\n", addr, block_size);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
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:
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_paged_write(): "
|
|
|
|
"Sending write memory command: ");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_send(pgm, cmd, page_size + 10);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_warning("timeout/error communicating with programmer (status %d)\n", 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
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2005-05-10 19:53:56 +00:00
|
|
|
free(cmd);
|
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status);
|
2005-05-10 19:53:56 +00:00
|
|
|
if (resp[0] != RSP_OK) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to write memory command: %s\n", 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;
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const 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;
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_paged_load(.., %s, %d, %d)\n", m->desc, page_size, n_bytes);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
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);
|
2022-08-30 15:33:42 +00:00
|
|
|
if (p->prog_modes & (PM_PDI | PM_UPDI))
|
2012-04-13 15:25:41 +00:00
|
|
|
/* dynamically decide between flash/boot memtype */
|
|
|
|
dynamic_memtype = 1;
|
|
|
|
} else if (strcmp(m->desc, "eeprom") == 0) {
|
2022-08-30 15:33:42 +00:00
|
|
|
cmd[1] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_EEPROM: MTYPE_EEPROM_PAGE;
|
2006-11-20 23:23:37 +00:00
|
|
|
if (pgm->flag & PGM_FL_IS_DW)
|
|
|
|
return -1;
|
2022-02-28 18:46:47 +00:00
|
|
|
} else if (strcmp(m->desc, "prodsig") == 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] = MTYPE_PRODSIG;
|
2022-02-28 18:46:47 +00:00
|
|
|
} else if (strcmp(m->desc, "usersig") == 0 ||
|
|
|
|
strcmp(m->desc, "userrow") == 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] = MTYPE_USERSIG;
|
2022-02-28 18:46:47 +00:00
|
|
|
} else if (strcmp(m->desc, "boot") == 0) {
|
2012-04-26 10:57:09 +00:00
|
|
|
cmd[1] = MTYPE_BOOT_FLASH;
|
2022-08-30 15:33:42 +00:00
|
|
|
} else if (p->prog_modes & (PM_PDI | PM_UPDI)) {
|
2012-04-26 10:57:09 +00:00
|
|
|
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;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_debug("jtagmkII_paged_load(): "
|
|
|
|
"block_size at addr %d is %d\n", addr, block_size);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
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;
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
retry:
|
|
|
|
pmsg_notice2("jtagmkII_paged_load(): sending read memory command: ");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_send(pgm, cmd, 10);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_warning("timeout/error communicating with programmer (status %d)\n", 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
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2005-05-10 19:53:56 +00:00
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status);
|
2005-05-10 19:53:56 +00:00
|
|
|
if (resp[0] != RSP_MEMORY) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to read memory command: %s\n", 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
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
|
|
|
|
static int jtagmkII_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
|
2005-05-10 19:53:56 +00:00
|
|
|
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;
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_read_byte(.., %s, 0x%lx, ...)\n", mem->desc, addr);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
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;
|
2022-08-30 15:33:42 +00:00
|
|
|
cmd[1] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_FLASH: MTYPE_FLASH_PAGE;
|
2022-08-15 13:57:04 +00:00
|
|
|
if (avr_mem_is_flash_type(mem)) {
|
2012-05-04 10:02:30 +00:00
|
|
|
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;
|
2022-08-15 13:57:04 +00:00
|
|
|
} else if (avr_mem_is_eeprom_type(mem)) {
|
2022-08-30 15:33:42 +00:00
|
|
|
if ( (pgm->flag & PGM_FL_IS_DW) || (p->prog_modes & (PM_PDI | PM_UPDI)) ) {
|
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;
|
2022-02-28 18:46:47 +00:00
|
|
|
} else if (strcmp(mem->desc, "usersig") == 0 ||
|
|
|
|
strcmp(mem->desc, "userrow") == 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] = 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:
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("illegal address %lu for signature memory\n", addr);
|
2006-11-20 23:23:37 +00:00
|
|
|
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;
|
2022-10-17 14:44:55 +00:00
|
|
|
retry:
|
|
|
|
pmsg_notice2("jtagmkII_read_byte(): sending read memory command: ");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_send(pgm, cmd, 10);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_warning("timeout/error communicating with programmer (status %d)\n", status);
|
2005-05-10 19:53:56 +00:00
|
|
|
if (tries++ < 3)
|
|
|
|
goto retry;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", 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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status);
|
2005-05-10 19:53:56 +00:00
|
|
|
if (resp[0] != RSP_MEMORY) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to read memory command: %s\n", 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
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
|
2005-05-10 19:53:56 +00:00
|
|
|
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
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_write_byte(.., %s, 0x%lx, ...)\n", mem->desc, addr);
|
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;
|
|
|
|
|
2005-05-10 19:53:56 +00:00
|
|
|
writedata = data;
|
|
|
|
cmd[0] = CMND_WRITE_MEMORY;
|
2022-08-30 15:33:42 +00:00
|
|
|
cmd[1] = p->prog_modes & (PM_PDI | PM_UPDI)? 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) {
|
2022-08-30 15:33:42 +00:00
|
|
|
cmd[1] = p->prog_modes & (PM_PDI | PM_UPDI)? 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;
|
2022-02-28 18:46:47 +00:00
|
|
|
} else if (strcmp(mem->desc, "usersig") == 0 ||
|
|
|
|
strcmp(mem->desc, "userrow") == 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] = 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;
|
2022-10-17 14:44:55 +00:00
|
|
|
retry:
|
|
|
|
pmsg_notice2("jtagmkII_write_byte(): sending write memory command: ");
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_notice2("jtagmkII_write_byte(): "
|
|
|
|
"timeout/error communicating with programmer (status %d)\n", status);
|
2005-05-10 19:53:56 +00:00
|
|
|
if (tries++ < 3)
|
|
|
|
goto retry;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2005-05-10 19:53:56 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status);
|
2005-05-10 19:53:56 +00:00
|
|
|
if (resp[0] != RSP_OK) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to write memory command: %s\n", 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.
|
|
|
|
*/
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_set_sck_period(const PROGRAMMER *pgm, double v) {
|
2005-05-10 19:53:56 +00:00
|
|
|
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.
|
|
|
|
*/
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
int jtagmkII_getparm(const PROGRAMMER *pgm, unsigned char parm,
|
2006-09-06 20:06:07 +00:00
|
|
|
unsigned char * value)
|
2005-05-10 19:53:56 +00:00
|
|
|
{
|
|
|
|
int status;
|
|
|
|
unsigned char buf[2], *resp, c;
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_getparm()\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
buf[0] = CMND_GET_PARAMETER;
|
|
|
|
buf[1] = parm;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_getparm(): "
|
|
|
|
"Sending get parameter command (parm 0x%02x): ", parm);
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_send(pgm, buf, 2);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to get parameter command: %s\n", 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.
|
|
|
|
*/
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_setparm(const PROGRAMMER *pgm, unsigned char parm,
|
2005-05-10 19:53:56 +00:00
|
|
|
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;
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_setparm()\n");
|
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:
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("unknown parameter 0x%02x\n", parm);
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
buf[0] = CMND_SET_PARAMETER;
|
|
|
|
buf[1] = parm;
|
|
|
|
memcpy(buf + 2, value, size);
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_setparm(): "
|
|
|
|
"Sending set parameter command (parm 0x%02x, %u bytes): ", 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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2005-05-10 19:53:56 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to set parameter command: %s\n", jtagmkII_get_rc(c));
|
2005-05-10 19:53:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static void jtagmkII_display(const 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;
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("%sM_MCU HW version: %d\n", p, hw[0]);
|
|
|
|
msg_info("%sM_MCU FW version: %d.%02d\n", p, fw[1], fw[0]);
|
|
|
|
msg_info("%sS_MCU HW version: %d\n", p, hw[1]);
|
|
|
|
msg_info("%sS_MCU FW version: %d.%02d\n", p, fw[3], fw[2]);
|
|
|
|
msg_info("%sSerial number : %02x:%02x:%02x:%02x:%02x:%02x\n", 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
|
|
|
|
2022-10-23 20:56:45 +00:00
|
|
|
jtagmkII_print_parms1(pgm, p, stderr);
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-10-23 20:56:45 +00:00
|
|
|
static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) {
|
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;
|
|
|
|
|
2022-10-23 20:56:45 +00:00
|
|
|
fmsg_out(fp, "%sVtarget : %.1f V\n", p, 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];
|
|
|
|
|
2022-10-23 20:56:45 +00:00
|
|
|
fmsg_out(fp, "%sJTAG clock : %s (%.1f us)\n", p, clkbuf, 1.0e6 / clk);
|
2006-11-20 23:23:37 +00:00
|
|
|
}
|
|
|
|
}
|
2005-05-10 19:53:56 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-10-23 20:56:45 +00:00
|
|
|
static void jtagmkII_print_parms(const PROGRAMMER *pgm, FILE *fp) {
|
|
|
|
jtagmkII_print_parms1(pgm, "", fp);
|
2005-05-10 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static unsigned char jtagmkII_memtype(const PROGRAMMER *pgm, const AVRPART *p, unsigned long addr) {
|
2022-08-30 15:33:42 +00:00
|
|
|
if (p->prog_modes & (PM_PDI | PM_UPDI)) {
|
2012-03-30 16:19:13 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static unsigned int jtagmkII_memaddr(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr) {
|
2012-04-13 15:25:41 +00:00
|
|
|
/*
|
|
|
|
* Xmega devices handled by V7+ firmware don't want to be told their
|
|
|
|
* m->offset within the write memory command.
|
|
|
|
*/
|
2022-08-30 15:33:42 +00:00
|
|
|
if (PDATA(pgm)->fwver >= 0x700 && (p->prog_modes & (PM_PDI | PM_UPDI))) {
|
2012-04-13 15:25:41 +00:00
|
|
|
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
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_avr32_reset(const PROGRAMMER *pgm, unsigned char val,
|
2010-01-13 08:37:57 +00:00
|
|
|
unsigned char ret1, unsigned char ret2)
|
2009-10-10 20:09:53 +00:00
|
|
|
{
|
|
|
|
int status;
|
|
|
|
unsigned char buf[3], *resp;
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice("jtagmkII_avr32_reset(%2.2x)\n", val);
|
2009-10-12 16:44:30 +00:00
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice("jtagmkII_avr32_reset(): "
|
|
|
|
"Get_IR, expecting %2.2x but got %2.2x\n", ret1, resp[1]);
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
//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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice("jtagmkII_avr32_reset(): "
|
|
|
|
"Get_XXX, expecting %2.2x but got %2.2x\n", ret2, resp[1]);
|
2009-10-10 20:09:53 +00:00
|
|
|
//return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// At init: AVR32_RESET_READ_IR | AVR32_RESET_READ_READ_CHIPINFO
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_reset32(const PROGRAMMER *pgm, unsigned short flags) {
|
2009-10-10 20:09:53 +00:00
|
|
|
int status, j, lineno;
|
|
|
|
unsigned char *resp, buf[3];
|
|
|
|
unsigned long val=0;
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice("jtagmkII_reset32(%2.2x)\n", flags);
|
2009-10-12 16:44:30 +00:00
|
|
|
|
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;}
|
|
|
|
|
2022-10-17 14:44:55 +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:
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("reset failed at line %d (status=%x val=%lx)\n", lineno, status, val);
|
2009-10-10 20:09:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_smc_init32(const PROGRAMMER *pgm) {
|
2009-10-10 20:09:53 +00:00
|
|
|
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:
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("init failed at line %d\n", lineno);
|
2009-10-10 20:09:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* initialize the AVR device and prepare it to accept commands
|
|
|
|
*/
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_initialize32(const PROGRAMMER *pgm, const 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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("unable to setup JTAG chain\n");
|
2009-10-10 20:09:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(PDATA(pgm)->flash_pagecache);
|
|
|
|
free(PDATA(pgm)->eeprom_pagecache);
|
|
|
|
if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("out of memory\n");
|
2009-10-10 20:09:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("out of memory\n");
|
2009-10-10 20:09:53 +00:00
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2009-10-10 20:09:53 +00:00
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2009-10-10 20:09:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status != 5 ||
|
|
|
|
resp[2] != p->signature[0] ||
|
|
|
|
resp[3] != p->signature[1] ||
|
|
|
|
resp[4] != p->signature[2]) {
|
2022-10-17 14:44:55 +00:00
|
|
|
if (ovsigck) {
|
|
|
|
pmsg_warning("expected signature for %s is %02X %02X %02X\n", p->desc,
|
|
|
|
p->signature[0], p->signature[1], p->signature[2]);
|
|
|
|
} else {
|
|
|
|
pmsg_error("expected signature for %s is %02X %02X %02X\n", p->desc,
|
2009-10-10 20:09:53 +00:00
|
|
|
p->signature[0], p->signature[1], p->signature[2]);
|
2022-10-17 14:44:55 +00:00
|
|
|
imsg_error("double check chip or use -F to override this check\n");
|
2009-10-10 20:09:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(resp);
|
|
|
|
}
|
|
|
|
|
2009-10-12 16:44:30 +00:00
|
|
|
return 0;
|
2009-10-10 20:09:53 +00:00
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_chip_erase32(const PROGRAMMER *pgm, const 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;
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice("jtagmkII_chip_erase32()\n");
|
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:
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("chip erase failed at line %d (status=%x val=%lx)\n", lineno, status, val);
|
2009-10-10 20:09:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static unsigned long jtagmkII_read_SABaddr(const PROGRAMMER *pgm, unsigned long addr,
|
2010-01-13 08:37:57 +00:00
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d) resp=%x\n", status, resp[0]);
|
2009-10-10 20:09:53 +00:00
|
|
|
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;
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("cmd: ");
|
|
|
|
for(i=0; i<6; ++i)
|
|
|
|
msg_error("%2.2x ", buf[i]);
|
|
|
|
msg_error("\n");
|
|
|
|
msg_error("Data: ");
|
|
|
|
for(i=0; i<status; ++i)
|
|
|
|
msg_error("%2.2x ", resp[i]);
|
|
|
|
msg_error("\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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_error("wrong number of bytes (status %d)\n", status);
|
2009-10-10 20:09:53 +00:00
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
return ERROR_SAB;
|
|
|
|
}
|
|
|
|
|
|
|
|
val = b4_to_u32r(&resp[1]);
|
|
|
|
free(resp);
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_notice("jtagmkII_read_SABaddr(): OCD Register %lx -> %4.4lx\n", addr, val);
|
2009-10-10 20:09:53 +00:00
|
|
|
serial_recv_timeout = otimeout;
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_write_SABaddr(const PROGRAMMER *pgm, unsigned long addr,
|
2010-01-13 08:37:57 +00:00
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2009-10-10 20:09:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_notice("jtagmkII_write_SABaddr(): OCD Register %lx -> %4.4lx\n", addr, val);
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_open32(PROGRAMMER *pgm, const char *port) {
|
2009-10-10 20:09:53 +00:00
|
|
|
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
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_open32()\n");
|
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
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("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
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_close32()\n");
|
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;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_close(): sending sign-off command: ");
|
2009-10-10 20:09:53 +00:00
|
|
|
jtagmkII_send(pgm, buf, 1);
|
|
|
|
|
|
|
|
status = jtagmkII_recv(pgm, &resp);
|
|
|
|
if (status <= 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_notice2("\n");
|
|
|
|
pmsg_error("timeout/error communicating with programmer (status %d)\n", status);
|
2009-10-10 20:09:53 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (verbose >= 3) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2009-10-10 20:09:53 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to sign-off command: %s\n", jtagmkII_get_rc(c));
|
2009-10-10 20:09:53 +00:00
|
|
|
}
|
|
|
|
|
2009-10-10 23:34:03 +00:00
|
|
|
ret:
|
|
|
|
serial_close(&pgm->fd);
|
|
|
|
pgm->fd.ifd = -1;
|
|
|
|
return;
|
|
|
|
|
|
|
|
eRR:
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("close failed at line %d (status=%x val=%lx)\n", lineno, status, val);
|
2009-10-10 23:34:03 +00:00
|
|
|
goto ret;
|
2009-10-10 20:09:53 +00:00
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_paged_load32(const PROGRAMMER *pgm, const AVRPART *p, const 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;
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("jtagmkII_paged_load32(.., %s, %d, %d)\n", m->desc, page_size, n_bytes);
|
2009-10-10 23:34:03 +00:00
|
|
|
|
|
|
|
serial_recv_timeout = 256;
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
if(!(PDATA(pgm)->flags32 & FLAGS32_WRITE)) {
|
2009-10-12 16:44:30 +00:00
|
|
|
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
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
if(!(PDATA(pgm)->flags32 & FLAGS32_INIT_SMC)) {
|
2009-10-12 16:44:30 +00:00
|
|
|
status = jtagmkII_smc_init32(pgm);
|
|
|
|
if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
PDATA(pgm)->flags32 |= FLAGS32_INIT_SMC;
|
2009-10-12 16:44:30 +00:00
|
|
|
}
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
//msg_error("\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;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_debug("jtagmkII_paged_load32(): "
|
|
|
|
"block_size at addr %d is %d\n", addr, block_size);
|
2009-10-10 23:34:03 +00:00
|
|
|
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2009-10-10 23:34:03 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status);
|
2009-10-10 23:34:03 +00:00
|
|
|
if (resp[0] != 0x87) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to write memory command: %s\n", jtagmkII_get_rc(resp[0]));
|
2009-10-10 23:34:03 +00:00
|
|
|
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;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("paged load failed at line %d (status=%x val=%lx)\n", lineno, status, val);
|
2009-10-10 23:34:03 +00:00
|
|
|
return -1;
|
2009-10-10 20:09:53 +00:00
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_paged_write32(const PROGRAMMER *pgm, const AVRPART *p, const 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;}
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
PDATA(pgm)->flags32 |= FLAGS32_WRITE;
|
2009-10-12 16:44:30 +00:00
|
|
|
|
2011-09-14 21:49:42 +00:00
|
|
|
pages = (n_bytes - addr - 1)/page_size + 1;
|
|
|
|
sPageNum = addr/page_size;
|
2022-10-17 14:44:55 +00:00
|
|
|
//msg_error("\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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("out of memory\n");
|
2009-10-10 20:09:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Init SMC and set clocks
|
2022-08-30 15:33:42 +00:00
|
|
|
if(!(PDATA(pgm)->flags32 & FLAGS32_INIT_SMC)) {
|
2009-10-12 16:44:30 +00:00
|
|
|
status = jtagmkII_smc_init32(pgm);
|
|
|
|
if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
PDATA(pgm)->flags32 |= FLAGS32_INIT_SMC;
|
2009-10-12 16:44:30 +00:00
|
|
|
}
|
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;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_debug("jtagmkII_paged_write32(): "
|
|
|
|
"block_size at addr %d is %d\n", addr, block_size);
|
2009-10-10 20:09:53 +00:00
|
|
|
|
|
|
|
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) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_debug("\n");
|
2009-10-10 20:09:53 +00:00
|
|
|
jtagmkII_prmsg(pgm, resp, status);
|
2022-10-17 14:44:55 +00:00
|
|
|
} else
|
|
|
|
msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status);
|
2009-10-10 20:09:53 +00:00
|
|
|
if (resp[0] != RSP_OK) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("bad response to write memory command: %s\n", jtagmkII_get_rc(resp[0]));
|
2009-10-10 20:09:53 +00:00
|
|
|
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);
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("paged write failed at line %d (status=%x val=%lx)\n", lineno, status, val);
|
2009-10-10 20:09:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_flash_lock32(const PROGRAMMER *pgm, unsigned char lock, unsigned int page) {
|
2009-10-10 20:09:53 +00:00
|
|
|
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:
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("flash lock failed at line %d page %d cmd %8.8lx\n", lineno, page, cmd);
|
|
|
|
return -1;
|
2009-10-10 20:09:53 +00:00
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_flash_erase32(const PROGRAMMER *pgm, unsigned int page) {
|
2009-10-10 20:09:53 +00:00
|
|
|
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
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
//msg_error("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:
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("flash erase failed at line %d page %d cmd %8.8lx val %lx\n", lineno, page, cmd, val);
|
2009-10-10 20:09:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_flash_write_page32(const PROGRAMMER *pgm, unsigned int page) {
|
2009-10-10 20:09:53 +00:00
|
|
|
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:
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("flash write failed at line %d page %d cmd %8.8lx val %lx\n", lineno, page, cmd, val);
|
2009-10-10 20:09:53 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2010-01-13 08:37:57 +00:00
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
static int jtagmkII_flash_clear_pagebuffer32(const PROGRAMMER *pgm) {
|
2009-10-10 20:09:53 +00:00
|
|
|
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:
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("clear page buffer failed at line %d cmd %8.8lx val %lx\n", lineno, cmd, val);
|
2009-10-10 20:09:53 +00:00
|
|
|
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";
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
void jtagmkII_initpgm(PROGRAMMER *pgm) {
|
2010-01-13 08:37:57 +00:00
|
|
|
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";
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
void jtagmkII_dw_initpgm(PROGRAMMER *pgm) {
|
2010-01-13 08:37:57 +00:00
|
|
|
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
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
void jtagmkII_pdi_initpgm(PROGRAMMER *pgm) {
|
2010-01-13 17:34:18 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-07-26 09:30:53 +00:00
|
|
|
const char jtagmkII_updi_desc[] = "Atmel JTAG ICE mkII in UPDI mode";
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
void jtagmkII_updi_initpgm(PROGRAMMER *pgm) {
|
2022-07-26 09:30:53 +00:00
|
|
|
strcpy(pgm->type, "JTAGMKII_UPDI");
|
|
|
|
|
|
|
|
/*
|
|
|
|
* mandatory functions
|
|
|
|
*/
|
|
|
|
pgm->initialize = jtagmkII_initialize;
|
|
|
|
pgm->display = jtagmkII_display;
|
|
|
|
pgm->enable = jtagmkII_enable;
|
|
|
|
pgm->disable = jtagmkII_disable;
|
|
|
|
pgm->program_enable = jtagmkII_program_enable_INFO;
|
|
|
|
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;
|
|
|
|
pgm->page_erase = jtagmkII_page_erase;
|
|
|
|
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
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
void jtagmkII_dragon_initpgm(PROGRAMMER *pgm) {
|
2010-01-13 08:37:57 +00:00
|
|
|
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
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
void jtagmkII_dragon_dw_initpgm(PROGRAMMER *pgm) {
|
2010-01-13 08:37:57 +00:00
|
|
|
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";
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
void jtagmkII_avr32_initpgm(PROGRAMMER *pgm) {
|
2010-01-13 08:37:57 +00:00
|
|
|
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";
|
|
|
|
|
Use const in PROGRAMMER function arguments where appropriate
In order to get meaningful const properties for the PROGRAMMER, AVRPART and
AVRMEM arguments, some code needed to be moved around, otherwise a network of
"tainted" assignments risked rendering nothing const:
- Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm,
const AVRPART *p); this allows changes in the PROGRAMMER structure after
the part is known. For example, use TPI, UPDI, PDI functions in that
programmer appropriate to the part. This used to be done later in the
process, eg, in the initialize() function, which "taints" all other
programmer functions wrt const and sometimes requires other finessing with
flags etc. Much clearer with the modified enable() interface.
- Move TPI initpgm-type code from initialize() to enable() --- note that
initpgm() does not have the info at the time when it is called whether or
not TPI is required
- buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate
modification of the flag does not change PROGRAMMER structure)
- Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in
AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and
FLAGS32_WRITE bits
- Move the xbeeResetPin component to private data in stk500.c as this is
needed by xbee when it saddles on the stk500 code (previously, the flags
component of the part was re-dedicated to this)
- Change the way the "chained" private data are used in jtag3.c whilst
keeping the PROGRAMMER structure read-only otherwise
- In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to
stk500v2_enable() so the former keeps the PROGRAMMER structure read-only
(for const assertion).
- In usbasp change the code from changing PROGRAMMER functions late to
dispatching to TPI or regular SPI protocol functions at runtime; reason
being the decision whether to use TPI protocol is done at run-time
depending on the capability of the attached programmer
Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
|
|
|
void jtagmkII_dragon_pdi_initpgm(PROGRAMMER *pgm) {
|
2010-01-13 17:34:18 +00:00
|
|
|
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
|
|
|
}
|