2002-12-01 04:30:01 +00:00
|
|
|
/*
|
2003-02-08 04:17:25 +00:00
|
|
|
* avrdude - A Downloader/Uploader for AVR device programmers
|
2004-12-22 01:52:45 +00:00
|
|
|
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
|
2014-01-22 07:42:18 +00:00
|
|
|
* Copyright (C) 2008,2014 Joerg Wunsch
|
2002-12-01 04:30:01 +00:00
|
|
|
*
|
2003-02-06 19:08:33 +00:00
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
2002-12-01 04:30:01 +00:00
|
|
|
*
|
2003-02-06 19:08:33 +00:00
|
|
|
* 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.
|
2002-12-01 04:30:01 +00:00
|
|
|
*
|
2003-02-06 19:08:33 +00:00
|
|
|
* 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/>.
|
2002-12-01 04:30:01 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* $Id$ */
|
|
|
|
|
2002-12-01 06:35:18 +00:00
|
|
|
/*
|
2003-02-06 05:13:32 +00:00
|
|
|
* avrdude interface for Atmel STK500 programmer
|
2002-12-01 06:35:18 +00:00
|
|
|
*
|
|
|
|
* Note: most commands use the "universal command" feature of the
|
|
|
|
* programmer in a "pass through" mode, exceptions are "program
|
|
|
|
* enable", "paged read", and "paged write".
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2003-02-14 20:34:03 +00:00
|
|
|
#include "ac_cfg.h"
|
|
|
|
|
2002-12-01 04:30:01 +00:00
|
|
|
#include <stdio.h>
|
2003-02-11 21:58:07 +00:00
|
|
|
#include <stdlib.h>
|
2002-12-01 04:30:01 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
2003-08-25 15:55:48 +00:00
|
|
|
#include <unistd.h>
|
2002-12-01 04:30:01 +00:00
|
|
|
|
2007-01-24 21:07:54 +00:00
|
|
|
#include "avrdude.h"
|
2014-05-19 10:01:59 +00:00
|
|
|
#include "libavrdude.h"
|
|
|
|
|
2012-01-31 17:03:43 +00:00
|
|
|
#include "stk500.h"
|
2002-12-01 04:30:01 +00:00
|
|
|
#include "stk500_private.h"
|
|
|
|
|
2004-07-07 08:59:07 +00:00
|
|
|
#define STK500_XTAL 7372800U
|
2013-09-13 14:59:15 +00:00
|
|
|
#define MAX_SYNC_ATTEMPTS 10
|
2002-12-01 04:30:01 +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 stk500_getparm(const PROGRAMMER *pgm, unsigned parm, unsigned *value);
|
|
|
|
static int stk500_setparm(const PROGRAMMER *pgm, unsigned parm, unsigned value);
|
2022-10-23 20:56:45 +00:00
|
|
|
static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp);
|
2003-09-16 20:40:13 +00:00
|
|
|
|
2003-03-04 02:03:11 +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 stk500_send(const PROGRAMMER *pgm, unsigned char *buf, size_t len) {
|
2006-12-11 12:47:35 +00:00
|
|
|
return serial_send(&pgm->fd, buf, len);
|
2002-12-01 04:30:01 +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 stk500_recv(const PROGRAMMER *pgm, unsigned char *buf, size_t len) {
|
2005-05-11 17:09:22 +00:00
|
|
|
int rv;
|
|
|
|
|
2006-12-11 12:47:35 +00:00
|
|
|
rv = serial_recv(&pgm->fd, buf, len);
|
2005-05-11 17:09:22 +00:00
|
|
|
if (rv < 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("programmer is not responding\n");
|
2006-09-19 22:27:30 +00:00
|
|
|
return -1;
|
2005-05-11 17:09:22 +00:00
|
|
|
}
|
|
|
|
return 0;
|
2002-12-01 04:30:01 +00:00
|
|
|
}
|
|
|
|
|
2003-03-13 03:52:19 +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 stk500_drain(const PROGRAMMER *pgm, int display) {
|
2006-12-11 12:47:35 +00:00
|
|
|
return serial_drain(&pgm->fd, display);
|
2002-12-01 04:30:01 +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 stk500_getsync(const PROGRAMMER *pgm) {
|
2002-12-01 04:30:01 +00:00
|
|
|
unsigned char buf[32], resp[32];
|
2013-09-13 14:59:15 +00:00
|
|
|
int attempt;
|
2022-01-25 08:40:24 +00:00
|
|
|
int max_sync_attempts;
|
2002-12-01 04:30:01 +00:00
|
|
|
|
|
|
|
buf[0] = Cmnd_STK_GET_SYNC;
|
|
|
|
buf[1] = Sync_CRC_EOP;
|
2006-09-01 21:00:36 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* First send and drain a few times to get rid of line noise
|
|
|
|
*/
|
|
|
|
|
|
|
|
stk500_send(pgm, buf, 2);
|
|
|
|
stk500_drain(pgm, 0);
|
|
|
|
stk500_send(pgm, buf, 2);
|
|
|
|
stk500_drain(pgm, 0);
|
|
|
|
|
2022-01-25 08:40:24 +00:00
|
|
|
if(PDATA(pgm)->retry_attempts)
|
|
|
|
max_sync_attempts = PDATA(pgm)->retry_attempts;
|
|
|
|
else
|
|
|
|
max_sync_attempts = MAX_SYNC_ATTEMPTS;
|
|
|
|
|
|
|
|
for (attempt = 0; attempt < max_sync_attempts; attempt++) {
|
2022-01-29 18:53:42 +00:00
|
|
|
// Restart Arduino bootloader for every sync attempt
|
|
|
|
if (strcmp(pgm->type, "Arduino") == 0 && attempt > 0) {
|
|
|
|
serial_set_dtr_rts(&pgm->fd, 0); // Set DTR and RTS low
|
|
|
|
usleep(250*1000);
|
|
|
|
serial_set_dtr_rts(&pgm->fd, 1); // Set DTR and RTS back to high
|
|
|
|
usleep(50*1000);
|
|
|
|
stk500_drain(pgm, 0);
|
|
|
|
}
|
2022-07-24 17:48:22 +00:00
|
|
|
|
2013-09-13 14:59:15 +00:00
|
|
|
stk500_send(pgm, buf, 2);
|
2022-07-24 18:27:07 +00:00
|
|
|
resp[0] = 0;
|
2022-07-24 17:48:22 +00:00
|
|
|
if(stk500_recv(pgm, resp, 1) >= 0 && resp[0] == Resp_STK_INSYNC)
|
2013-09-13 14:59:15 +00:00
|
|
|
break;
|
2022-07-24 17:48:22 +00:00
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("attempt %d of %d: not in sync: resp=0x%02x\n", attempt + 1, max_sync_attempts, resp[0]);
|
2013-09-13 14:59:15 +00:00
|
|
|
}
|
2022-01-25 08:40:24 +00:00
|
|
|
if (attempt == max_sync_attempts) {
|
2002-12-01 20:09:38 +00:00
|
|
|
stk500_drain(pgm, 0);
|
2006-09-19 22:27:30 +00:00
|
|
|
return -1;
|
2002-12-01 04:30:01 +00:00
|
|
|
}
|
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, resp, 1) < 0)
|
|
|
|
return -1;
|
2002-12-01 04:30:01 +00:00
|
|
|
if (resp[0] != Resp_STK_OK) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("cannot communicate with device: resp=0x%02x\n", resp[0]);
|
2006-09-19 22:27:30 +00:00
|
|
|
return -1;
|
2002-12-01 04:30:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* transmit an AVR device command and return the results; 'cmd' and
|
|
|
|
* 'res' must point to at least a 4 byte data 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 stk500_cmd(const PROGRAMMER *pgm, const unsigned char *cmd,
|
2013-09-02 20:22:53 +00:00
|
|
|
unsigned char *res)
|
2002-12-01 04:30:01 +00:00
|
|
|
{
|
|
|
|
unsigned char buf[32];
|
|
|
|
|
|
|
|
buf[0] = Cmnd_STK_UNIVERSAL;
|
|
|
|
buf[1] = cmd[0];
|
|
|
|
buf[2] = cmd[1];
|
|
|
|
buf[3] = cmd[2];
|
|
|
|
buf[4] = cmd[3];
|
|
|
|
buf[5] = Sync_CRC_EOP;
|
|
|
|
|
2002-12-01 20:09:38 +00:00
|
|
|
stk500_send(pgm, buf, 6);
|
2002-12-01 04:30:01 +00:00
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2002-12-01 04:30:01 +00:00
|
|
|
if (buf[0] != Resp_STK_INSYNC) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("programmer is out of sync\n");
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2002-12-01 04:30:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
res[0] = cmd[1];
|
|
|
|
res[1] = cmd[2];
|
|
|
|
res[2] = cmd[3];
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, &res[3], 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2002-12-01 04:30:01 +00:00
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2002-12-01 04:30:01 +00:00
|
|
|
if (buf[0] != Resp_STK_OK) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]);
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2002-12-01 04:30:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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 stk500_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
|
2002-12-01 04:30:01 +00:00
|
|
|
unsigned char cmd[4];
|
|
|
|
unsigned char res[4];
|
|
|
|
|
2006-11-20 15:04:09 +00:00
|
|
|
if (pgm->cmd == NULL) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("%s programmer uses stk500_chip_erase() but does not\n", pgm->type);
|
|
|
|
imsg_error("provide a cmd() method\n");
|
2006-11-20 15:04:09 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2002-12-01 04:30:01 +00:00
|
|
|
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("chip erase instruction not defined for part %s\n", p->desc);
|
2002-12-01 04:30:01 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
pgm->pgm_led(pgm, ON);
|
|
|
|
|
|
|
|
memset(cmd, 0, sizeof(cmd));
|
|
|
|
avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
|
|
|
|
pgm->cmd(pgm, cmd, res);
|
|
|
|
usleep(p->chip_erase_delay);
|
|
|
|
pgm->initialize(pgm, p);
|
|
|
|
|
|
|
|
pgm->pgm_led(pgm, OFF);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* issue the 'program enable' command to the AVR device
|
|
|
|
*/
|
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 stk500_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
|
2002-12-01 04:30:01 +00:00
|
|
|
unsigned char buf[16];
|
|
|
|
int tries=0;
|
|
|
|
|
|
|
|
retry:
|
|
|
|
|
|
|
|
tries++;
|
|
|
|
|
|
|
|
buf[0] = Cmnd_STK_ENTER_PROGMODE;
|
|
|
|
buf[1] = Sync_CRC_EOP;
|
|
|
|
|
2002-12-01 20:09:38 +00:00
|
|
|
stk500_send(pgm, buf, 2);
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2002-12-01 04:30:01 +00:00
|
|
|
if (buf[0] == Resp_STK_NOSYNC) {
|
|
|
|
if (tries > 33) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("cannot get into sync\n");
|
2002-12-01 04:30:01 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_getsync(pgm) < 0)
|
|
|
|
return -1;
|
2002-12-01 04:30:01 +00:00
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
else if (buf[0] != Resp_STK_INSYNC) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
|
2002-12-01 04:30:01 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2002-12-01 04:30:01 +00:00
|
|
|
if (buf[0] == Resp_STK_OK) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (buf[0] == Resp_STK_NODEVICE) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("no device\n");
|
2002-12-01 04:30:01 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2003-02-20 18:09:57 +00:00
|
|
|
if(buf[0] == Resp_STK_FAILED)
|
|
|
|
{
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("unable to enter programming mode\n");
|
|
|
|
return -1;
|
2003-02-20 18:09:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("unknown response=0x%02x\n", buf[0]);
|
2002-12-01 04:30:01 +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 stk500_set_extended_parms(const PROGRAMMER *pgm, int n,
|
2003-03-04 02:03:11 +00:00
|
|
|
unsigned char * cmd)
|
|
|
|
{
|
|
|
|
unsigned char buf[16];
|
|
|
|
int tries=0;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
retry:
|
|
|
|
|
|
|
|
tries++;
|
|
|
|
|
|
|
|
buf[0] = Cmnd_STK_SET_DEVICE_EXT;
|
|
|
|
for (i=0; i<n; i++) {
|
|
|
|
buf[1+i] = cmd[i];
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
buf[i] = Sync_CRC_EOP;
|
|
|
|
|
|
|
|
stk500_send(pgm, buf, i+1);
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2003-03-04 02:03:11 +00:00
|
|
|
if (buf[0] == Resp_STK_NOSYNC) {
|
|
|
|
if (tries > 33) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("cannot get into sync\n");
|
2003-03-04 02:03:11 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_getsync(pgm) < 0)
|
|
|
|
return -1;
|
2003-03-04 02:03:11 +00:00
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
else if (buf[0] != Resp_STK_INSYNC) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
|
2003-03-04 02:03:11 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2003-03-04 02:03:11 +00:00
|
|
|
if (buf[0] == Resp_STK_OK) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (buf[0] == Resp_STK_NODEVICE) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("no device\n");
|
2003-03-04 02:03:11 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
if(buf[0] == Resp_STK_FAILED) {
|
|
|
|
pmsg_error("unable to set extended device programming parameters\n");
|
|
|
|
return -1;
|
2003-03-04 02:03:11 +00:00
|
|
|
}
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("unknown response=0x%02x\n", buf[0]);
|
2003-03-04 02:03:11 +00:00
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-06-13 21:19:46 +00:00
|
|
|
/*
|
|
|
|
* Crossbow MIB510 initialization and shutdown. Use cmd = 1 to
|
|
|
|
* initialize, cmd = 0 to close.
|
|
|
|
*/
|
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 mib510_isp(const PROGRAMMER *pgm, unsigned char cmd) {
|
2008-06-13 21:19:46 +00:00
|
|
|
unsigned char buf[9];
|
|
|
|
int tries = 0;
|
|
|
|
|
|
|
|
buf[0] = 0xaa;
|
|
|
|
buf[1] = 0x55;
|
|
|
|
buf[2] = 0x55;
|
|
|
|
buf[3] = 0xaa;
|
|
|
|
buf[4] = 0x17;
|
|
|
|
buf[5] = 0x51;
|
|
|
|
buf[6] = 0x31;
|
|
|
|
buf[7] = 0x13;
|
|
|
|
buf[8] = cmd;
|
|
|
|
|
|
|
|
|
|
|
|
retry:
|
|
|
|
|
|
|
|
tries++;
|
|
|
|
|
|
|
|
stk500_send(pgm, buf, 9);
|
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2008-06-13 21:19:46 +00:00
|
|
|
if (buf[0] == Resp_STK_NOSYNC) {
|
|
|
|
if (tries > 33) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("cannot get into sync\n");
|
2008-06-13 21:19:46 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (stk500_getsync(pgm) < 0)
|
|
|
|
return -1;
|
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
else if (buf[0] != Resp_STK_INSYNC) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
|
2008-06-13 21:19:46 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2008-06-13 21:19:46 +00:00
|
|
|
if (buf[0] == Resp_STK_OK) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (buf[0] == Resp_STK_NODEVICE) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("no device\n");
|
2008-06-13 21:19:46 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (buf[0] == Resp_STK_FAILED)
|
|
|
|
{
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("command %d failed\n", cmd);
|
2008-06-13 21:19:46 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("unknown response=0x%02x\n", buf[0]);
|
2008-06-13 21:19:46 +00:00
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2003-03-04 02:03:11 +00:00
|
|
|
|
2002-12-01 04:30:01 +00:00
|
|
|
/*
|
|
|
|
* 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 stk500_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
|
2002-12-01 04:30:01 +00:00
|
|
|
unsigned char buf[32];
|
|
|
|
AVRMEM * m;
|
|
|
|
int tries;
|
2003-03-04 02:03:11 +00:00
|
|
|
unsigned maj, min;
|
|
|
|
int rc;
|
2008-06-13 21:19:46 +00:00
|
|
|
int n_extparms;
|
2003-03-04 02:03:11 +00:00
|
|
|
|
|
|
|
stk500_getparm(pgm, Parm_STK_SW_MAJOR, &maj);
|
|
|
|
stk500_getparm(pgm, Parm_STK_SW_MINOR, &min);
|
|
|
|
|
2008-06-13 21:19:46 +00:00
|
|
|
// MIB510 does not need extparams
|
|
|
|
if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0)
|
|
|
|
n_extparms = 0;
|
|
|
|
else if ((maj > 1) || ((maj == 1) && (min > 10)))
|
2003-03-04 02:11:41 +00:00
|
|
|
n_extparms = 4;
|
2008-06-13 21:19:46 +00:00
|
|
|
else
|
|
|
|
n_extparms = 3;
|
2002-12-01 04:30:01 +00:00
|
|
|
|
2002-12-01 20:09:38 +00:00
|
|
|
tries = 0;
|
|
|
|
|
|
|
|
retry:
|
|
|
|
tries++;
|
|
|
|
|
2003-03-05 04:30:20 +00:00
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
|
2002-12-01 04:30:01 +00:00
|
|
|
/*
|
|
|
|
* set device programming parameters
|
|
|
|
*/
|
|
|
|
buf[0] = Cmnd_STK_SET_DEVICE;
|
|
|
|
|
2003-03-17 06:20:02 +00:00
|
|
|
buf[1] = p->stk500_devcode;
|
2002-12-01 04:30:01 +00:00
|
|
|
buf[2] = 0; /* device revision */
|
2003-02-20 19:46:23 +00:00
|
|
|
|
|
|
|
if ((p->flags & AVRPART_SERIALOK) && (p->flags & AVRPART_PARALLELOK))
|
|
|
|
buf[3] = 0; /* device supports parallel and serial programming */
|
|
|
|
else
|
|
|
|
buf[3] = 1; /* device supports parallel only */
|
|
|
|
|
2003-02-20 19:50:32 +00:00
|
|
|
if (p->flags & AVRPART_PARALLELOK) {
|
2003-03-04 02:11:41 +00:00
|
|
|
if (p->flags & AVRPART_PSEUDOPARALLEL) {
|
2003-02-20 19:50:32 +00:00
|
|
|
buf[4] = 0; /* pseudo parallel interface */
|
2003-03-04 02:11:41 +00:00
|
|
|
n_extparms = 0;
|
|
|
|
}
|
|
|
|
else {
|
2003-02-20 19:50:32 +00:00
|
|
|
buf[4] = 1; /* full parallel interface */
|
2003-03-04 02:11:41 +00:00
|
|
|
}
|
2003-02-20 19:50:32 +00:00
|
|
|
}
|
2003-03-04 02:11:41 +00:00
|
|
|
|
2003-03-10 22:58:21 +00:00
|
|
|
#if 0
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_info("stk500_initialize(): n_extparms = %d\n", n_extparms);
|
2003-03-10 22:58:21 +00:00
|
|
|
#endif
|
2003-02-20 19:46:23 +00:00
|
|
|
|
2002-12-01 04:30:01 +00:00
|
|
|
buf[5] = 1; /* polling supported - XXX need this in config file */
|
|
|
|
buf[6] = 1; /* programming is self-timed - XXX need in config file */
|
|
|
|
|
|
|
|
m = avr_locate_mem(p, "lock");
|
|
|
|
if (m)
|
|
|
|
buf[7] = m->size;
|
|
|
|
else
|
|
|
|
buf[7] = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* number of fuse bytes
|
|
|
|
*/
|
|
|
|
buf[8] = 0;
|
|
|
|
m = avr_locate_mem(p, "fuse");
|
|
|
|
if (m)
|
|
|
|
buf[8] += m->size;
|
|
|
|
m = avr_locate_mem(p, "lfuse");
|
|
|
|
if (m)
|
|
|
|
buf[8] += m->size;
|
|
|
|
m = avr_locate_mem(p, "hfuse");
|
|
|
|
if (m)
|
|
|
|
buf[8] += m->size;
|
|
|
|
m = avr_locate_mem(p, "efuse");
|
|
|
|
if (m)
|
|
|
|
buf[8] += m->size;
|
|
|
|
|
|
|
|
m = avr_locate_mem(p, "flash");
|
|
|
|
if (m) {
|
|
|
|
buf[9] = m->readback[0];
|
|
|
|
buf[10] = m->readback[1];
|
|
|
|
if (m->paged) {
|
|
|
|
buf[13] = (m->page_size >> 8) & 0x00ff;
|
|
|
|
buf[14] = m->page_size & 0x00ff;
|
|
|
|
}
|
|
|
|
buf[17] = (m->size >> 24) & 0xff;
|
|
|
|
buf[18] = (m->size >> 16) & 0xff;
|
|
|
|
buf[19] = (m->size >> 8) & 0xff;
|
|
|
|
buf[20] = m->size & 0xff;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
buf[9] = 0xff;
|
|
|
|
buf[10] = 0xff;
|
|
|
|
buf[13] = 0;
|
|
|
|
buf[14] = 0;
|
|
|
|
buf[17] = 0;
|
|
|
|
buf[18] = 0;
|
|
|
|
buf[19] = 0;
|
|
|
|
buf[20] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
m = avr_locate_mem(p, "eeprom");
|
|
|
|
if (m) {
|
|
|
|
buf[11] = m->readback[0];
|
|
|
|
buf[12] = m->readback[1];
|
|
|
|
buf[15] = (m->size >> 8) & 0x00ff;
|
|
|
|
buf[16] = m->size & 0x00ff;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
buf[11] = 0xff;
|
|
|
|
buf[12] = 0xff;
|
|
|
|
buf[15] = 0;
|
|
|
|
buf[16] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
buf[21] = Sync_CRC_EOP;
|
|
|
|
|
2002-12-01 20:09:38 +00:00
|
|
|
stk500_send(pgm, buf, 22);
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2002-12-01 04:30:01 +00:00
|
|
|
if (buf[0] == Resp_STK_NOSYNC) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("programmer not in sync, resp=0x%02x\n", buf[0]);
|
2002-12-01 04:30:01 +00:00
|
|
|
if (tries > 33)
|
|
|
|
return -1;
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_getsync(pgm) < 0)
|
|
|
|
return -1;
|
2002-12-01 04:30:01 +00:00
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
else if (buf[0] != Resp_STK_INSYNC) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
|
2002-12-01 04:30:01 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2002-12-01 04:30:01 +00:00
|
|
|
if (buf[0] != Resp_STK_OK) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]);
|
2002-12-01 04:30:01 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2003-03-04 02:11:41 +00:00
|
|
|
if (n_extparms) {
|
2003-03-04 14:33:19 +00:00
|
|
|
if ((p->pagel == 0) || (p->bs2 == 0)) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_notice2("PAGEL and BS2 signals not defined in the configuration "
|
|
|
|
"file for part %s, using dummy values\n", p->desc);
|
2012-04-19 13:59:09 +00:00
|
|
|
buf[2] = 0xD7; /* they look somehow possible, */
|
|
|
|
buf[3] = 0xA0; /* don't they? ;) */
|
2003-03-04 02:11:41 +00:00
|
|
|
}
|
2003-03-04 14:33:19 +00:00
|
|
|
else {
|
|
|
|
buf[2] = p->pagel;
|
|
|
|
buf[3] = p->bs2;
|
2012-04-19 13:59:09 +00:00
|
|
|
}
|
|
|
|
buf[0] = n_extparms+1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* m is currently pointing to eeprom memory if the part has it
|
|
|
|
*/
|
|
|
|
if (m)
|
|
|
|
buf[1] = m->page_size;
|
|
|
|
else
|
|
|
|
buf[1] = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (n_extparms == 4) {
|
|
|
|
if (p->reset_disposition == RESET_DEDICATED)
|
|
|
|
buf[4] = 0;
|
|
|
|
else
|
|
|
|
buf[4] = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = stk500_set_extended_parms(pgm, n_extparms+1, buf);
|
|
|
|
if (rc) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("failed to initialise programmer\n");
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2003-03-04 02:03:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-08-31 15:40:59 +00:00
|
|
|
return pgm->program_enable(pgm, p);
|
2002-12-01 04:30:01 +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 stk500_parseextparms(const PROGRAMMER *pgm, const LISTID extparms)
|
2022-01-25 08:40:24 +00:00
|
|
|
{
|
|
|
|
LNODEID ln;
|
|
|
|
const char *extended_param;
|
|
|
|
int attempts;
|
|
|
|
int rv = 0;
|
|
|
|
|
|
|
|
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
|
|
|
|
extended_param = ldata(ln);
|
|
|
|
|
|
|
|
if (sscanf(extended_param, "attempts=%2d", &attempts) == 1) {
|
|
|
|
PDATA(pgm)->retry_attempts = attempts;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_info("setting number of retry attempts to %d\n", attempts);
|
2022-01-25 08:40:24 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("invalid extended parameter '%s'\n", extended_param);
|
2022-01-25 08:40:24 +00:00
|
|
|
rv = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
2002-12-01 04:30:01 +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 stk500_disable(const PROGRAMMER *pgm) {
|
2002-12-01 04:30:01 +00:00
|
|
|
unsigned char buf[16];
|
|
|
|
int tries=0;
|
|
|
|
|
|
|
|
retry:
|
|
|
|
|
|
|
|
tries++;
|
|
|
|
|
|
|
|
buf[0] = Cmnd_STK_LEAVE_PROGMODE;
|
|
|
|
buf[1] = Sync_CRC_EOP;
|
|
|
|
|
2002-12-01 20:09:38 +00:00
|
|
|
stk500_send(pgm, buf, 2);
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return;
|
2002-12-01 04:30:01 +00:00
|
|
|
if (buf[0] == Resp_STK_NOSYNC) {
|
|
|
|
if (tries > 33) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("cannot get into sync\n");
|
2002-12-01 04:30:01 +00:00
|
|
|
return;
|
|
|
|
}
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_getsync(pgm) < 0)
|
|
|
|
return;
|
2002-12-01 04:30:01 +00:00
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
else if (buf[0] != Resp_STK_INSYNC) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
|
2002-12-01 04:30:01 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return;
|
2002-12-01 04:30:01 +00:00
|
|
|
if (buf[0] == Resp_STK_OK) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (buf[0] == Resp_STK_NODEVICE) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("no device\n");
|
2002-12-01 04:30:01 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("unknown response=0x%02x\n", buf[0]);
|
2002-12-01 04:30:01 +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 void stk500_enable(PROGRAMMER *pgm, const AVRPART *p) {
|
2022-10-23 21:32:29 +00:00
|
|
|
AVRMEM *mem;
|
|
|
|
if(pgm->prog_modes & PM_SPM) // For bootloaders (eg, arduino)
|
|
|
|
if(!(p->prog_modes & (PM_UPDI | PM_PDI | PM_aWire))) // Classic parts, eg, optiboot with word addresses
|
|
|
|
if((mem = avr_locate_mem(p, "eeprom")))
|
|
|
|
if(mem->page_size == 1) // Increase pagesize if it is 1
|
|
|
|
mem->page_size = 16;
|
2002-12-01 04:30:01 +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 stk500_open(PROGRAMMER *pgm, const char *port) {
|
2014-02-21 13:44:11 +00:00
|
|
|
union pinfo pinfo;
|
2002-12-01 04:30:01 +00:00
|
|
|
strcpy(pgm->port, port);
|
2021-12-08 10:09:52 +00:00
|
|
|
pinfo.serialinfo.baud = pgm->baudrate? pgm->baudrate: 115200;
|
|
|
|
pinfo.serialinfo.cflags = SERIAL_8N1;
|
2014-02-21 13:44:11 +00:00
|
|
|
if (serial_open(port, pinfo, &pgm->fd)==-1) {
|
2010-10-22 14:29:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2002-12-01 04:30:01 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* drain any extraneous input
|
|
|
|
*/
|
2002-12-01 20:09:38 +00:00
|
|
|
stk500_drain(pgm, 0);
|
2002-12-01 04:30:01 +00:00
|
|
|
|
2008-06-13 21:19:46 +00:00
|
|
|
// MIB510 init
|
|
|
|
if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0 &&
|
|
|
|
mib510_isp(pgm, 1) != 0)
|
|
|
|
return -1;
|
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_getsync(pgm) < 0)
|
|
|
|
return -1;
|
2002-12-01 04:30:01 +00:00
|
|
|
|
2004-01-28 20:01:44 +00:00
|
|
|
return 0;
|
2002-12-01 04:30:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-02-13 19:27:50 +00:00
|
|
|
static void stk500_close(PROGRAMMER * pgm)
|
2002-12-01 04:30:01 +00:00
|
|
|
{
|
2008-06-13 21:19:46 +00:00
|
|
|
// MIB510 close
|
|
|
|
if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0)
|
|
|
|
(void)mib510_isp(pgm, 0);
|
|
|
|
|
2006-12-11 12:47:35 +00:00
|
|
|
serial_close(&pgm->fd);
|
|
|
|
pgm->fd.ifd = -1;
|
2002-12-01 04:30:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-10-23 21:32:29 +00:00
|
|
|
// Address is byte address; a_div == 2: send word address; a_div == 1: send byte address
|
|
|
|
static int stk500_loadaddr(const PROGRAMMER *pgm, const AVRMEM *mem, unsigned int addr, int a_div) {
|
2002-12-01 06:35:18 +00:00
|
|
|
unsigned char buf[16];
|
|
|
|
int tries;
|
2014-01-22 07:42:18 +00:00
|
|
|
unsigned char ext_byte;
|
2022-10-23 21:32:29 +00:00
|
|
|
|
|
|
|
addr /= a_div;
|
2002-12-01 06:35:18 +00:00
|
|
|
|
|
|
|
tries = 0;
|
|
|
|
retry:
|
|
|
|
tries++;
|
2014-01-22 07:42:18 +00:00
|
|
|
|
2022-10-23 21:32:29 +00:00
|
|
|
// Support large flash by sending the correct extended address byte when needed
|
|
|
|
|
|
|
|
if(pgm->prog_modes & PM_SPM) { // Bootloaders, eg, optiboot, optiboot_dx, optiboot_x
|
|
|
|
if(mem->size/a_div > 64*1024) { // Extended addressing needed
|
|
|
|
ext_byte = (addr >> 16) & 0xff;
|
|
|
|
if(ext_byte != PDATA(pgm)->ext_addr_byte) { // First addr load or a different 64k section
|
|
|
|
buf[0] = 0x4d; // Protocol bytes that bootloaders expect
|
|
|
|
buf[1] = 0x00;
|
|
|
|
buf[2] = ext_byte;
|
|
|
|
buf[3] = 0x00;
|
|
|
|
if(stk500_cmd(pgm, buf, buf) == 0)
|
|
|
|
PDATA(pgm)->ext_addr_byte = ext_byte;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Ensure next paged r/w will load ext addr again if page sits just below a 64k boundary
|
|
|
|
*
|
|
|
|
* Some bootloaders increment their copy of ext_addr_byte in that situation, eg, when they
|
|
|
|
* use elpm rx,Z+ to read a byte from flash or spm Z+ to write to flash whilst they keep
|
|
|
|
* ext_addr_byte in RAMPZ, which in turn gets incremented by Z+ at 64k page boundaries. So,
|
|
|
|
* if an upload with automated verify finishes just below 64k, AVRDUDE still holds
|
|
|
|
* ext_addr_byte at the current 64k segment whilst its copy in the bootloader has been
|
|
|
|
* auto-incremented. Verifying the code from start exposes the discrepancy.
|
|
|
|
*/
|
|
|
|
if((addr & 0xffff0000) != ((addr+mem->page_size/a_div) & 0xffff0000))
|
|
|
|
PDATA(pgm)->ext_addr_byte = 0xff;
|
|
|
|
}
|
|
|
|
} else { // Programmer *not* for bootloaders? Original stk500v1 protocol!
|
|
|
|
OPCODE *lext = mem->op[AVR_OP_LOAD_EXT_ADDR];
|
|
|
|
|
|
|
|
if(lext) {
|
|
|
|
ext_byte = (addr >> 16) & 0xff;
|
|
|
|
if(ext_byte != PDATA(pgm)->ext_addr_byte) { // First addr load or a different 64k section
|
|
|
|
memset(buf, 0, 4); // Part's load_ext_addr command is typically 4d 00 ext_addr 00
|
|
|
|
avr_set_bits(lext, buf);
|
|
|
|
avr_set_addr(lext, buf, addr);
|
|
|
|
if(stk500_cmd(pgm, buf, buf) == 0)
|
|
|
|
PDATA(pgm)->ext_addr_byte = ext_byte;
|
|
|
|
}
|
2014-01-22 07:42:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-01 06:35:18 +00:00
|
|
|
buf[0] = Cmnd_STK_LOAD_ADDRESS;
|
|
|
|
buf[1] = addr & 0xff;
|
|
|
|
buf[2] = (addr >> 8) & 0xff;
|
|
|
|
buf[3] = Sync_CRC_EOP;
|
|
|
|
|
2002-12-01 20:09:38 +00:00
|
|
|
stk500_send(pgm, buf, 4);
|
2002-12-01 06:35:18 +00:00
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2002-12-01 06:35:18 +00:00
|
|
|
if (buf[0] == Resp_STK_NOSYNC) {
|
|
|
|
if (tries > 33) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("cannot get into sync\n");
|
2002-12-01 06:35:18 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_getsync(pgm) < 0)
|
|
|
|
return -1;
|
2002-12-01 06:35:18 +00:00
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
else if (buf[0] != Resp_STK_INSYNC) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
|
2002-12-01 06:35:18 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2022-07-24 18:27:07 +00:00
|
|
|
if (buf[0] == Resp_STK_OK)
|
2002-12-01 06:35:18 +00:00
|
|
|
return 0;
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]);
|
2002-12-01 20:09:38 +00:00
|
|
|
|
2002-12-01 06:35:18 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-10-23 21:32:29 +00:00
|
|
|
static int set_memtype_a_div(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int *memtypep, int *a_divp) {
|
|
|
|
if(avr_mem_is_flash_type(m)) {
|
|
|
|
*memtypep = 'F';
|
|
|
|
if(!(pgm->prog_modes & PM_SPM)) // Programmer *not* for bootloaders: original stk500v1 protocol
|
|
|
|
*a_divp = m->op[AVR_OP_LOADPAGE_LO] || m->op[AVR_OP_READ_LO]? 2: 1;
|
|
|
|
else if(!(p->prog_modes & (PM_UPDI | PM_PDI | PM_aWire)))
|
|
|
|
*a_divp = 2; // Bootloader where part is a "classic" part (eg, optiboot)
|
|
|
|
else
|
|
|
|
*a_divp = 1; // Bootloader where part is Xmega or "new" families (optiboot_x, optiboot_dx)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(avr_mem_is_eeprom_type(m)) {
|
|
|
|
*memtypep = 'E';
|
|
|
|
// Word addr for bootloaders where part is a "classic" part (eg, optiboot, arduinoisp, ...), byte addr otherwise
|
|
|
|
*a_divp = (pgm->prog_modes & PM_SPM) && !(p->prog_modes & (PM_UPDI | PM_PDI))? 2: 1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
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 stk500_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)
|
2002-12-01 06:35:18 +00:00
|
|
|
{
|
2022-01-07 16:23:50 +00:00
|
|
|
unsigned char* buf = alloca(page_size + 16);
|
2002-12-01 06:35:18 +00:00
|
|
|
int memtype;
|
|
|
|
int a_div;
|
2003-10-13 21:32:53 +00:00
|
|
|
int block_size;
|
2002-12-01 06:35:18 +00:00
|
|
|
int tries;
|
|
|
|
unsigned int n;
|
2006-10-09 09:56:10 +00:00
|
|
|
unsigned int i;
|
2002-12-01 06:35:18 +00:00
|
|
|
|
2022-10-23 21:32:29 +00:00
|
|
|
if(set_memtype_a_div(pgm, p, m, &memtype, &a_div) < 0)
|
2002-12-01 06:35:18 +00:00
|
|
|
return -2;
|
|
|
|
|
2011-09-14 21:49:42 +00:00
|
|
|
n = addr + n_bytes;
|
2003-03-05 02:35:50 +00:00
|
|
|
#if 0
|
2022-10-23 21:32:29 +00:00
|
|
|
msg_debug(
|
2022-10-17 14:44:55 +00:00
|
|
|
"n_bytes = %d\n"
|
|
|
|
"n = %u\n"
|
|
|
|
"a_div = %d\n"
|
|
|
|
"page_size = %d\n",
|
|
|
|
n_bytes, n, a_div, page_size);
|
2022-07-24 19:18:15 +00:00
|
|
|
#endif
|
2003-03-05 02:35:50 +00:00
|
|
|
|
2011-09-14 21:49:42 +00:00
|
|
|
for (; addr < n; addr += block_size) {
|
2008-06-13 21:19:46 +00:00
|
|
|
// MIB510 uses fixed blocks size of 256 bytes
|
2011-09-14 21:49:42 +00:00
|
|
|
if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0) {
|
|
|
|
block_size = 256;
|
|
|
|
} else {
|
|
|
|
if (n - addr < page_size)
|
|
|
|
block_size = n - addr;
|
|
|
|
else
|
|
|
|
block_size = page_size;
|
2003-09-16 20:40:13 +00:00
|
|
|
}
|
2002-12-01 06:35:18 +00:00
|
|
|
tries = 0;
|
|
|
|
retry:
|
|
|
|
tries++;
|
2022-10-23 21:32:29 +00:00
|
|
|
stk500_loadaddr(pgm, m, addr, a_div);
|
2003-10-13 21:32:53 +00:00
|
|
|
|
2006-10-09 09:56:10 +00:00
|
|
|
/* build command block and avoid multiple send commands as it leads to a crash
|
|
|
|
of the silabs usb serial driver on mac os x */
|
|
|
|
i = 0;
|
|
|
|
buf[i++] = Cmnd_STK_PROG_PAGE;
|
|
|
|
buf[i++] = (block_size >> 8) & 0xff;
|
|
|
|
buf[i++] = block_size & 0xff;
|
|
|
|
buf[i++] = memtype;
|
|
|
|
memcpy(&buf[i], &m->buf[addr], block_size);
|
|
|
|
i += block_size;
|
|
|
|
buf[i++] = Sync_CRC_EOP;
|
|
|
|
stk500_send( pgm, buf, i);
|
2002-12-01 06:35:18 +00:00
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2002-12-01 06:35:18 +00:00
|
|
|
if (buf[0] == Resp_STK_NOSYNC) {
|
|
|
|
if (tries > 33) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("cannot get into sync\n");
|
2002-12-01 06:35:18 +00:00
|
|
|
return -3;
|
|
|
|
}
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_getsync(pgm) < 0)
|
2022-10-17 14:44:55 +00:00
|
|
|
return -1;
|
2002-12-01 06:35:18 +00:00
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
else if (buf[0] != Resp_STK_INSYNC) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
|
2002-12-01 06:35:18 +00:00
|
|
|
return -4;
|
|
|
|
}
|
2022-07-24 19:18:15 +00:00
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2002-12-01 06:35:18 +00:00
|
|
|
if (buf[0] != Resp_STK_OK) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]);
|
2002-12-01 06:35:18 +00:00
|
|
|
return -5;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-13 21:32:53 +00:00
|
|
|
return n_bytes;
|
2002-12-01 06:35: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
|
|
|
static int stk500_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)
|
2002-12-01 06:35:18 +00:00
|
|
|
{
|
|
|
|
unsigned char buf[16];
|
|
|
|
int memtype;
|
|
|
|
int a_div;
|
|
|
|
int tries;
|
|
|
|
unsigned int n;
|
2003-10-13 21:32:53 +00:00
|
|
|
int block_size;
|
2002-12-01 06:35:18 +00:00
|
|
|
|
2022-10-23 21:32:29 +00:00
|
|
|
if(set_memtype_a_div(pgm, p, m, &memtype, &a_div) < 0)
|
2002-12-01 06:35:18 +00:00
|
|
|
return -2;
|
|
|
|
|
2011-09-14 21:49:42 +00:00
|
|
|
n = addr + n_bytes;
|
|
|
|
for (; addr < n; addr += block_size) {
|
|
|
|
// MIB510 uses fixed blocks size of 256 bytes
|
|
|
|
if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0) {
|
|
|
|
block_size = 256;
|
|
|
|
} else {
|
|
|
|
if (n - addr < page_size)
|
|
|
|
block_size = n - addr;
|
|
|
|
else
|
|
|
|
block_size = page_size;
|
2002-12-01 06:35:18 +00:00
|
|
|
}
|
2003-10-13 21:32:53 +00:00
|
|
|
|
2002-12-01 06:35:18 +00:00
|
|
|
tries = 0;
|
|
|
|
retry:
|
|
|
|
tries++;
|
2022-10-23 21:32:29 +00:00
|
|
|
stk500_loadaddr(pgm, m, addr, a_div);
|
2002-12-01 06:35:18 +00:00
|
|
|
buf[0] = Cmnd_STK_READ_PAGE;
|
2003-10-13 21:32:53 +00:00
|
|
|
buf[1] = (block_size >> 8) & 0xff;
|
|
|
|
buf[2] = block_size & 0xff;
|
2002-12-01 06:35:18 +00:00
|
|
|
buf[3] = memtype;
|
|
|
|
buf[4] = Sync_CRC_EOP;
|
2002-12-01 20:09:38 +00:00
|
|
|
stk500_send(pgm, buf, 5);
|
2002-12-01 06:35:18 +00:00
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2002-12-01 06:35:18 +00:00
|
|
|
if (buf[0] == Resp_STK_NOSYNC) {
|
|
|
|
if (tries > 33) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("cannot get into sync\n");
|
2002-12-01 06:35:18 +00:00
|
|
|
return -3;
|
|
|
|
}
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_getsync(pgm) < 0)
|
2022-10-17 14:44:55 +00:00
|
|
|
return -1;
|
2002-12-01 06:35:18 +00:00
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
else if (buf[0] != Resp_STK_INSYNC) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
|
2002-12-01 06:35:18 +00:00
|
|
|
return -4;
|
|
|
|
}
|
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, &m->buf[addr], block_size) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2002-12-01 06:35:18 +00:00
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2009-02-16 10:19:46 +00:00
|
|
|
|
|
|
|
if(strcmp(ldata(lfirst(pgm->id)), "mib510") == 0) {
|
|
|
|
if (buf[0] != Resp_STK_INSYNC) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
|
|
|
|
return -5;
|
|
|
|
}
|
2002-12-01 06:35:18 +00:00
|
|
|
}
|
2009-02-16 10:19:46 +00:00
|
|
|
else {
|
|
|
|
if (buf[0] != Resp_STK_OK) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]);
|
2009-02-16 10:19:46 +00:00
|
|
|
return -5;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-12-01 06:35:18 +00:00
|
|
|
|
2003-10-13 21:32:53 +00:00
|
|
|
return n_bytes;
|
2002-12-01 06:35: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
|
|
|
static int stk500_set_vtarget(const PROGRAMMER *pgm, double v) {
|
2003-07-24 21:26:28 +00:00
|
|
|
unsigned uaref, utarg;
|
|
|
|
|
|
|
|
utarg = (unsigned)((v + 0.049) * 10);
|
|
|
|
|
|
|
|
if (stk500_getparm(pgm, Parm_STK_VADJUST, &uaref) != 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("cannot obtain V[aref]\n");
|
2003-07-24 21:26:28 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uaref > utarg) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("reducing V[aref] from %.1f to %.1f\n", uaref / 10.0, v);
|
|
|
|
if (stk500_setparm(pgm, Parm_STK_VADJUST, utarg) != 0)
|
2003-07-24 21:26:28 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return stk500_setparm(pgm, Parm_STK_VTARGET, utarg);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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 stk500_set_varef(const PROGRAMMER *pgm, unsigned int chan /* unused */,
|
2008-03-14 13:00:08 +00:00
|
|
|
double v)
|
2003-07-24 21:26:28 +00:00
|
|
|
{
|
|
|
|
unsigned uaref, utarg;
|
|
|
|
|
|
|
|
uaref = (unsigned)((v + 0.049) * 10);
|
|
|
|
|
|
|
|
if (stk500_getparm(pgm, Parm_STK_VTARGET, &utarg) != 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("cannot obtain V[target]\n");
|
2003-07-24 21:26:28 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uaref > utarg) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("V[aref] must not be greater than "
|
|
|
|
"V[target] = %.1f\n", utarg/10.0);
|
2003-07-24 21:26:28 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return stk500_setparm(pgm, Parm_STK_VADJUST, uaref);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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 stk500_set_fosc(const PROGRAMMER *pgm, double v) {
|
2003-07-24 21:26:28 +00:00
|
|
|
unsigned prescale, cmatch, fosc;
|
|
|
|
static unsigned ps[] = {
|
|
|
|
1, 8, 32, 64, 128, 256, 1024
|
|
|
|
};
|
2022-07-24 18:41:42 +00:00
|
|
|
size_t idx;
|
|
|
|
int rc;
|
2003-07-24 21:26:28 +00:00
|
|
|
|
2003-08-28 23:02:25 +00:00
|
|
|
prescale = cmatch = 0;
|
|
|
|
if (v > 0.0) {
|
2004-07-07 08:59:07 +00:00
|
|
|
if (v > STK500_XTAL / 2) {
|
2003-08-28 23:02:25 +00:00
|
|
|
const char *unit;
|
|
|
|
if (v > 1e6) {
|
|
|
|
v /= 1e6;
|
|
|
|
unit = "MHz";
|
|
|
|
} else if (v > 1e3) {
|
|
|
|
v /= 1e3;
|
|
|
|
unit = "kHz";
|
|
|
|
} else
|
|
|
|
unit = "Hz";
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("f = %.3f %s too high, using %.3f MHz\n", v, unit, STK500_XTAL/2e6);
|
2004-07-07 08:59:07 +00:00
|
|
|
fosc = STK500_XTAL / 2;
|
2003-07-24 21:26:28 +00:00
|
|
|
} else
|
2022-10-17 14:44:55 +00:00
|
|
|
fosc = (unsigned) v;
|
2003-08-28 23:02:25 +00:00
|
|
|
|
|
|
|
for (idx = 0; idx < sizeof(ps) / sizeof(ps[0]); idx++) {
|
2004-07-07 08:59:07 +00:00
|
|
|
if (fosc >= STK500_XTAL / (256 * ps[idx] * 2)) {
|
2003-08-28 23:02:25 +00:00
|
|
|
/* this prescaler value can handle our frequency */
|
|
|
|
prescale = idx + 1;
|
2004-07-07 08:59:07 +00:00
|
|
|
cmatch = (unsigned)(STK500_XTAL / (2 * fosc * ps[idx])) - 1;
|
2003-08-28 23:02:25 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (idx == sizeof(ps) / sizeof(ps[0])) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("f = %u Hz too low, %u Hz min\n", fosc, STK500_XTAL / (256 * 1024 * 2));
|
2003-08-28 23:02:25 +00:00
|
|
|
return -1;
|
2003-07-24 21:26:28 +00:00
|
|
|
}
|
|
|
|
}
|
2003-08-28 23:02:25 +00:00
|
|
|
|
2003-07-24 21:26:28 +00:00
|
|
|
if ((rc = stk500_setparm(pgm, Parm_STK_OSC_PSCALE, prescale)) != 0
|
|
|
|
|| (rc = stk500_setparm(pgm, Parm_STK_OSC_CMATCH, cmatch)) != 0)
|
|
|
|
return rc;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-07 08:59:07 +00:00
|
|
|
/* This code assumes that each count of the SCK duration parameter
|
2022-11-22 17:11:33 +00:00
|
|
|
represents 8/f, where f is the clock frequency of the STK500 controller
|
2004-07-07 08:59:07 +00:00
|
|
|
processors (not the target). This number comes from Atmel
|
|
|
|
application note AVR061. It appears that the STK500 bit bangs SCK.
|
|
|
|
For small duration values, the actual SCK width is larger than
|
|
|
|
expected. As the duration value increases, the SCK width error
|
|
|
|
diminishes. */
|
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 stk500_set_sck_period(const PROGRAMMER *pgm, double v) {
|
2004-07-07 08:59:07 +00:00
|
|
|
int dur;
|
|
|
|
double min, max;
|
|
|
|
|
|
|
|
min = 8.0 / STK500_XTAL;
|
|
|
|
max = 255 * min;
|
|
|
|
dur = v / min + 0.5;
|
|
|
|
|
|
|
|
if (v < min) {
|
|
|
|
dur = 1;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("p = %.1f us too small, using %.1f us\n",
|
|
|
|
v/1e-6, dur*min/1e-6);
|
2004-07-07 08:59:07 +00:00
|
|
|
} else if (v > max) {
|
|
|
|
dur = 255;
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_warning("p = %.1f us too large, using %.1f us\n",
|
|
|
|
v/1e-6, dur*min/1e-6);
|
2004-07-07 08:59:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return stk500_setparm(pgm, Parm_STK_SCK_DURATION, dur);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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 stk500_getparm(const PROGRAMMER *pgm, unsigned parm, unsigned *value) {
|
2002-12-01 06:35:18 +00:00
|
|
|
unsigned char buf[16];
|
|
|
|
unsigned v;
|
|
|
|
int tries = 0;
|
|
|
|
|
|
|
|
retry:
|
|
|
|
tries++;
|
|
|
|
buf[0] = Cmnd_STK_GET_PARAMETER;
|
|
|
|
buf[1] = parm;
|
|
|
|
buf[2] = Sync_CRC_EOP;
|
|
|
|
|
2002-12-01 20:09:38 +00:00
|
|
|
stk500_send(pgm, buf, 3);
|
2002-12-01 06:35:18 +00:00
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2002-12-01 06:35:18 +00:00
|
|
|
if (buf[0] == Resp_STK_NOSYNC) {
|
|
|
|
if (tries > 33) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("cannot get into sync\n");
|
2002-12-01 06:35:18 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_getsync(pgm) < 0)
|
|
|
|
return -1;
|
2002-12-01 06:35:18 +00:00
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
else if (buf[0] != Resp_STK_INSYNC) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
|
2002-12-01 06:35:18 +00:00
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2002-12-01 06:35:18 +00:00
|
|
|
v = buf[0];
|
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2002-12-01 06:35:18 +00:00
|
|
|
if (buf[0] == Resp_STK_FAILED) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("parameter 0x%02x failed\n", v);
|
2002-12-01 06:35:18 +00:00
|
|
|
return -3;
|
|
|
|
}
|
|
|
|
else if (buf[0] != Resp_STK_OK) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]);
|
2002-12-01 06:35:18 +00:00
|
|
|
return -3;
|
|
|
|
}
|
|
|
|
|
|
|
|
*value = v;
|
|
|
|
|
|
|
|
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 stk500_setparm(const PROGRAMMER *pgm, unsigned parm, unsigned value) {
|
2003-07-24 21:26:28 +00:00
|
|
|
unsigned char buf[16];
|
|
|
|
int tries = 0;
|
|
|
|
|
|
|
|
retry:
|
|
|
|
tries++;
|
|
|
|
buf[0] = Cmnd_STK_SET_PARAMETER;
|
|
|
|
buf[1] = parm;
|
|
|
|
buf[2] = value;
|
|
|
|
buf[3] = Sync_CRC_EOP;
|
|
|
|
|
|
|
|
stk500_send(pgm, buf, 4);
|
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2003-07-24 21:26:28 +00:00
|
|
|
if (buf[0] == Resp_STK_NOSYNC) {
|
|
|
|
if (tries > 33) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("cannot get into sync\n");
|
2003-07-24 21:26:28 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_getsync(pgm) < 0)
|
|
|
|
return -1;
|
2003-07-24 21:26:28 +00:00
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
else if (buf[0] != Resp_STK_INSYNC) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
|
2003-07-24 21:26:28 +00:00
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2003-07-24 21:26:28 +00:00
|
|
|
if (buf[0] == Resp_STK_OK)
|
|
|
|
return 0;
|
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
parm = buf[0]; /* if not STK_OK, we've been echoed parm here */
|
2006-09-19 22:27:30 +00:00
|
|
|
if (stk500_recv(pgm, buf, 1) < 0)
|
2014-05-16 15:52:25 +00:00
|
|
|
return -1;
|
2003-07-24 21:26:28 +00:00
|
|
|
if (buf[0] == Resp_STK_FAILED) {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("parameter 0x%02x failed\n", parm);
|
2003-07-24 21:26:28 +00:00
|
|
|
return -3;
|
|
|
|
}
|
|
|
|
else {
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_error("\n");
|
|
|
|
pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]);
|
2003-07-24 21:26:28 +00:00
|
|
|
return -3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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 stk500_display(const PROGRAMMER *pgm, const char *p) {
|
2003-07-24 21:26:28 +00:00
|
|
|
unsigned maj, min, hdw, topcard;
|
2002-12-01 06:35:18 +00:00
|
|
|
|
2002-12-01 20:09:38 +00:00
|
|
|
stk500_getparm(pgm, Parm_STK_HW_VER, &hdw);
|
|
|
|
stk500_getparm(pgm, Parm_STK_SW_MAJOR, &maj);
|
|
|
|
stk500_getparm(pgm, Parm_STK_SW_MINOR, &min);
|
2003-07-24 21:26:28 +00:00
|
|
|
stk500_getparm(pgm, Param_STK500_TOPCARD_DETECT, &topcard);
|
2002-12-01 06:35:18 +00:00
|
|
|
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("%sHardware Version: %d\n", p, hdw);
|
|
|
|
msg_info("%sFirmware Version: %d.%d\n", p, maj, min);
|
2003-07-24 21:26:28 +00:00
|
|
|
if (topcard < 3) {
|
|
|
|
const char *n = "Unknown";
|
|
|
|
|
|
|
|
switch (topcard) {
|
|
|
|
case 1:
|
2022-10-17 14:44:55 +00:00
|
|
|
n = "STK502";
|
|
|
|
break;
|
2003-07-24 21:26:28 +00:00
|
|
|
|
|
|
|
case 2:
|
2022-10-17 14:44:55 +00:00
|
|
|
n = "STK501";
|
|
|
|
break;
|
2003-07-24 21:26:28 +00:00
|
|
|
}
|
2022-10-17 14:44:55 +00:00
|
|
|
msg_info("%sTopcard : %s\n", p, n);
|
2003-07-24 21:26:28 +00:00
|
|
|
}
|
2022-01-24 21:16:31 +00:00
|
|
|
if(strcmp(pgm->type, "Arduino") != 0)
|
2022-10-23 20:56:45 +00:00
|
|
|
stk500_print_parms1(pgm, p, stderr);
|
2003-07-24 21:26:28 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-10-23 20:56:45 +00:00
|
|
|
static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) {
|
2004-07-07 08:59:07 +00:00
|
|
|
unsigned vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration;
|
2003-07-24 21:26:28 +00:00
|
|
|
|
|
|
|
stk500_getparm(pgm, Parm_STK_VTARGET, &vtarget);
|
|
|
|
stk500_getparm(pgm, Parm_STK_VADJUST, &vadjust);
|
|
|
|
stk500_getparm(pgm, Parm_STK_OSC_PSCALE, &osc_pscale);
|
|
|
|
stk500_getparm(pgm, Parm_STK_OSC_CMATCH, &osc_cmatch);
|
2004-07-07 08:59:07 +00:00
|
|
|
stk500_getparm(pgm, Parm_STK_SCK_DURATION, &sck_duration);
|
2003-07-24 21:26:28 +00:00
|
|
|
|
2022-10-23 20:56:45 +00:00
|
|
|
fmsg_out(fp, "%sVtarget : %.1f V\n", p, vtarget / 10.0);
|
|
|
|
fmsg_out(fp, "%sVaref : %.1f V\n", p, vadjust / 10.0);
|
|
|
|
fmsg_out(fp, "%sOscillator : ", p);
|
2003-07-24 21:26:28 +00:00
|
|
|
if (osc_pscale == 0)
|
2022-10-23 20:56:45 +00:00
|
|
|
fmsg_out(fp, "Off\n");
|
2003-07-24 21:26:28 +00:00
|
|
|
else {
|
|
|
|
int prescale = 1;
|
2004-07-07 08:59:07 +00:00
|
|
|
double f = STK500_XTAL / 2;
|
2003-07-24 21:26:28 +00:00
|
|
|
const char *unit;
|
|
|
|
|
|
|
|
switch (osc_pscale) {
|
|
|
|
case 2: prescale = 8; break;
|
|
|
|
case 3: prescale = 32; break;
|
|
|
|
case 4: prescale = 64; break;
|
|
|
|
case 5: prescale = 128; break;
|
|
|
|
case 6: prescale = 256; break;
|
|
|
|
case 7: prescale = 1024; break;
|
|
|
|
}
|
|
|
|
f /= prescale;
|
|
|
|
f /= (osc_cmatch + 1);
|
|
|
|
if (f > 1e6) {
|
|
|
|
f /= 1e6;
|
|
|
|
unit = "MHz";
|
|
|
|
} else if (f > 1e3) {
|
|
|
|
f /= 1000;
|
|
|
|
unit = "kHz";
|
|
|
|
} else
|
|
|
|
unit = "Hz";
|
2022-10-23 20:56:45 +00:00
|
|
|
fmsg_out(fp, "%.3f %s\n", f, unit);
|
2003-07-24 21:26:28 +00:00
|
|
|
}
|
2022-10-23 20:56:45 +00:00
|
|
|
fmsg_out(fp, "%sSCK period : %.1f us\n", p, sck_duration * 8.0e6 / STK500_XTAL + 0.05);
|
2002-12-01 06:35:18 +00:00
|
|
|
|
2002-12-01 04:30:01 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-10-23 20:56:45 +00:00
|
|
|
static void stk500_print_parms(const PROGRAMMER *pgm, FILE *fp) {
|
|
|
|
stk500_print_parms1(pgm, "", fp);
|
2003-07-24 21:26:28 +00:00
|
|
|
}
|
|
|
|
|
2014-01-22 07:42:18 +00:00
|
|
|
static void stk500_setup(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
|
2022-10-17 14:44:55 +00:00
|
|
|
pmsg_error("out of memory allocating private data\n");
|
2014-05-16 15:52:25 +00:00
|
|
|
return;
|
2014-01-22 07:42:18 +00:00
|
|
|
}
|
|
|
|
memset(pgm->cookie, 0, sizeof(struct pdata));
|
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)->ext_addr_byte = 0xff;
|
|
|
|
PDATA(pgm)->xbeeResetPin = XBEE_DEFAULT_RESET_PIN;
|
2014-01-22 07:42:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void stk500_teardown(PROGRAMMER * pgm)
|
|
|
|
{
|
|
|
|
free(pgm->cookie);
|
|
|
|
}
|
|
|
|
|
2012-01-31 17:03:43 +00:00
|
|
|
const char stk500_desc[] = "Atmel STK500 Version 1.x firmware";
|
2003-07-24 21:26:28 +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 stk500_initpgm(PROGRAMMER *pgm) {
|
2002-12-01 04:30:01 +00:00
|
|
|
strcpy(pgm->type, "STK500");
|
|
|
|
|
2002-12-01 06:35:18 +00:00
|
|
|
/*
|
|
|
|
* mandatory functions
|
|
|
|
*/
|
2002-12-01 04:30:01 +00:00
|
|
|
pgm->initialize = stk500_initialize;
|
2022-01-25 08:40:24 +00:00
|
|
|
pgm->parseextparams = stk500_parseextparms;
|
2002-12-01 04:30:01 +00:00
|
|
|
pgm->display = stk500_display;
|
|
|
|
pgm->enable = stk500_enable;
|
|
|
|
pgm->disable = stk500_disable;
|
|
|
|
pgm->program_enable = stk500_program_enable;
|
|
|
|
pgm->chip_erase = stk500_chip_erase;
|
|
|
|
pgm->cmd = stk500_cmd;
|
|
|
|
pgm->open = stk500_open;
|
|
|
|
pgm->close = stk500_close;
|
2006-11-20 15:04:09 +00:00
|
|
|
pgm->read_byte = avr_read_byte_default;
|
|
|
|
pgm->write_byte = avr_write_byte_default;
|
2002-12-01 06:35:18 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* optional functions
|
|
|
|
*/
|
|
|
|
pgm->paged_write = stk500_paged_write;
|
|
|
|
pgm->paged_load = stk500_paged_load;
|
2003-07-24 21:26:28 +00:00
|
|
|
pgm->print_parms = stk500_print_parms;
|
|
|
|
pgm->set_vtarget = stk500_set_vtarget;
|
|
|
|
pgm->set_varef = stk500_set_varef;
|
|
|
|
pgm->set_fosc = stk500_set_fosc;
|
2004-07-07 08:59:07 +00:00
|
|
|
pgm->set_sck_period = stk500_set_sck_period;
|
2014-01-22 07:42:18 +00:00
|
|
|
pgm->setup = stk500_setup;
|
|
|
|
pgm->teardown = stk500_teardown;
|
2002-12-01 15:05:56 +00:00
|
|
|
pgm->page_size = 256;
|
2002-12-01 04:30:01 +00:00
|
|
|
}
|