avrdude/src/pgm.c

345 lines
10 KiB
C
Raw Normal View History

/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
* Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* $Id$ */
#include "ac_cfg.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "avrdude.h"
#include "libavrdude.h"
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 pgm_default(void);
static int pgm_default_2(const PROGRAMMER *, const AVRPART *);
static int pgm_default_3(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char * value);
static void pgm_default_4(const PROGRAMMER *);
static int pgm_default_5(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char data);
static void pgm_default_6(const PROGRAMMER *, const char *);
static int pgm_default_open(PROGRAMMER *pgm, const char *name) {
pmsg_error("programmer does not support open()");
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 void pgm_default_close(PROGRAMMER *pgm) {
pgm_default();
}
static void pgm_default_enable(PROGRAMMER *pgm, const AVRPART *p) {
pgm_default();
}
static int pgm_default_led(const PROGRAMMER *pgm, int value) {
// If programmer has no LEDs, just do nothing
return 0;
}
Use const in PROGRAMMER function arguments where appropriate In order to get meaningful const properties for the PROGRAMMER, AVRPART and AVRMEM arguments, some code needed to be moved around, otherwise a network of "tainted" assignments risked rendering nothing const: - Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm, const AVRPART *p); this allows changes in the PROGRAMMER structure after the part is known. For example, use TPI, UPDI, PDI functions in that programmer appropriate to the part. This used to be done later in the process, eg, in the initialize() function, which "taints" all other programmer functions wrt const and sometimes requires other finessing with flags etc. Much clearer with the modified enable() interface. - Move TPI initpgm-type code from initialize() to enable() --- note that initpgm() does not have the info at the time when it is called whether or not TPI is required - buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate modification of the flag does not change PROGRAMMER structure) - Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and FLAGS32_WRITE bits - Move the xbeeResetPin component to private data in stk500.c as this is needed by xbee when it saddles on the stk500 code (previously, the flags component of the part was re-dedicated to this) - Change the way the "chained" private data are used in jtag3.c whilst keeping the PROGRAMMER structure read-only otherwise - In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to stk500v2_enable() so the former keeps the PROGRAMMER structure read-only (for const assertion). - In usbasp change the code from changing PROGRAMMER functions late to dispatching to TPI or regular SPI protocol functions at runtime; reason being the decision whether to use TPI protocol is done at run-time depending on the capability of the attached programmer Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
static void pgm_default_powerup_powerdown(const PROGRAMMER *pgm) {
// If programmer does not support powerup/down, just do nothing
}
PROGRAMMER *pgm_new(void) {
PROGRAMMER *pgm = (PROGRAMMER *) cfg_malloc("pgm_new()", sizeof(*pgm));
const char *nulp = cache_string("");
// Initialise const char * and LISTID entities
pgm->id = lcreat(NULL, 0);
pgm->usbpid = lcreat(NULL, 0);
pgm->hvupdi_support = lcreat(NULL, 0);
pgm->desc = nulp;
pgm->parent_id = nulp;
pgm->usbdev = nulp;
pgm->usbsn = nulp;
pgm->usbvendor = nulp;
pgm->usbproduct = nulp;
pgm->config_file = nulp;
Provide cached byte-wise read/write API (#1106) * Provide cached byte-wise read/write API int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char *value); int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char data); int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p); int avr_chip_erase_cached(const PROGRAMMER *pgm, const AVRPART *p); int avr_reset_cache(const PROGRAMMER *pgm, const AVRPART *p); avr_read_byte_cached() and avr_write_byte_cached() use a cache if paged routines are available and if the device memory is EEPROM or flash, otherwise they fall back to pgm->read_byte() and pgm->write_byte(), respectively. Byte-wise cached read always gets its data from the cache, possibly after reading a page from the device memory. Byte-wise cached write with an address in memory range only ever modifies the cache. Any modifications are written to the device after calling avr_flush_cache() or when attempting to read or write from a location outside the address range of the device memory. avr_flush_cache() synchronises pending writes to EEPROM and flash with the device. With some programmer and part combinations, flash (and sometimes EEPROM, too) looks like a NOR memory, ie, one can only write 0 bits, not 1 bits. When this is detected, either page erase is deployed (eg, with parts that have PDI/UPDI interfaces), or if that is not available, both EEPROM and flash caches are fully read in, a pgm->chip_erase() command is issued and both EEPROM and flash are written back to the device. Hence, it can take minutes to ensure that a single previously cleared bit is set and, therefore, this routine should be called sparingly. avr_chip_erase_cached() erases the chip and discards pending writes() to flash or EEPROM. It presets the flash cache to all 0xff alleviating the need to read from the device flash. However, if the programmer serves bootloaders (pgm->prog_modes & PM_SPM) then the flash cache is reset instead, necessitating flash memory be fetched from the device on first read; the reason for this is that bootloaders emulate chip erase and they won't overwrite themselves (some bootloaders, eg, optiboot ignore chip erase commands altogether) making it truly unknowable what the flash contents on device is after a chip erase. For EEPROM avr_chip_erase_cached() concludes that it has been deleted if a previously cached EEPROM page that contained cleared bits now no longer has these clear bits on the device. Only with this evidence is the EEPROM cache preset to all 0xff otherwise the cache discards all pending writes to EEPROM and is left unchanged otherwise. Finally, avr_reset_cache() resets the cache without synchronising pending writes() to the device.
2022-10-05 21:16:15 +00:00
// Allocate cache structures for flash and EEPROM, *do not* free in pgm_free()
pgm->cp_flash = cfg_malloc("pgm_new()", sizeof(AVR_Cache));
pgm->cp_eeprom = cfg_malloc("pgm_new()", sizeof(AVR_Cache));
// Default values
pgm->initpgm = NULL;
pgm->lineno = 0;
pgm->baudrate = 0;
// Clear pin array
for(int i=0; i<N_PINS; i++) {
pgm->pinno[i] = 0;
pin_clear_all(&(pgm->pin[i]));
}
/*
* mandatory functions - these are called without checking to see
* whether they are assigned or not
*/
pgm->initialize = pgm_default_2;
pgm->display = pgm_default_6;
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
pgm->enable = pgm_default_enable;
pgm->disable = pgm_default_4;
pgm->powerup = pgm_default_powerup_powerdown;
pgm->powerdown = pgm_default_powerup_powerdown;
pgm->program_enable = pgm_default_2;
pgm->chip_erase = pgm_default_2;
pgm->open = pgm_default_open;
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
pgm->close = pgm_default_close;
pgm->read_byte = pgm_default_3;
pgm->write_byte = pgm_default_5;
/*
* predefined functions - these functions have a valid default
* implementation. Hence, they don't need to be defined in
* the programmer.
*/
pgm->rdy_led = pgm_default_led;
pgm->err_led = pgm_default_led;
pgm->pgm_led = pgm_default_led;
pgm->vfy_led = pgm_default_led;
Provide cached byte-wise read/write API (#1106) * Provide cached byte-wise read/write API int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char *value); int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char data); int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p); int avr_chip_erase_cached(const PROGRAMMER *pgm, const AVRPART *p); int avr_reset_cache(const PROGRAMMER *pgm, const AVRPART *p); avr_read_byte_cached() and avr_write_byte_cached() use a cache if paged routines are available and if the device memory is EEPROM or flash, otherwise they fall back to pgm->read_byte() and pgm->write_byte(), respectively. Byte-wise cached read always gets its data from the cache, possibly after reading a page from the device memory. Byte-wise cached write with an address in memory range only ever modifies the cache. Any modifications are written to the device after calling avr_flush_cache() or when attempting to read or write from a location outside the address range of the device memory. avr_flush_cache() synchronises pending writes to EEPROM and flash with the device. With some programmer and part combinations, flash (and sometimes EEPROM, too) looks like a NOR memory, ie, one can only write 0 bits, not 1 bits. When this is detected, either page erase is deployed (eg, with parts that have PDI/UPDI interfaces), or if that is not available, both EEPROM and flash caches are fully read in, a pgm->chip_erase() command is issued and both EEPROM and flash are written back to the device. Hence, it can take minutes to ensure that a single previously cleared bit is set and, therefore, this routine should be called sparingly. avr_chip_erase_cached() erases the chip and discards pending writes() to flash or EEPROM. It presets the flash cache to all 0xff alleviating the need to read from the device flash. However, if the programmer serves bootloaders (pgm->prog_modes & PM_SPM) then the flash cache is reset instead, necessitating flash memory be fetched from the device on first read; the reason for this is that bootloaders emulate chip erase and they won't overwrite themselves (some bootloaders, eg, optiboot ignore chip erase commands altogether) making it truly unknowable what the flash contents on device is after a chip erase. For EEPROM avr_chip_erase_cached() concludes that it has been deleted if a previously cached EEPROM page that contained cleared bits now no longer has these clear bits on the device. Only with this evidence is the EEPROM cache preset to all 0xff otherwise the cache discards all pending writes to EEPROM and is left unchanged otherwise. Finally, avr_reset_cache() resets the cache without synchronising pending writes() to the device.
2022-10-05 21:16:15 +00:00
pgm->read_byte_cached = avr_read_byte_cached;
pgm->write_byte_cached = avr_write_byte_cached;
pgm->chip_erase_cached = avr_chip_erase_cached;
pgm->page_erase_cached = avr_page_erase_cached;
Provide cached byte-wise read/write API (#1106) * Provide cached byte-wise read/write API int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char *value); int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char data); int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p); int avr_chip_erase_cached(const PROGRAMMER *pgm, const AVRPART *p); int avr_reset_cache(const PROGRAMMER *pgm, const AVRPART *p); avr_read_byte_cached() and avr_write_byte_cached() use a cache if paged routines are available and if the device memory is EEPROM or flash, otherwise they fall back to pgm->read_byte() and pgm->write_byte(), respectively. Byte-wise cached read always gets its data from the cache, possibly after reading a page from the device memory. Byte-wise cached write with an address in memory range only ever modifies the cache. Any modifications are written to the device after calling avr_flush_cache() or when attempting to read or write from a location outside the address range of the device memory. avr_flush_cache() synchronises pending writes to EEPROM and flash with the device. With some programmer and part combinations, flash (and sometimes EEPROM, too) looks like a NOR memory, ie, one can only write 0 bits, not 1 bits. When this is detected, either page erase is deployed (eg, with parts that have PDI/UPDI interfaces), or if that is not available, both EEPROM and flash caches are fully read in, a pgm->chip_erase() command is issued and both EEPROM and flash are written back to the device. Hence, it can take minutes to ensure that a single previously cleared bit is set and, therefore, this routine should be called sparingly. avr_chip_erase_cached() erases the chip and discards pending writes() to flash or EEPROM. It presets the flash cache to all 0xff alleviating the need to read from the device flash. However, if the programmer serves bootloaders (pgm->prog_modes & PM_SPM) then the flash cache is reset instead, necessitating flash memory be fetched from the device on first read; the reason for this is that bootloaders emulate chip erase and they won't overwrite themselves (some bootloaders, eg, optiboot ignore chip erase commands altogether) making it truly unknowable what the flash contents on device is after a chip erase. For EEPROM avr_chip_erase_cached() concludes that it has been deleted if a previously cached EEPROM page that contained cleared bits now no longer has these clear bits on the device. Only with this evidence is the EEPROM cache preset to all 0xff otherwise the cache discards all pending writes to EEPROM and is left unchanged otherwise. Finally, avr_reset_cache() resets the cache without synchronising pending writes() to the device.
2022-10-05 21:16:15 +00:00
pgm->flush_cache = avr_flush_cache;
pgm->reset_cache = avr_reset_cache;
/*
* optional functions - these are checked to make sure they are
* assigned before they are called
*/
pgm->unlock = NULL;
pgm->cmd = NULL;
pgm->cmd_tpi = NULL;
pgm->spi = NULL;
pgm->paged_write = NULL;
pgm->paged_load = NULL;
pgm->page_erase = NULL;
pgm->write_setup = NULL;
pgm->read_sig_bytes = NULL;
pgm->read_sib = NULL;
pgm->term_keep_alive= NULL;
pgm->print_parms = NULL;
pgm->set_vtarget = NULL;
pgm->set_varef = NULL;
pgm->set_fosc = NULL;
pgm->set_sck_period = NULL;
pgm->setpin = NULL;
pgm->getpin = NULL;
pgm->highpulsepin = NULL;
pgm->parseexitspecs = NULL;
pgm->perform_osccal = NULL;
pgm->parseextparams = NULL;
pgm->setup = NULL;
pgm->teardown = NULL;
// For allocating "global" memory by the programmer
pgm->cookie = NULL;
return pgm;
}
void pgm_free(PROGRAMMER *p) {
if(p) {
if(p->id) {
ldestroy_cb(p->id, free);
p->id = NULL;
}
if(p->usbpid) {
ldestroy_cb(p->usbpid, free);
p->usbpid = NULL;
}
if(p->hvupdi_support) {
ldestroy_cb(p->hvupdi_support, free);
p->hvupdi_support = NULL;
}
// Never free const char *, eg, p->desc, which are set by cache_string()
// p->cookie is freed by pgm_teardown
Provide cached byte-wise read/write API (#1106) * Provide cached byte-wise read/write API int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char *value); int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char data); int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p); int avr_chip_erase_cached(const PROGRAMMER *pgm, const AVRPART *p); int avr_reset_cache(const PROGRAMMER *pgm, const AVRPART *p); avr_read_byte_cached() and avr_write_byte_cached() use a cache if paged routines are available and if the device memory is EEPROM or flash, otherwise they fall back to pgm->read_byte() and pgm->write_byte(), respectively. Byte-wise cached read always gets its data from the cache, possibly after reading a page from the device memory. Byte-wise cached write with an address in memory range only ever modifies the cache. Any modifications are written to the device after calling avr_flush_cache() or when attempting to read or write from a location outside the address range of the device memory. avr_flush_cache() synchronises pending writes to EEPROM and flash with the device. With some programmer and part combinations, flash (and sometimes EEPROM, too) looks like a NOR memory, ie, one can only write 0 bits, not 1 bits. When this is detected, either page erase is deployed (eg, with parts that have PDI/UPDI interfaces), or if that is not available, both EEPROM and flash caches are fully read in, a pgm->chip_erase() command is issued and both EEPROM and flash are written back to the device. Hence, it can take minutes to ensure that a single previously cleared bit is set and, therefore, this routine should be called sparingly. avr_chip_erase_cached() erases the chip and discards pending writes() to flash or EEPROM. It presets the flash cache to all 0xff alleviating the need to read from the device flash. However, if the programmer serves bootloaders (pgm->prog_modes & PM_SPM) then the flash cache is reset instead, necessitating flash memory be fetched from the device on first read; the reason for this is that bootloaders emulate chip erase and they won't overwrite themselves (some bootloaders, eg, optiboot ignore chip erase commands altogether) making it truly unknowable what the flash contents on device is after a chip erase. For EEPROM avr_chip_erase_cached() concludes that it has been deleted if a previously cached EEPROM page that contained cleared bits now no longer has these clear bits on the device. Only with this evidence is the EEPROM cache preset to all 0xff otherwise the cache discards all pending writes to EEPROM and is left unchanged otherwise. Finally, avr_reset_cache() resets the cache without synchronising pending writes() to the device.
2022-10-05 21:16:15 +00:00
// Never free cp_eeprom or cp_flash cache structures
free(p);
}
}
PROGRAMMER *pgm_dup(const PROGRAMMER *src) {
PROGRAMMER *pgm = pgm_new();
if(src) {
ldestroy_cb(pgm->id, free);
ldestroy_cb(pgm->usbpid, free);
ldestroy_cb(pgm->hvupdi_support, free);
Provide cached byte-wise read/write API (#1106) * Provide cached byte-wise read/write API int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char *value); int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char data); int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p); int avr_chip_erase_cached(const PROGRAMMER *pgm, const AVRPART *p); int avr_reset_cache(const PROGRAMMER *pgm, const AVRPART *p); avr_read_byte_cached() and avr_write_byte_cached() use a cache if paged routines are available and if the device memory is EEPROM or flash, otherwise they fall back to pgm->read_byte() and pgm->write_byte(), respectively. Byte-wise cached read always gets its data from the cache, possibly after reading a page from the device memory. Byte-wise cached write with an address in memory range only ever modifies the cache. Any modifications are written to the device after calling avr_flush_cache() or when attempting to read or write from a location outside the address range of the device memory. avr_flush_cache() synchronises pending writes to EEPROM and flash with the device. With some programmer and part combinations, flash (and sometimes EEPROM, too) looks like a NOR memory, ie, one can only write 0 bits, not 1 bits. When this is detected, either page erase is deployed (eg, with parts that have PDI/UPDI interfaces), or if that is not available, both EEPROM and flash caches are fully read in, a pgm->chip_erase() command is issued and both EEPROM and flash are written back to the device. Hence, it can take minutes to ensure that a single previously cleared bit is set and, therefore, this routine should be called sparingly. avr_chip_erase_cached() erases the chip and discards pending writes() to flash or EEPROM. It presets the flash cache to all 0xff alleviating the need to read from the device flash. However, if the programmer serves bootloaders (pgm->prog_modes & PM_SPM) then the flash cache is reset instead, necessitating flash memory be fetched from the device on first read; the reason for this is that bootloaders emulate chip erase and they won't overwrite themselves (some bootloaders, eg, optiboot ignore chip erase commands altogether) making it truly unknowable what the flash contents on device is after a chip erase. For EEPROM avr_chip_erase_cached() concludes that it has been deleted if a previously cached EEPROM page that contained cleared bits now no longer has these clear bits on the device. Only with this evidence is the EEPROM cache preset to all 0xff otherwise the cache discards all pending writes to EEPROM and is left unchanged otherwise. Finally, avr_reset_cache() resets the cache without synchronising pending writes() to the device.
2022-10-05 21:16:15 +00:00
// There must be only one cache, even though the part is duplicated
if(pgm->cp_flash)
free(pgm->cp_flash);
if(pgm->cp_eeprom)
free(pgm->cp_eeprom);
memcpy(pgm, src, sizeof(*pgm));
Provide cached byte-wise read/write API (#1106) * Provide cached byte-wise read/write API int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char *value); int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char data); int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p); int avr_chip_erase_cached(const PROGRAMMER *pgm, const AVRPART *p); int avr_reset_cache(const PROGRAMMER *pgm, const AVRPART *p); avr_read_byte_cached() and avr_write_byte_cached() use a cache if paged routines are available and if the device memory is EEPROM or flash, otherwise they fall back to pgm->read_byte() and pgm->write_byte(), respectively. Byte-wise cached read always gets its data from the cache, possibly after reading a page from the device memory. Byte-wise cached write with an address in memory range only ever modifies the cache. Any modifications are written to the device after calling avr_flush_cache() or when attempting to read or write from a location outside the address range of the device memory. avr_flush_cache() synchronises pending writes to EEPROM and flash with the device. With some programmer and part combinations, flash (and sometimes EEPROM, too) looks like a NOR memory, ie, one can only write 0 bits, not 1 bits. When this is detected, either page erase is deployed (eg, with parts that have PDI/UPDI interfaces), or if that is not available, both EEPROM and flash caches are fully read in, a pgm->chip_erase() command is issued and both EEPROM and flash are written back to the device. Hence, it can take minutes to ensure that a single previously cleared bit is set and, therefore, this routine should be called sparingly. avr_chip_erase_cached() erases the chip and discards pending writes() to flash or EEPROM. It presets the flash cache to all 0xff alleviating the need to read from the device flash. However, if the programmer serves bootloaders (pgm->prog_modes & PM_SPM) then the flash cache is reset instead, necessitating flash memory be fetched from the device on first read; the reason for this is that bootloaders emulate chip erase and they won't overwrite themselves (some bootloaders, eg, optiboot ignore chip erase commands altogether) making it truly unknowable what the flash contents on device is after a chip erase. For EEPROM avr_chip_erase_cached() concludes that it has been deleted if a previously cached EEPROM page that contained cleared bits now no longer has these clear bits on the device. Only with this evidence is the EEPROM cache preset to all 0xff otherwise the cache discards all pending writes to EEPROM and is left unchanged otherwise. Finally, avr_reset_cache() resets the cache without synchronising pending writes() to the device.
2022-10-05 21:16:15 +00:00
pgm->id = lcreat(NULL, 0);
pgm->usbpid = lcreat(NULL, 0);
pgm->hvupdi_support = lcreat(NULL, 0);
// Leave id list empty but copy usbpid and hvupdi_support over
if(src->hvupdi_support)
for(LNODEID ln = lfirst(src->hvupdi_support); ln; ln = lnext(ln)) {
int *ip = cfg_malloc("pgm_dup()", sizeof(int));
*ip = *(int *) ldata(ln);
ladd(pgm->hvupdi_support, ip);
}
if(src->usbpid)
for(LNODEID ln = lfirst(src->usbpid); ln; ln = lnext(ln)) {
int *ip = cfg_malloc("pgm_dup()", sizeof(int));
*ip = *(int *) ldata(ln);
ladd(pgm->usbpid, ip);
}
}
return pgm;
}
Use const in PROGRAMMER function arguments where appropriate In order to get meaningful const properties for the PROGRAMMER, AVRPART and AVRMEM arguments, some code needed to be moved around, otherwise a network of "tainted" assignments risked rendering nothing const: - Change void (*enable)(PROGRAMMER *pgm) to void (*enable)(PROGRAMMER *pgm, const AVRPART *p); this allows changes in the PROGRAMMER structure after the part is known. For example, use TPI, UPDI, PDI functions in that programmer appropriate to the part. This used to be done later in the process, eg, in the initialize() function, which "taints" all other programmer functions wrt const and sometimes requires other finessing with flags etc. Much clearer with the modified enable() interface. - Move TPI initpgm-type code from initialize() to enable() --- note that initpgm() does not have the info at the time when it is called whether or not TPI is required - buspirate.c: move pgm->flag to PDATA(pgm)->flag (so legitimate modification of the flag does not change PROGRAMMER structure) - Move AVRPART_INIT_SMC and AVRPART_WRITE bits from the flags field in AVRPART to jtagmkII.c's private data flags32 fiels as FLAGS32_INIT_SMC and FLAGS32_WRITE bits - Move the xbeeResetPin component to private data in stk500.c as this is needed by xbee when it saddles on the stk500 code (previously, the flags component of the part was re-dedicated to this) - Change the way the "chained" private data are used in jtag3.c whilst keeping the PROGRAMMER structure read-only otherwise - In stk500v2.c move the STK600 pgm update from stk500v2_initialize() to stk500v2_enable() so the former keeps the PROGRAMMER structure read-only (for const assertion). - In usbasp change the code from changing PROGRAMMER functions late to dispatching to TPI or regular SPI protocol functions at runtime; reason being the decision whether to use TPI protocol is done at run-time depending on the capability of the attached programmer Also fixes Issue #1071, the treatment of default eecr value.
2022-08-17 15:05:28 +00:00
static void pgm_default(void) {
pmsg_error("programmer operation not supported\n");
}
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 pgm_default_2 (const PROGRAMMER *pgm, const AVRPART *p) {
pgm_default();
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 pgm_default_3 (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char * value) {
pgm_default();
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 void pgm_default_4 (const PROGRAMMER *pgm) {
pgm_default();
}
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 pgm_default_5 (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char data) {
pgm_default();
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 void pgm_default_6 (const PROGRAMMER *pgm, const char *p) {
pgm_default();
}
void programmer_display(PROGRAMMER *pgm, const char * p) {
msg_info("%sProgrammer Type : %s\n", p, pgm->type);
msg_info("%sDescription : %s\n", p, pgm->desc);
pgm->display(pgm, p);
}
void pgm_display_generic_mask(const PROGRAMMER *pgm, const char *p, unsigned int show) {
if(show & (1<<PPI_AVR_VCC))
msg_info("%s VCC = %s\n", p, pins_to_str(&pgm->pin[PPI_AVR_VCC]));
if(show & (1<<PPI_AVR_BUFF))
msg_info("%s BUFF = %s\n", p, pins_to_str(&pgm->pin[PPI_AVR_BUFF]));
if(show & (1<<PIN_AVR_RESET))
msg_info("%s RESET = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_RESET]));
if(show & (1<<PIN_AVR_SCK))
msg_info("%s SCK = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_SCK]));
if(show & (1<<PIN_AVR_MOSI))
msg_info("%s MOSI = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_MOSI]));
if(show & (1<<PIN_AVR_MISO))
msg_info("%s MISO = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_MISO]));
if(show & (1<<PIN_LED_ERR))
msg_info("%s ERR LED = %s\n", p, pins_to_str(&pgm->pin[PIN_LED_ERR]));
if(show & (1<<PIN_LED_RDY))
msg_info("%s RDY LED = %s\n", p, pins_to_str(&pgm->pin[PIN_LED_RDY]));
if(show & (1<<PIN_LED_PGM))
msg_info("%s PGM LED = %s\n", p, pins_to_str(&pgm->pin[PIN_LED_PGM]));
if(show & (1<<PIN_LED_VFY))
msg_info("%s VFY LED = %s\n", p, pins_to_str(&pgm->pin[PIN_LED_VFY]));
}
void pgm_display_generic(const PROGRAMMER *pgm, const char *p) {
pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS);
}
PROGRAMMER *locate_programmer(const LISTID programmers, const char *configid) {
PROGRAMMER *p = NULL;
int found = 0;
for(LNODEID ln1=lfirst(programmers); ln1 && !found; ln1=lnext(ln1)) {
p = ldata(ln1);
for(LNODEID ln2=lfirst(p->id); ln2 && !found; ln2=lnext(ln2))
if(strcasecmp(configid, (const char *) ldata(ln2)) == 0)
found = 1;
}
return found? p: NULL;
}
/*
* Iterate over the list of programmers given as "programmers", and
* call the callback function cb for each entry found. cb is being
* passed the following arguments:
* . the name of the programmer (for -c)
* . the descriptive text given in the config file
* . the name of the config file this programmer has been defined in
* . the line number of the config file this programmer has been defined at
* . the "cookie" passed into walk_programmers() (opaque client data)
*/
void walk_programmers(LISTID programmers, walk_programmers_cb cb, void *cookie)
{
LNODEID ln1;
LNODEID ln2;
PROGRAMMER * p;
for (ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) {
p = ldata(ln1);
for (ln2=lfirst(p->id); ln2; ln2=lnext(ln2)) {
cb(ldata(ln2), p->desc, p->config_file, p->lineno, cookie);
}
}
}
/*
* Compare function to sort the list of programmers
*/
static int sort_programmer_compare(const PROGRAMMER *p1, const PROGRAMMER *p2) {
if(p1 == NULL || p1->id == NULL || p2 == NULL || p2->id == NULL)
return 0;
return strcasecmp(ldata(lfirst(p1->id)), ldata(lfirst(p2->id)));
}
/*
* Sort the list of programmers given as "programmers"
*/
void sort_programmers(LISTID programmers)
{
lsort(programmers,(int (*)(void*, void*)) sort_programmer_compare);
}