Merge pull request #1 from avrdudes/main

Merge latest avrdudes/avrdude main branch
This commit is contained in:
Dawid Buchwald
2022-10-23 13:56:52 +02:00
committed by GitHub
116 changed files with 31124 additions and 24066 deletions

View File

@@ -37,6 +37,8 @@ jobs:
- uses: actions/checkout@v2
- name: Install prerequisites
run: >-
sudo apt-get update
sudo apt-get install -y
build-essential
cmake
@@ -47,9 +49,13 @@ jobs:
libusb-1.0-0-dev
libhidapi-dev
libftdi1-dev
texinfo
texlive
texi2html
- name: Configure
run: >-
cmake
-D BUILD_DOC=1
-D DEBUG_CMAKE=1
-D HAVE_LINUXGPIO=1
-D HAVE_LINUXSPI=1
@@ -91,6 +97,8 @@ jobs:
apt-get update
- name: Install prerequisites
run: >-
apt-get update
apt-get install -y
git
cmake
@@ -141,6 +149,8 @@ jobs:
- uses: actions/checkout@v2
- name: Install prerequisites
run: >-
brew update
brew install
cmake
flex

View File

@@ -21,7 +21,7 @@
# cmake --build build
cmake_minimum_required(VERSION 3.12)
project(avrdude VERSION 7.0)
project(avrdude VERSION 7.0 LANGUAGES C)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED True)
@@ -281,25 +281,8 @@ endif()
add_subdirectory(src)
# =====================================
# Setup default port names
# =====================================
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(DEFAULT_PAR_PORT "/dev/parport0")
set(DEFAULT_SER_PORT "/dev/ttyS0")
elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
set(DEFAULT_PAR_PORT "/dev/ppi0")
set(DEFAULT_SER_PORT "/dev/cuad0")
elseif (CMAKE_SYSTEM_NAME STREQUAL "Solaris")
set(DEFAULT_PAR_PORT "/dev/printers/0")
set(DEFAULT_SER_PORT "/dev/term/a")
elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(DEFAULT_PAR_PORT "lpt1")
set(DEFAULT_SER_PORT "com1")
else()
set(DEFAULT_PAR_PORT "unknown")
set(DEFAULT_SER_PORT "unknown")
if(BUILD_DOC)
add_subdirectory(src/doc)
endif()
# =====================================

134
NEWS
View File

@@ -18,7 +18,46 @@ Changes since version 7.0:
- Fix micronucleus bootloader to check for unresponsive USB
devices #945
- Fix src/CMakeLists.txt to honor CMAKE_INSTALL_LIBDIR #972
- [bug #43898] atmega644p remains stopped after JTAG transaction #366
- [bug #43898] atmega644p remains stopped after JTAG
transaction #366
- Wrong timings for ATmega328PB and other parts in avrdude.conf
#976
- FT232R based programmer ATmega2560 Flash Reading Problem #995
also #474
- Enable avrdude to send full input file incl trailing 0xff
#936
- Portname default for linuxspi programmer not recognized #926
- JTAG1 unable to write fuse and lock bits #443
- Unknown option '-s' on command line (legacy) #1032
- STK500/arduino/xbee programmers fail EEPROM r/w for some
parts #967 also #421
- Design issue: jtag2updi is hardcoded to fail for parts with
has_pdi = yes #1037
- Option parse error: after -U flash:w:program_to_upload.hex,
subsequent -V ignored #441
- Automatic verification is designed to fail for stdin #1044
- Display correct number of bytes when input file has holes
#1005
- Cmake installs avrdude.1 in the wrong place on Linux #1064
- avr910 -qq prompt too verbose #1081
- avrftdi.c: paged write can fail at addr 0 #1073
- Permission denied accessing /sys/class/gpio/gpioX/direction
would leave pin exported #472 also #372
- Raspberry Pi sysfs bug workaround for linuxgpio driver #386
- Fix CMake avrdude.conf dependency to avrdude.conf.in #1035
- CMake infrastructure does not handle documentation #947
- New feature: ability to reset FLIPv2 targets #733
- Fix Extended address not sent with avr109/butterfly #360
and #454
- Enable AVR JTAG ICE mkI program EEPROM in terminal mode
#1054
- Make flash writes work in terminal mode #1020
- Add support for XMEGA specific AVR109 protocol extensions
used by XBoot #200
- jtag2updi can not write EEPROM in terminal mode #1116
- Make UPDI programmers less verbose during initialization
#1084
- Quell mode isn't handled systematically #1114
* Pull requests:
@@ -32,11 +71,100 @@ Changes since version 7.0:
- Replace internal knowledge in jtag3.c by a public API #996
- JTAG3 UPDI EEPROM fix #1013
- Treat x bits in .conf SPI commands as 0 #943
- Fix avrftdi support for ATmega2560 et al #474
- Fix avrdude.conf timings for ATmega328PB and other parts #976
- Fix avrftdi support for ATmega2560 et al #998
- Fix avrdude.conf timings for ATmega328PB and other parts #1001
- Fix PICKit2 ATmega2560 flash paged flash read #1023
- Fix ft245r paged read for ATmega2560 et al #1018
- Add option -A that supresses trailing 0xff optimisation
and automatically do so for -c arduino #936
- Fix linuxspi default port #933
- Add support for high-voltage UPDI im jtag3.c #1015
- Fix terminal write edge cases; add one read mode; add quell
command #1025
- Fix usbtiny read for parts with more than 64 kB flash #1029
- CMakeLists.txt: fix build without C++ #1016
- Provide file format I: Intel HEX with comments that ignores
checksum errors #1030
- Enable writing fuse and lock bits for AVR-JTAGICE #1031
- Ignore -s flag as safemode is no longer supported #1033
- Developer options to describe parts and
extend avrdude.conf syntax #1040
- Deprecate original STK500 v1 protocol in favour of optiboot
and Arduino as ISP #1046
- Add jtagmkii_updi programmer option #1048
- Enable stdin verification, display correct number of bytes
written/verified, check -U memory names against spelling
errors and exit but skip -U memory updates with known
memories that the part lacks #1053
- Handle invalid -U file format specifiers for input #1042
- Implement a dry run for -U updates before opening the
programmer #1056
- Implement -c <wildcard>/dev_options for printing avrdude.conf
show comments with -p*/s or -c*/s; Reduce -p */r raw output;
specifying the full memory name now always works; stop
listing programmers where id starts with dot #1059
- Fix logfile short option in man-page; fix install dir for man
page #1063
- Use const for programmer functions where useful; add second
argument for programmer enable interface function
void (*enable)(PROGRAMMER *pgm, const AVRPART *p) #1078
- Make avr910 programmer initialize() less verbose #1083
- Fix flash paged write for avrftdi.c #1074
- Fix 4 parts wrt to their interfaces in avrdude.conf; rewrite
avrdude.conf.in file from avrdude -c* -p* output; reformat
conditional programmers in avrdude.conf.in using -c*; fix
reset=dedicated|io; entries #1086
- Add prog_modes, a bitwise or of prgramming modes, to part and
programmer definitions; add to part definition
+ mcuid, a unique id in 0..2039 for 8-bit AVR
+ n_interrupts, the number of interrupts
+ n_page_erase, if set, the # of pages erased for NVM erase
implement a simple calculator in config_gram.y for numeric
values; set part prog_modes, mcuid, n_interrupts and
n_page_erase in avrdude.conf.in; add external intelligence
about AVRs avrintel.[ch] to the project and warn during
parsing if mcuid is incompatible with it #1091
- Fix permission denied error in linuxgpio programmer #917
- Add a programmer arduino_gemma for the Arduino Gemma
bootloader and another one, adafruit_gemma, for the Adafruit
Trinket Gemma bootloader in avrdude.conf; #1093
- Add digilent-hs2 programmer in avrdude.conf #1094
- Fix dependency chain between avrdude.conf.in and
avrdude.conf #1095
- Build docs with CMake #1096
- New feature so user can print all compatible parts for a
programmer using -p\? -c programmer and vice versa #1099
- Add extended parameter disable_no_cs for linuxspi programmer
#1100
- Fix avr109 extended address #1101
- Add support for Flip 2 reset on exit #1102
- Support for Power Debugger analog readings in terminal mode
#1105
- Provide cached byte-wise read/write API #1106
- AVR109: support for prodsig read and usersig read/write #1108
- Add missing AVR variants the original JTAG ICE supports #1109
- Improve help message in terminal and provide new command
pgerase #1113
- Fix pointer truncation for Windows x64 #1119
- Fix jtag3_page_erase for targets with UPDI #1112
- Fix writing of last word on DWORD TPI parts #1115
- Use byte-wise read/write when page size is 1 in terminal
cache #1121
- Suppress Teensy USB communication error message on reboot #1122
- Fix UPDI erase when target is locked #1125
- Review and overhaul AVRDUDE's messaging system #1126
* Internals:
- Implement -c <wildcard>/dev_opts and -p <wildcard>/dev_opts
for printing avrdude.conf programmer and part entries
- Reviewed API for prgrammer functions: use const for
programmer functions where useful; add second argument for
void (*enable)(PROGRAMMER *pgm, const AVRPART *p) #1078
- Reviewed messaging system making warnings and errors explicit
and treat them systematically
Changes in version 7.0:
* Major changes compared to the previous version:

View File

@@ -37,7 +37,7 @@ case "${ostype}" in
# try to find out whether this is an Embedded Linux
# platform (e.g. Raspberry Pi)
machine=$(uname -m)
if expr "${machine}" : 'arm' >/dev/null
if expr "${machine}" : '^\(arm\|aarch\)' >/dev/null
then
extra_enable="${extra_enable} -D HAVE_LINUXGPIO=ON -D HAVE_LINUXSPI=ON"
fi

View File

@@ -56,6 +56,8 @@ if(WIN32)
endif()
if(MSVC)
enable_language(CXX)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS=1)
add_compile_definitions(_CRT_NONSTDC_NO_WARNINGS=1)
add_compile_definitions(_WINSOCK_DEPRECATED_NO_WARNINGS=1)
@@ -79,31 +81,53 @@ else()
add_compile_options(-Wall) # -Wextra
endif()
# =====================================
# Setup default port names
# =====================================
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(DEFAULT_PAR_PORT "/dev/parport0")
set(DEFAULT_SER_PORT "/dev/ttyS0")
elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
set(DEFAULT_PAR_PORT "/dev/ppi0")
set(DEFAULT_SER_PORT "/dev/cuad0")
elseif (CMAKE_SYSTEM_NAME STREQUAL "Solaris")
set(DEFAULT_PAR_PORT "/dev/printers/0")
set(DEFAULT_SER_PORT "/dev/term/a")
elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(DEFAULT_PAR_PORT "lpt1")
set(DEFAULT_SER_PORT "com1")
else()
set(DEFAULT_PAR_PORT "unknown")
set(DEFAULT_SER_PORT "unknown")
endif()
# =====================================
# Configure files
# =====================================
macro(configure_option option)
if(${${option}})
string(REGEX REPLACE "(.*)@${option}_BEGIN@(.*)@${option}_END@(.*)" "\\1\\2\\3" conf_file "${conf_file}")
else()
string(REGEX REPLACE "(.*)@${option}_BEGIN@(.*)@${option}_END@(.*)" "\\1\\3" conf_file "${conf_file}")
endif()
endmacro()
file(READ avrdude.conf.in conf_file)
configure_option(HAVE_PARPORT)
configure_option(HAVE_LINUXGPIO)
configure_option(HAVE_LINUXSPI)
file(WRITE "${PROJECT_BINARY_DIR}/avrdude.conf.in" "${conf_file}")
configure_file(cmake_config.h.in ac_cfg.h)
configure_file("${PROJECT_BINARY_DIR}/avrdude.conf.in" avrdude.conf)
configure_file(avrdude.spec.in avrdude.spec)
if(WIN32)
configure_file(windows.rc.in windows.rc)
endif()
add_custom_command(
OUTPUT avrdude.conf
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/avrdude.conf.in" avrdude.conf.in
COMMAND ${CMAKE_COMMAND}
-D HAVE_PARPORT=${HAVE_PARPORT}
-D HAVE_LINUXSPI=${HAVE_LINUXSPI}
-D HAVE_LINUXGPIO=${HAVE_LINUXGPIO}
-D DEFAULT_PAR_PORT=${DEFAULT_PAR_PORT}
-D DEFAULT_SER_PORT=${DEFAULT_SER_PORT}
-P "${CMAKE_CURRENT_SOURCE_DIR}/configure.cmake"
DEPENDS avrdude.conf.in
VERBATIM
)
add_custom_target(conf ALL DEPENDS avrdude.conf)
# =====================================
# Project
# =====================================
@@ -115,6 +139,7 @@ add_library(libavrdude
avr.c
avr910.c
avr910.h
avrcache.c
avrdude.h
avrftdi.c
avrftdi.h
@@ -250,6 +275,11 @@ add_executable(avrdude
main.c
term.c
term.h
avrintel.c
avrintel.h
developer_opts.c
developer_opts.h
developer_opts_private.h
whereami.c
whereami.h
"${EXTRA_WINDOWS_RESOURCES}"
@@ -268,4 +298,6 @@ install(TARGETS libavrdude
PUBLIC_HEADER DESTINATION include COMPONENT dev
)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/avrdude.conf" TYPE SYSCONF)
install(FILES avrdude.1 TYPE MAN)
install(FILES "avrdude.1"
DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"
)

View File

@@ -92,6 +92,7 @@ libavrdude_a_SOURCES = \
avr.c \
avr910.c \
avr910.h \
avrcache.c \
avrdude.h \
avrftdi.c \
avrftdi.h \
@@ -198,6 +199,11 @@ avrdude_SOURCES = \
main.c \
whereami.c \
whereami.h \
avrintel.c \
avrintel.h \
developer_opts.c \
developer_opts.h \
developer_opts_private.h \
term.c \
term.h

View File

@@ -38,14 +38,13 @@
#include "arduino.h"
/* read signature bytes - arduino version */
static int arduino_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
{
static int arduino_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m) {
unsigned char buf[32];
/* Signature byte reads are always 3 bytes. */
if (m->size < 3) {
avrdude_message(MSG_INFO, "%s: memsize too small for sig byte read", progname);
pmsg_error("memsize too small for sig byte read");
return -1;
}
@@ -57,19 +56,16 @@ static int arduino_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
if (serial_recv(&pgm->fd, buf, 5) < 0)
return -1;
if (buf[0] == Resp_STK_NOSYNC) {
avrdude_message(MSG_INFO, "%s: stk500_cmd(): programmer is out of sync\n",
progname);
pmsg_error("programmer is out of sync\n");
return -1;
} else if (buf[0] != Resp_STK_INSYNC) {
avrdude_message(MSG_INFO, "\n%s: arduino_read_sig_bytes(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
return -2;
msg_error("\n");
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
return -2;
}
if (buf[4] != Resp_STK_OK) {
avrdude_message(MSG_INFO, "\n%s: arduino_read_sig_bytes(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_OK, buf[4]);
msg_error("\n");
pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[4]);
return -3;
}
@@ -80,8 +76,7 @@ static int arduino_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
return 3;
}
static int arduino_open(PROGRAMMER * pgm, char * port)
{
static int arduino_open(PROGRAMMER *pgm, const char *port) {
union pinfo pinfo;
strcpy(pgm->port, port);
pinfo.serialinfo.baud = pgm->baudrate? pgm->baudrate: 115200;
@@ -118,8 +113,7 @@ static void arduino_close(PROGRAMMER * pgm)
const char arduino_desc[] = "Arduino programmer";
void arduino_initpgm(PROGRAMMER * pgm)
{
void arduino_initpgm(PROGRAMMER *pgm) {
/* This is mostly a STK500; just the signature is read
differently than on real STK500v1
and the DTR signal is set when opening the serial port
@@ -130,4 +124,6 @@ void arduino_initpgm(PROGRAMMER * pgm)
pgm->read_sig_bytes = arduino_read_sig_bytes;
pgm->open = arduino_open;
pgm->close = arduino_close;
disable_trailing_ff_removal(); /* so that arduino bootloader can ignore chip erase */
}

View File

@@ -22,7 +22,7 @@
#define arduino_h__
extern const char arduino_desc[];
void arduino_initpgm (PROGRAMMER * pgm);
void arduino_initpgm(PROGRAMMER *pgm);
#endif

491
src/avr.c
View File

@@ -38,8 +38,7 @@ FP_UpdateProgress update_progress;
#define DEBUG 0
/* TPI: returns 1 if NVM controller busy, 0 if free */
int avr_tpi_poll_nvmbsy(PROGRAMMER *pgm)
{
int avr_tpi_poll_nvmbsy(const PROGRAMMER *pgm) {
unsigned char cmd;
unsigned char res;
@@ -49,19 +48,17 @@ int avr_tpi_poll_nvmbsy(PROGRAMMER *pgm)
}
/* TPI chip erase sequence */
int avr_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
int avr_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
int err;
AVRMEM *mem;
if (p->flags & AVRPART_HAS_TPI) {
if (p->prog_modes & PM_TPI) {
pgm->pgm_led(pgm, ON);
/* Set Pointer Register */
mem = avr_locate_mem(p, "flash");
if (mem == NULL) {
avrdude_message(MSG_INFO, "No flash memory to erase for part %s\n",
p->desc);
pmsg_error("no flash memory to erase for part %s\n", p->desc);
return -1;
}
@@ -93,19 +90,18 @@ int avr_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
return 0;
} else {
avrdude_message(MSG_INFO, "%s called for a part that has no TPI\n", __func__);
return -1;
}
pmsg_error("part has no TPI\n");
return -1;
}
}
/* TPI program enable sequence */
int avr_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p, unsigned char guard_time)
{
int avr_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p, unsigned char guard_time) {
int err, retry;
unsigned char cmd[2];
unsigned char response;
if(p->flags & AVRPART_HAS_TPI) {
if(p->prog_modes & PM_TPI) {
/* set guard time */
cmd[0] = (TPI_CMD_SSTCS | TPI_REG_TPIPCR);
cmd[1] = guard_time;
@@ -118,7 +114,7 @@ int avr_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p, unsigned char guard_ti
cmd[0] = (TPI_CMD_SLDCS | TPI_REG_TPIIR);
err = pgm->cmd_tpi(pgm, cmd, 1, &response, sizeof(response));
if (err || response != TPI_IDENT_CODE) {
avrdude_message(MSG_INFO, "TPIIR not correct\n");
pmsg_error("TPIIR not correct\n");
return -1;
}
@@ -138,18 +134,17 @@ int avr_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p, unsigned char guard_ti
return 0;
}
avrdude_message(MSG_INFO, "Error enabling TPI external programming mode:");
avrdude_message(MSG_INFO, "Target does not reply\n");
pmsg_error("target does not reply when enabling TPI external programming mode\n");
return -1;
} else {
avrdude_message(MSG_INFO, "%s called for a part that has no TPI\n", __func__);
pmsg_error("part has no TPI\n");
return -1;
}
}
/* TPI: setup NVMCMD register and pointer register (PR) for read/write/erase */
static int avr_tpi_setup_rw(PROGRAMMER * pgm, AVRMEM * mem,
static int avr_tpi_setup_rw(const PROGRAMMER *pgm, const AVRMEM *mem,
unsigned long addr, unsigned char nvmcmd)
{
unsigned char cmd[4];
@@ -178,7 +173,7 @@ static int avr_tpi_setup_rw(PROGRAMMER * pgm, AVRMEM * mem,
return 0;
}
int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
int avr_read_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char * value)
{
unsigned char cmd[4];
@@ -188,19 +183,17 @@ int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
OPCODE * readop, * lext;
if (pgm->cmd == NULL) {
avrdude_message(MSG_INFO, "%s: Error: %s programmer uses avr_read_byte_default() but does not\n"
"provide a cmd() method.\n",
progname, pgm->type);
pmsg_error("%s programmer uses avr_read_byte_default() but does not\n", pgm->type);
imsg_error("provide a cmd() method\n");
return -1;
}
pgm->pgm_led(pgm, ON);
pgm->err_led(pgm, OFF);
if (p->flags & AVRPART_HAS_TPI) {
if (p->prog_modes & PM_TPI) {
if (pgm->cmd_tpi == NULL) {
avrdude_message(MSG_INFO, "%s: Error: %s programmer does not support TPI\n",
progname, pgm->type);
pmsg_error("%s programmer does not support TPI\n", pgm->type);
return -1;
}
@@ -234,8 +227,7 @@ int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
if (readop == NULL) {
#if DEBUG
avrdude_message(MSG_INFO, "avr_read_byte_default(): operation not supported on memory type \"%s\"\n",
mem->desc);
pmsg_error("operation not supported on memory type %s\n", mem->desc);
#endif
return -1;
}
@@ -278,10 +270,25 @@ int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
* value. This is useful for determining where to stop when dealing
* with "flash" memory, since writing 0xff to flash is typically a
* no-op. Always return an even number since flash is word addressed.
* Only apply this optimisation on flash-type memory.
*/
int avr_mem_hiaddr(AVRMEM * mem)
int avr_mem_hiaddr(const AVRMEM * mem)
{
int i, n;
static int disableffopt;
/* calling once with NULL disables any future trailing-0xff optimisation */
if(!mem) {
disableffopt = 1;
return 0;
}
if(disableffopt)
return mem->size;
/* if the memory is not a flash-type memory do not remove trailing 0xff */
if(!avr_mem_is_flash_type(mem))
return mem->size;
/* return the highest non-0xff address regardless of how much
memory was read */
@@ -300,37 +307,46 @@ int avr_mem_hiaddr(AVRMEM * mem)
/*
* Read the entirety of the specified memory type into the
* corresponding buffer of the avrpart pointed to by 'p'.
* If v is non-NULL, verify against v's memory area, only
* those cells that are tagged TAG_ALLOCATED are verified.
* Read the entirety of the specified memory type into the corresponding
* buffer of the avrpart pointed to by p. If v is non-NULL, verify against
* v's memory area, only those cells that are tagged TAG_ALLOCATED are
* verified.
*
* Return the number of bytes read, or < 0 if an error occurs.
* Return the number of bytes read, or < 0 if an error occurs.
*/
int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
AVRPART * v)
{
unsigned long i, lastaddr;
unsigned char cmd[4];
AVRMEM * mem, * vmem = NULL;
int rc;
mem = avr_locate_mem(p, memtype);
if (v != NULL)
vmem = avr_locate_mem(v, memtype);
int avr_read(const PROGRAMMER *pgm, const AVRPART *p, const char *memtype, const AVRPART *v) {
AVRMEM *mem = avr_locate_mem(p, memtype);
if (mem == NULL) {
avrdude_message(MSG_INFO, "No \"%s\" memory for part %s\n",
memtype, p->desc);
return -1;
pmsg_error("no %s memory for part %s\n", memtype, p->desc);
return LIBAVRDUDE_GENERAL_FAILURE;
}
return avr_read_mem(pgm, p, mem, v);
}
/*
* Read the entirety of the specified memory into the corresponding buffer of
* the avrpart pointed to by p. If v is non-NULL, verify against v's memory
* area, only those cells that are tagged TAG_ALLOCATED are verified.
*
* Return the number of bytes read, or < 0 if an error occurs.
*/
int avr_read_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, const AVRPART *v) {
unsigned long i, lastaddr;
unsigned char cmd[4];
AVRMEM *vmem = NULL;
int rc;
if (v != NULL)
vmem = avr_locate_mem(v, mem->desc);
/*
* start with all 0xff
*/
memset(mem->buf, 0xff, mem->size);
/* supports "paged load" thru post-increment */
if ((p->flags & AVRPART_HAS_TPI) && mem->page_size > 1 &&
if ((p->prog_modes & PM_TPI) && mem->page_size > 1 &&
mem->size % mem->page_size == 0 && pgm->cmd_tpi != NULL) {
while (avr_tpi_poll_nvmbsy(pgm));
@@ -352,7 +368,7 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
rc = pgm->cmd_tpi(pgm, cmd, 1, mem->buf + i, 1);
lastaddr++;
if (rc == -1) {
avrdude_message(MSG_INFO, "avr_read(): error reading address 0x%04lx\n", i);
pmsg_error("unable to read address 0x%04lx\n", i);
return -1;
}
}
@@ -410,21 +426,13 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
/* paged load failed, fall back to byte-at-a-time read below */
failure = 1;
} else {
avrdude_message(MSG_DEBUG, "%s: avr_read(): skipping page %u: no interesting data\n",
progname, pageaddr / mem->page_size);
pmsg_debug("avr_read_mem(): skipping page %u: no interesting data\n", pageaddr / mem->page_size);
}
nread++;
report_progress(nread, npages, NULL);
}
if (!failure) {
if (strcasecmp(mem->desc, "flash") == 0 ||
strcasecmp(mem->desc, "application") == 0 ||
strcasecmp(mem->desc, "apptable") == 0 ||
strcasecmp(mem->desc, "boot") == 0)
return avr_mem_hiaddr(mem);
else
return mem->size;
}
if (!failure)
return avr_mem_hiaddr(mem);
/* else: fall back to byte-at-a-time write, for historical reasons */
}
@@ -440,34 +448,27 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
{
rc = pgm->read_byte(pgm, p, mem, i, mem->buf + i);
if (rc != LIBAVRDUDE_SUCCESS) {
avrdude_message(MSG_INFO, "avr_read(): error reading address 0x%04lx\n", i);
pmsg_error("unable to read byte at address 0x%04lx\n", i);
if (rc == LIBAVRDUDE_GENERAL_FAILURE) {
avrdude_message(MSG_INFO, " read operation not supported for memory \"%s\"\n",
memtype);
pmsg_error("read operation not supported for memory %s\n", mem->desc);
return LIBAVRDUDE_NOTSUPPORTED;
}
avrdude_message(MSG_INFO, " read operation failed for memory \"%s\"\n",
memtype);
pmsg_error("read operation failed for memory %s\n", mem->desc);
return LIBAVRDUDE_SOFTFAIL;
}
}
report_progress(i, mem->size, NULL);
}
if (strcasecmp(mem->desc, "flash") == 0 ||
strcasecmp(mem->desc, "application") == 0 ||
strcasecmp(mem->desc, "apptable") == 0 ||
strcasecmp(mem->desc, "boot") == 0)
return avr_mem_hiaddr(mem);
else
return i;
return avr_mem_hiaddr(mem);
}
/*
* write a page data at the specified address
*/
int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
int avr_write_page(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr)
{
unsigned char cmd[4];
@@ -475,16 +476,14 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
OPCODE * wp, * lext;
if (pgm->cmd == NULL) {
avrdude_message(MSG_INFO, "%s: Error: %s programmer uses avr_write_page() but does not\n"
"provide a cmd() method.\n",
progname, pgm->type);
pmsg_error("%s programmer uses avr_write_page() but does not\n", pgm->type);
imsg_error("provide a cmd() method\n");
return -1;
}
wp = mem->op[AVR_OP_WRITEPAGE];
if (wp == NULL) {
avrdude_message(MSG_INFO, "avr_write_page(): memory \"%s\" not configured for page writes\n",
mem->desc);
pmsg_error("memory %s not configured for page writes\n", mem->desc);
return -1;
}
@@ -527,7 +526,7 @@ int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
}
int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char data)
{
unsigned char cmd[4];
@@ -545,24 +544,22 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
struct timeval tv;
if (pgm->cmd == NULL) {
avrdude_message(MSG_INFO, "%s: Error: %s programmer uses avr_write_byte_default() but does not\n"
"provide a cmd() method.\n",
progname, pgm->type);
pmsg_error("%s programmer uses avr_write_byte_default() but does not\n", pgm->type);
imsg_error("provide a cmd() method\n");
return -1;
}
if (p->flags & AVRPART_HAS_TPI) {
if (p->prog_modes & PM_TPI) {
if (pgm->cmd_tpi == NULL) {
avrdude_message(MSG_INFO, "%s: Error: %s programmer does not support TPI\n",
progname, pgm->type);
pmsg_error("%s programmer does not support TPI\n", pgm->type);
return -1;
}
if (strcmp(mem->desc, "flash") == 0) {
avrdude_message(MSG_INFO, "Writing a byte to flash is not supported for %s\n", p->desc);
pmsg_error("writing a byte to flash is not supported for %s\n", p->desc);
return -1;
} else if ((mem->offset + addr) & 1) {
avrdude_message(MSG_INFO, "Writing a byte to an odd location is not supported for %s\n", p->desc);
pmsg_error("writing a byte to an odd location is not supported for %s\n", p->desc);
return -1;
}
@@ -597,8 +594,7 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
return 0;
}
if (!mem->paged &&
(p->flags & AVRPART_IS_AT90S1200) == 0) {
if (!mem->paged && (p->flags & AVRPART_IS_AT90S1200) == 0) {
/*
* check to see if the write is necessary by reading the existing
* value and only write if we are changing the value; we can't
@@ -650,8 +646,7 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
if (writeop == NULL) {
#if DEBUG
avrdude_message(MSG_INFO, "avr_write_byte_default(): write not supported for memory type \"%s\"\n",
mem->desc);
pmsg_error("write not supported for memory type %s\n", mem->desc);
#endif
return -1;
}
@@ -743,25 +738,20 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
* device if the data read back does not match what we wrote.
*/
pgm->pgm_led(pgm, OFF);
avrdude_message(MSG_INFO, "%s: this device must be powered off and back on to continue\n",
progname);
pmsg_info("this device must be powered off and back on to continue\n");
if (pgm->pinno[PPI_AVR_VCC]) {
avrdude_message(MSG_INFO, "%s: attempting to do this now ...\n", progname);
pmsg_info("attempting to do this now ...\n");
pgm->powerdown(pgm);
usleep(250000);
rc = pgm->initialize(pgm, p);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: initialization failed, rc=%d\n", progname, rc);
avrdude_message(MSG_INFO, "%s: can't re-initialize device after programming the "
"%s bits\n", progname, mem->desc);
avrdude_message(MSG_INFO, "%s: you must manually power-down the device and restart\n"
"%s: %s to continue.\n",
progname, progname, progname);
pmsg_error("initialization failed, rc=%d\n", rc);
imsg_error("cannot re-initialize device after programming the %s bits\n", mem->desc);
imsg_error("you must manually power-down the device and restart %s to continue\n", progname);
return -3;
}
avrdude_message(MSG_INFO, "%s: device was successfully re-initialized\n",
progname);
pmsg_info("device was successfully re-initialized\n");
return 0;
}
}
@@ -788,7 +778,7 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
/*
* write a byte of data at the specified address
*/
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
int avr_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char data)
{
return pgm->write_byte(pgm, p, mem, addr, data);
@@ -796,17 +786,32 @@ int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
/*
* Write the whole memory region of the specified memory from the
* corresponding buffer of the avrpart pointed to by 'p'. Write up to
* 'size' bytes from the buffer. Data is only written if the new data
* value is different from the existing data value. Data beyond
* 'size' bytes is not affected.
* Write the whole memory region of the specified memory from its buffer of
* the avrpart pointed to by p to the device. Write up to size bytes from
* the buffer. Data is only written if the corresponding tags byte is set.
* Data beyond size bytes are not affected.
*
* Return the number of bytes written, or -1 if an error occurs.
* Return the number of bytes written, or LIBAVRDUDE_GENERAL_FAILURE on error.
*/
int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
int auto_erase)
{
int avr_write(const PROGRAMMER *pgm, const AVRPART *p, const char *memtype, int size, int auto_erase) {
AVRMEM *m = avr_locate_mem(p, memtype);
if (m == NULL) {
pmsg_error("no %s memory for part %s\n", memtype, p->desc);
return LIBAVRDUDE_GENERAL_FAILURE;
}
return avr_write_mem(pgm, p, m, size, auto_erase);
}
/*
* Write the whole memory region of the specified memory from its buffer of
* the avrpart pointed to by p to the device. Write up to size bytes from
* the buffer. Data is only written if the corresponding tags byte is set.
* Data beyond size bytes are not affected.
*
* Return the number of bytes written, or LIBAVRDUDE_GENERAL_FAILURE on error.
*/
int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int size, int auto_erase) {
int rc;
int newpage, page_tainted, flush_page, do_write;
int wsize;
@@ -814,14 +819,6 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
unsigned char data;
int werror;
unsigned char cmd[4];
AVRMEM * m;
m = avr_locate_mem(p, memtype);
if (m == NULL) {
avrdude_message(MSG_INFO, "No \"%s\" memory for part %s\n",
memtype, p->desc);
return -1;
}
pgm->err_led(pgm, OFF);
@@ -832,20 +829,18 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
wsize = size;
}
else if (size > wsize) {
avrdude_message(MSG_INFO, "%s: WARNING: %d bytes requested, but memory region is only %d"
"bytes\n"
"%sOnly %d bytes will actually be written\n",
progname, size, wsize,
progbuf, wsize);
pmsg_warning("%d bytes requested, but memory region is only %d bytes\n", size, wsize);
imsg_warning("Only %d bytes will actually be written\n", wsize);
}
if ((p->flags & AVRPART_HAS_TPI) && m->page_size > 1 &&
pgm->cmd_tpi != NULL) {
if ((p->prog_modes & PM_TPI) && m->page_size > 1 && pgm->cmd_tpi) {
unsigned int chunk; /* number of words for each write command */
unsigned int j, writeable_chunk;
if (wsize == 1) {
/* fuse (configuration) memory: only single byte to write */
return avr_write_byte(pgm, p, m, 0, m->buf[0]) == 0? 1: -1;
return avr_write_byte(pgm, p, m, 0, m->buf[0]) == 0? 1: LIBAVRDUDE_GENERAL_FAILURE;
}
while (avr_tpi_poll_nvmbsy(pgm));
@@ -853,35 +848,49 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
/* setup for WORD_WRITE */
avr_tpi_setup_rw(pgm, m, 0, TPI_NVMCMD_WORD_WRITE);
/* make sure it's aligned to a word boundary */
if (wsize & 0x1) {
wsize++;
/*
* Some TPI devices can only program 2 or 4 words (4 or 8 bytes) at a time.
* This is set by the n_word_writes option of the AVRMEM config section.
* Ensure that we align our write size to this boundary.
*/
if (m->n_word_writes < 0 || m->n_word_writes > 4 || m->n_word_writes == 3) {
msg_error("\n");
pmsg_error("unsupported n_word_writes value of %d for %s memory\n",
m->n_word_writes, m->desc);
return LIBAVRDUDE_GENERAL_FAILURE;
}
chunk = m->n_word_writes > 0 ? 2*m->n_word_writes : 2;
wsize = (wsize+chunk-1) / chunk * chunk;
/* write words, low byte first */
for (lastaddr = i = 0; i < wsize; i += 2) {
if ((m->tags[i] & TAG_ALLOCATED) != 0 ||
(m->tags[i + 1] & TAG_ALLOCATED) != 0) {
/* write words in chunks, low byte first */
for (lastaddr = i = 0; i < wsize; i += chunk) {
/* check that at least one byte in this chunk is allocated */
for (writeable_chunk = j = 0; !writeable_chunk && j < chunk; j++) {
writeable_chunk = m->tags[i+j] & TAG_ALLOCATED;
}
if (writeable_chunk) {
if (lastaddr != i) {
/* need to setup new address */
avr_tpi_setup_rw(pgm, m, i, TPI_NVMCMD_WORD_WRITE);
lastaddr = i;
}
// Write each byte of the chunk. Unallocated bytes should read
// as 0xFF, which should no-op.
cmd[0] = TPI_CMD_SST_PI;
cmd[1] = m->buf[i];
rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
for (j = 0; j < chunk; j++) {
cmd[1] = m->buf[i+j];
rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
}
cmd[1] = m->buf[i + 1];
rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
lastaddr += 2;
lastaddr += chunk;
while (avr_tpi_poll_nvmbsy(pgm));
}
report_progress(i, wsize, NULL);
}
return i;
}
@@ -928,8 +937,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
/* paged write failed, fall back to byte-at-a-time write below */
failure = 1;
} else {
avrdude_message(MSG_DEBUG, "%s: avr_write(): skipping page %u: no interesting data\n",
progname, pageaddr / m->page_size);
pmsg_debug("avr_write_mem(): skipping page %u: no interesting data\n", pageaddr / m->page_size);
}
nwritten++;
report_progress(nwritten, npages, NULL);
@@ -988,8 +996,7 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
if (do_write) {
rc = avr_write_byte(pgm, p, m, i, data);
if (rc) {
avrdude_message(MSG_INFO, " ***failed; ");
avrdude_message(MSG_INFO, "\n");
msg_error(" ***failed;\n");
pgm->err_led(pgm, ON);
werror = 1;
}
@@ -1002,11 +1009,8 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
if (flush_page) {
rc = avr_write_page(pgm, p, m, i);
if (rc) {
avrdude_message(MSG_INFO, " *** page %d (addresses 0x%04x - 0x%04x) failed "
"to write\n",
i % m->page_size,
i - m->page_size + 1, i);
avrdude_message(MSG_INFO, "\n");
msg_error(" *** page %d (addresses 0x%04x - 0x%04x) failed to write\n\n",
i / m->page_size, i - m->page_size + 1, i);
pgm->err_led(pgm, ON);
werror = 1;
}
@@ -1029,15 +1033,13 @@ int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
/*
* read the AVR device's signature bytes
*/
int avr_signature(PROGRAMMER * pgm, AVRPART * p)
{
int avr_signature(const PROGRAMMER *pgm, const AVRPART *p) {
int rc;
report_progress (0,1,"Reading");
rc = avr_read(pgm, p, "signature", 0);
if (rc < LIBAVRDUDE_SUCCESS) {
avrdude_message(MSG_INFO, "%s: error reading signature data for part \"%s\", rc=%d\n",
progname, p->desc, rc);
pmsg_error("unable to read signature data for part %s, rc=%d\n", p->desc, rc);
return rc;
}
report_progress (1,1,NULL);
@@ -1082,7 +1084,7 @@ int compare_memory_masked(AVRMEM * m, uint8_t b1, uint8_t b2) {
*
* Return the number of bytes verified, or -1 if they don't match.
*/
int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
int avr_verify(const AVRPART * p, const AVRPART * v, const char * memtype, int size)
{
int i;
unsigned char * buf1, * buf2;
@@ -1091,15 +1093,13 @@ int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
a = avr_locate_mem(p, memtype);
if (a == NULL) {
avrdude_message(MSG_INFO, "avr_verify(): memory type \"%s\" not defined for part %s\n",
memtype, p->desc);
pmsg_error("memory type %s not defined for part %s\n", memtype, p->desc);
return -1;
}
b = avr_locate_mem(v, memtype);
if (b == NULL) {
avrdude_message(MSG_INFO, "avr_verify(): memory type \"%s\" not defined for part %s\n",
memtype, v->desc);
pmsg_error("memory type %s not defined for part %s\n", memtype, v->desc);
return -1;
}
@@ -1108,40 +1108,32 @@ int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
vsize = a->size;
if (vsize < size) {
avrdude_message(MSG_INFO, "%s: WARNING: requested verification for %d bytes\n"
"%s%s memory region only contains %d bytes\n"
"%sOnly %d bytes will be verified.\n",
progname, size,
progbuf, memtype, vsize,
progbuf, vsize);
pmsg_warning("requested verification for %d bytes\n", size);
imsg_warning("%s memory region only contains %d bytes\n", memtype, vsize);
imsg_warning("only %d bytes will be verified\n", vsize);
size = vsize;
}
for (i=0; i<size; i++) {
if ((b->tags[i] & TAG_ALLOCATED) != 0 &&
buf1[i] != buf2[i]) {
if ((b->tags[i] & TAG_ALLOCATED) != 0 && buf1[i] != buf2[i]) {
uint8_t bitmask = get_fuse_bitmask(a);
if((buf1[i] & bitmask) != (buf2[i] & bitmask)) {
// Mismatch is not just in unused bits
avrdude_message(MSG_INFO, "%s: verification error, first mismatch at byte 0x%04x\n"
"%s0x%02x != 0x%02x\n",
progname, i,
progbuf, buf1[i], buf2[i]);
pmsg_error("verification mismatch, first encountered at addr 0x%04x\n", i);
imsg_error("device 0x%02x != input 0x%02x\n", buf1[i], buf2[i]);
return -1;
} else {
// Mismatch is only in unused bits
if ((buf1[i] | bitmask) != 0xff) {
// Programmer returned unused bits as 0, must be the part/programmer
avrdude_message(MSG_INFO, "%s: WARNING: ignoring mismatch in unused bits of \"%s\"\n"
"%s(0x%02x != 0x%02x). To prevent this warning fix the part\n"
"%sor programmer definition in the config file.\n",
progname, memtype, progbuf, buf1[i], buf2[i], progbuf);
pmsg_warning("ignoring mismatch in unused bits of %s\n", memtype);
imsg_warning("(device 0x%02x != input 0x%02x); to prevent this warning fix\n", buf1[i], buf2[i]);
imsg_warning("the part or programmer definition in the config file\n");
} else {
// Programmer returned unused bits as 1, must be the user
avrdude_message(MSG_INFO, "%s: WARNING: ignoring mismatch in unused bits of \"%s\"\n"
"%s(0x%02x != 0x%02x). To prevent this warning set unused bits\n"
"%sto 1 when writing (double check with your datasheet first).\n",
progname, memtype, progbuf, buf1[i], buf2[i], progbuf);
pmsg_warning("ignoring mismatch in unused bits of %s\n", memtype);
imsg_warning("(device 0x%02x != input 0x%02x); to prevent this warning set\n", buf1[i], buf2[i]);
imsg_warning("unused bits to 1 when writing (double check with datasheet)\n");
}
}
}
@@ -1151,8 +1143,7 @@ int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
}
int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles)
{
int avr_get_cycle_count(const PROGRAMMER *pgm, const AVRPART *p, int *cycles) {
AVRMEM * a;
unsigned int cycle_count = 0;
unsigned char v1;
@@ -1167,8 +1158,7 @@ int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles)
for (i=4; i>0; i--) {
rc = pgm->read_byte(pgm, p, a, a->size-i, &v1);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: WARNING: can't read memory for cycle count, rc=%d\n",
progname, rc);
pmsg_warning("cannot read memory for cycle count, rc=%d\n", rc);
return -1;
}
cycle_count = (cycle_count << 8) | v1;
@@ -1190,8 +1180,7 @@ int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles)
}
int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles)
{
int avr_put_cycle_count(const PROGRAMMER *pgm, const AVRPART *p, int cycles) {
AVRMEM * a;
unsigned char v1;
int rc;
@@ -1208,26 +1197,77 @@ int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles)
rc = avr_write_byte(pgm, p, a, a->size-i, v1);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: WARNING: can't write memory for cycle count, rc=%d\n",
progname, rc);
pmsg_warning("cannot write memory for cycle count, rc=%d\n", rc);
return -1;
}
}
return 0;
}
int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
int rc;
rc = pgm->chip_erase(pgm, p);
return rc;
}
int avr_unlock(PROGRAMMER * pgm, AVRPART * p)
{
// Typical order in which memories show in avrdude.conf, runtime adds unknown ones (if any)
const char *avr_mem_order[100] = {
"eeprom", "flash", "application", "apptable",
"boot", "lfuse", "hfuse", "efuse",
"fuse", "fuse0", "wdtcfg", "fuse1",
"bodcfg", "fuse2", "osccfg", "fuse3",
"fuse4", "tcd0cfg", "fuse5", "syscfg0",
"fuse6", "syscfg1", "fuse7", "append",
"codesize", "fuse8", "fuse9", "bootend",
"bootsize", "fuses", "lock", "lockbits",
"tempsense", "signature", "prodsig", "sernum",
"calibration", "osccal16", "osccal20", "osc16err",
"osc20err", "usersig", "userrow", "data",
};
void avr_add_mem_order(const char *str) {
for(size_t i=0; i < sizeof avr_mem_order/sizeof *avr_mem_order; i++) {
if(avr_mem_order[i] && !strcmp(avr_mem_order[i], str))
return;
if(!avr_mem_order[i]) {
avr_mem_order[i] = cfg_strdup("avr_mem_order()", str);
return;
}
}
pmsg_error("avr_mem_order[] under-dimensioned in avr.c; increase and recompile\n");
exit(1);
}
int avr_mem_is_flash_type(const AVRMEM *mem) {
return
strcmp(mem->desc, "flash") == 0 ||
strcmp(mem->desc, "application") == 0 ||
strcmp(mem->desc, "apptable") == 0 ||
strcmp(mem->desc, "boot") == 0;
}
int avr_mem_is_eeprom_type(const AVRMEM *mem) {
return strcmp(mem->desc, "eeprom") == 0;
}
int avr_mem_is_known(const char *str) {
if(str && *str)
for(size_t i=0; i < sizeof avr_mem_order/sizeof *avr_mem_order; i++)
if(avr_mem_order[i] && !strcmp(avr_mem_order[i], str))
return 1;
return 0;
}
int avr_mem_might_be_known(const char *str) {
if(str && *str)
for(size_t i=0; i < sizeof avr_mem_order/sizeof *avr_mem_order; i++)
if(avr_mem_order[i] && !strncmp(avr_mem_order[i], str, strlen(str)))
return 1;
return 0;
}
int avr_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
return pgm->chip_erase(pgm, p);
}
int avr_unlock(const PROGRAMMER *pgm, const AVRPART *p) {
int rc = -1;
if (pgm->unlock)
@@ -1237,52 +1277,51 @@ int avr_unlock(PROGRAMMER * pgm, AVRPART * p)
}
/*
* Report the progress of a read or write operation from/to the
* device.
* Report the progress of a read or write operation from/to the device
*
* The first call of report_progress() should look like this (for a write op):
* The first call of report_progress() should look like this (for a write):
*
* report_progress (0, 1, "Writing");
* report_progress(0, 1, "Writing");
*
* Then hdr should be passed NULL on subsequent calls while the
* operation is progressing. Once the operation is complete, a final
* call should be made as such to ensure proper termination of the
* progress report:
* Then hdr should be passed NULL on subsequent calls *
* report_progress(k, n, NULL); // k/n signifies proportion of work done
*
* report_progress (1, 1, NULL);
* with 0 <= k < n, while the operation is progressing. Once the operation is
* complete, a final call should be made as such to ensure proper termination
* of the progress report; choose one of the following three forms:
*
* It would be nice if we could reduce the usage to one and only one
* call for each of start, during and end cases. As things stand now,
* that is not possible and makes maintenance a bit more work.
* report_progress(n, n, NULL); // finished OK, terminate with double \n
* report_progress(1, 0, NULL); // finished OK, do not print terminating \n
* report_progress(1, -1, NULL); // finished not OK, print double \n
*
* It is OK to call report_progress(1, -1, NULL) in a subroutine when
* encountering a fatal error to terminate the reporting here and there even
* though no report may have been started.
*/
void report_progress (int completed, int total, char *hdr)
{
static int last = 0;
void report_progress(int completed, int total, const char *hdr) {
static int last;
static double start_time;
int percent = (total > 0) ? ((completed * 100) / total) : 100;
int percent;
struct timeval tv;
double t;
if (update_progress == NULL)
return;
percent =
completed >= total || total <= 0? 100:
completed < 0? 0:
completed < INT_MAX/100? 100*completed/total: completed/(total/100);
gettimeofday(&tv, NULL);
t = tv.tv_sec + ((double)tv.tv_usec)/1000000;
if (hdr) {
last = 0;
if(hdr || !start_time)
start_time = t;
update_progress (percent, t - start_time, hdr);
}
if (percent > 100)
percent = 100;
if (percent > last) {
if(hdr || percent > last) {
last = percent;
update_progress (percent, t - start_time, hdr);
update_progress(percent, t - start_time, hdr, total < 0? -1: !!total);
}
if (percent == 100)
last = 0; /* Get ready for next time. */
}

View File

@@ -57,8 +57,7 @@ struct pdata
static void avr910_setup(PROGRAMMER * pgm)
{
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
avrdude_message(MSG_INFO, "%s: avr910_setup(): Out of memory allocating private data\n",
progname);
pmsg_error("out of memory allocating private data\n");
exit(1);
}
memset(pgm->cookie, 0, sizeof(struct pdata));
@@ -71,40 +70,34 @@ static void avr910_teardown(PROGRAMMER * pgm)
}
static int avr910_send(PROGRAMMER * pgm, char * buf, size_t len)
{
static int avr910_send(const PROGRAMMER *pgm, char *buf, size_t len) {
return serial_send(&pgm->fd, (unsigned char *)buf, len);
}
static int avr910_recv(PROGRAMMER * pgm, char * buf, size_t len)
{
static int avr910_recv(const PROGRAMMER *pgm, char *buf, size_t len) {
int rv;
rv = serial_recv(&pgm->fd, (unsigned char *)buf, len);
if (rv < 0) {
avrdude_message(MSG_INFO, "%s: avr910_recv(): programmer is not responding\n",
progname);
pmsg_error("programmer is not responding\n");
return 1;
}
return 0;
}
static int avr910_drain(PROGRAMMER * pgm, int display)
{
static int avr910_drain(const PROGRAMMER *pgm, int display) {
return serial_drain(&pgm->fd, display);
}
static int avr910_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
{
static int avr910_vfy_cmd_sent(const PROGRAMMER *pgm, char *errmsg) {
char c;
avr910_recv(pgm, &c, 1);
if (c != '\r') {
avrdude_message(MSG_INFO, "%s: error: programmer did not respond to command: %s\n",
progname, errmsg);
pmsg_error("programmer did not respond to command: %s\n", errmsg);
return 1;
}
return 0;
@@ -114,8 +107,7 @@ static int avr910_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
/*
* issue the 'chip erase' command to the AVR device
*/
static int avr910_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
static int avr910_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
avr910_send(pgm, "e", 1);
if (avr910_vfy_cmd_sent(pgm, "chip erase") < 0)
return -1;
@@ -129,15 +121,13 @@ static int avr910_chip_erase(PROGRAMMER * pgm, AVRPART * p)
}
static int avr910_enter_prog_mode(PROGRAMMER * pgm)
{
static int avr910_enter_prog_mode(const PROGRAMMER *pgm) {
avr910_send(pgm, "P", 1);
return avr910_vfy_cmd_sent(pgm, "enter prog mode");
}
static int avr910_leave_prog_mode(PROGRAMMER * pgm)
{
static int avr910_leave_prog_mode(const PROGRAMMER *pgm) {
avr910_send(pgm, "L", 1);
return avr910_vfy_cmd_sent(pgm, "leave prog mode");
}
@@ -146,8 +136,7 @@ static int avr910_leave_prog_mode(PROGRAMMER * pgm)
/*
* issue the 'program enable' command to the AVR device
*/
static int avr910_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
static int avr910_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
return -1;
}
@@ -155,8 +144,7 @@ static int avr910_program_enable(PROGRAMMER * pgm, AVRPART * p)
/*
* initialize the AVR device and prepare it to accept commands
*/
static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
{
static int avr910_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
char id[8];
char sw[2];
char hw[2];
@@ -185,16 +173,16 @@ static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
avr910_send(pgm, "p", 1);
avr910_recv(pgm, &type, 1);
avrdude_message(MSG_INFO, "Found programmer: Id = \"%s\"; type = %c\n", id, type);
avrdude_message(MSG_INFO, " Software Version = %c.%c; ", sw[0], sw[1]);
avrdude_message(MSG_INFO, "Hardware Version = %c.%c\n", hw[0], hw[1]);
msg_notice("Programmer id = %s; type = %c\n", id, type);
msg_notice("Software version = %c.%c; ", sw[0], sw[1]);
msg_notice("Hardware version = %c.%c\n", hw[0], hw[1]);
/* See if programmer supports autoincrement of address. */
avr910_send(pgm, "a", 1);
avr910_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1);
if (PDATA(pgm)->has_auto_incr_addr == 'Y')
avrdude_message(MSG_INFO, "Programmer supports auto addr increment.\n");
msg_notice("programmer supports auto addr increment\n");
/* Check support for buffered memory access, ignore if not available */
@@ -206,8 +194,8 @@ static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
PDATA(pgm)->buffersize = (unsigned int)(unsigned char)c<<8;
avr910_recv(pgm, &c, 1);
PDATA(pgm)->buffersize += (unsigned int)(unsigned char)c;
avrdude_message(MSG_INFO, "Programmer supports buffered memory access with "
"buffersize = %u bytes.\n",
msg_notice("programmer supports buffered memory access with "
"buffersize = %u bytes\n",
PDATA(pgm)->buffersize);
PDATA(pgm)->use_blockmode = 1;
} else {
@@ -224,7 +212,7 @@ static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
/* Get list of devices that the programmer supports. */
avr910_send(pgm, "t", 1);
avrdude_message(MSG_INFO, "\nProgrammer supports the following devices:\n");
msg_notice2("\nProgrammer supports the following devices:\n");
devtype_1st = 0;
while (1) {
avr910_recv(pgm, &c, 1);
@@ -234,20 +222,22 @@ static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
break;
part = locate_part_by_avr910_devcode(part_list, c);
avrdude_message(MSG_INFO, " Device code: 0x%02x = %s\n", c, part ? part->desc : "(unknown)");
msg_notice2(" Device code: 0x%02x = %s\n", c & 0xff, part? part->desc: "(unknown)");
/* FIXME: Need to lookup devcode and report the device. */
if (p->avr910_devcode == c)
dev_supported = 1;
};
avrdude_message(MSG_INFO, "\n");
msg_notice2("\n");
if (!dev_supported) {
avrdude_message(MSG_INFO, "%s: %s: selected device is not supported by programmer: %s\n",
progname, ovsigck? "warning": "error", p->id);
if (!ovsigck)
if(ovsigck)
pmsg_warning("selected device is not supported by programmer %s\n", p->id);
else {
pmsg_error("selected device is not supported by programmer %s\n", p->id);
return -1;
}
}
/* If the user forced the selection, use the first device
type that is supported by the programmer. */
@@ -264,8 +254,7 @@ static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
avr910_send(pgm, buf, 2);
avr910_vfy_cmd_sent(pgm, "select device");
avrdude_message(MSG_NOTICE, "%s: avr910_devcode selected: 0x%02x\n",
progname, (unsigned)buf[1]);
pmsg_notice("avr910_devcode selected: 0x%02x\n", (unsigned) buf[1]);
avr910_enter_prog_mode(pgm);
@@ -273,16 +262,14 @@ static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
}
static void avr910_disable(PROGRAMMER * pgm)
{
static void avr910_disable(const PROGRAMMER *pgm) {
/* Do nothing. */
return;
}
static void avr910_enable(PROGRAMMER * pgm)
{
static void avr910_enable(PROGRAMMER *pgm, const AVRPART *p) {
/* Do nothing. */
return;
@@ -293,7 +280,7 @@ static void avr910_enable(PROGRAMMER * pgm)
* transmit an AVR device command and return the results; 'cmd' and
* 'res' must point to at least a 4 byte data buffer
*/
static int avr910_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
static int avr910_cmd(const PROGRAMMER *pgm, const unsigned char *cmd,
unsigned char *res)
{
char buf[5];
@@ -318,8 +305,7 @@ static int avr910_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
}
static int avr910_parseextparms(PROGRAMMER * pgm, LISTID extparms)
{
static int avr910_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
LNODEID ln;
const char *extended_param;
int rv = 0;
@@ -331,27 +317,23 @@ static int avr910_parseextparms(PROGRAMMER * pgm, LISTID extparms)
int devcode;
if (sscanf(extended_param, "devcode=%i", &devcode) != 1 ||
devcode <= 0 || devcode > 255) {
avrdude_message(MSG_INFO, "%s: avr910_parseextparms(): invalid devcode '%s'\n",
progname, extended_param);
pmsg_error("invalid devcode '%s'\n", extended_param);
rv = -1;
continue;
}
avrdude_message(MSG_NOTICE2, "%s: avr910_parseextparms(): devcode overwritten as 0x%02x\n",
progname, devcode);
pmsg_notice2("avr910_parseextparms(): devcode overwritten as 0x%02x\n", devcode);
PDATA(pgm)->devcode = devcode;
continue;
}
if (strncmp(extended_param, "no_blockmode", strlen("no_blockmode")) == 0) {
avrdude_message(MSG_NOTICE2, "%s: avr910_parseextparms(-x): no testing for Blockmode\n",
progname);
pmsg_notice2("avr910_parseextparms(-x): no testing for Blockmode\n");
PDATA(pgm)->test_blockmode = 0;
continue;
}
avrdude_message(MSG_INFO, "%s: avr910_parseextparms(): invalid extended parameter '%s'\n",
progname, extended_param);
pmsg_error("invalid extended parameter '%s'\n", extended_param);
rv = -1;
}
@@ -359,8 +341,7 @@ static int avr910_parseextparms(PROGRAMMER * pgm, LISTID extparms)
}
static int avr910_open(PROGRAMMER * pgm, char * port)
{
static int avr910_open(PROGRAMMER *pgm, const char *port) {
union pinfo pinfo;
/*
* If baudrate was not specified use 19.200 Baud
@@ -393,14 +374,12 @@ static void avr910_close(PROGRAMMER * pgm)
}
static void avr910_display(PROGRAMMER * pgm, const char * p)
{
static void avr910_display(const PROGRAMMER *pgm, const char *p) {
return;
}
static void avr910_set_addr(PROGRAMMER * pgm, unsigned long addr)
{
static void avr910_set_addr(const PROGRAMMER *pgm, unsigned long addr) {
char cmd[3];
cmd[0] = 'A';
@@ -412,7 +391,7 @@ static void avr910_set_addr(PROGRAMMER * pgm, unsigned long addr)
}
static int avr910_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int avr910_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned long addr, unsigned char value)
{
char cmd[2];
@@ -445,7 +424,7 @@ static int avr910_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
}
static int avr910_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int avr910_read_byte_flash(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned long addr, unsigned char * value)
{
char buf[2];
@@ -468,7 +447,7 @@ static int avr910_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
}
static int avr910_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int avr910_read_byte_eeprom(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned long addr, unsigned char * value)
{
avr910_set_addr(pgm, addr);
@@ -479,7 +458,7 @@ static int avr910_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
}
static int avr910_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int avr910_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned long addr, unsigned char * value)
{
if (strcmp(m->desc, "flash") == 0) {
@@ -494,7 +473,7 @@ static int avr910_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
}
static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int avr910_paged_write_flash(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
@@ -553,8 +532,8 @@ static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
}
static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
AVRMEM * m,
static int avr910_paged_write_eeprom(const PROGRAMMER *pgm, const AVRPART *p,
const AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
@@ -582,7 +561,7 @@ static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
}
static int avr910_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int avr910_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
@@ -642,7 +621,7 @@ static int avr910_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
}
static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int avr910_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
@@ -719,12 +698,11 @@ static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
/* Signature byte reads are always 3 bytes. */
static int avr910_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
{
static int avr910_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m) {
unsigned char tmp;
if (m->size < 3) {
avrdude_message(MSG_INFO, "%s: memsize too small for sig byte read", progname);
pmsg_error("memsize too small for sig byte read");
return -1;
}
@@ -740,8 +718,7 @@ static int avr910_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
const char avr910_desc[] = "Serial programmers using protocol described in application note AVR910";
void avr910_initpgm(PROGRAMMER * pgm)
{
void avr910_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "avr910");
/*

View File

@@ -26,7 +26,7 @@ extern "C" {
#endif
extern const char avr910_desc[];
void avr910_initpgm (PROGRAMMER * pgm);
void avr910_initpgm(PROGRAMMER *pgm);
#ifdef __cplusplus
}

737
src/avrcache.c Normal file
View File

@@ -0,0 +1,737 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2022 Stefan Rueger <stefan.rueger@urclocks.c>
*
* 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 <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include "avrdude.h"
#include "libavrdude.h"
#include "avrintel.h"
/*
* Provides an API for cached bytewise access
*
* 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_page_erase_cached(const PROGRAMMER *pgm, const AVRPART *p, const
* AVRMEM *mem, unsigned int baseaddr);
*
* 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. Bytewise cached read always gets its data from the cache,
* possibly after reading a page from the device memory. Bytewise 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) 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.
*
* The avr_page_erase_cached() function erases a page and synchronises it
* with the cache.
*
* Finally, avr_reset_cache() resets the cache without synchronising pending
* writes() to the device.
*
* This file also holds the following utility functions
*
* // Does the programmer/memory combo have paged memory access?
* int avr_has_paged_access(const PROGRAMMER *pgm, const AVRMEM *mem);
*
* // Read the page containing addr from the device into buf
* int avr_read_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int addr, unsigned char *buf);
*
* // Write the data page to the device into the page containing addr
* int avr_write_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int addr, unsigned char *data);
*
* // Could memory region s1 be the result of a NOR-memory copy of s3 onto s2?
* int avr_is_and(const unsigned char *s1, const unsigned char *s2, const unsigned char *s3, size_t n);
*
*/
/*
* Paged access?
* - Programmer must have paged routines
* - Memory has positive page size, which is a power of two
* - Memory has positive size, which is a multiple of the page size
* - Memory is flash type or eeprom type
*
* Note that in this definition the page size can be 1
*/
int avr_has_paged_access(const PROGRAMMER *pgm, const AVRMEM *mem) {
return pgm->paged_load && pgm->paged_write &&
mem->page_size > 0 && (mem->page_size & (mem->page_size-1)) == 0 &&
mem->size > 0 && mem->size % mem->page_size == 0 &&
(avr_mem_is_flash_type(mem) || avr_mem_is_eeprom_type(mem));
}
/*
* Read the page containing addr from the device into buf
* - Caller to ensure buf has mem->page_size bytes
* - Part memory buffer mem is unaffected by this (though temporarily changed)
* - Uses read_byte() if memory page size is one, otherwise paged_load()
* - Fall back to bytewise read if paged_load() returned an error
*/
int avr_read_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int addr, unsigned char *buf) {
if(!avr_has_paged_access(pgm, mem) || addr < 0 || addr >= mem->size)
return LIBAVRDUDE_GENERAL_FAILURE;
int rc, pgsize = mem->page_size, base = addr & ~(pgsize-1);
unsigned char *pagecopy = cfg_malloc("avr_read_page_default()", pgsize);
if(pgsize == 1)
return pgm->read_byte(pgm, p, mem, addr, buf);
memcpy(pagecopy, mem->buf + base, pgsize);
if((rc = pgm->paged_load(pgm, p, mem, pgsize, base, pgsize)) >= 0)
memcpy(buf, mem->buf + base, pgsize);
memcpy(mem->buf + base, pagecopy, pgsize);
if(rc < 0) {
rc = LIBAVRDUDE_SUCCESS;
for(int i=0; i<pgsize; i++) {
if(pgm->read_byte(pgm, p, mem, base+i, pagecopy+i) < 0) {
rc = LIBAVRDUDE_GENERAL_FAILURE;
break;
}
}
if(rc == LIBAVRDUDE_SUCCESS)
memcpy(buf, pagecopy, pgsize);
}
free(pagecopy);
return rc;
}
/*
* Write the data page to the device into the page containing addr
* - Caller to provide all mem->page_size bytes incl padding if any
* - Part memory buffer mem is unaffected by this (though temporarily changed)
* - Uses write_byte() if memory page size is one, otherwise paged_write()
*/
int avr_write_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int addr, unsigned char *data) {
if(!avr_has_paged_access(pgm, mem) || addr < 0 || addr >= mem->size)
return LIBAVRDUDE_GENERAL_FAILURE;
int rc, pgsize = mem->page_size, base = addr & ~(pgsize-1);
unsigned char *pagecopy = cfg_malloc("avr_write_page_default()", pgsize);
if(pgsize == 1)
return pgm->write_byte(pgm, p, mem, addr, *data);
memcpy(pagecopy, mem->buf + base, pgsize);
memcpy(mem->buf + base, data, pgsize);
rc = pgm->paged_write(pgm, p, mem, pgsize, base, pgsize);
memcpy(mem->buf + base, pagecopy, pgsize);
free(pagecopy);
return rc;
}
// Could memory region s1 be the result of a NOR-memory copy of s3 onto s2?
int avr_is_and(const unsigned char *s1, const unsigned char *s2, const unsigned char *s3, size_t n) {
while(n--)
if(*s1++ != (*s2++ & *s3++))
return 0;
return 1;
}
static int initCache(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p) {
AVRMEM *basemem = avr_locate_mem(p, cp == pgm->cp_flash? "flash": "eeprom");
if(!basemem || !avr_has_paged_access(pgm, basemem))
return LIBAVRDUDE_GENERAL_FAILURE;
cp->size = basemem->size;
cp->page_size = basemem->page_size;
cp->offset = basemem->offset;
cp->cont = cfg_malloc("initCache()", cp->size);
cp->copy = cfg_malloc("initCache()", cp->size);
cp->iscached = cfg_malloc("initCache()", cp->size/cp->page_size);
return LIBAVRDUDE_SUCCESS;
}
static int cacheAddress(int addr, const AVR_Cache *cp, const AVRMEM *mem) {
int cacheaddr = addr + (int) (mem->offset - cp->offset);
if(cacheaddr < 0 || cacheaddr >= cp->size) { // Should never happen (unless offsets wrong in avrdude.conf)
pmsg_error("%s cache address 0x%04x out of range [0, 0x%04x]\n", mem->desc, cacheaddr, cp->size-1);
return LIBAVRDUDE_GENERAL_FAILURE;
}
if(mem->page_size != cp->page_size) { // Should never happen (unless incompatible page sizes in avrdude.conf)
pmsg_error("%s page size %d incompatible with cache page size %d\n", mem->desc, mem->page_size, cp->page_size);
return LIBAVRDUDE_GENERAL_FAILURE;
}
return cacheaddr;
}
static int loadCachePage(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int addr, int cacheaddr, int nlOnErr) {
int pgno = cacheaddr/cp->page_size;
if(!cp->iscached[pgno]) {
// Read cached section from device
int cachebase = cacheaddr & ~(cp->page_size-1);
if(avr_read_page_default(pgm, p, mem, addr & ~(cp->page_size-1), cp->cont + cachebase) < 0) {
report_progress(1, -1, NULL);
if(nlOnErr && quell_progress)
msg_info("\n");
pmsg_error("unable to read %s page at addr 0x%04x\n", mem->desc, addr);
return LIBAVRDUDE_GENERAL_FAILURE;
}
// Copy last read device page, so we can later check for changes
memcpy(cp->copy + cachebase, cp->cont + cachebase, cp->page_size);
cp->iscached[pgno] = 1;
}
return LIBAVRDUDE_SUCCESS;
}
static int writeCachePage(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int base, int nlOnErr) {
// Write modified page cont to device; if unsuccessful try bytewise access
if(avr_write_page_default(pgm, p, mem, base, cp->cont + base) < 0) {
for(int i=0; i < cp->page_size; i++)
if(cp->cont[base+i] != cp->copy[base+i])
if(pgm->write_byte(pgm, p, mem, base+i, cp->cont[base+i]) < 0 ||
pgm->read_byte(pgm, p, mem, base+i, cp->copy+base+i) < 0) {
report_progress(1, -1, NULL);
if(nlOnErr && quell_progress)
msg_info("\n");
pmsg_error("writeCachePage() %s access error at addr 0x%04x\n", mem->desc, base+i);
return LIBAVRDUDE_GENERAL_FAILURE;
}
return LIBAVRDUDE_SUCCESS; // Bytewise writes & reads successful
}
// Read page back from device and update copy to what is on device
if(avr_read_page_default(pgm, p, mem, base, cp->copy + base) < 0) {
report_progress(1, -1, NULL);
if(nlOnErr && quell_progress)
msg_info("\n");
pmsg_error("unable to read %s page at addr 0x%04x\n", mem->desc, base);
return LIBAVRDUDE_GENERAL_FAILURE;
}
return LIBAVRDUDE_SUCCESS;
}
// Does the memory region only haxe 0xff?
static int _is_all_0xff(const void *p, size_t n) {
const unsigned char *q = (const unsigned char *) p;
return n <= 0 || (*q == 0xff && memcmp(q, q+1, n-1) == 0);
}
// A coarse guess where any bootloader might start (prob underestimates the start)
static int guessBootStart(const PROGRAMMER *pgm, const AVRPART *p) {
int bootstart = 0;
const AVR_Cache *cp = pgm->cp_flash;
for(size_t i = 0; i < sizeof uP_table/sizeof*uP_table; i++)
if(p->mcuid == uP_table[i].mcuid) {
if(uP_table[i].nboots > 0 && uP_table[i].bootsize > 0 && uP_table[i].flashsize == cp->size)
bootstart = cp->size - uP_table[i].nboots * uP_table[i].bootsize;
break;
}
if(bootstart <= cp->size/2 || bootstart >= cp->size)
bootstart = cp->size > 32768? cp->size - 16384: cp->size*3/4;
return bootstart & ~(cp->page_size-1);
}
typedef struct {
AVRMEM *mem;
AVR_Cache *cp;
int isflash, zopaddr, pgerase;
} CacheDesc_t;
// Write both EEPROM and flash caches to device and free them
int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) {
CacheDesc_t mems[2] = {
{ avr_locate_mem(p, "flash"), pgm->cp_flash, 1, -1, 0 },
{ avr_locate_mem(p, "eeprom"), pgm->cp_eeprom, 0, -1, 0 },
};
int chpages = 0;
bool chiperase = 0;
// Count page changes and find a page that needs a clear bit set
for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) {
AVRMEM *mem = mems[i].mem;
AVR_Cache *cp = mems[i].cp;
if(!mem || !cp->cont)
continue;
for(int pgno = 0, n = 0; n < cp->size; pgno++, n += cp->page_size) {
if(cp->iscached[pgno])
if(memcmp(cp->copy + n, cp->cont + n, cp->page_size)) {
chpages++;
if(mems[i].zopaddr == -1 && !avr_is_and(cp->cont + n, cp->copy + n, cp->cont + n, cp->page_size))
mems[i].zopaddr = n;
}
}
}
if(!chpages)
return LIBAVRDUDE_SUCCESS;
pmsg_info("synching cache to device ... ");
fflush(stderr);
// Check whether page erase needed and working and whether chip erase needed
for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) {
AVRMEM *mem = mems[i].mem;
AVR_Cache *cp = mems[i].cp;
if(!cp->cont) // Ensure cache is initialised from now on
if(initCache(cp, pgm, p) < 0) {
if(quell_progress)
msg_info("\n");
pmsg_error("unable to initialise the cache\n");
return LIBAVRDUDE_GENERAL_FAILURE;
}
if(chiperase || !mem || mems[i].zopaddr < 0)
continue;
int n=mems[i].zopaddr;
if(writeCachePage(cp, pgm, p, mem, n, 1) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
// Same? OK, can set cleared bit to one, "normal" memory
if(!memcmp(cp->copy + n, cp->cont + n, cp->page_size)) {
chpages--;
continue;
}
// Probably NOR memory, check out page erase
if(pgm->page_erase && pgm->page_erase(pgm, p, mem, n) >= 0) {
if(writeCachePage(cp, pgm, p, mem, n, 1) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
// Worked OK? Can use page erase on this memory
if(!memcmp(cp->copy + n, cp->cont + n, cp->page_size)) {
mems[i].pgerase = 1;
chpages--;
continue;
}
}
chiperase = 1;
}
if(!chpages) {
msg_info("done\n");
return LIBAVRDUDE_SUCCESS;
}
if(chiperase) {
if(quell_progress) {
msg_info("reading/chip erase/writing cycle needed ... ");
fflush(stderr);
}
int nrd = 0;
// Count read operations needed
for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) {
AVRMEM *mem = mems[i].mem;
AVR_Cache *cp = mems[i].cp;
if(!mem)
continue;
for(int pgno = 0, n = 0; n < cp->size; pgno++, n += cp->page_size)
if(!cp->iscached[pgno])
nrd++;
}
report_progress(0, 1, "Reading");
if(nrd) {
// Read full flash and EEPROM
for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) {
AVRMEM *mem = mems[i].mem;
AVR_Cache *cp = mems[i].cp;
if(!mem)
continue;
for(int ird = 0, pgno = 0, n = 0; n < cp->size; pgno++, n += cp->page_size) {
if(!cp->iscached[pgno]) {
report_progress(ird++, nrd, NULL);
if(loadCachePage(cp, pgm, p, mem, n, n, 1) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
}
}
}
}
report_progress(1, 0, NULL);
report_progress(0, 1, "Erasing");
if(avr_chip_erase(pgm, p) < 0) {
report_progress(1, -1, NULL);
if(quell_progress)
msg_info("\n");
pmsg_error("chip erase failed\n");
return LIBAVRDUDE_GENERAL_FAILURE;
}
// Update cache copies after chip erase so that writing back is efficient
for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) {
AVRMEM *mem = mems[i].mem;
AVR_Cache *cp = mems[i].cp;
if(!mem)
continue;
if(mems[i].isflash) { // flash
memset(cp->copy, 0xff, cp->size); // record device memory as erased
if(pgm->prog_modes & PM_SPM) { // Bootloaders will not overwrite themselves
// Read back generously estimated bootloader section to avoid verification errors
int bootstart = guessBootStart(pgm, p);
int nbo = (cp->size - bootstart)/cp->page_size;
for(int ibo = 0, n = bootstart; n < cp->size; n += cp->page_size) {
report_progress(1+ibo++, nbo+2, NULL);
if(avr_read_page_default(pgm, p, mem, n, cp->copy + n) < 0) {
report_progress(1, -1, NULL);
if(quell_progress)
msg_info("\n");
pmsg_error("flash read failed at addr 0x%04x\n", n);
return LIBAVRDUDE_GENERAL_FAILURE;
}
}
}
} else { // EEPROM
// Don't know whether chip erase has zapped EEPROM
for(int n = 0; n < cp->size; n += cp->page_size) {
if(!_is_all_0xff(cp->copy + n, cp->page_size)) { // First page that had EEPROM data
if(avr_read_page_default(pgm, p, mem, n, cp->copy + n) < 0) {
report_progress(1, -1, NULL);
if(quell_progress)
msg_info("\n");
pmsg_error("EEPROM read failed at addr 0x%04x\n", n);
return LIBAVRDUDE_GENERAL_FAILURE;
}
// EEPROM zapped by chip erase? Set all copy to 0xff
if(_is_all_0xff(cp->copy + n, cp->page_size))
memset(cp->copy, 0xff, cp->size);
break;
}
}
}
}
report_progress(1, 0, NULL);
}
int nwr = 0;
// Count number of writes
for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) {
AVRMEM *mem = mems[i].mem;
AVR_Cache *cp = mems[i].cp;
if(!mem)
continue;
for(int pgno = 0, n = 0; n < cp->size; pgno++, n += cp->page_size)
if(cp->iscached[pgno] && memcmp(cp->copy + n, cp->cont + n, cp->page_size))
nwr++;
}
report_progress(0, 1, "Writing");
if(nwr) {
// Write all modified pages to the device
for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) {
AVRMEM *mem = mems[i].mem;
AVR_Cache *cp = mems[i].cp;
if(!mem || !cp->cont)
continue;
for(int iwr = 0, pgno = 0, n = 0; n < cp->size; pgno++, n += cp->page_size) {
if(cp->iscached[pgno] && memcmp(cp->copy + n, cp->cont + n, cp->page_size)) {
if(!chiperase && mems[i].pgerase)
pgm->page_erase(pgm, p, mem, n);
if(writeCachePage(cp, pgm, p, mem, n, 1) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
if(memcmp(cp->copy + n, cp->cont + n, cp->page_size)) {
report_progress(1, -1, NULL);
if(quell_progress)
msg_info("\n");
pmsg_error("verification mismatch at %s page addr 0x%04x\n", mem->desc, n);
return LIBAVRDUDE_GENERAL_FAILURE;
}
report_progress(iwr++, nwr, NULL);
}
}
}
}
report_progress(1, 0, NULL);
msg_info(quell_progress? "done\n": "\n");
return LIBAVRDUDE_SUCCESS;
}
/*
* Read byte via a read/write cache
* - Used if paged routines available and if memory is EEPROM or flash
* - Otherwise fall back to pgm->read_byte()
* - Out of memory addr: synchronise cache and, if successful, pretend reading a zero
* - Cache is automagically created and initialised if needed
*/
int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char *value) {
// Use pgm->read_byte() if not EEPROM/flash or no paged access
if(!avr_has_paged_access(pgm, mem))
return pgm->read_byte(pgm, p, mem, addr, value);
// If address is out of range synchronise cache and, if successful, pretend reading a zero
if(addr >= (unsigned long) mem->size) {
if(avr_flush_cache(pgm, p) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
*value = 0;
return LIBAVRDUDE_SUCCESS;
}
AVR_Cache *cp = avr_mem_is_eeprom_type(mem)? pgm->cp_eeprom: pgm->cp_flash;
if(!cp->cont) // Init cache if needed
if(initCache(cp, pgm, p) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
int cacheaddr = cacheAddress((int) addr, cp, mem);
if(cacheaddr < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
// Ensure cache page is there
if(loadCachePage(cp, pgm, p, mem, addr, cacheaddr, 0) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
*value = cp->cont[cacheaddr];
return LIBAVRDUDE_SUCCESS;
}
/*
* Write byte via a read/write cache
* - Used if paged routines available and if memory is EEPROM or flash
* - Otherwise fall back to pgm->write_byte()
* - Out of memory addr: synchronise cache with device and return whether successful
* - Cache is automagically created and initialised if needed
*/
int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char data) {
// Use pgm->read_byte() if not EEPROM/flash or no paged access
if(!avr_has_paged_access(pgm, mem))
return pgm->write_byte(pgm, p, mem, addr, data);
// If address is out of range synchronise caches with device and return whether successful
if(addr >= (unsigned long) mem->size)
return avr_flush_cache(pgm, p);
AVR_Cache *cp = avr_mem_is_eeprom_type(mem)? pgm->cp_eeprom: pgm->cp_flash;
if(!cp->cont) // Init cache if needed
if(initCache(cp, pgm, p) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
int cacheaddr = cacheAddress((int) addr, cp, mem);
if(cacheaddr < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
// Ensure cache page is there
if(loadCachePage(cp, pgm, p, mem, addr, cacheaddr, 0) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
cp->cont[cacheaddr] = data;
return LIBAVRDUDE_SUCCESS;
}
// Erase the chip and set the cache accordingly
int avr_chip_erase_cached(const PROGRAMMER *pgm, const AVRPART *p) {
CacheDesc_t mems[2] = {
{ avr_locate_mem(p, "flash"), pgm->cp_flash, 1 },
{ avr_locate_mem(p, "eeprom"), pgm->cp_eeprom, 0 },
};
if(pgm->chip_erase(pgm, p) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) {
AVRMEM *mem = mems[i].mem;
AVR_Cache *cp = mems[i].cp;
if(!mem || !avr_has_paged_access(pgm, mem))
continue;
if(!cp->cont) // Init cache if needed
if(initCache(cp, pgm, p) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
if(mems[i].isflash) { // flash
if(pgm->prog_modes & PM_SPM) { // reset cache to unknown
memset(cp->iscached, 0, cp->size/cp->page_size);
} else { // preset all pages as erased
memset(cp->copy, 0xff, cp->size);
memset(cp->cont, 0xff, cp->size);
memset(cp->iscached, 1, cp->size/cp->page_size);
}
} else { // EEPROM: test whether cached pages were zapped
bool erasedee = 0;
for(int pgno = 0, n = 0; n < cp->size; pgno++, n += cp->page_size) {
if(cp->iscached[pgno]) {
if(!_is_all_0xff(cp->copy + n, cp->page_size)) { // Page has EEPROM data?
if(avr_read_page_default(pgm, p, mem, n, cp->copy + n) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
erasedee = _is_all_0xff(cp->copy + n, cp->page_size);
break;
}
}
}
if(erasedee) { // EEPROM was erased, set cache correspondingly
memset(cp->copy, 0xff, cp->size);
memset(cp->cont, 0xff, cp->size);
memset(cp->iscached, 1, cp->size/cp->page_size);
} else { // discard previous writes, but leave cache
for(int pgno = 0, n = 0; n < cp->size; pgno++, n += cp->page_size)
if(cp->iscached[pgno])
memcpy(cp->cont + n, cp->copy + n, cp->page_size);
}
}
}
return LIBAVRDUDE_SUCCESS;
}
// Erase a page and synchronise it with the cache
int avr_page_erase_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned int uaddr) {
int addr = uaddr;
if(!avr_has_paged_access(pgm, mem) || addr < 0 || addr >= mem->size)
return LIBAVRDUDE_GENERAL_FAILURE;
if(mem->page_size == 1) {
if(pgm->write_byte(pgm, p, mem, uaddr, 0xff) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
} else {
if(!pgm->page_erase || pgm->page_erase(pgm, p, mem, uaddr) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
}
AVR_Cache *cp = avr_mem_is_eeprom_type(mem)? pgm->cp_eeprom: pgm->cp_flash;
if(!cp->cont) // Init cache if needed
if(initCache(cp, pgm, p) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
int cacheaddr = cacheAddress(addr, cp, mem);
if(cacheaddr < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
// Invalidate this cache page and read back, ie, we don't trust the page_erase() routine
cp->iscached[cacheaddr/cp->page_size] = 0;
// Reload cache page
if(loadCachePage(cp, pgm, p, mem, (int) addr, cacheaddr, 0) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
if(!_is_all_0xff(cp->cont + (cacheaddr & ~(cp->page_size-1)), cp->page_size))
return LIBAVRDUDE_GENERAL_FAILURE;
return LIBAVRDUDE_SUCCESS;
}
// Free cache(s) discarding any pending writes
int avr_reset_cache(const PROGRAMMER *pgm, const AVRPART *p) {
AVR_Cache *mems[2] = { pgm->cp_flash, pgm->cp_eeprom, };
for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) {
AVR_Cache *cp = mems[i];
if(cp->cont)
free(cp->cont);
if(cp->copy)
free(cp->copy);
if(cp->iscached)
free(cp->iscached);
memset(cp, 0, sizeof*cp);
}
return LIBAVRDUDE_SUCCESS;
}

View File

@@ -18,7 +18,7 @@
.\"
.\" $Id$
.\"
.Dd November 22, 2021
.Dd July 12, 2022
.Os
.Dt AVRDUDE 1
.Sh NAME
@@ -31,6 +31,7 @@
.Op Fl B Ar bitclock
.Op Fl c Ar programmer-id
.Op Fl C Ar config-file
.Op Fl A
.Op Fl D
.Op Fl e
.Oo Fl E Ar exitspec Ns
@@ -38,14 +39,12 @@
.Oc
.Op Fl F
.Op Fl i Ar delay
.Op Fl n logfile
.Op Fl l Ar logfile
.Op Fl n
.Op Fl O
.Op Fl P Ar port
.Op Fl q
.Op Fl s
.Op Fl t
.Op Fl u
.Op Fl U Ar memtype:op:filename:filefmt
.Op Fl v
.Op Fl x Ar extended_param
@@ -102,7 +101,7 @@ available (like almost all embedded Linux boards) you can do without
any additional hardware - just connect them to the MOSI, MISO, RESET
and SCK pins on the AVR and use the linuxgpio programmer type. It bitbangs
the lines using the Linux sysfs GPIO interface. Of course, care should
be taken about voltage level compatibility. Also, although not strictrly
be taken about voltage level compatibility. Also, although not strictly
required, it is strongly advisable to protect the GPIO pins from
overcurrent situations in some way. The simplest would be to just put
some resistors in series or better yet use a 3-state buffer driver like
@@ -179,7 +178,7 @@ has a revision 1 hardware and firmware version of at least 5.37 (decimal).
For ATxmega devices, the JTAGICE3 is supported in PDI mode.
.Pp
Atmel-ICE (ARM/AVR) is supported in all modes (JTAG, PDI for Xmega, debugWIRE,
ISP).
ISP, UPDI).
.Pp
Atmel's XplainedPro boards, using the EDBG protocol (CMSIS-DAP compatible),
are supported using the "jtag3" programmer type.
@@ -225,7 +224,7 @@ thus the name
SerialUPDI programmer implementation is based on Microchip's
.Em pymcuprog Li https://github.com/microchip-pic-avr-tools/pymcuprog
utility, but it also contains some performance improvements included in
Spence Kohde's
Spence Konde's
.Em DxCore
Arduino core
.Li https://github.com/SpenceKonde/DxCore .
@@ -253,7 +252,7 @@ The Teensy bootloader is supported for all AVR boards.
As the bootloader does not support reading from flash memory,
use the
.Fl V
option to prevent AVRDUDE from verifing the flash memory.
option to prevent AVRDUDE from verifying the flash memory.
See the section on
.Em extended parameters
for Teensy specific options.
@@ -302,10 +301,15 @@ need to be specified to
.Nm avrdude .
.Bl -tag -offset indent -width indent
.It Fl p Ar partno
This is the only option that is mandatory for every invocation of
.Nm avrdude .
It specifies the type of the MCU connected to the programmer. These are read from the config file.
For currently supported MCU types use ? as partno, this will print a list of partno ids and official part names on the terminal. (Both can be used with the -p option.)
This option specifies the MCU connected to the programmer. The MCU
descriptions are read from the config file. For currently supported MCUs use
? as partno, which will print a list of partno ids and official part names.
Both can be used with the -p option. If -p ? is specified with a specific
programmer, see -c below, then only those parts are output that the
programmer expects to be able to handle, together with the programming
interface(s) that can be used in that combination. In reality there can be
deviations from this list, particularly if programming is directly via a
bootloader.
.Pp
Following parts need special attention:
.Bl -tag -width "ATmega1234"
@@ -358,6 +362,11 @@ file to assign a default programmer to keep from having to specify
this option on every invocation.
A full list of all supported programmers is output to the terminal
by using ? as programmer-id.
If -c ? is specified with a specific part, see
-p above, then only those programmers are output that expect
to be able to handle this part, together with the programming interface(s) that can be
used in that combination. In reality there can be deviations from this list,
particularly if programming is directly via a bootloader.
.It Fl C Ar config-file
Use the specified config file to load configuration data. This file
contains all programmer and part definitions that
@@ -376,6 +385,20 @@ files. This can be used to add entries to the configuration
without patching your system wide configuration file. It can be used
several times, the files are read in same order as given on the command
line.
.It Fl A
Disable the automatic removal of trailing-0xFF sequences in file
input that is to be programmed to flash and in AVR reads from
flash memory. Normally, trailing 0xFFs can be discarded, as flash
programming requires the memory be erased to 0xFF beforehand.
.Fl A
should be used when the programmer hardware, or bootloader
software for that matter, does not carry out chip erase and
instead handles the memory erase on a page level. The popular
Arduino bootloader exhibits this behaviour; for this reason
.Fl A
is engaged by default when specifying
. Fl c
arduino.
.It Fl D
Disable auto erase for flash. When the
.Fl U
@@ -389,6 +412,10 @@ use page erase before writing each page so no explicit chip erase
is required.
Note however that any page not affected by the current operation
will retain its previous contents.
Setting
.Fl D
implies
.Fl A.
.It Fl e
Causes a chip erase to be executed. This will reset the contents of the
flash ROM and EEPROM to the value
@@ -434,11 +461,17 @@ MCU type, a previous invocation of
.Nm
with this option specified is one of the possible ways to guarantee this
condition.
.Em reset
is supported by the linuxspi and flip2 programmer options, as well as all
parallel port based programmers.
.It Ar noreset
The
.Ql /RESET
line will be deactivated at program exit, thus allowing the MCU target
program to run while the programming hardware remains connected.
.Em noreset
is supported by the linuxspi and flip2 programmer options, as well as all
parallel port based programmers.
.It Ar vcc
This option will leave those parallel port pins active
.Pq \&i. \&e. Em high
@@ -606,7 +639,10 @@ Note: The ability to handle IPv6 hostnames and addresses is limited to
Posix systems (by now).
.It Fl q
Disable (or quell) output of the progress bar while reading or writing
to the device. Specify it a second time for even quieter operation.
to the device. Specify it more often for even quieter operations.
.It Fl s, u
These options used to control the obsolete "safemode" feature which
is no longer present. They are silently ignored for backwards compatibility.
.It Fl t
Tells
.Nm
@@ -690,6 +726,8 @@ can be one of:
.Bl -tag -width sss
.It Ar i
Intel Hex
.It Ar I
Intel Hex with comments on download and tolerance of checksum errors on upload
.It Ar s
Motorola S-record
.It Ar r
@@ -714,14 +752,17 @@ fuse bit settings.
hexadecimal; each value will get the string
.Em 0x
prepended.
Only valid on output.
.It Ar o
octal; each value will get a
.Em 0
prepended unless it is less than 8 in which case it gets no prefix.
Only valid on output.
.It Ar b
binary; each value will get the string
.Em 0b
prepended.
Only valid on output.
.El
.Pp
The default is to use auto detection for input files, and raw binary
@@ -771,30 +812,124 @@ abbreviated to the shortest unambiguous form. Terminal mode provides
a command history using
.Xr readline 3 ,
so previously entered command lines can be recalled and edited. The
following commands are currently implemented:
following commands are currently implemented for all programmers:
.Bl -tag -offset indent -width indent
.It Ar dump memtype addr nbytes
.It Ar dump memory addr len
Read
.Ar nbytes
.Ar len
bytes from the specified memory area, and display them in the usual
hexadecimal and ASCII form.
.It Ar dump
.It Ar dump memory addr ...
Read all bytes from the specified memory starting at address
.Ar addr,
and display them.
.It Ar dump memory addr
Read 256 bytes from the specified memory area, and display them.
.It Ar dump memory ...
Read all bytes from the specified memory, and display them.
.It Ar dump memory
Continue dumping the memory contents for another
.Ar nbytes
where the previous
.Ar 256
bytes where the previous
.Ar dump
command left off.
.It Ar write memtype addr byte1 ... byteN
.It Ar read
can be used as an alias for dump
.It Ar write memory addr data[,] {data[,]}
Manually program the respective memory cells, starting at address
.Ar addr ,
using the values
.Ar byte1
through
.Ar byteN .
This feature is not implemented for bank-addressed memories such as
the flash memory of ATMega devices.
using the data items provided.
The terminal implements reading from and writing to flash and EEPROM type
memories normally through a cache and paged access functions. All other
memories are directly written to without use of a cache. Some
older parts without paged access will also have flash and EEPROM directly
accessed without cache.
.Pp
.Ar data
can be hexadecimal, octal or decimal integers, floating point numbers
or C-style strings and characters. For integers, an optional case-insensitive
suffix specifies the data size: HH 8 bit, H/S 16 bit, L 32 bit, LL 64 bit.
Suffix D indicates a 64-bit double, F a 32-bit float, whilst a floating point
number without suffix defaults to 32-bit float. Hexadecimal floating point
notation is supported. An ambiguous trailing suffix, eg, 0x1.8D, is read as
no-suffix float where D is part of the mantissa; use a zero exponent 0x1.8p0D
to clarify.
.Pp
An optional U suffix makes integers unsigned. Ordinary 0x hex integers are
always treated as unsigned. +0x or -0x hex numbers are treated as signed
unless they have a U suffix. Unsigned integers cannot be larger than 2^64-1.
If n is an unsigned integer then -n is also a valid unsigned integer as in C.
Signed integers must fall into the [-2^63, 2^63-1] range or a correspondingly
smaller range when a suffix specifies a smaller type. Out of range signed
numbers trigger a warning.
.Pp
Ordinary 0x hex integers with n hex digits (counting leading zeros) use the
smallest size of 1, 2, 4 and 8 bytes that can accommodate any n-digit hex
integer. If an integer suffix specifies a size explicitly the corresponding
number of least significant bytes are written. Otherwise, signed and unsigned
integers alike occupy the smallest of 1, 2, 4, or 8 bytes needed to
accommodate them in their respective representation.
.Pp
One trailing comma at the end of
.Ar data
items is ignored to facilitate copy & paste of lists.
.It Ar write memory addr len data[,] {data[,]} ...
The ellipsis ... form writes <len> bytes padded by repeating the last
.Ar data
item.
.It Ar flush
Synchronise with the device all pending cached writes to EEPROM or flash.
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 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 command should be used sparingly.
.It Ar abort
Normally, caches are only ever
actually written to the device when using the
.Ar flush
command, at the end of the terminal session after typing
.Ar quit ,
or after EOF on input is encountered. The abort command resets
the cache discarding all previous writes to the flash and EEPROM cache.
.It Ar erase
Perform a chip erase.
Perform a chip erase and discard all pending writes to EEPROM and flash.
.It Ar sig
Display the device signature bytes.
.It Ar part
Display the current part settings and parameters. Includes chip
specific information including all memory types supported by the
device, read/write timing, etc.
.It Ar verbose Op Ar level
Change (when
.Ar level
is provided), or display the verbosity level.
The initial verbosity level is controlled by the number of
.Fl v
options given on the commandline.
.It Ar quell Op Ar level
Change (when
.Ar level
is provided), or display the quell level. 1 is used to suppress progress reports.
2 or higher yields in progressively quieter operations.
The initial quell level is controlled by the number of
.Fl q
options given on the commandline.
.It Ar \&?
.It Ar help
Give a short on-line summary of the available commands.
.It Ar quit
Leave terminal mode and thus
.Nm avrdude .
.El
.Pp
The terminal commands below may only be implemented on some specific programmers, and may therefore not be available in the help menu.
.Bl -tag -offset indent -width indent
.It pgerase memory addr
Erase one page of the memory specified.
.It Ar send b1 b2 b3 b4
Send raw instruction codes to the AVR device. If you need access to a
feature of an AVR part that is not directly supported by
@@ -803,24 +938,18 @@ this command allows you to use it, even though
.Nm
does not implement the command. When using direct SPI mode, up to 3 bytes
can be omitted.
.It Ar sig
Display the device signature bytes.
.It Ar spi
Enter direct SPI mode. The
.Em pgmled
pin acts as slave select.
.Em Only supported on parallel bitbang programmers, and partially by USBtiny.
.It Ar part
Display the current part settings and parameters. Includes chip
specific information including all memory types supported by the
device, read/write timing, etc.
.Em Supported on parallel bitbang programmers, and partially by USBtiny.
.It Ar pgm
Return to programming mode (from direct SPI mode).
.It Ar vtarg voltage
Set the target's supply voltage to
.Ar voltage
Volts.
.Em Only supported on the STK500 and STK600 programmer.
.Em Supported on the STK500 and STK600 programmer.
.It Ar varef Oo Ar channel Oc Ar voltage
Set the adjustable voltage source to
.Ar voltage
@@ -832,7 +961,7 @@ On the Atmel STK600, two reference voltages are available, which
can be selected by the optional
.Ar channel
argument (either 0 or 1).
.Em Only supported on the STK500 and STK600 programmer.
.Em Supported on the STK500 and STK600 programmer.
.It Ar fosc freq Ns Op M Ns \&| Ns k
Set the master oscillator to
.Ar freq
@@ -842,17 +971,16 @@ An optional trailing letter
multiplies by 1E6, a trailing letter
.Ar \&k
by 1E3.
.Em Only supported on the STK500 and STK600 programmer.
.Em Supported on the STK500 and STK600 programmer.
.It Ar fosc off
Turn the master oscillator off.
.Em Only supported on the STK500 and STK600 programmer.
.Em Supported on the STK500 and STK600 programmer.
.It Ar sck period
.Em STK500 and STK600 programmer only:
.Em STK500 and STK600 programmer:
Set the SCK clock period to
.Ar period
microseconds.
.Pp
.Em JTAG ICE only:
.Em JTAG ICE:
Set the JTAG ICE bit clock period to
.Ar period
microseconds.
@@ -862,24 +990,12 @@ software signs off from the JTAG ICE.
This parameter can also be used on the JTAG ICE mkII, JTAGICE3, and Atmel-ICE to specify the
ISP clock period when operating the ICE in ISP mode.
.It Ar parms
.Em STK500 and STK600 programmer only:
.Em STK500 and STK600 programmer:
Display the current voltage and master oscillator parameters.
.Pp
.Em JTAG ICE only:
.Em JTAG ICE:
Display the current target supply voltage and JTAG bit clock rate/period.
.It Ar verbose Op Ar level
Change (when
.Ar level
is provided), or display the verbosity level.
The initial verbosity level is controlled by the number of
.Fl v
options given on the commandline.
.It Ar \&?
.It Ar help
Give a short on-line summary of the available commands.
.It Ar quit
Leave terminal mode and thus
.Nm avrdude .
.Em Other programmers:
Display the programmer specific parameters.
.El
.Ss Default Parallel port pin connections
(these can be changed, see the
@@ -959,9 +1075,13 @@ versions of the bootloader.
.It Ar JTAG ICE mkII
.It Ar JTAGICE3
.It Ar Atmel-ICE
.It Ar Power Debugger
.It Ar PICkit 4
.It Ar MPLAB SNAP
.It Ar AVR Dragon
When using the JTAG ICE mkII, JTAGICE3, Atmel-ICE or AVR Dragon in JTAG mode, the
following extended parameter is accepted:
When using the JTAG ICE mkII, JTAGICE3, Atmel-ICE, PICkit 4, MPLAB SNAP,
Power Debugger or AVR Dragon in JTAG mode, the following extended parameter
is accepted:
.Bl -tag -offset indent -width indent
.It Ar jtagchain=UB,UA,BB,BA
Setup the JTAG scan chain for
@@ -976,6 +1096,14 @@ bits after the target AVR, respectively.
Each AVR unit within the chain shifts by 4 bits.
Other JTAG units might require a different bit shift count.
.El
.Pp
The PICkit 4 and the Power Debugger also supports high-voltage UPDI programming.
This is used to enable a UPDI pin that has previously been set to RESET or
GPIO mode. High-voltage UPDI can be utilized by using an extended parameter:
.Bl -tag -offset indent -width indent
.It Ar hvupdi
Enable high-voltage UPDI initialization for targets that supports this.
.El
.It Ar AVR910
.Bl -tag -offset indent -width indent
.It Ar devcode=VALUE
@@ -1180,6 +1308,14 @@ specific.
.Pp
When not provided, driver/OS default value will be used.
.El
.It Ar linuxspi
Extended parameter:
.Bl -tag -offset indent -width indent
.It Ar disable_no_cs
Ensures the programmer does not use the SPI_NO_CS bit for the SPI
driver. This parameter is useful for kernels that do not support
the CS line being managed outside the application.
.El
.El
.Sh FILES
.Bl -tag -offset indent -width /dev/ppi0XXX

File diff suppressed because it is too large Load Diff

View File

@@ -28,20 +28,62 @@
#define USER_CONF_FILE ".avrduderc"
#endif
extern char * progname; /* name of program, for messages */
extern char progbuf[]; /* spaces same length as progname */
extern char *progname; // name of program, for messages
extern char progbuf[]; // spaces same length as progname
extern int ovsigck; /* override signature check (-F) */
extern int verbose; /* verbosity level (-v, -vv, ...) */
extern int quell_progress; /* quietness level (-q, -qq) */
extern int ovsigck; // override signature check (-F)
extern int verbose; // verbosity level (-v, -vv, ...)
extern int quell_progress; // quell progress report -q, reduce effective verbosity level (-qq, -qqq)
int avrdude_message(const int msglvl, const char *format, ...);
int avrdude_message(int msglvl, const char *format, ...);
int avrdude_message2(const char *fname, int msgmode, int msglvl, const char *format, ...);
#define MSG_INFO (0) /* no -v option, can be suppressed with -qq */
#define MSG_NOTICE (1) /* displayed with -v */
#define MSG_NOTICE2 (2) /* displayed with -vv, used rarely */
#define MSG_DEBUG (3) /* displayed with -vvv */
#define MSG_TRACE (4) /* displayed with -vvvv, show trace communication */
#define MSG_TRACE2 (5) /* displayed with -vvvvv */
#define MSG_EXT_ERROR (-3) // OS-type error, no -v option, can be suppressed with -qqqqq
#define MSG_ERROR (-2) // Avrdude error, no -v option, can be suppressed with -qqqq
#define MSG_WARNING (-1) // Warning, no -v option, can be suppressed with -qqq
#define MSG_INFO 0 // Commentary, no -v option, can be suppressed with -qq
#define MSG_NOTICE 1 // Displayed with -v
#define MSG_NOTICE2 2 // Displayed with -vv
#define MSG_DEBUG 3 // Displayed with -vvv
#define MSG_TRACE 4 // Displayed with -vvvv, show trace communication
#define MSG_TRACE2 5 // Displayed with -vvvvv
#define MSG2_PROGNAME 1 // Start by printing progname
#define MSG2_FUNCTION 2 // Print calling function (1st arg) after progname
#define MSG2_TYPE 4 // Print message type after function or progname
#define MSG2_INDENT1 8 // Start by printing indentation of progname+1 blanks
#define MSG2_INDENT2 16 // Start by printing indentation of progname+2 blanks
#define MSG2_FLUSH 32 // Flush before and after printing
// Shortcuts
#define msg_ext_error(...) avrdude_message2(__func__, 0, MSG_EXT_ERROR, __VA_ARGS__)
#define msg_error(...) avrdude_message2(__func__, 0, MSG_ERROR, __VA_ARGS__)
#define msg_warning(...) avrdude_message2(__func__, 0, MSG_WARNING, __VA_ARGS__)
#define msg_info(...) avrdude_message2(__func__, 0, MSG_INFO, __VA_ARGS__)
#define msg_notice(...) avrdude_message2(__func__, 0, MSG_NOTICE, __VA_ARGS__)
#define msg_notice2(...) avrdude_message2(__func__, 0, MSG_NOTICE2, __VA_ARGS__)
#define msg_debug(...) avrdude_message2(__func__, 0, MSG_DEBUG, __VA_ARGS__)
#define msg_trace(...) avrdude_message2(__func__, 0, MSG_TRACE, __VA_ARGS__)
#define msg_trace2(...) avrdude_message2(__func__, 0, MSG_TRACE2, __VA_ARGS__)
#define pmsg_ext_error(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FUNCTION|MSG2_TYPE|MSG2_FLUSH, MSG_EXT_ERROR, __VA_ARGS__)
#define pmsg_error(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FUNCTION|MSG2_TYPE|MSG2_FLUSH, MSG_ERROR, __VA_ARGS__)
#define pmsg_warning(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FUNCTION|MSG2_TYPE|MSG2_FLUSH, MSG_WARNING, __VA_ARGS__)
#define pmsg_info(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_INFO, __VA_ARGS__)
#define pmsg_notice(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_NOTICE, __VA_ARGS__)
#define pmsg_notice2(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_NOTICE2, __VA_ARGS__)
#define pmsg_debug(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_DEBUG, __VA_ARGS__)
#define pmsg_trace(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_TRACE, __VA_ARGS__)
#define pmsg_trace2(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_TRACE2, __VA_ARGS__)
#define imsg_ext_error(...) avrdude_message2(__func__, MSG2_INDENT1|MSG2_FLUSH, MSG_EXT_ERROR, __VA_ARGS__)
#define imsg_error(...) avrdude_message2(__func__, MSG2_INDENT1|MSG2_FLUSH, MSG_ERROR, __VA_ARGS__)
#define imsg_warning(...) avrdude_message2(__func__, MSG2_INDENT1|MSG2_FLUSH, MSG_WARNING, __VA_ARGS__)
#define imsg_info(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_INFO, __VA_ARGS__)
#define imsg_notice(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_NOTICE, __VA_ARGS__)
#define imsg_notice2(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_NOTICE2, __VA_ARGS__)
#define imsg_debug(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_DEBUG, __VA_ARGS__)
#define imsg_trace(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_TRACE, __VA_ARGS__)
#define imsg_trace2(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_TRACE2, __VA_ARGS__)
#endif

View File

@@ -50,16 +50,12 @@
#ifdef DO_NOT_BUILD_AVRFTDI
static int avrftdi_noftdi_open (struct programmer_t *pgm, char * name)
{
avrdude_message(MSG_INFO, "%s: Error: no libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.\n",
progname);
static int avrftdi_noftdi_open(PROGRAMMER *pgm, const char *name) {
pmsg_error("no libftdi or libusb support; install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again\n");
return -1;
}
void avrftdi_initpgm(PROGRAMMER * pgm)
{
void avrftdi_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "avrftdi");
pgm->open = avrftdi_noftdi_open;
}
@@ -142,14 +138,14 @@ void avrftdi_log(int level, const char * func, int line,
if(!skip_prefix)
{
switch(level) {
case ERR: avrdude_message(MSG_INFO, "E "); break;
case WARN: avrdude_message(MSG_INFO, "W "); break;
case INFO: avrdude_message(MSG_INFO, "I "); break;
case DEBUG: avrdude_message(MSG_INFO, "D "); break;
case TRACE: avrdude_message(MSG_INFO, "T "); break;
default: avrdude_message(MSG_INFO, " "); break;
case ERR: msg_error("E "); break;
case WARN: msg_error("W "); break;
case INFO: msg_error("I "); break;
case DEBUG: msg_error("D "); break;
case TRACE: msg_error("T "); break;
default: msg_error(" "); break;
}
avrdude_message(MSG_INFO, "%s(%d): ", func, line);
msg_error("%s(%d): ", func, line);
}
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
@@ -172,16 +168,16 @@ static void buf_dump(const unsigned char *buf, int len, char *desc,
int offset, int width)
{
int i;
avrdude_message(MSG_INFO, "%s begin:\n", desc);
msg_info("%s begin:\n", desc);
for (i = 0; i < offset; i++)
avrdude_message(MSG_INFO, "%02x ", buf[i]);
avrdude_message(MSG_INFO, "\n");
msg_info("%02x ", buf[i]);
msg_info("\n");
for (i++; i <= len; i++) {
avrdude_message(MSG_INFO, "%02x ", buf[i-1]);
msg_info("%02x ", buf[i-1]);
if((i-offset) != 0 && (i-offset)%width == 0)
avrdude_message(MSG_INFO, "\n");
msg_info("\n");
}
avrdude_message(MSG_INFO, "%s end\n", desc);
msg_info("%s end\n", desc);
}
/*
@@ -227,8 +223,7 @@ static int set_frequency(avrftdi_t* ftdi, uint32_t freq)
* Because we configured the pin direction mask earlier, nothing bad can happen
* here.
*/
static int set_pin(PROGRAMMER * pgm, int pinfunc, int value)
{
static int set_pin(const PROGRAMMER *pgm, int pinfunc, int value) {
avrftdi_t* pdata = to_pdata(pgm);
struct pindef_t pin = pgm->pin[pinfunc];
@@ -250,47 +245,43 @@ static int set_pin(PROGRAMMER * pgm, int pinfunc, int value)
/*
* Mandatory callbacks which boil down to GPIO.
*/
static int set_led_pgm(struct programmer_t * pgm, int value)
{
static int set_led_pgm(const PROGRAMMER *pgm, int value) {
return set_pin(pgm, PIN_LED_PGM, value);
}
static int set_led_rdy(struct programmer_t * pgm, int value)
{
static int set_led_rdy(const PROGRAMMER *pgm, int value) {
return set_pin(pgm, PIN_LED_RDY, value);
}
static int set_led_err(struct programmer_t * pgm, int value)
{
static int set_led_err(const PROGRAMMER *pgm, int value) {
return set_pin(pgm, PIN_LED_ERR, value);
}
static int set_led_vfy(struct programmer_t * pgm, int value)
{
static int set_led_vfy(const PROGRAMMER *pgm, int value) {
return set_pin(pgm, PIN_LED_VFY, value);
}
static void avrftdi_enable(PROGRAMMER * pgm)
{
static void avrftdi_enable(PROGRAMMER *pgm, const AVRPART *p) {
set_pin(pgm, PPI_AVR_BUFF, ON);
// Switch to TPI initialisation in avrftdi_tpi.c
if(p->prog_modes & PM_TPI)
avrftdi_tpi_initpgm(pgm);
}
static void avrftdi_disable(PROGRAMMER * pgm)
{
static void avrftdi_disable(const PROGRAMMER *pgm) {
set_pin(pgm, PPI_AVR_BUFF, OFF);
}
static void avrftdi_powerup(PROGRAMMER * pgm)
{
static void avrftdi_powerup(const PROGRAMMER *pgm) {
set_pin(pgm, PPI_AVR_VCC, ON);
}
static void avrftdi_powerdown(PROGRAMMER * pgm)
{
static void avrftdi_powerdown(const PROGRAMMER *pgm) {
set_pin(pgm, PPI_AVR_VCC, OFF);
}
static inline int set_data(PROGRAMMER * pgm, unsigned char *buf, unsigned char data, bool read_data) {
static inline int set_data(const PROGRAMMER *pgm, unsigned char *buf, unsigned char data, bool read_data) {
int j;
int buf_pos = 0;
unsigned char bit = 0x80;
@@ -324,7 +315,7 @@ static inline int set_data(PROGRAMMER * pgm, unsigned char *buf, unsigned char d
return buf_pos;
}
static inline unsigned char extract_data(PROGRAMMER * pgm, unsigned char *buf, int offset) {
static inline unsigned char extract_data(const PROGRAMMER *pgm, unsigned char *buf, int offset) {
int j;
unsigned char bit = 0x80;
unsigned char r = 0;
@@ -342,7 +333,7 @@ static inline unsigned char extract_data(PROGRAMMER * pgm, unsigned char *buf, i
}
static int avrftdi_transmit_bb(PROGRAMMER * pgm, unsigned char mode, const unsigned char *buf,
static int avrftdi_transmit_bb(const PROGRAMMER *pgm, unsigned char mode, const unsigned char *buf,
unsigned char *data, int buf_size)
{
size_t remaining = buf_size;
@@ -351,10 +342,10 @@ static int avrftdi_transmit_bb(PROGRAMMER * pgm, unsigned char mode, const unsig
size_t blocksize = pdata->rx_buffer_size/2; // we are reading 2 bytes per data byte
// determine a maximum size of data block
size_t max_size = MIN(pdata->ftdic->max_packet_size,pdata->tx_buffer_size);
size_t max_size = MIN(pdata->ftdic->max_packet_size, (unsigned int) pdata->tx_buffer_size);
// select block size so that resulting commands does not exceed max_size if possible
blocksize = MAX(1,(max_size-7)/((8*2*6)+(8*1*2)));
//avrdude_message(MSG_INFO, "blocksize %d \n",blocksize);
// msg_info("blocksize %d \n", blocksize);
unsigned char* send_buffer = alloca((8 * 2 * 6) * blocksize + (8 * 1 * 2) * blocksize + 7);
unsigned char* recv_buffer = alloca(2 * 16 * blocksize);
@@ -368,9 +359,8 @@ static int avrftdi_transmit_bb(PROGRAMMER * pgm, unsigned char mode, const unsig
// (8*1) inputs per data byte, 2 transmit bytes per input (GET_BITS_LOW/HIGH),
// 1x SEND_IMMEDIATE
int len = 0;
int i;
for(i = 0 ; i< transfer_size; i++) {
for(size_t i = 0 ; i < transfer_size; i++) {
len += set_data(pgm, send_buffer + len, buf[written+i], (mode & MPSSE_DO_READ) != 0);
}
@@ -387,14 +377,14 @@ static int avrftdi_transmit_bb(PROGRAMMER * pgm, unsigned char mode, const unsig
E(ftdi_write_data(pdata->ftdic, send_buffer, len) != len, pdata->ftdic);
if (mode & MPSSE_DO_READ) {
int n;
int k = 0;
size_t k = 0;
do {
n = ftdi_read_data(pdata->ftdic, &recv_buffer[k], 2*16*transfer_size - k);
E(n < 0, pdata->ftdic);
k += n;
} while (k < transfer_size);
for(i = 0 ; i< transfer_size; i++) {
for(size_t i = 0 ; i< transfer_size; i++) {
data[written + i] = extract_data(pgm, recv_buffer, i);
}
}
@@ -437,7 +427,7 @@ static int avrftdi_transmit_mpsse(avrftdi_t* pdata, unsigned char mode, const un
{
size_t transfer_size = (remaining > blocksize) ? blocksize : remaining;
E(ftdi_write_data(pdata->ftdic, (unsigned char*)&buf[written], transfer_size) != transfer_size, pdata->ftdic);
E((size_t) ftdi_write_data(pdata->ftdic, (unsigned char*)&buf[written], transfer_size) != transfer_size, pdata->ftdic);
#if 0
if(remaining < blocksize)
E(ftdi_write_data(pdata->ftdic, &si, sizeof(si)) != sizeof(si), pdata->ftdic);
@@ -445,7 +435,7 @@ static int avrftdi_transmit_mpsse(avrftdi_t* pdata, unsigned char mode, const un
if (mode & MPSSE_DO_READ) {
int n;
int k = 0;
size_t k = 0;
do {
n = ftdi_read_data(pdata->ftdic, &data[written + k], transfer_size - k);
E(n < 0, pdata->ftdic);
@@ -461,7 +451,7 @@ static int avrftdi_transmit_mpsse(avrftdi_t* pdata, unsigned char mode, const un
return written;
}
static inline int avrftdi_transmit(PROGRAMMER * pgm, unsigned char mode, const unsigned char *buf,
static inline int avrftdi_transmit(const PROGRAMMER *pgm, unsigned char mode, const unsigned char *buf,
unsigned char *data, int buf_size)
{
avrftdi_t* pdata = to_pdata(pgm);
@@ -520,8 +510,7 @@ static int write_flush(avrftdi_t* pdata)
}
static int avrftdi_check_pins_bb(PROGRAMMER * pgm, bool output)
{
static int avrftdi_check_pins_bb(const PROGRAMMER *pgm, bool output) {
int pin;
/* pin checklist. */
@@ -548,8 +537,7 @@ static int avrftdi_check_pins_bb(PROGRAMMER * pgm, bool output)
return pins_check(pgm, pin_checklist, N_PINS, output);
}
static int avrftdi_check_pins_mpsse(PROGRAMMER * pgm, bool output)
{
static int avrftdi_check_pins_mpsse(const PROGRAMMER *pgm, bool output) {
int pin;
/* pin checklist. */
@@ -593,8 +581,7 @@ static int avrftdi_check_pins_mpsse(PROGRAMMER * pgm, bool output)
return pins_check(pgm, pin_checklist, N_PINS, output);
}
static int avrftdi_pin_setup(PROGRAMMER * pgm)
{
static int avrftdi_pin_setup(const PROGRAMMER *pgm) {
int pin;
/*************
@@ -622,7 +609,8 @@ static int avrftdi_pin_setup(PROGRAMMER * pgm)
}
pdata->use_bitbanging = !pin_check_mpsse;
if (pdata->use_bitbanging) log_info("Because of pin configuration fallback to bitbanging mode.\n");
if (pdata->use_bitbanging)
log_info("Because of pin configuration fallback to bitbanging mode.\n");
/*
* TODO: No need to fail for a wrongly configured led or something.
@@ -648,10 +636,9 @@ static int avrftdi_pin_setup(PROGRAMMER * pgm)
return 0;
}
static int avrftdi_open(PROGRAMMER * pgm, char *port)
{
static int avrftdi_open(PROGRAMMER *pgm, const char *port) {
int vid, pid, interface, index, err;
char * serial, *desc;
const char *serial, *desc;
avrftdi_t* pdata = to_pdata(pgm);
@@ -671,8 +658,7 @@ static int avrftdi_open(PROGRAMMER * pgm, char *port)
if (usbpid) {
pid = *(int *)(ldata(usbpid));
if (lnext(usbpid))
avrdude_message(MSG_INFO, "%s: Warning: using PID 0x%04x, ignoring remaining PIDs in list\n",
progname, pid);
pmsg_warning("using PID 0x%04x, ignoring remaining PIDs in list\n", pid);
} else
pid = USB_DEVICE_FT2232;
@@ -817,11 +803,10 @@ static void avrftdi_close(PROGRAMMER * pgm)
return;
}
static int avrftdi_initialize(PROGRAMMER * pgm, AVRPART * p)
{
static int avrftdi_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
avrftdi_powerup(pgm);
if(p->flags & AVRPART_HAS_TPI)
if(p->prog_modes & PM_TPI)
{
/* see avrftdi_tpi.c */
avrftdi_tpi_initialize(pgm, p);
@@ -847,21 +832,18 @@ static int avrftdi_initialize(PROGRAMMER * pgm, AVRPART * p)
return pgm->program_enable(pgm, p);
}
static void avrftdi_display(PROGRAMMER * pgm, const char *p)
{
static void avrftdi_display(const PROGRAMMER *pgm, const char *p) {
// print the full pin definitions as in ft245r ?
return;
}
static int avrftdi_cmd(PROGRAMMER * pgm, const unsigned char *cmd, unsigned char *res)
{
static int avrftdi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) {
return avrftdi_transmit(pgm, MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, res, 4);
}
static int avrftdi_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
static int avrftdi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
int i;
unsigned char buf[4];
@@ -892,8 +874,7 @@ static int avrftdi_program_enable(PROGRAMMER * pgm, AVRPART * p)
}
static int avrftdi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
static int avrftdi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char cmd[4];
unsigned char res[4];
@@ -915,8 +896,7 @@ static int avrftdi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
/* Load extended address byte command */
static int
avrftdi_lext(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m, unsigned int address)
{
avrftdi_lext(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int address) {
/* nothing to do if load extended address command unavailable */
if(m->op[AVR_OP_LOAD_EXT_ADDR] == NULL)
return 0;
@@ -943,7 +923,7 @@ avrftdi_lext(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m, unsigned int address)
return 0;
}
static int avrftdi_eeprom_write(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
static int avrftdi_eeprom_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size, unsigned int addr, unsigned int len)
{
unsigned char cmd[] = { 0x00, 0x00, 0x00, 0x00 };
@@ -965,7 +945,7 @@ static int avrftdi_eeprom_write(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
return len;
}
static int avrftdi_eeprom_read(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
static int avrftdi_eeprom_read(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size, unsigned int addr, unsigned int len)
{
unsigned char cmd[4];
@@ -991,7 +971,7 @@ static int avrftdi_eeprom_read(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
return len;
}
static int avrftdi_flash_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int avrftdi_flash_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size, unsigned int addr, unsigned int len)
{
unsigned int word;
@@ -1015,7 +995,7 @@ static int avrftdi_flash_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
return -1;
}
if(page_size != m->page_size) {
if(page_size != (unsigned int) m->page_size) {
log_warn("Parameter page_size is %d, ", page_size);
log_warn("but m->page_size is %d. Using the latter.\n", m->page_size);
}
@@ -1059,12 +1039,11 @@ static int avrftdi_flash_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
/* find a poll byte. We cannot poll a value of 0xff, so look
* for a value != 0xff
*/
for(poll_index = addr+len-1; poll_index > addr-1; poll_index--)
for(poll_index = addr+len-1; poll_index+1 > addr; poll_index--)
if(m->buf[poll_index] != 0xff)
break;
if((poll_index < addr + len) && m->buf[poll_index] != 0xff)
{
if(poll_index+1 > addr) {
buf_size = bufptr - buf;
if(verbose > TRACE)
@@ -1101,16 +1080,15 @@ static int avrftdi_flash_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
/*
*Reading from flash
*/
static int avrftdi_flash_read(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int avrftdi_flash_read(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size, unsigned int addr, unsigned int len)
{
OPCODE * readop;
int byte, word;
unsigned int buf_size = 4 * len + 4;
unsigned char* o_buf = alloca(buf_size);
unsigned char* i_buf = alloca(buf_size);
unsigned int index;
memset(o_buf, 0, buf_size);
memset(i_buf, 0, buf_size);
@@ -1129,7 +1107,7 @@ static int avrftdi_flash_read(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
return -1;
/* word addressing! */
for(word = addr/2, index = 0; word < (addr + len)/2; word++)
for(unsigned int word = addr/2, index = 0; word < (addr + len)/2; word++)
{
/* one byte is transferred via a 4-byte opcode.
* TODO: reduce magic numbers
@@ -1160,7 +1138,7 @@ static int avrftdi_flash_read(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
memset(&m->buf[addr], 0, page_size);
/* every (read) op is 4 bytes in size and yields one byte of memory data */
for(byte = 0; byte < page_size; byte++) {
for(unsigned int byte = 0; byte < page_size; byte++) {
if(byte & 1)
readop = m->op[AVR_OP_READ_HI];
else
@@ -1178,7 +1156,7 @@ static int avrftdi_flash_read(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
return len;
}
static int avrftdi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int avrftdi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size, unsigned int addr, unsigned int n_bytes)
{
if (strcmp(m->desc, "flash") == 0)
@@ -1189,7 +1167,7 @@ static int avrftdi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
return -2;
}
static int avrftdi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int avrftdi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size, unsigned int addr, unsigned int n_bytes)
{
if (strcmp(m->desc, "flash") == 0)
@@ -1238,9 +1216,7 @@ avrftdi_teardown(PROGRAMMER * pgm)
}
}
void avrftdi_initpgm(PROGRAMMER * pgm)
{
void avrftdi_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "avrftdi");
/*

View File

@@ -29,7 +29,7 @@ extern "C" {
extern const char avrftdi_desc[];
void avrftdi_initpgm (PROGRAMMER * pgm);
void avrftdi_initpgm(PROGRAMMER *pgm);
#ifdef __cplusplus
}

View File

@@ -14,7 +14,8 @@
# define HAVE_LIBFTDI_TYPE_232H 1
#elif defined(HAVE_LIBFTDI)
#include <ftdi.h>
#else
#else
#ifdef _MSC_VER
#pragma message("No libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.")
#else
@@ -30,7 +31,7 @@ enum { ERR, WARN, INFO, DEBUG, TRACE };
#define __log(lvl, fmt, ...) \
do { \
avrftdi_log(lvl, __func__, __LINE__, fmt, ##__VA_ARGS__); \
} while(0)
} while(0)
#define log_err(fmt, ...) __log(ERR, fmt, ##__VA_ARGS__)
@@ -40,49 +41,49 @@ enum { ERR, WARN, INFO, DEBUG, TRACE };
#define log_trace(fmt, ...) __log(TRACE, fmt, ##__VA_ARGS__)
#define E(x, ftdi) \
do { \
if ((x)) \
{ \
avrdude_message(MSG_INFO, "%s:%d %s() %s: %s (%d)\n\t%s\n", \
__FILE__, __LINE__, __FUNCTION__, \
#x, strerror(errno), errno, ftdi_get_error_string(ftdi)); \
return -1; \
} \
} while(0)
do { \
if ((x)) \
{ \
msg_error("%s:%d %s() %s: %s (%d)\n\t%s\n", \
__FILE__, __LINE__, __FUNCTION__, \
#x, strerror(errno), errno, ftdi_get_error_string(ftdi)); \
return -1; \
} \
} while(0)
#define E_VOID(x, ftdi) \
do { \
if ((x)) \
{ \
avrdude_message(MSG_INFO, "%s:%d %s() %s: %s (%d)\n\t%s\n", \
__FILE__, __LINE__, __FUNCTION__, \
#x, strerror(errno), errno, ftdi_get_error_string(ftdi)); \
} \
} while(0)
do { \
if ((x)) \
{ \
msg_error("%s:%d %s() %s: %s (%d)\n\t%s\n", \
__FILE__, __LINE__, __FUNCTION__, \
#x, strerror(errno), errno, ftdi_get_error_string(ftdi)); \
} \
} while(0)
#define to_pdata(pgm) \
((avrftdi_t *)((pgm)->cookie))
((avrftdi_t *)((pgm)->cookie))
typedef struct avrftdi_s {
/* pointer to struct maintained by libftdi to identify the device */
struct ftdi_context* ftdic;
/* bitmask of values for pins. bit 0 represents pin 0 ([A|B]DBUS0) */
uint16_t pin_value;
/* bitmask of pin direction. a '1' make a pin an output.
* bit 0 corresponds to pin 0. */
uint16_t pin_direction;
/* don't know. not useful. someone put it in. */
uint16_t led_mask;
/* total number of pins supported by a programmer. varies with FTDI chips */
int pin_limit;
/* internal RX buffer of the device. needed for INOUT transfers */
int rx_buffer_size;
int tx_buffer_size;
/* use bitbanging instead of mpsse spi */
bool use_bitbanging;
/* bits 16-23 of extended 24-bit word flash address for parts with flash > 128k */
uint8_t lext_byte;
/* pointer to struct maintained by libftdi to identify the device */
struct ftdi_context* ftdic;
/* bitmask of values for pins. bit 0 represents pin 0 ([A|B]DBUS0) */
uint16_t pin_value;
/* bitmask of pin direction. a '1' make a pin an output.
* bit 0 corresponds to pin 0. */
uint16_t pin_direction;
/* don't know. not useful. someone put it in. */
uint16_t led_mask;
/* total number of pins supported by a programmer. varies with FTDI chips */
int pin_limit;
/* internal RX buffer of the device. needed for INOUT transfers */
int rx_buffer_size;
int tx_buffer_size;
/* use bitbanging instead of mpsse spi */
bool use_bitbanging;
/* bits 16-23 of extended 24-bit word flash address for parts with flash > 128k */
uint8_t lext_byte;
} avrftdi_t;
void avrftdi_log(int level, const char * func, int line, const char * fmt, ...);

View File

@@ -15,8 +15,8 @@
#ifndef DO_NOT_BUILD_AVRFTDI
static void avrftdi_tpi_disable(PROGRAMMER *);
static int avrftdi_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p);
static void avrftdi_tpi_disable(const PROGRAMMER *);
static int avrftdi_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p);
#ifdef notyet
static void
@@ -63,23 +63,12 @@ avrftdi_debug_frame(uint16_t frame)
#endif /* notyet */
int
avrftdi_tpi_initialize(PROGRAMMER * pgm, AVRPART * p)
{
avrftdi_tpi_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
int ret;
avrftdi_t* pdata = to_pdata(pgm);
unsigned char buf[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 0x01, 0x00, 0xff, 0xff };
log_info("Using TPI interface\n");
pgm->program_enable = avrftdi_tpi_program_enable;
pgm->cmd_tpi = avrftdi_cmd_tpi;
pgm->chip_erase = avr_tpi_chip_erase;
pgm->disable = avrftdi_tpi_disable;
pgm->paged_load = NULL;
pgm->paged_write = NULL;
log_info("Setting /Reset pin low\n");
pgm->setpin(pgm, PIN_AVR_RESET, OFF);
pgm->setpin(pgm, PIN_AVR_SCK, OFF);
@@ -101,6 +90,20 @@ avrftdi_tpi_initialize(PROGRAMMER * pgm, AVRPART * p)
return ret;
}
void avrftdi_tpi_initpgm(PROGRAMMER *pgm) {
log_info("Using TPI interface\n");
pgm->program_enable = avrftdi_tpi_program_enable;
pgm->cmd_tpi = avrftdi_cmd_tpi;
pgm->chip_erase = avr_tpi_chip_erase;
pgm->disable = avrftdi_tpi_disable;
pgm->paged_load = NULL;
pgm->paged_write = NULL;
}
#define TPI_PARITY_MASK 0x2000
static inline int count1s(unsigned int x)
@@ -148,8 +151,7 @@ tpi_frame2byte(uint16_t frame, uint8_t * byte)
#ifdef notyet
static int
avrftdi_tpi_break(PROGRAMMER * pgm)
{
avrftdi_tpi_break(const PROGRAMMER *pgm) {
unsigned char buffer[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 1, 0, 0, 0 };
E(ftdi_write_data(to_pdata(pgm)->ftdic, buffer, sizeof(buffer)) != sizeof(buffer), to_pdata(pgm)->ftdic);
@@ -158,8 +160,7 @@ avrftdi_tpi_break(PROGRAMMER * pgm)
#endif /* notyet */
static int
avrftdi_tpi_write_byte(PROGRAMMER * pgm, unsigned char byte)
{
avrftdi_tpi_write_byte(const PROGRAMMER *pgm, unsigned char byte) {
uint16_t frame;
struct ftdi_context* ftdic = to_pdata(pgm)->ftdic;
@@ -185,8 +186,7 @@ avrftdi_tpi_write_byte(PROGRAMMER * pgm, unsigned char byte)
#define TPI_IDLE_BITS 2
static int
avrftdi_tpi_read_byte(PROGRAMMER * pgm, unsigned char * byte)
{
avrftdi_tpi_read_byte(const PROGRAMMER *pgm, unsigned char *byte) {
uint16_t frame;
/* use 2 guard bits, 2 default idle bits + 12 frame bits = 16 bits total */
@@ -230,13 +230,12 @@ avrftdi_tpi_read_byte(PROGRAMMER * pgm, unsigned char * byte)
}
static int
avrftdi_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
avrftdi_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
return avr_tpi_program_enable(pgm, p, TPIPCR_GT_2b);
}
int
avrftdi_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd, int cmd_len,
avrftdi_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd, int cmd_len,
unsigned char *res, int res_len)
{
int i, err = 0;
@@ -259,8 +258,7 @@ avrftdi_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd, int cmd_len,
}
static void
avrftdi_tpi_disable(PROGRAMMER * pgm)
{
avrftdi_tpi_disable(const PROGRAMMER *pgm) {
unsigned char cmd[] = {TPI_OP_SSTCS(TPIPCR), 0};
pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0);

View File

@@ -1,9 +1,10 @@
#pragma once
//int avrftdi_tpi_write_byte(PROGRAMMER * pgm, unsigned char byte);
//int avrftdi_tpi_read_byte(PROGRAMMER * pgm, unsigned char * byte);
int avrftdi_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd, int cmd_len,
//int avrftdi_tpi_write_byte(PROGRAMMER *pgm, unsigned char byte);
//int avrftdi_tpi_read_byte(PROGRAMMER *pgm, unsigned char * byte);
int avrftdi_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd, int cmd_len,
unsigned char *res, int res_len);
int avrftdi_tpi_initialize(PROGRAMMER * pgm, AVRPART * p);
int avrftdi_tpi_initialize(const PROGRAMMER *pgm, const AVRPART *p);
void avrftdi_tpi_initpgm(PROGRAMMER *pgm);

5458
src/avrintel.c Normal file

File diff suppressed because it is too large Load Diff

1477
src/avrintel.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -76,8 +76,7 @@ static void bitbang_calibrate_delay(void)
if (QueryPerformanceFrequency(&freq))
{
has_perfcount = 1;
avrdude_message(MSG_NOTICE2, "%s: Using performance counter for bitbang delays\n",
progname);
pmsg_notice2("using performance counter for bitbang delays\n");
}
else
{
@@ -90,16 +89,14 @@ static void bitbang_calibrate_delay(void)
* auto-calibration figures seen on various Unix systems on
* comparable hardware.
*/
avrdude_message(MSG_NOTICE2, "%s: Using guessed per-microsecond delay count for bitbang delays\n",
progname);
pmsg_notice2("using guessed per-microsecond delay count for bitbang delays\n");
delay_decrement = 100;
}
#else /* !WIN32 */
struct itimerval itv;
volatile int i;
avrdude_message(MSG_NOTICE2, "%s: Calibrating delay loop...",
progname);
pmsg_notice2("calibrating delay loop ...");
i = 0;
done = 0;
saved_alarmhandler = signal(SIGALRM, alarmhandler);
@@ -125,7 +122,7 @@ static void bitbang_calibrate_delay(void)
* Calculate back from 100 ms to 1 us.
*/
delay_decrement = -i / 100000;
avrdude_message(MSG_NOTICE2, " calibrated to %d cycles per us\n",
msg_notice2(" calibrated to %d cycles per us\n",
delay_decrement);
#endif /* WIN32 */
}
@@ -163,8 +160,7 @@ void bitbang_delay(unsigned int us)
/*
* transmit and receive a byte of data to/from the AVR device
*/
static unsigned char bitbang_txrx(PROGRAMMER * pgm, unsigned char byte)
{
static unsigned char bitbang_txrx(const PROGRAMMER *pgm, unsigned char byte) {
int i;
unsigned char r, b, rbyte;
@@ -208,8 +204,7 @@ static unsigned char bitbang_txrx(PROGRAMMER * pgm, unsigned char byte)
return rbyte;
}
static int bitbang_tpi_clk(PROGRAMMER * pgm)
{
static int bitbang_tpi_clk(const PROGRAMMER *pgm) {
unsigned char r = 0;
pgm->setpin(pgm, PIN_AVR_SCK, 1);
@@ -220,8 +215,7 @@ static int bitbang_tpi_clk(PROGRAMMER * pgm)
return r;
}
void bitbang_tpi_tx(PROGRAMMER * pgm, unsigned char byte)
{
void bitbang_tpi_tx(const PROGRAMMER *pgm, unsigned char byte) {
int i;
unsigned char b, parity;
@@ -249,8 +243,7 @@ void bitbang_tpi_tx(PROGRAMMER * pgm, unsigned char byte)
bitbang_tpi_clk(pgm);
}
int bitbang_tpi_rx(PROGRAMMER * pgm)
{
int bitbang_tpi_rx(const PROGRAMMER *pgm) {
int i;
unsigned char b, rbyte, parity;
@@ -265,7 +258,7 @@ int bitbang_tpi_rx(PROGRAMMER * pgm)
break;
}
if (b != 0) {
avrdude_message(MSG_INFO, "bitbang_tpi_rx: start bit not received correctly\n");
pmsg_error("start bit not received correctly\n");
return -1;
}
@@ -280,7 +273,7 @@ int bitbang_tpi_rx(PROGRAMMER * pgm)
/* parity bit */
if (bitbang_tpi_clk(pgm) != parity) {
avrdude_message(MSG_INFO, "bitbang_tpi_rx: parity bit is wrong\n");
pmsg_error("parity bit is wrong\n");
return -1;
}
@@ -289,33 +282,29 @@ int bitbang_tpi_rx(PROGRAMMER * pgm)
b &= bitbang_tpi_clk(pgm);
b &= bitbang_tpi_clk(pgm);
if (b != 1) {
avrdude_message(MSG_INFO, "bitbang_tpi_rx: stop bits not received correctly\n");
pmsg_error("stop bits not received correctly\n");
return -1;
}
return rbyte;
}
int bitbang_rdy_led(PROGRAMMER * pgm, int value)
{
int bitbang_rdy_led(const PROGRAMMER *pgm, int value) {
pgm->setpin(pgm, PIN_LED_RDY, !value);
return 0;
}
int bitbang_err_led(PROGRAMMER * pgm, int value)
{
int bitbang_err_led(const PROGRAMMER *pgm, int value) {
pgm->setpin(pgm, PIN_LED_ERR, !value);
return 0;
}
int bitbang_pgm_led(PROGRAMMER * pgm, int value)
{
int bitbang_pgm_led(const PROGRAMMER *pgm, int value) {
pgm->setpin(pgm, PIN_LED_PGM, !value);
return 0;
}
int bitbang_vfy_led(PROGRAMMER * pgm, int value)
{
int bitbang_vfy_led(const PROGRAMMER *pgm, int value) {
pgm->setpin(pgm, PIN_LED_VFY, !value);
return 0;
}
@@ -325,7 +314,7 @@ int bitbang_vfy_led(PROGRAMMER * pgm, int value)
* transmit an AVR device command and return the results; 'cmd' and
* 'res' must point to at least a 4 byte data buffer
*/
int bitbang_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
int bitbang_cmd(const PROGRAMMER *pgm, const unsigned char *cmd,
unsigned char *res)
{
int i;
@@ -336,21 +325,21 @@ int bitbang_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
if(verbose >= 2)
{
avrdude_message(MSG_NOTICE2, "bitbang_cmd(): [ ");
msg_notice2("bitbang_cmd(): [ ");
for(i = 0; i < 4; i++)
avrdude_message(MSG_NOTICE2, "%02X ", cmd[i]);
avrdude_message(MSG_NOTICE2, "] [ ");
msg_notice2("%02X ", cmd[i]);
msg_notice2("] [ ");
for(i = 0; i < 4; i++)
{
avrdude_message(MSG_NOTICE2, "%02X ", res[i]);
msg_notice2("%02X ", res[i]);
}
avrdude_message(MSG_NOTICE2, "]\n");
msg_notice2("]\n");
}
return 0;
}
int bitbang_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd,
int bitbang_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd,
int cmd_len, unsigned char *res, int res_len)
{
int i, r;
@@ -371,15 +360,15 @@ int bitbang_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd,
if(verbose >= 2)
{
avrdude_message(MSG_NOTICE2, "bitbang_cmd_tpi(): [ ");
msg_notice2("bitbang_cmd_tpi(): [ ");
for(i = 0; i < cmd_len; i++)
avrdude_message(MSG_NOTICE2, "%02X ", cmd[i]);
avrdude_message(MSG_NOTICE2, "] [ ");
msg_notice2("%02X ", cmd[i]);
msg_notice2("] [ ");
for(i = 0; i < res_len; i++)
{
avrdude_message(MSG_NOTICE2, "%02X ", res[i]);
msg_notice2("%02X ", res[i]);
}
avrdude_message(MSG_NOTICE2, "]\n");
msg_notice2("]\n");
}
pgm->pgm_led(pgm, OFF);
@@ -392,7 +381,7 @@ int bitbang_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd,
* transmit bytes via SPI and return the results; 'cmd' and
* 'res' must point to data buffers
*/
int bitbang_spi(PROGRAMMER * pgm, const unsigned char *cmd,
int bitbang_spi(const PROGRAMMER *pgm, const unsigned char *cmd,
unsigned char *res, int count)
{
int i;
@@ -407,15 +396,15 @@ int bitbang_spi(PROGRAMMER * pgm, const unsigned char *cmd,
if(verbose >= 2)
{
avrdude_message(MSG_NOTICE2, "bitbang_cmd(): [ ");
msg_notice2("bitbang_cmd(): [ ");
for(i = 0; i < count; i++)
avrdude_message(MSG_NOTICE2, "%02X ", cmd[i]);
avrdude_message(MSG_NOTICE2, "] [ ");
msg_notice2("%02X ", cmd[i]);
msg_notice2("] [ ");
for(i = 0; i < count; i++)
{
avrdude_message(MSG_NOTICE2, "%02X ", res[i]);
msg_notice2("%02X ", res[i]);
}
avrdude_message(MSG_NOTICE2, "]\n");
msg_notice2("]\n");
}
return 0;
@@ -425,13 +414,12 @@ int bitbang_spi(PROGRAMMER * pgm, const unsigned char *cmd,
/*
* issue the 'chip erase' command to the AVR device
*/
int bitbang_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
int bitbang_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char cmd[4];
unsigned char res[4];
AVRMEM *mem;
if (p->flags & AVRPART_HAS_TPI) {
if (p->prog_modes & PM_TPI) {
pgm->pgm_led(pgm, ON);
while (avr_tpi_poll_nvmbsy(pgm));
@@ -443,8 +431,7 @@ int bitbang_chip_erase(PROGRAMMER * pgm, AVRPART * p)
/* Set Pointer Register */
mem = avr_locate_mem(p, "flash");
if (mem == NULL) {
avrdude_message(MSG_INFO, "No flash memory to erase for part %s\n",
p->desc);
pmsg_error("no flash memory to erase for part %s\n", p->desc);
return -1;
}
bitbang_tpi_tx(pgm, TPI_CMD_SSTPR | 0);
@@ -464,8 +451,7 @@ int bitbang_chip_erase(PROGRAMMER * pgm, AVRPART * p)
}
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
avrdude_message(MSG_INFO, "chip erase instruction not defined for part \"%s\"\n",
p->desc);
pmsg_error("chip erase instruction not defined for part %s\n", p->desc);
return -1;
}
@@ -486,13 +472,12 @@ int bitbang_chip_erase(PROGRAMMER * pgm, AVRPART * p)
/*
* issue the 'program enable' command to the AVR device
*/
int bitbang_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
int bitbang_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char cmd[4];
unsigned char res[4];
int i;
if (p->flags & AVRPART_HAS_TPI) {
if (p->prog_modes & PM_TPI) {
/* enable NVM programming */
bitbang_tpi_tx(pgm, TPI_CMD_SKEY);
for (i = sizeof(tpi_skey) - 1; i >= 0; i--)
@@ -505,8 +490,7 @@ int bitbang_program_enable(PROGRAMMER * pgm, AVRPART * p)
}
if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
avrdude_message(MSG_INFO, "program enable instruction not defined for part \"%s\"\n",
p->desc);
pmsg_error("program enable instruction not defined for part %s\n", p->desc);
return -1;
}
@@ -523,8 +507,7 @@ int bitbang_program_enable(PROGRAMMER * pgm, AVRPART * p)
/*
* initialize the AVR device and prepare it to accept commands
*/
int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
{
int bitbang_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
int rc;
int tries;
int i;
@@ -535,11 +518,10 @@ int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
usleep(20000);
/* TPIDATA is a single line, so MISO & MOSI should be connected */
if (p->flags & AVRPART_HAS_TPI) {
if (p->prog_modes & PM_TPI) {
/* make sure cmd_tpi() is defined */
if (pgm->cmd_tpi == NULL) {
avrdude_message(MSG_INFO, "%s: Error: %s programmer does not support TPI\n",
progname, pgm->type);
pmsg_error("%s programmer does not support TPI\n", pgm->type);
return -1;
}
@@ -550,27 +532,27 @@ int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
/* RESET must be LOW in case the existing code is driving the TPI pins: */
pgm->setpin(pgm, PIN_AVR_RESET, 0);
avrdude_message(MSG_NOTICE2, "doing MOSI-MISO link check\n");
msg_notice2("doing MOSI-MISO link check\n");
pgm->setpin(pgm, PIN_AVR_MOSI, 0);
if (pgm->getpin(pgm, PIN_AVR_MISO) != 0) {
avrdude_message(MSG_INFO, "MOSI->MISO 0 failed\n");
pmsg_error("MOSI->MISO 0 failed\n");
return -1;
}
pgm->setpin(pgm, PIN_AVR_MOSI, 1);
if (pgm->getpin(pgm, PIN_AVR_MISO) != 1) {
avrdude_message(MSG_INFO, "MOSI->MISO 1 failed\n");
pmsg_error("MOSI->MISO 1 failed\n");
return -1;
}
avrdude_message(MSG_NOTICE2, "MOSI-MISO link present\n");
msg_notice2("MOSI-MISO link present\n");
}
pgm->setpin(pgm, PIN_AVR_SCK, 0);
pgm->setpin(pgm, PIN_AVR_RESET, 0);
usleep(20000);
if (p->flags & AVRPART_HAS_TPI) {
if (p->prog_modes & PM_TPI) {
/* keep TPIDATA high for 16 clock cycles */
pgm->setpin(pgm, PIN_AVR_MOSI, 1);
for (i = 0; i < 16; i++)
@@ -584,7 +566,7 @@ int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
bitbang_tpi_tx(pgm, TPI_CMD_SLDCS | TPI_REG_TPIIR);
rc = bitbang_tpi_rx(pgm);
if (rc != 0x80) {
avrdude_message(MSG_INFO, "TPIIR not correct\n");
pmsg_error("TPIIR not correct\n");
return -1;
}
} else {
@@ -618,7 +600,7 @@ int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
* can't sync with the device, maybe it's not attached?
*/
if (rc) {
avrdude_message(MSG_INFO, "%s: AVR device not responding\n", progname);
pmsg_error("AVR device not responding\n");
return -1;
}
}
@@ -626,11 +608,9 @@ int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
return 0;
}
static int verify_pin_assigned(PROGRAMMER * pgm, int pin, char * desc)
{
static int verify_pin_assigned(const PROGRAMMER *pgm, int pin, char *desc) {
if (pgm->pinno[pin] == 0) {
avrdude_message(MSG_INFO, "%s: error: no pin has been assigned for %s\n",
progname, desc);
pmsg_error("no pin has been assigned for %s\n", desc);
return -1;
}
return 0;
@@ -640,8 +620,7 @@ static int verify_pin_assigned(PROGRAMMER * pgm, int pin, char * desc)
/*
* Verify all prerequisites for a bit-bang programmer are present.
*/
int bitbang_check_prerequisites(PROGRAMMER *pgm)
{
int bitbang_check_prerequisites(const PROGRAMMER *pgm) {
if (verify_pin_assigned(pgm, PIN_AVR_RESET, "AVR RESET") < 0)
return -1;
@@ -653,8 +632,7 @@ int bitbang_check_prerequisites(PROGRAMMER *pgm)
return -1;
if (pgm->cmd == NULL) {
avrdude_message(MSG_INFO, "%s: error: no cmd() method defined for bitbang programmer\n",
progname);
pmsg_error("no cmd() method defined for bitbang programmer\n");
return -1;
}
return 0;

View File

@@ -31,25 +31,25 @@ int bitbang_getpin(int fd, int pin);
int bitbang_highpulsepin(int fd, int pin);
void bitbang_delay(unsigned int us);
int bitbang_check_prerequisites(PROGRAMMER *pgm);
int bitbang_check_prerequisites(const PROGRAMMER *pgm);
int bitbang_rdy_led (PROGRAMMER * pgm, int value);
int bitbang_err_led (PROGRAMMER * pgm, int value);
int bitbang_pgm_led (PROGRAMMER * pgm, int value);
int bitbang_vfy_led (PROGRAMMER * pgm, int value);
int bitbang_cmd (PROGRAMMER * pgm, const unsigned char *cmd,
int bitbang_rdy_led (const PROGRAMMER *pgm, int value);
int bitbang_err_led (const PROGRAMMER *pgm, int value);
int bitbang_pgm_led (const PROGRAMMER *pgm, int value);
int bitbang_vfy_led (const PROGRAMMER *pgm, int value);
int bitbang_cmd (const PROGRAMMER *pgm, const unsigned char *cmd,
unsigned char *res);
int bitbang_cmd_tpi (PROGRAMMER * pgm, const unsigned char *cmd,
int bitbang_cmd_tpi (const PROGRAMMER *pgm, const unsigned char *cmd,
int cmd_len, unsigned char *res, int res_len);
int bitbang_spi (PROGRAMMER * pgm, const unsigned char *cmd,
int bitbang_spi (const PROGRAMMER *pgm, const unsigned char *cmd,
unsigned char *res, int count);
int bitbang_chip_erase (PROGRAMMER * pgm, AVRPART * p);
int bitbang_program_enable (PROGRAMMER * pgm, AVRPART * p);
void bitbang_powerup (PROGRAMMER * pgm);
void bitbang_powerdown (PROGRAMMER * pgm);
int bitbang_initialize (PROGRAMMER * pgm, AVRPART * p);
void bitbang_disable (PROGRAMMER * pgm);
void bitbang_enable (PROGRAMMER * pgm);
int bitbang_chip_erase (const PROGRAMMER *pgm, const AVRPART *p);
int bitbang_program_enable (const PROGRAMMER *pgm, const AVRPART *p);
void bitbang_powerup (const PROGRAMMER *pgm);
void bitbang_powerdown (const PROGRAMMER *pgm);
int bitbang_initialize (const PROGRAMMER *pgm, const AVRPART *p);
void bitbang_disable (const PROGRAMMER *pgm);
void bitbang_enable (PROGRAMMER *pgm, const AVRPART *p);
#ifdef __cplusplus
}

View File

@@ -76,68 +76,66 @@ struct pdata
unsigned char pin_dir; /* Last written pin direction for bitbang mode */
unsigned char pin_val; /* Last written pin values for bitbang mode */
int unread_bytes; /* How many bytes we expected, but ignored */
int flag;
};
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
/* ====== Feature checks ====== */
static inline int
buspirate_uses_ascii(struct programmer_t *pgm)
{
return (pgm->flag & BP_FLAG_XPARM_FORCE_ASCII);
buspirate_uses_ascii(const PROGRAMMER *pgm) {
return (PDATA(pgm)->flag & BP_FLAG_XPARM_FORCE_ASCII);
}
/* ====== Serial talker functions - binmode ====== */
static void dump_mem(const int msglvl, const unsigned char *buf, size_t len)
static void dump_mem(const unsigned char *buf, size_t len)
{
size_t i;
for (i = 0; i<len; i++) {
if (i % 8 == 0)
avrdude_message(msglvl, "\t");
avrdude_message(msglvl, "0x%02x ", buf[i]);
msg_debug("\t");
msg_debug("0x%02x ", buf[i]);
if (i % 8 == 3)
avrdude_message(msglvl, " ");
msg_debug(" ");
else if (i % 8 == 7)
avrdude_message(msglvl, "\n");
msg_debug("\n");
}
if (i % 8 != 7)
avrdude_message(msglvl, "\n");
msg_debug("\n");
}
static int buspirate_send_bin(struct programmer_t *pgm, const unsigned char *data, size_t len)
{
static int buspirate_send_bin(const PROGRAMMER *pgm, const unsigned char *data, size_t len) {
int rc;
avrdude_message(MSG_DEBUG, "%s: buspirate_send_bin():\n", progname);
dump_mem(MSG_DEBUG, data, len);
pmsg_debug("buspirate_send_bin():\n");
dump_mem(data, len);
rc = serial_send(&pgm->fd, data, len);
return rc;
}
static int buspirate_recv_bin(struct programmer_t *pgm, unsigned char *buf, size_t len)
{
static int buspirate_recv_bin(const PROGRAMMER *pgm, unsigned char *buf, size_t len) {
int rc;
rc = serial_recv(&pgm->fd, buf, len);
if (rc < 0)
return EOF;
avrdude_message(MSG_DEBUG, "%s: buspirate_recv_bin():\n", progname);
dump_mem(MSG_DEBUG, buf, len);
pmsg_debug("buspirate_recv_bin():\n");
dump_mem(buf, len);
return len;
}
static int buspirate_expect_bin(struct programmer_t *pgm,
static int buspirate_expect_bin(const PROGRAMMER *pgm,
unsigned char *send_data, size_t send_len,
unsigned char *expect_data, size_t expect_len)
{
unsigned char *recv_buf = alloca(expect_len);
if ((pgm->flag & BP_FLAG_IN_BINMODE) == 0) {
avrdude_message(MSG_INFO, "BusPirate: Internal error: buspirate_send_bin() called from ascii mode\n");
if ((PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) == 0) {
pmsg_error("called from ascii mode\n");
return -1;
}
@@ -148,7 +146,7 @@ static int buspirate_expect_bin(struct programmer_t *pgm,
return 1;
}
static int buspirate_expect_bin_byte(struct programmer_t *pgm,
static int buspirate_expect_bin_byte(const PROGRAMMER *pgm,
unsigned char send_byte, unsigned char expect_byte)
{
return buspirate_expect_bin(pgm, &send_byte, 1, &expect_byte, 1);
@@ -156,13 +154,12 @@ static int buspirate_expect_bin_byte(struct programmer_t *pgm,
/* ====== Serial talker functions - ascii mode ====== */
static int buspirate_getc(struct programmer_t *pgm)
{
static int buspirate_getc(const PROGRAMMER *pgm) {
int rc;
unsigned char ch = 0;
if (pgm->flag & BP_FLAG_IN_BINMODE) {
avrdude_message(MSG_INFO, "BusPirate: Internal error: buspirate_getc() called from binmode\n");
if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) {
pmsg_error("called from binmode\n");
return EOF;
}
@@ -172,8 +169,7 @@ static int buspirate_getc(struct programmer_t *pgm)
return ch;
}
static char *buspirate_readline_noexit(struct programmer_t *pgm, char *buf, size_t len)
{
static char *buspirate_readline_noexit(const PROGRAMMER *pgm, char *buf, size_t len) {
char *buf_p;
int c;
long orig_serial_recv_timeout = serial_recv_timeout;
@@ -201,36 +197,31 @@ static char *buspirate_readline_noexit(struct programmer_t *pgm, char *buf, size
serial_recv_timeout = PDATA(pgm)->serial_recv_timeout;
}
serial_recv_timeout = orig_serial_recv_timeout;
avrdude_message(MSG_DEBUG, "%s: buspirate_readline(): %s%s",
progname, buf,
buf[strlen(buf) - 1] == '\n' ? "" : "\n");
pmsg_debug("buspirate_readline(): %s%s", buf, *buf && buf[strlen(buf)-1] == '\n'? "": "\n");
if (! buf[0])
return NULL;
return buf;
}
static char *buspirate_readline(struct programmer_t *pgm, char *buf, size_t len)
{
static char *buspirate_readline(const PROGRAMMER *pgm, char *buf, size_t len) {
char *ret;
ret = buspirate_readline_noexit(pgm, buf, len);
if (! ret) {
avrdude_message(MSG_INFO, "%s: buspirate_readline(): programmer is not responding\n",
progname);
pmsg_error("programmer is not responding\n");
return NULL;
}
return ret;
}
static int buspirate_send(struct programmer_t *pgm, const char *str)
{
static int buspirate_send(const PROGRAMMER *pgm, const char *str) {
int rc;
const char * readline;
avrdude_message(MSG_DEBUG, "%s: buspirate_send(): %s", progname, str);
pmsg_debug("buspirate_send(): %s", str);
if (pgm->flag & BP_FLAG_IN_BINMODE) {
avrdude_message(MSG_INFO, "BusPirate: Internal error: buspirate_send() called from binmode\n");
if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) {
pmsg_error("called from binmode\n");
return -1;
}
@@ -256,7 +247,7 @@ static int buspirate_is_prompt(const char *str)
return (str[strlen_str - 1] == '>' || str[strlen_str - 2] == '>');
}
static int buspirate_expect(struct programmer_t *pgm, char *send,
static int buspirate_expect(const PROGRAMMER *pgm, char *send,
char *expect, int wait_for_prompt)
{
int got_it = 0;
@@ -285,14 +276,12 @@ static int buspirate_expect(struct programmer_t *pgm, char *send,
}
/* ====== Do-nothing functions ====== */
static void buspirate_dummy_6(struct programmer_t *pgm, const char *p)
{
static void buspirate_dummy_6(const PROGRAMMER *pgm, const char *p) {
}
/* ====== Config / parameters handling functions ====== */
static int
buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
{
buspirate_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
LNODEID ln;
const char *extended_param;
char reset[10];
@@ -305,36 +294,35 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
extended_param = ldata(ln);
if (strcmp(extended_param, "ascii") == 0) {
pgm->flag |= BP_FLAG_XPARM_FORCE_ASCII;
PDATA(pgm)->flag |= BP_FLAG_XPARM_FORCE_ASCII;
continue;
}
if (sscanf(extended_param, "spifreq=%u", &spifreq) == 1) {
if (spifreq & (~0x07)) {
avrdude_message(MSG_INFO, "BusPirate: spifreq must be between 0 and 7.\n");
avrdude_message(MSG_INFO, "BusPirate: see BusPirate manual for details.\n");
pmsg_error("spifreq must be between 0 and 7\n");
imsg_error("see BusPirate manual for details\n");
return -1;
}
if (pgm->flag & BP_FLAG_XPARM_RAWFREQ) {
avrdude_message(MSG_INFO, "BusPirate: set either spifreq or rawfreq\n");
if (PDATA(pgm)->flag & BP_FLAG_XPARM_RAWFREQ) {
pmsg_error("set either spifreq or rawfreq\n");
return -1;
}
pgm->flag |= BP_FLAG_XPARM_SPIFREQ;
PDATA(pgm)->flag |= BP_FLAG_XPARM_SPIFREQ;
PDATA(pgm)->spifreq = spifreq;
continue;
}
if (sscanf(extended_param, "rawfreq=%u", &rawfreq) == 1) {
if (rawfreq >= 4) {
avrdude_message(MSG_INFO, "BusPirate: rawfreq must be "
"between 0 and 3.\n");
pmsg_error("rawfreq must be between 0 and 3\n");
return -1;
}
if (pgm->flag & BP_FLAG_XPARM_SPIFREQ) {
avrdude_message(MSG_INFO, "BusPirate: set either spifreq or rawfreq\n");
if (PDATA(pgm)->flag & BP_FLAG_XPARM_SPIFREQ) {
pmsg_error("set either spifreq or rawfreq\n");
return -1;
}
pgm->flag |= BP_FLAG_XPARM_RAWFREQ;
PDATA(pgm)->flag |= BP_FLAG_XPARM_RAWFREQ;
PDATA(pgm)->spifreq = rawfreq;
continue;
}
@@ -342,12 +330,12 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
if (sscanf(extended_param, "cpufreq=%u", &cpufreq) == 1) {
/* lower limit comes from 'cpufreq > 4 * spifreq', spifreq in ascii mode is 30kHz. */
if (cpufreq < 125 || cpufreq > 4000) {
avrdude_message(MSG_INFO, "BusPirate: cpufreq must be between 125 and 4000 kHz.\n");
avrdude_message(MSG_INFO, "BusPirate: see BusPirate manual for details.\n");
pmsg_error("cpufreq must be between 125 and 4000 kHz\n");
imsg_error("see BusPirate manual for details\n");
return -1;
}
PDATA(pgm)->cpufreq = cpufreq;
pgm->flag |= BP_FLAG_XPARM_CPUFREQ;
PDATA(pgm)->flag |= BP_FLAG_XPARM_CPUFREQ;
continue;
}
@@ -362,34 +350,34 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
else if (strcasecmp(resetpin, "aux2") == 0)
PDATA(pgm)->reset |= BP_RESET_AUX2;
else {
avrdude_message(MSG_INFO, "BusPirate: reset must be either CS or AUX.\n");
pmsg_error("reset must be either CS or AUX\n");
return -1;
}
}
pgm->flag |= BP_FLAG_XPARM_RESET;
PDATA(pgm)->flag |= BP_FLAG_XPARM_RESET;
continue;
}
if (strcmp(extended_param, "nopagedwrite") == 0) {
pgm->flag |= BP_FLAG_NOPAGEDWRITE;
PDATA(pgm)->flag |= BP_FLAG_NOPAGEDWRITE;
continue;
}
if (strcmp(extended_param, "nopagedread") == 0) {
pgm->flag |= BP_FLAG_NOPAGEDREAD;
PDATA(pgm)->flag |= BP_FLAG_NOPAGEDREAD;
continue;
}
if (sscanf(extended_param, "serial_recv_timeout=%d", &serial_recv_timeout) == 1) {
if (serial_recv_timeout < 1) {
avrdude_message(MSG_INFO, "BusPirate: serial_recv_timeout must be greater 0.\n");
pmsg_error("serial_recv_timeout must be greater 0\n");
return -1;
}
PDATA(pgm)->serial_recv_timeout = serial_recv_timeout;
continue;
}
avrdude_message(MSG_INFO, "BusPirate: do not understand extended param '%s'.\n", extended_param);
pmsg_error("do not understand extended param '%s'\n", extended_param);
return -1;
}
@@ -397,20 +385,19 @@ buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
}
static int
buspirate_verifyconfig(struct programmer_t *pgm)
{
buspirate_verifyconfig(const PROGRAMMER *pgm) {
/* Default reset pin is CS */
if (PDATA(pgm)->reset == 0x00)
PDATA(pgm)->reset |= BP_RESET_CS;
if ((PDATA(pgm)->reset != BP_RESET_CS) && buspirate_uses_ascii(pgm)) {
avrdude_message(MSG_INFO, "BusPirate: RESET pin other than CS is not supported in ASCII mode\n");
pmsg_error("RESET pin other than CS is not supported in ASCII mode\n");
return -1;
}
if ( ((pgm->flag & BP_FLAG_XPARM_SPIFREQ) || (pgm->flag & BP_FLAG_XPARM_RAWFREQ))
if ( ((PDATA(pgm)->flag & BP_FLAG_XPARM_SPIFREQ) || (PDATA(pgm)->flag & BP_FLAG_XPARM_RAWFREQ))
&& buspirate_uses_ascii(pgm)) {
avrdude_message(MSG_INFO, "BusPirate: SPI speed selection is not supported in ASCII mode\n");
pmsg_error("SPI speed selection is not supported in ASCII mode\n");
return -1;
}
@@ -418,8 +405,7 @@ buspirate_verifyconfig(struct programmer_t *pgm)
}
/* ====== Programmer methods ======= */
static int buspirate_open(struct programmer_t *pgm, char * port)
{
static int buspirate_open(PROGRAMMER *pgm, const char *port) {
union pinfo pinfo;
/* BusPirate runs at 115200 by default */
if(pgm->baudrate == 0)
@@ -438,30 +424,29 @@ static int buspirate_open(struct programmer_t *pgm, char * port)
return 0;
}
static void buspirate_close(struct programmer_t *pgm)
static void buspirate_close(PROGRAMMER *pgm)
{
serial_close(&pgm->fd);
pgm->fd.ifd = -1;
}
static void buspirate_reset_from_binmode(struct programmer_t *pgm)
{
static void buspirate_reset_from_binmode(const PROGRAMMER *pgm) {
unsigned char buf[10];
buf[0] = 0x00; /* BinMode: revert to raw bitbang mode */
buspirate_send_bin(pgm, buf, 1);
buspirate_recv_bin(pgm, buf, 5);
if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) {
if (PDATA(pgm)->flag & BP_FLAG_XPARM_CPUFREQ) {
/* disable pwm */
if (buspirate_expect_bin_byte(pgm, 0x13, 0x01) != 1) {
avrdude_message(MSG_INFO, "%s: warning: did not get a response to stop PWM command.\n", progname);
pmsg_error("did not get a response to stop PWM command\n");
}
}
/* 0b0100wxyz - Configure peripherals w=power, x=pull-ups, y=AUX, z=CS
* we want everything off -- 0b01000000 = 0x40 */
if (buspirate_expect_bin_byte(pgm, 0x40, 0x00) == 1) {
avrdude_message(MSG_INFO, "%s: warning: did not get a response to power off command.\n", progname);
pmsg_error("did not get a response to power off command\n");
}
buf[0] = 0x0F; /* BinMode: reset */
@@ -474,7 +459,7 @@ static void buspirate_reset_from_binmode(struct programmer_t *pgm)
rc = buspirate_recv_bin(pgm, buf, sizeof(buf) - 1);
if (buspirate_is_prompt((const char*)buf)) {
pgm->flag &= ~BP_FLAG_IN_BINMODE;
PDATA(pgm)->flag &= ~BP_FLAG_IN_BINMODE;
break;
}
if (rc == EOF)
@@ -482,15 +467,15 @@ static void buspirate_reset_from_binmode(struct programmer_t *pgm)
memset(buf, '\0', sizeof(buf));
}
if (pgm->flag & BP_FLAG_IN_BINMODE) {
avrdude_message(MSG_INFO, "BusPirate reset failed. You may need to powercycle it.\n");
if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) {
pmsg_error("reset failed; you may need to powercycle it\n");
return;
}
avrdude_message(MSG_NOTICE, "BusPirate is back in the text mode\n");
msg_notice("BusPirate is back in text mode\n");
}
static int buspirate_start_mode_bin(struct programmer_t *pgm)
static int buspirate_start_mode_bin(PROGRAMMER *pgm)
{
struct submode {
const char *name; /* Name of mode for user messages */
@@ -499,13 +484,13 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
char config; /* Command to setup submode parameters */
} submode;
if (pgm->flag & BP_FLAG_XPARM_RAWFREQ) {
if (PDATA(pgm)->flag & BP_FLAG_XPARM_RAWFREQ) {
submode.name = "Raw-wire";
submode.enter = 0x05;
submode.entered_format = "RAW%1d";
submode.config = 0x8C;
pgm->flag |= BP_FLAG_NOPAGEDWRITE;
pgm->flag |= BP_FLAG_NOPAGEDREAD;
PDATA(pgm)->flag |= BP_FLAG_NOPAGEDWRITE;
PDATA(pgm)->flag |= BP_FLAG_NOPAGEDREAD;
} else {
submode.name = "SPI";
submode.enter = 0x01;
@@ -528,24 +513,24 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
memset(buf, 0, sizeof(buf));
buspirate_recv_bin(pgm, buf, 5);
if (sscanf((const char*)buf, "BBIO%1d", &PDATA(pgm)->binmode_version) != 1) {
avrdude_message(MSG_INFO, "Binary mode not confirmed: '%s'\n", buf);
pmsg_error("binary mode not confirmed: '%s'\n", buf);
buspirate_reset_from_binmode(pgm);
return -1;
}
avrdude_message(MSG_NOTICE, "BusPirate binmode version: %d\n",
msg_notice("BusPirate binmode version: %d\n",
PDATA(pgm)->binmode_version);
pgm->flag |= BP_FLAG_IN_BINMODE;
PDATA(pgm)->flag |= BP_FLAG_IN_BINMODE;
if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) {
if (PDATA(pgm)->flag & BP_FLAG_XPARM_CPUFREQ) {
unsigned short pwm_duty;
unsigned short pwm_period;
pwm_period = 16000/(PDATA(pgm)->cpufreq) - 1; // oscillator runs at 32MHz, we don't use a prescaler
pwm_duty = pwm_period/2; // 50% duty cycle
avrdude_message(MSG_NOTICE, "Setting up PWM for cpufreq\n");
avrdude_message(MSG_DEBUG, "PWM settings: Prescaler=1, Duty Cycle=%hd, Period=%hd\n", pwm_duty, pwm_period);
msg_notice("setting up PWM for cpufreq\n");
msg_debug("PWM settings: Prescaler=1, Duty Cycle=%hd, Period=%hd\n", pwm_duty, pwm_period);
buf[0] = 0x12; // pwm setup
buf[1] = 0; // prescaler 1
@@ -557,7 +542,7 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
buspirate_recv_bin(pgm, buf, 1);
if (buf[0] != 0x01)
avrdude_message(MSG_INFO, "cpufreq (PWM) setup failed\n");
pmsg_error("cpufreq (PWM) setup failed\n");
}
/* == Set protocol sub-mode of binary mode == */
@@ -566,16 +551,14 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
memset(buf, 0, sizeof(buf));
buspirate_recv_bin(pgm, buf, 4);
if (sscanf((const char*)buf, submode.entered_format, &PDATA(pgm)->submode_version) != 1) {
avrdude_message(MSG_INFO, "%s mode not confirmed: '%s'\n",
submode.name, buf);
pmsg_error("%s mode not confirmed: '%s'\n", submode.name, buf);
buspirate_reset_from_binmode(pgm);
return -1;
}
avrdude_message(MSG_NOTICE, "BusPirate %s version: %d\n",
submode.name, PDATA(pgm)->submode_version);
if (pgm->flag & BP_FLAG_NOPAGEDWRITE) {
avrdude_message(MSG_NOTICE, "%s: Paged flash write disabled.\n", progname);
msg_notice("BusPirate %s version: %d\n",
submode.name, PDATA(pgm)->submode_version);
if (PDATA(pgm)->flag & BP_FLAG_NOPAGEDWRITE) {
pmsg_notice("paged flash write disabled\n");
pgm->paged_write = NULL;
} else {
/* Check for write-then-read without !CS/CS and disable paged_write if absent: */
@@ -583,21 +566,20 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
buspirate_send_bin(pgm, buf2, sizeof(buf2));
buspirate_recv_bin(pgm, buf, 1);
if (buf[0] != 0x01) {
/* Disable paged write: */
pgm->flag |= BP_FLAG_NOPAGEDWRITE;
PDATA(pgm)->flag |= BP_FLAG_NOPAGEDWRITE;
pgm->paged_write = NULL;
/* Return to SPI mode (0x00s have landed us back in binary bitbang mode): */
buf[0] = 0x1;
buspirate_send_bin(pgm, buf, 1);
avrdude_message(MSG_NOTICE, "%s: Disabling paged flash write. (Need BusPirate firmware >=v5.10.)\n", progname);
pmsg_notice("disabling paged flash write (need BusPirate firmware >= v5.10)\n");
/* Flush serial buffer: */
serial_drain(&pgm->fd, 0);
} else {
avrdude_message(MSG_INFO, "%s: Paged flash write enabled.\n", progname);
pmsg_info("paged flash write enabled\n");
}
}
@@ -617,8 +599,8 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
return -1;
/* AVR Extended Commands - test for existence */
if (pgm->flag & BP_FLAG_NOPAGEDREAD) {
avrdude_message(MSG_NOTICE, "%s: Paged flash read disabled.\n", progname);
if (PDATA(pgm)->flag & BP_FLAG_NOPAGEDREAD) {
pmsg_notice("paged flash read disabled\n");
pgm->paged_load = NULL;
} else {
int rv = buspirate_expect_bin_byte(pgm, 0x06, 0x01);
@@ -630,10 +612,10 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
buspirate_send_bin(pgm, buf2, sizeof(buf2));
buspirate_recv_bin(pgm, buf, 3);
ver = buf[1] << 8 | buf[2];
avrdude_message(MSG_NOTICE, "AVR Extended Commands version %d\n", ver);
msg_notice("AVR Extended Commands version %d\n", ver);
} else {
avrdude_message(MSG_NOTICE, "AVR Extended Commands not found.\n");
pgm->flag |= BP_FLAG_NOPAGEDREAD;
msg_notice("AVR Extended Commands not found\n");
PDATA(pgm)->flag |= BP_FLAG_NOPAGEDREAD;
pgm->paged_load = NULL;
}
}
@@ -641,8 +623,7 @@ static int buspirate_start_mode_bin(struct programmer_t *pgm)
return 0;
}
static int buspirate_start_spi_mode_ascii(struct programmer_t *pgm)
{
static int buspirate_start_spi_mode_ascii(const PROGRAMMER *pgm) {
int spi_cmd = -1;
int cmd;
char *rcvd;
@@ -663,10 +644,8 @@ static int buspirate_start_spi_mode_ascii(struct programmer_t *pgm)
break;
}
if (spi_cmd == -1) {
avrdude_message(MSG_INFO, "%s: SPI mode number not found. Does your BusPirate support SPI?\n",
progname);
avrdude_message(MSG_INFO, "%s: Try powercycling your BusPirate and try again.\n",
progname);
pmsg_error("SPI mode number not found; does your BusPirate support SPI?\n");
imsg_error("try powercycling your BusPirate and try again\n");
return -1;
}
snprintf(buf, sizeof(buf), "%d\n", spi_cmd);
@@ -686,7 +665,7 @@ static int buspirate_start_spi_mode_ascii(struct programmer_t *pgm)
}
if (buspirate_is_prompt(rcvd)) {
if (strncmp(rcvd, "SPI>", 4) == 0) {
avrdude_message(MSG_INFO, "BusPirate is now configured for SPI\n");
msg_info("BusPirate is now configured for SPI\n");
break;
}
/* Not yet 'SPI>' prompt */
@@ -700,8 +679,7 @@ static int buspirate_start_spi_mode_ascii(struct programmer_t *pgm)
return 0;
}
static void buspirate_enable(struct programmer_t *pgm)
{
static void buspirate_enable(PROGRAMMER *pgm, const AVRPART *p) {
static const char *reset_str = "#\n";
static const char *accept_str = "y\n";
char *rcvd;
@@ -713,7 +691,7 @@ static void buspirate_enable(struct programmer_t *pgm)
/* Attempt to start binary SPI mode unless explicitly told otherwise: */
if (!buspirate_uses_ascii(pgm)) {
avrdude_message(MSG_INFO, "Attempting to initiate BusPirate binary mode...\n");
msg_info("attempting to initiate BusPirate binary mode ...\n");
/* Send two CRs to ensure we're not in a sub-menu of the UI if we're in ASCII mode: */
buspirate_send_bin(pgm, (const unsigned char*)"\n\n", 2);
@@ -725,23 +703,23 @@ static void buspirate_enable(struct programmer_t *pgm)
if (buspirate_start_mode_bin(pgm) >= 0)
return;
else
avrdude_message(MSG_INFO, "%s: Failed to start binary mode, falling back to ASCII...\n", progname);
pmsg_info("unable to start binary mode, falling back to ASCII ...\n");
}
avrdude_message(MSG_INFO, "Attempting to initiate BusPirate ASCII mode...\n");
msg_info("attempting to initiate BusPirate ASCII mode ...\n");
/* Call buspirate_send_bin() instead of buspirate_send()
* because we don't know if BP is in text or bin mode */
rc = buspirate_send_bin(pgm, (const unsigned char*)reset_str, strlen(reset_str));
if (rc) {
avrdude_message(MSG_INFO, "BusPirate is not responding. Serial port error: %d\n", rc);
pmsg_error("BusPirate is not responding; serial port error code %d\n", rc);
return;
}
while(1) {
rcvd = buspirate_readline_noexit(pgm, NULL, 0);
if (! rcvd) {
avrdude_message(MSG_INFO, "%s: Fatal: Programmer is not responding.\n", progname);
pmsg_error("programmer is not responding\n");
return;
}
if (strncmp(rcvd, "Are you sure?", 13) == 0) {
@@ -752,25 +730,24 @@ static void buspirate_enable(struct programmer_t *pgm)
continue;
}
if (buspirate_is_prompt(rcvd)) {
avrdude_message(MSG_DEBUG, "**\n");
msg_debug("**\n");
break;
}
if (print_banner)
avrdude_message(MSG_DEBUG, "** %s", rcvd);
msg_debug("** %s", rcvd);
}
if (!(pgm->flag & BP_FLAG_IN_BINMODE)) {
avrdude_message(MSG_INFO, "BusPirate: using ASCII mode\n");
if (!(PDATA(pgm)->flag & BP_FLAG_IN_BINMODE)) {
msg_info("using ASCII mode\n");
if (buspirate_start_spi_mode_ascii(pgm) < 0) {
avrdude_message(MSG_INFO, "%s: Failed to start ascii SPI mode\n", progname);
pmsg_error("unable to start ascii SPI mode\n");
return;
}
}
}
static void buspirate_disable(struct programmer_t *pgm)
{
if (pgm->flag & BP_FLAG_IN_BINMODE) {
static void buspirate_disable(const PROGRAMMER *pgm) {
if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) {
serial_recv_timeout = 100;
buspirate_reset_from_binmode(pgm);
} else {
@@ -778,21 +755,19 @@ static void buspirate_disable(struct programmer_t *pgm)
}
}
static int buspirate_initialize(struct programmer_t *pgm, AVRPART * p)
{
static int buspirate_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
pgm->powerup(pgm);
return pgm->program_enable(pgm, p);
}
static void buspirate_powerup(struct programmer_t *pgm)
{
if (pgm->flag & BP_FLAG_IN_BINMODE) {
static void buspirate_powerup(const PROGRAMMER *pgm) {
if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) {
/* Powerup in BinMode is handled in binary mode init */
return;
} else {
if (buspirate_expect(pgm, "W\n", "POWER SUPPLIES ON", 1)) {
if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) {
if (PDATA(pgm)->flag & BP_FLAG_XPARM_CPUFREQ) {
char buf[25];
int ok = 0;
snprintf(buf, sizeof(buf), "%d\n", PDATA(pgm)->cpufreq);
@@ -804,36 +779,35 @@ static void buspirate_powerup(struct programmer_t *pgm)
}
}
if(!ok) {
avrdude_message(MSG_INFO, "%s: warning: did not get a response to start PWM command.\n", progname);
pmsg_error("did not get a response to start PWM command\n");
}
}
return;
}
}
avrdude_message(MSG_INFO, "%s: warning: did not get a response to PowerUp command.\n", progname);
avrdude_message(MSG_INFO, "%s: warning: Trying to continue anyway...\n", progname);
pmsg_warning("did not get a response to PowerUp command\n");
imsg_warning("trying to continue anyway ...\n");
}
static void buspirate_powerdown(struct programmer_t *pgm)
{
if (pgm->flag & BP_FLAG_IN_BINMODE) {
static void buspirate_powerdown(const PROGRAMMER *pgm) {
if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) {
/* Powerdown in BinMode is handled in binary mode init */
return;
} else {
if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) {
if (PDATA(pgm)->flag & BP_FLAG_XPARM_CPUFREQ) {
if (!buspirate_expect(pgm, "g\n", "PWM disabled", 1)) {
avrdude_message(MSG_INFO, "%s: warning: did not get a response to stop PWM command.\n", progname);
pmsg_error("did not get a response to stop PWM command\n");
}
}
if (buspirate_expect(pgm, "w\n", "POWER SUPPLIES OFF", 1))
return;
}
avrdude_message(MSG_INFO, "%s: warning: did not get a response to PowerDown command.\n", progname);
pmsg_error("did not get a response to PowerDown command\n");
}
static int buspirate_cmd_bin(struct programmer_t *pgm,
static int buspirate_cmd_bin(const PROGRAMMER *pgm,
const unsigned char *cmd,
unsigned char *res)
{
@@ -851,7 +825,7 @@ static int buspirate_cmd_bin(struct programmer_t *pgm,
return 0;
}
static int buspirate_cmd_ascii(struct programmer_t *pgm,
static int buspirate_cmd_ascii(const PROGRAMMER *pgm,
const unsigned char *cmd,
unsigned char *res)
{
@@ -877,7 +851,7 @@ static int buspirate_cmd_ascii(struct programmer_t *pgm,
}
if (i != 4) {
avrdude_message(MSG_INFO, "%s: error: SPI has not read 4 bytes back\n", progname);
pmsg_error("SPI has not read 4 bytes back\n");
return -1;
}
@@ -888,34 +862,29 @@ static int buspirate_cmd_ascii(struct programmer_t *pgm,
return 0;
}
static int buspirate_cmd(struct programmer_t *pgm,
static int buspirate_cmd(const PROGRAMMER *pgm,
const unsigned char *cmd,
unsigned char *res)
{
if (pgm->flag & BP_FLAG_IN_BINMODE)
if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE)
return buspirate_cmd_bin(pgm, cmd, res);
else
return buspirate_cmd_ascii(pgm, cmd, res);
}
/* Paged load function which utilizes the AVR Extended Commands set */
static int buspirate_paged_load(
PROGRAMMER *pgm,
AVRPART *p,
AVRMEM *m,
unsigned int page_size,
unsigned int address,
unsigned int n_bytes)
{
static int buspirate_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size, unsigned int address, unsigned int n_bytes) {
unsigned char commandbuf[10];
unsigned char buf[275];
unsigned int addr = 0;
avrdude_message(MSG_NOTICE, "BusPirate: buspirate_paged_load(..,%s,%d,%d,%d)\n",m->desc,m->page_size,address,n_bytes);
msg_notice("buspirate_paged_load(..,%s,%d,%d,%d)\n",m->desc,m->page_size,address,n_bytes);
// This should never happen, but still...
if (pgm->flag & BP_FLAG_NOPAGEDREAD) {
avrdude_message(MSG_INFO, "BusPirate: buspirate_paged_load() called while in nopagedread mode!\n");
// This should never happen, but still ...
if (PDATA(pgm)->flag & BP_FLAG_NOPAGEDREAD) {
pmsg_error("called while in nopagedread mode\n");
return -1;
}
@@ -945,7 +914,7 @@ static int buspirate_paged_load(
buspirate_recv_bin(pgm, buf, 1);
if (buf[0] != 0x01) {
avrdude_message(MSG_INFO, "BusPirate: Paged Read command returned zero.\n");
pmsg_error("Paged Read command returned zero\n");
return -1;
}
@@ -956,13 +925,9 @@ static int buspirate_paged_load(
return n_bytes;
}
/* Paged write function which utilizes the Bus Pirate's "Write then Read" binary SPI instruction */
static int buspirate_paged_write(struct programmer_t *pgm,
AVRPART *p,
AVRMEM *m,
unsigned int page_size,
unsigned int base_addr,
unsigned int n_data_bytes)
{
static int buspirate_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size, unsigned int base_addr, unsigned int n_data_bytes) {
int page, i;
int addr = base_addr;
int n_page_writes;
@@ -970,12 +935,12 @@ static int buspirate_paged_write(struct programmer_t *pgm,
unsigned char cmd_buf[4096] = {'\0'};
unsigned char send_byte, recv_byte;
if (!(pgm->flag & BP_FLAG_IN_BINMODE)) {
if (!(PDATA(pgm)->flag & BP_FLAG_IN_BINMODE)) {
/* Return if we are not in binary mode. */
return -1;
}
if (pgm->flag & BP_FLAG_NOPAGEDWRITE) {
if (PDATA(pgm)->flag & BP_FLAG_NOPAGEDWRITE) {
/* Return if we've nominated not to use paged writes. */
return -1;
}
@@ -992,13 +957,11 @@ static int buspirate_paged_write(struct programmer_t *pgm,
/* pre-check opcodes */
if (m->op[AVR_OP_LOADPAGE_LO] == NULL) {
avrdude_message(MSG_INFO, "%s failure: %s command not defined for %s\n",
progname, "AVR_OP_LOADPAGE_LO", p->desc);
pmsg_error("AVR_OP_LOADPAGE_LO command not defined for %s\n", p->desc);
return -1;
}
if (m->op[AVR_OP_LOADPAGE_HI] == NULL) {
avrdude_message(MSG_INFO, "%s failure: %s command not defined for %s\n",
progname, "AVR_OP_LOADPAGE_HI", p->desc);
pmsg_error("AVR_OP_LOADPAGE_HI command not defined for %s\n", p->desc);
return -1;
}
@@ -1058,7 +1021,7 @@ static int buspirate_paged_write(struct programmer_t *pgm,
/* Check for write failure: */
if ((buspirate_recv_bin(pgm, &recv_byte, 1) == EOF) || (recv_byte != 0x01)) {
avrdude_message(MSG_INFO, "BusPirate: Fatal error: Write Then Read did not succeed.\n");
pmsg_error("write then read did not succeed\n");
pgm->pgm_led(pgm, OFF);
pgm->err_led(pgm, ON);
return -1;
@@ -1074,12 +1037,11 @@ static int buspirate_paged_write(struct programmer_t *pgm,
return n_data_bytes;
}
static int buspirate_program_enable(struct programmer_t *pgm, AVRPART * p)
{
static int buspirate_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char cmd[4];
unsigned char res[4];
if (pgm->flag & BP_FLAG_IN_BINMODE) {
if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) {
/* Clear configured reset pin(s): CS and/or AUX and/or AUX2 */
PDATA(pgm)->current_peripherals_config &= ~PDATA(pgm)->reset;
if (buspirate_expect_bin_byte(pgm, PDATA(pgm)->current_peripherals_config, 0x01) < 0)
@@ -1089,8 +1051,7 @@ static int buspirate_program_enable(struct programmer_t *pgm, AVRPART * p)
buspirate_expect(pgm, "{\n", "CS ENABLED", 1);
if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
avrdude_message(MSG_INFO, "program enable instruction not defined for part \"%s\"\n",
p->desc);
pmsg_error("program enable instruction not defined for part %s\n", p->desc);
return -1;
}
@@ -1104,14 +1065,12 @@ static int buspirate_program_enable(struct programmer_t *pgm, AVRPART * p)
return 0;
}
static int buspirate_chip_erase(struct programmer_t *pgm, AVRPART * p)
{
static int buspirate_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char cmd[4];
unsigned char res[4];
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
avrdude_message(MSG_INFO, "chip erase instruction not defined for part \"%s\"\n",
p->desc);
pmsg_error("chip erase instruction not defined for part %s\n", p->desc);
return -1;
}
@@ -1130,25 +1089,23 @@ static int buspirate_chip_erase(struct programmer_t *pgm, AVRPART * p)
}
/* Interface - management */
static void buspirate_setup(struct programmer_t *pgm)
static void buspirate_setup(PROGRAMMER *pgm)
{
/* Allocate private data */
if ((pgm->cookie = calloc(1, sizeof(struct pdata))) == 0) {
avrdude_message(MSG_INFO, "%s: buspirate_initpgm(): Out of memory allocating private data\n",
progname);
pmsg_error("out of memory allocating private data\n");
exit(1);
}
PDATA(pgm)->serial_recv_timeout = 100;
}
static void buspirate_teardown(struct programmer_t *pgm)
static void buspirate_teardown(PROGRAMMER *pgm)
{
free(pgm->cookie);
}
const char buspirate_desc[] = "Using the Bus Pirate's SPI interface for programming";
void buspirate_initpgm(struct programmer_t *pgm)
{
void buspirate_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "BusPirate");
pgm->display = buspirate_dummy_6;
@@ -1181,14 +1138,13 @@ void buspirate_initpgm(struct programmer_t *pgm)
/* Bitbang support */
static void buspirate_bb_enable(struct programmer_t *pgm)
{
static void buspirate_bb_enable(PROGRAMMER *pgm, const AVRPART *p) {
unsigned char buf[20] = { '\0' };
if (bitbang_check_prerequisites(pgm) < 0)
return; /* XXX should treat as error */
avrdude_message(MSG_INFO, "Attempting to initiate BusPirate bitbang binary mode...\n");
pmsg_error("attempting to initiate BusPirate bitbang binary mode ...\n");
/* Send two CRs to ensure we're not in a sub-menu of the UI if we're in ASCII mode: */
buspirate_send_bin(pgm, (const unsigned char*)"\n\n", 2);
@@ -1203,14 +1159,13 @@ static void buspirate_bb_enable(struct programmer_t *pgm)
memset(buf, 0, sizeof(buf));
buspirate_recv_bin(pgm, buf, 5);
if (sscanf((char*)buf, "BBIO%1d", &PDATA(pgm)->binmode_version) != 1) {
avrdude_message(MSG_INFO, "Binary mode not confirmed: '%s'\n", buf);
pmsg_error("binary mode not confirmed: '%s'\n", buf);
buspirate_reset_from_binmode(pgm);
return;
}
avrdude_message(MSG_INFO, "BusPirate binmode version: %d\n",
PDATA(pgm)->binmode_version);
msg_info("BusPirate binmode version: %d\n", PDATA(pgm)->binmode_version);
pgm->flag |= BP_FLAG_IN_BINMODE;
PDATA(pgm)->flag |= BP_FLAG_IN_BINMODE;
/* Set pin directions and an initial pin status (all high) */
PDATA(pgm)->pin_dir = 0x12; /* AUX, MISO input; everything else output */
@@ -1241,8 +1196,7 @@ static void buspirate_bb_enable(struct programmer_t *pgm)
Both respond with a byte with current status:
0|POWER|PULLUP|AUX|MOSI|CLK|MISO|CS
*/
static int buspirate_bb_getpin(struct programmer_t *pgm, int pinfunc)
{
static int buspirate_bb_getpin(const PROGRAMMER *pgm, int pinfunc) {
unsigned char buf[10];
int value = 0;
int pin = pgm->pinno[pinfunc];
@@ -1272,13 +1226,12 @@ static int buspirate_bb_getpin(struct programmer_t *pgm, int pinfunc)
if (buf[0] & (1 << (pin - 1)))
value ^= 1;
avrdude_message(MSG_DEBUG, "get pin %d = %d\n", pin, value);
msg_debug("get pin %d = %d\n", pin, value);
return value;
}
static int buspirate_bb_setpin_internal(struct programmer_t *pgm, int pin, int value)
{
static int buspirate_bb_setpin_internal(const PROGRAMMER *pgm, int pin, int value) {
unsigned char buf[10];
if (pin & PIN_INVERSE) {
@@ -1289,7 +1242,7 @@ static int buspirate_bb_setpin_internal(struct programmer_t *pgm, int pin, int v
if ((pin < 1 || pin > 5) && (pin != 7)) // 7 is POWER
return -1;
avrdude_message(MSG_DEBUG, "set pin %d = %d\n", pin, value);
msg_debug("set pin %d = %d\n", pin, value);
if (value)
PDATA(pgm)->pin_val |= (1 << (pin - 1));
@@ -1307,14 +1260,12 @@ static int buspirate_bb_setpin_internal(struct programmer_t *pgm, int pin, int v
return 0;
}
static int buspirate_bb_setpin(struct programmer_t *pgm, int pinfunc, int value)
{
static int buspirate_bb_setpin(const PROGRAMMER *pgm, int pinfunc, int value) {
return buspirate_bb_setpin_internal(pgm, pgm->pinno[pinfunc], value);
}
static int buspirate_bb_highpulsepin(struct programmer_t *pgm, int pinfunc)
{
static int buspirate_bb_highpulsepin(const PROGRAMMER *pgm, int pinfunc) {
int ret;
ret = buspirate_bb_setpin(pgm, pinfunc, 1);
if (ret < 0)
@@ -1322,20 +1273,17 @@ static int buspirate_bb_highpulsepin(struct programmer_t *pgm, int pinfunc)
return buspirate_bb_setpin(pgm, pinfunc, 0);
}
static void buspirate_bb_powerup(struct programmer_t *pgm)
{
static void buspirate_bb_powerup(const PROGRAMMER *pgm) {
buspirate_bb_setpin_internal(pgm, 7, 1);
}
static void buspirate_bb_powerdown(struct programmer_t *pgm)
{
static void buspirate_bb_powerdown(const PROGRAMMER *pgm) {
buspirate_bb_setpin_internal(pgm, 7, 0);
}
const char buspirate_bb_desc[] = "Using the Bus Pirate's bitbang interface for programming";
void buspirate_bb_initpgm(struct programmer_t *pgm)
{
void buspirate_bb_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "BusPirate_BB");
pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed

View File

@@ -26,7 +26,7 @@
extern const char buspirate_desc[];
extern const char buspirate_bb_desc[];
void buspirate_initpgm (struct programmer_t *pgm);
void buspirate_bb_initpgm (struct programmer_t *pgm);
void buspirate_initpgm(PROGRAMMER *pgm);
void buspirate_bb_initpgm(PROGRAMMER *pgm);
#endif

View File

@@ -63,8 +63,7 @@ struct pdata
static void butterfly_setup(PROGRAMMER * pgm)
{
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
avrdude_message(MSG_INFO, "%s: butterfly_setup(): Out of memory allocating private data\n",
progname);
pmsg_error("out of memory allocating private data\n");
exit(1);
}
memset(pgm->cookie, 0, sizeof(struct pdata));
@@ -75,72 +74,62 @@ static void butterfly_teardown(PROGRAMMER * pgm)
free(pgm->cookie);
}
static int butterfly_send(PROGRAMMER * pgm, char * buf, size_t len)
{
static int butterfly_send(const PROGRAMMER *pgm, char *buf, size_t len) {
return serial_send(&pgm->fd, (unsigned char *)buf, len);
}
static int butterfly_recv(PROGRAMMER * pgm, char * buf, size_t len)
{
static int butterfly_recv(const PROGRAMMER *pgm, char *buf, size_t len) {
int rv;
rv = serial_recv(&pgm->fd, (unsigned char *)buf, len);
if (rv < 0) {
avrdude_message(MSG_INFO, "%s: butterfly_recv(): programmer is not responding\n",
progname);
pmsg_error("programmer is not responding\n");
return -1;
}
return 0;
}
static int butterfly_drain(PROGRAMMER * pgm, int display)
{
static int butterfly_drain(const PROGRAMMER *pgm, int display) {
return serial_drain(&pgm->fd, display);
}
static int butterfly_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
{
static int butterfly_vfy_cmd_sent(const PROGRAMMER *pgm, char *errmsg) {
char c;
butterfly_recv(pgm, &c, 1);
if (c != '\r') {
avrdude_message(MSG_INFO, "%s: error: programmer did not respond to command: %s\n",
progname, errmsg);
pmsg_error("programmer did not respond to command: %s\n", errmsg);
return -1;
}
return 0;
}
static int butterfly_rdy_led(PROGRAMMER * pgm, int value)
{
static int butterfly_rdy_led(const PROGRAMMER *pgm, int value) {
/* Do nothing. */
return 0;
}
static int butterfly_err_led(PROGRAMMER * pgm, int value)
{
static int butterfly_err_led(const PROGRAMMER *pgm, int value) {
/* Do nothing. */
return 0;
}
static int butterfly_pgm_led(PROGRAMMER * pgm, int value)
{
static int butterfly_pgm_led(const PROGRAMMER *pgm, int value) {
/* Do nothing. */
return 0;
}
static int butterfly_vfy_led(PROGRAMMER * pgm, int value)
{
static int butterfly_vfy_led(const PROGRAMMER *pgm, int value) {
/* Do nothing. */
return 0;
@@ -150,8 +139,7 @@ static int butterfly_vfy_led(PROGRAMMER * pgm, int value)
/*
* issue the 'chip erase' command to the butterfly board
*/
static int butterfly_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
static int butterfly_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
butterfly_send(pgm, "e", 1);
if (butterfly_vfy_cmd_sent(pgm, "chip erase") < 0)
return -1;
@@ -160,15 +148,13 @@ static int butterfly_chip_erase(PROGRAMMER * pgm, AVRPART * p)
}
static void butterfly_enter_prog_mode(PROGRAMMER * pgm)
{
static void butterfly_enter_prog_mode(const PROGRAMMER *pgm) {
butterfly_send(pgm, "P", 1);
butterfly_vfy_cmd_sent(pgm, "enter prog mode");
}
static void butterfly_leave_prog_mode(PROGRAMMER * pgm)
{
static void butterfly_leave_prog_mode(const PROGRAMMER *pgm) {
butterfly_send(pgm, "L", 1);
butterfly_vfy_cmd_sent(pgm, "leave prog mode");
}
@@ -177,8 +163,7 @@ static void butterfly_leave_prog_mode(PROGRAMMER * pgm)
/*
* issue the 'program enable' command to the AVR device
*/
static int butterfly_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
static int butterfly_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
return -1;
}
@@ -186,8 +171,7 @@ static int butterfly_program_enable(PROGRAMMER * pgm, AVRPART * p)
/*
* apply power to the AVR processor
*/
static void butterfly_powerup(PROGRAMMER * pgm)
{
static void butterfly_powerup(const PROGRAMMER *pgm) {
/* Do nothing. */
return;
@@ -197,8 +181,7 @@ static void butterfly_powerup(PROGRAMMER * pgm)
/*
* remove power from the AVR processor
*/
static void butterfly_powerdown(PROGRAMMER * pgm)
{
static void butterfly_powerdown(const PROGRAMMER *pgm) {
/* Do nothing. */
return;
@@ -209,8 +192,7 @@ static void butterfly_powerdown(PROGRAMMER * pgm)
/*
* initialize the AVR device and prepare it to accept commands
*/
static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
{
static int butterfly_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
char id[8];
char sw[2];
char hw[2];
@@ -222,13 +204,13 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
* Send some ESC to activate butterfly bootloader. This is not needed
* for plain avr109 bootloaders but does not harm there either.
*/
avrdude_message(MSG_INFO, "Connecting to programmer: ");
msg_notice("connecting to programmer: ");
if (pgm->flag & IS_BUTTERFLY_MK)
{
char mk_reset_cmd[6] = {"#aR@S\r"};
unsigned char mk_timeout = 0;
putc('.', stderr);
msg_notice(".");
butterfly_send(pgm, mk_reset_cmd, sizeof(mk_reset_cmd));
usleep(20000);
@@ -240,13 +222,15 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
c = 0xaa;
usleep(80000);
butterfly_send(pgm, &c, 1);
if (mk_timeout % 10 == 0) putc('.', stderr);
if (mk_timeout % 10 == 0)
msg_notice(".");
} while (mk_timeout++ < 10);
butterfly_recv(pgm, &c, 1);
if ( c != 'M' && c != '?')
{
avrdude_message(MSG_INFO, "\nConnection FAILED.");
msg_error("\n");
pmsg_error("connection failed");
return -1;
}
else
@@ -257,13 +241,13 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
else
{
do {
putc('.', stderr);
msg_notice(".");
butterfly_send(pgm, "\033", 1);
butterfly_drain(pgm, 0);
butterfly_send(pgm, "S", 1);
butterfly_recv(pgm, &c, 1);
if (c != '?') {
putc('\n', stderr);
msg_notice("\n");
/*
* Got a useful response, continue getting the programmer
* identifier. Programmer returns exactly 7 chars _without_
@@ -293,12 +277,12 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
butterfly_send(pgm, "p", 1);
butterfly_recv(pgm, &type, 1);
avrdude_message(MSG_INFO, "Found programmer: Id = \"%s\"; type = %c\n", id, type);
avrdude_message(MSG_INFO, " Software Version = %c.%c; ", sw[0], sw[1]);
msg_notice("Programmer id = %s; type = %c\n", id, type);
msg_notice("Software version = %c.%c; ", sw[0], sw[1]);
if (hw[0]=='?') {
avrdude_message(MSG_INFO, "No Hardware Version given.\n");
msg_notice("no hardware version given\n");
} else {
avrdude_message(MSG_INFO, "Hardware Version = %c.%c\n", hw[0], hw[1]);
msg_notice("Hardware version = %c.%c\n", hw[0], hw[1]);
};
/* See if programmer supports autoincrement of address. */
@@ -306,28 +290,28 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
butterfly_send(pgm, "a", 1);
butterfly_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1);
if (PDATA(pgm)->has_auto_incr_addr == 'Y')
avrdude_message(MSG_INFO, "Programmer supports auto addr increment.\n");
msg_notice("programmer supports auto addr increment\n");
/* Check support for buffered memory access, abort if not available */
butterfly_send(pgm, "b", 1);
butterfly_recv(pgm, &c, 1);
if (c != 'Y') {
avrdude_message(MSG_INFO, "%s: error: buffered memory access not supported. Maybe it isn't\n"\
"a butterfly/AVR109 but a AVR910 device?\n", progname);
pmsg_notice("buffered memory access not supported; maybe it isn't\n"\
"a butterfly/AVR109 but a AVR910 device?\n");
return -1;
};
butterfly_recv(pgm, &c, 1);
PDATA(pgm)->buffersize = (unsigned int)(unsigned char)c<<8;
butterfly_recv(pgm, &c, 1);
PDATA(pgm)->buffersize += (unsigned int)(unsigned char)c;
avrdude_message(MSG_INFO, "Programmer supports buffered memory access with buffersize=%i bytes.\n",
msg_notice("programmer supports buffered memory access with buffersize=%i bytes\n",
PDATA(pgm)->buffersize);
/* Get list of devices that the programmer supports. */
butterfly_send(pgm, "t", 1);
avrdude_message(MSG_INFO, "\nProgrammer supports the following devices:\n");
msg_notice2("\nProgrammer supports the following devices:\n");
devtype_1st = 0;
while (1) {
butterfly_recv(pgm, &c, 1);
@@ -336,9 +320,9 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
if (c == 0)
break;
avrdude_message(MSG_INFO, " Device code: 0x%02x\n", (unsigned int)(unsigned char)c);
msg_notice2(" Device code: 0x%02x\n", (unsigned int) (unsigned char) c);
};
avrdude_message(MSG_INFO, "\n");
msg_notice2("\n");
/* Tell the programmer which part we selected.
According to the AVR109 code, this is ignored by the bootloader. As
@@ -355,9 +339,7 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
if (butterfly_vfy_cmd_sent(pgm, "select device") < 0)
return -1;
if (verbose)
avrdude_message(MSG_INFO, "%s: devcode selected: 0x%02x\n",
progname, (unsigned)buf[1]);
pmsg_notice("devcode selected: 0x%02x\n", (unsigned) buf[1]);
butterfly_enter_prog_mode(pgm);
butterfly_drain(pgm, 0);
@@ -367,22 +349,19 @@ static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
static void butterfly_disable(PROGRAMMER * pgm)
{
static void butterfly_disable(const PROGRAMMER *pgm) {
butterfly_leave_prog_mode(pgm);
return;
}
static void butterfly_enable(PROGRAMMER * pgm)
{
static void butterfly_enable(PROGRAMMER *pgm, const AVRPART *p) {
return;
}
static int butterfly_open(PROGRAMMER * pgm, char * port)
{
static int butterfly_open(PROGRAMMER *pgm, const char *port) {
union pinfo pinfo;
strcpy(pgm->port, port);
/*
@@ -417,27 +396,36 @@ static void butterfly_close(PROGRAMMER * pgm)
}
static void butterfly_display(PROGRAMMER * pgm, const char * p)
{
static void butterfly_display(const PROGRAMMER *pgm, const char *p) {
return;
}
static void butterfly_set_addr(PROGRAMMER * pgm, unsigned long addr)
{
char cmd[3];
static void butterfly_set_addr(const PROGRAMMER *pgm, unsigned long addr) {
if( addr < 0x10000 ) {
char cmd[3];
cmd[0] = 'A';
cmd[1] = (addr >> 8) & 0xff;
cmd[2] = addr & 0xff;
cmd[0] = 'A';
cmd[1] = (addr >> 8) & 0xff;
cmd[2] = addr & 0xff;
butterfly_send(pgm, cmd, sizeof(cmd));
butterfly_vfy_cmd_sent(pgm, "set addr");
butterfly_send(pgm, cmd, sizeof(cmd));
butterfly_vfy_cmd_sent(pgm, "set addr");
} else {
char cmd[4];
cmd[0] = 'H';
cmd[1] = (addr >> 16) & 0xff;
cmd[2] = (addr >> 8) & 0xff;
cmd[3] = addr & 0xff;
butterfly_send(pgm, cmd, sizeof(cmd));
butterfly_vfy_cmd_sent(pgm, "set extaddr");
}
}
static void butterfly_set_extaddr(PROGRAMMER * pgm, unsigned long addr)
{
static void butterfly_set_extaddr(const PROGRAMMER *pgm, unsigned long addr) {
char cmd[4];
cmd[0] = 'H';
@@ -451,7 +439,7 @@ static void butterfly_set_extaddr(PROGRAMMER * pgm, unsigned long addr)
static int butterfly_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int butterfly_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned long addr, unsigned char value)
{
char cmd[6];
@@ -495,7 +483,7 @@ static int butterfly_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
}
static int butterfly_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int butterfly_read_byte_flash(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned long addr, unsigned char * value)
{
static int cached = 0;
@@ -515,9 +503,13 @@ static int butterfly_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
} else {
butterfly_set_addr(pgm, addr >> 1);
}
butterfly_send(pgm, "g\000\002F", 4);
// Defaults to flash read ('F')
char msg[4] = {'g', 0x00, 0x02, 'F'};
if (strcmp(m->desc, "prodsig") == 0)
msg[3] = 'P';
else if (strcmp(m->desc, "usersig") == 0)
msg[3] = 'U';
butterfly_send(pgm, msg, 4);
/* Read back the program mem word (MSB first) */
butterfly_recv(pgm, buf, sizeof(buf));
@@ -536,7 +528,7 @@ static int butterfly_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
}
static int butterfly_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int butterfly_read_byte_eeprom(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned long addr, unsigned char * value)
{
butterfly_set_addr(pgm, addr);
@@ -545,23 +537,23 @@ static int butterfly_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
return 0;
}
static int butterfly_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned int addr)
{
static int butterfly_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int addr) {
if (strcmp(m->desc, "flash") == 0)
return -1; /* not supported */
if (strcmp(m->desc, "eeprom") == 0)
return 0; /* nothing to do */
avrdude_message(MSG_INFO, "%s: butterfly_page_erase() called on memory type \"%s\"\n",
progname, m->desc);
pmsg_warning("called on memory type %s\n", m->desc);
return -1;
}
static int butterfly_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int butterfly_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned long addr, unsigned char * value)
{
char cmd;
if (strcmp(m->desc, "flash") == 0) {
if (strcmp(m->desc, "flash") == 0 ||
strcmp(m->desc, "prodsig") == 0 ||
strcmp(m->desc, "usersig") == 0) {
return butterfly_read_byte_flash(pgm, p, m, addr, value);
}
@@ -592,7 +584,7 @@ static int butterfly_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int butterfly_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
@@ -602,7 +594,9 @@ static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
unsigned int wr_size = 2;
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
if (strcmp(m->desc, "flash") &&
strcmp(m->desc, "eeprom") &&
strcmp(m->desc, "usersig"))
return -2;
if (m->desc[0] == 'e')
@@ -647,7 +641,7 @@ static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int butterfly_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
@@ -656,8 +650,10 @@ static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int blocksize = PDATA(pgm)->buffersize;
int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
/* check parameter syntax: only "flash" or "eeprom" is allowed */
if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
/* check parameter syntax: only "flash", "eeprom" or "usersig" is allowed */
if (strcmp(m->desc, "flash") &&
strcmp(m->desc, "eeprom") &&
strcmp(m->desc, "usersig"))
return -2;
if (m->desc[0] == 'e')
@@ -693,12 +689,11 @@ static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
/* Signature byte reads are always 3 bytes. */
static int butterfly_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
{
static int butterfly_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m) {
unsigned char tmp;
if (m->size < 3) {
avrdude_message(MSG_INFO, "%s: memsize too small for sig byte read", progname);
pmsg_error("memsize too small for sig byte read");
return -1;
}
@@ -714,8 +709,7 @@ static int butterfly_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
const char butterfly_desc[] = "Atmel Butterfly evaluation board; Atmel AppNotes AVR109, AVR911";
void butterfly_initpgm(PROGRAMMER * pgm)
{
void butterfly_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "butterfly");
/*
@@ -755,8 +749,7 @@ void butterfly_initpgm(PROGRAMMER * pgm)
const char butterfly_mk_desc[] = "Mikrokopter.de Butterfly";
void butterfly_mk_initpgm(PROGRAMMER * pgm)
{
void butterfly_mk_initpgm(PROGRAMMER *pgm) {
butterfly_initpgm(pgm);
strcpy(pgm->type, "butterfly_mk");
pgm->flag = IS_BUTTERFLY_MK;

View File

@@ -27,8 +27,8 @@ extern "C" {
extern const char butterfly_desc[];
extern const char butterfly_mk_desc[];
void butterfly_initpgm (PROGRAMMER * pgm);
void butterfly_mk_initpgm (PROGRAMMER * pgm);
void butterfly_initpgm(PROGRAMMER *pgm);
void butterfly_mk_initpgm(PROGRAMMER *pgm);
#ifdef __cplusplus
}

View File

@@ -24,36 +24,57 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stddef.h>
#include <string.h>
#include <ctype.h>
#include "avrdude.h"
#include "libavrdude.h"
#include "config.h"
#include "avrintel.h"
#include "config_gram.h"
char default_programmer[MAX_STR_CONST];
char default_parallel[PATH_MAX];
char default_serial[PATH_MAX];
const char *default_programmer;
const char *default_parallel;
const char *default_serial;
const char *default_spi;
double default_bitclock;
char string_buf[MAX_STR_CONST];
char *string_buf_ptr;
LISTID string_list;
LISTID number_list;
PROGRAMMER * current_prog;
AVRPART * current_part;
AVRMEM * current_mem;
int current_strct;
LISTID part_list;
LISTID programmers;
bool is_alias;
int lineno;
const char * infile;
int cfg_lineno;
char * cfg_infile;
extern char * yytext;
#define pgm_comp_desc(x, type) { #x, COMP_PROGRAMMER, offsetof(PROGRAMMER, x), sizeof(((PROGRAMMER *) NULL)->x), type }
#define part_comp_desc(x, type) { #x, COMP_AVRPART, offsetof(AVRPART, x), sizeof(((AVRPART *) NULL)->x), type }
#define mem_comp_desc(x, type) { #x, COMP_AVRMEM, offsetof(AVRMEM, x), sizeof(((AVRMEM *) NULL)->x), type }
// Component description for config_gram.y, will be sorted appropriately on first use
Component_t avr_comp[] = {
// PROGRAMMER
pgm_comp_desc(prog_modes, COMP_INT),
// AVRPART
part_comp_desc(prog_modes, COMP_INT),
part_comp_desc(mcuid, COMP_INT),
part_comp_desc(n_interrupts, COMP_INT),
part_comp_desc(n_page_erase, COMP_INT),
// AVRMEM
mem_comp_desc(n_word_writes, COMP_INT),
};
#define DEBUG 0
void cleanup_config(void)
@@ -75,12 +96,42 @@ int init_config(void)
programmers = lcreat(NULL, 0);
is_alias = false;
lineno = 1;
infile = NULL;
cfg_lineno = 1;
cfg_infile = NULL;
return 0;
}
void *cfg_malloc(const char *funcname, size_t n) {
void *ret = malloc(n);
if(!ret) {
pmsg_error("out of memory in %s (needed %lu bytes)\n", funcname, (unsigned long) n);
exit(1);
}
memset(ret, 0, n);
return ret;
}
void *cfg_realloc(const char *funcname, void *p, size_t n) {
void *ret;
if(!(ret = p? realloc(p, n): calloc(1, n))) {
pmsg_error("out of memory in %s (needed %lu bytes)\n", funcname, (unsigned long) n);
exit(1);
}
return ret;
}
char *cfg_strdup(const char *funcname, const char *s) {
char *ret = strdup(s);
if(!ret) {
pmsg_error("out of memory in %s\n", funcname);
exit(1);
}
return ret;
}
int yywrap()
@@ -98,7 +149,7 @@ int yyerror(char * errmsg, ...)
va_start(args, errmsg);
vsnprintf(message, sizeof(message), errmsg, args);
avrdude_message(MSG_INFO, "%s: error at %s:%d: %s\n", progname, infile, lineno, message);
pmsg_error("%s [%s:%d]\n", message, cfg_infile, cfg_lineno);
va_end(args);
@@ -115,7 +166,7 @@ int yywarning(char * errmsg, ...)
va_start(args, errmsg);
vsnprintf(message, sizeof(message), errmsg, args);
avrdude_message(MSG_INFO, "%s: warning at %s:%d: %s\n", progname, infile, lineno, message);
pmsg_warning("%s [%s:%d]\n", message, cfg_infile, cfg_lineno);
va_end(args);
@@ -123,20 +174,9 @@ int yywarning(char * errmsg, ...)
}
TOKEN * new_token(int primary)
{
TOKEN * tkn;
tkn = (TOKEN *)malloc(sizeof(TOKEN));
if (tkn == NULL) {
yyerror("new_token(): out of memory");
return NULL;
}
memset(tkn, 0, sizeof(TOKEN));
TOKEN * new_token(int primary) {
TOKEN * tkn = (TOKEN *) cfg_malloc("new_token()", sizeof(TOKEN));
tkn->primary = primary;
return tkn;
}
@@ -172,100 +212,98 @@ void free_tokens(int n, ...)
TOKEN * number(char * text)
{
struct token_t * tkn;
tkn = new_token(TKN_NUMBER);
if (tkn == NULL) {
return NULL; /* yyerror already called */
}
TOKEN *new_number(const char *text) {
struct token_t *tkn = new_token(TKN_NUMBER);
tkn->value.type = V_NUM;
tkn->value.number = atoi(text);
#if DEBUG
avrdude_message(MSG_INFO, "NUMBER(%d)\n", tkn->value.number);
msg_info("NUMBER(%d)\n", tkn->value.number);
#endif
return tkn;
}
TOKEN * number_real(char * text)
{
struct token_t * tkn;
tkn = new_token(TKN_NUMBER);
TOKEN *new_number_real(const char *text) {
struct token_t * tkn = new_token(TKN_NUMBER);
tkn->value.type = V_NUM_REAL;
tkn->value.number_real = atof(text);
#if DEBUG
avrdude_message(MSG_INFO, "NUMBER(%g)\n", tkn->value.number_real);
msg_info("NUMBER(%g)\n", tkn->value.number_real);
#endif
return tkn;
}
TOKEN * hexnumber(char * text)
{
struct token_t * tkn;
TOKEN *new_hexnumber(const char *text) {
struct token_t *tkn = new_token(TKN_NUMBER);
char * e;
tkn = new_token(TKN_NUMBER);
if (tkn == NULL) {
return NULL; /* yyerror already called */
}
tkn->value.type = V_NUM;
tkn->value.number = strtoul(text, &e, 16);
if ((e == text) || (*e != 0)) {
yyerror("can't scan hex number \"%s\"", text);
yyerror("cannot scan hex number %s", text);
free_token(tkn);
return NULL;
}
#if DEBUG
avrdude_message(MSG_INFO, "HEXNUMBER(%g)\n", tkn->value.number);
msg_info("HEXNUMBER(%d)\n", tkn->value.number);
#endif
return tkn;
}
TOKEN *new_constant(const char *con) {
struct token_t *tkn = new_token(TKN_NUMBER);
int assigned = 1;
TOKEN * string(char * text)
{
struct token_t * tkn;
int len;
tkn->value.type = V_NUM;
tkn->value.number =
!strcmp("PM_SPM", con)? PM_SPM:
!strcmp("PM_TPI", con)? PM_TPI:
!strcmp("PM_ISP", con)? PM_ISP:
!strcmp("PM_PDI", con)? PM_PDI:
!strcmp("PM_UPDI", con)? PM_UPDI:
!strcmp("PM_HVSP", con)? PM_HVSP:
!strcmp("PM_HVPP", con)? PM_HVPP:
!strcmp("PM_debugWIRE", con)? PM_debugWIRE:
!strcmp("PM_JTAG", con)? PM_JTAG:
!strcmp("PM_JTAGmkI", con)? PM_JTAGmkI:
!strcmp("PM_XMEGAJTAG", con)? PM_XMEGAJTAG:
!strcmp("PM_AVR32JTAG", con)? PM_AVR32JTAG:
!strcmp("PM_aWire", con)? PM_aWire:
(assigned = 0);
tkn = new_token(TKN_STRING);
if (tkn == NULL) {
return NULL; /* yyerror already called */
}
len = strlen(text);
tkn->value.type = V_STR;
tkn->value.string = (char *) malloc(len+1);
if (tkn->value.string == NULL) {
yyerror("string(): out of memory");
if(!assigned) {
yyerror("can't identify constant %s", con);
free_token(tkn);
return NULL;
}
strcpy(tkn->value.string, text);
#if DEBUG
avrdude_message(MSG_INFO, "STRING(%s)\n", tkn->value.string);
msg_info("CONSTANT(%s=%d)\n", con, tkn->value.number);
#endif
return tkn;
}
TOKEN *new_string(const char *text) {
struct token_t *tkn = new_token(TKN_STRING);
tkn->value.type = V_STR;
tkn->value.string = cfg_strdup("new_string()", text);
#if DEBUG
msg_info("STRING(%s)\n", tkn->value.string);
#endif
return tkn;
}
TOKEN * keyword(int primary)
{
struct token_t * tkn;
tkn = new_token(primary);
return tkn;
TOKEN *new_keyword(int primary) {
return new_token(primary);
}
@@ -274,50 +312,37 @@ void print_token(TOKEN * tkn)
if (!tkn)
return;
avrdude_message(MSG_INFO, "token = %d = ", tkn->primary);
msg_info("token = %d = ", tkn->primary);
switch (tkn->value.type) {
case V_NUM:
avrdude_message(MSG_INFO, "NUMBER, value=%d", tkn->value.number);
msg_info("NUMBER, value=%d", tkn->value.number);
break;
case V_NUM_REAL:
avrdude_message(MSG_INFO, "NUMBER, value=%g", tkn->value.number_real);
msg_info("NUMBER, value=%g", tkn->value.number_real);
break;
case V_STR:
avrdude_message(MSG_INFO, "STRING, value=%s", tkn->value.string);
msg_info("STRING, value=%s", tkn->value.string);
break;
default:
avrdude_message(MSG_INFO, "<other>");
msg_info("<other>");
break;
}
avrdude_message(MSG_INFO, "\n");
msg_info("\n");
}
void pyytext(void)
{
#if DEBUG
avrdude_message(MSG_INFO, "TOKEN: \"%s\"\n", yytext);
msg_info("TOKEN: %s\n", yytext);
#endif
}
char * dup_string(const char * str)
{
char * s;
s = strdup(str);
if (s == NULL) {
yyerror("dup_string(): out of memory");
return NULL;
}
return s;
}
#ifdef HAVE_YYLEX_DESTROY
/* reset lexer and free any allocated memory */
extern int yylex_destroy(void);
@@ -328,15 +353,20 @@ int read_config(const char * file)
FILE * f;
int r;
f = fopen(file, "r");
if (f == NULL) {
avrdude_message(MSG_INFO, "%s: can't open config file \"%s\": %s\n",
progname, file, strerror(errno));
if(!(cfg_infile = realpath(file, NULL))) {
pmsg_ext_error("cannot determine realpath() of config file %s: %s\n", file, strerror(errno));
return -1;
}
lineno = 1;
infile = file;
f = fopen(cfg_infile, "r");
if (f == NULL) {
pmsg_ext_error("cannot open config file %s: %s\n", cfg_infile, strerror(errno));
free(cfg_infile);
cfg_infile = NULL;
return -1;
}
cfg_lineno = 1;
yyin = f;
r = yyparse();
@@ -348,5 +378,513 @@ int read_config(const char * file)
fclose(f);
if(cfg_infile) {
free(cfg_infile);
cfg_infile = NULL;
}
return r;
}
// Adapted version of a neat empirical hash function from comp.lang.c by Daniel Bernstein
unsigned strhash(const char *str) {
unsigned c, hash = 5381, n = 0;
while((c = (unsigned char) *str++) && n++ < 20)
hash = 33*hash ^ c;
return hash;
}
static char **hstrings[1<<12];
// Return a copy of the argument as hashed string
const char *cache_string(const char *p) {
int h, k;
char **hs;
if(!p)
p = "(NULL)";
h = strhash(p) % (sizeof hstrings/sizeof*hstrings);
if(!(hs=hstrings[h]))
hs = hstrings[h] = (char **) cfg_realloc("cache_string()", NULL, (16+1)*sizeof**hstrings);
for(k=0; hs[k]; k++)
if(*p == *hs[k] && !strcmp(p, hs[k]))
return hs[k];
if(k && k%16 == 0)
hstrings[h] = (char **) cfg_realloc("cache_string()", hstrings[h], (k+16+1)*sizeof**hstrings);
hstrings[h][k+1]=NULL;
return hstrings[h][k] = cfg_strdup("cache_string()", p);
}
static LISTID cfg_comms; // A chain of comment lines
static LISTID cfg_prologue; // Comment lines at start of avrdude.conf
static char *lkw; // Last seen keyword
static int lkw_lineno; // Line number of that
static LISTID cfg_strctcomms; // Passed on to config_gram.y
static LISTID cfg_pushedcomms; // Temporarily pushed main comments
static int cfg_pushed; // ... for memory sections
COMMENT *locate_comment(const LISTID comments, const char *where, int rhs) {
if(comments)
for(LNODEID ln=lfirst(comments); ln; ln=lnext(ln)) {
COMMENT *n = ldata(ln);
if(n && rhs == n->rhs && n->kw && strcmp(where, n->kw) == 0)
return n;
}
return NULL;
}
static void addcomment(int rhs) {
if(lkw) {
COMMENT *node = cfg_malloc("addcomment()", sizeof(*node));
node->rhs = rhs;
node->kw = cfg_strdup("addcomment()", lkw);
node->comms = cfg_comms;
cfg_comms = NULL;
if(!cfg_strctcomms)
cfg_strctcomms = lcreat(NULL, 0);
ladd(cfg_strctcomms, node);
}
}
// Capture prologue during parsing (triggered by lexer.l)
void cfg_capture_prologue(void) {
cfg_prologue = cfg_comms;
cfg_comms = NULL;
}
LISTID cfg_get_prologue(void) {
return cfg_prologue;
}
// Captures comments during parsing
void capture_comment_str(const char *com, int lineno) {
if(!cfg_comms)
cfg_comms = lcreat(NULL, 0);
ladd(cfg_comms, cfg_strdup("capture_comment_str()", com));
// Last keyword lineno is the same as this comment's
if(lkw && lkw_lineno == lineno)
addcomment(1); // Register comms to show right of lkw = ...;
}
// Capture assignments (keywords left of =) and associate comments to them
void capture_lvalue_kw(const char *kw, int lineno) {
if(!strcmp(kw, "memory")) { // Push part comments and start memory comments
if(!cfg_pushed) { // config_gram.y pops the part comments
cfg_pushed = 1;
cfg_pushedcomms = cfg_strctcomms;
cfg_strctcomms = NULL;
}
}
if(!strcmp(kw, "programmer") || !strcmp(kw, "part") || !strcmp(kw, "memory"))
kw = "*"; // Show comment before programmer/part/memory
if(lkw)
free(lkw);
lkw = cfg_strdup("capture_lvalue_kw()", kw);
lkw_lineno = lineno;
if(cfg_comms) // Accrued list of # one-line comments
addcomment(0); // Register comment to appear before lkw assignment
}
// config_gram.y calls this once for each programmer/part/memory structure
LISTID cfg_move_comments(void) {
capture_lvalue_kw(";", -1);
LISTID ret = cfg_strctcomms;
cfg_strctcomms = NULL;
return ret;
}
// config_gram.y calls this after ingressing the memory structure
void cfg_pop_comms(void) {
if(cfg_pushed) {
cfg_pushed = 0;
cfg_strctcomms = cfg_pushedcomms;
}
}
// Convert the next n hex digits of s to a hex number
static unsigned int tohex(const unsigned char *s, unsigned int n) {
int ret, c;
ret = 0;
while(n--) {
ret *= 16;
c = *s++;
ret += c >= '0' && c <= '9'? c - '0': c >= 'a' && c <= 'f'? c - 'a' + 10: c - 'A' + 10;
}
return ret;
}
/*
* Create a utf-8 character sequence from a single unicode character.
* Permissive for some invalid unicode sequences but not for those with
* high bit set). Returns numbers of characters written (0-6).
*/
static int wc_to_utf8str(unsigned int wc, unsigned char *str) {
if(!(wc & ~0x7fu)) {
*str = (char) wc;
return 1;
}
if(!(wc & ~0x7ffu)) {
*str++ = (char) ((wc >> 6) | 0xc0);
*str++ = (char) ((wc & 0x3f) | 0x80);
return 2;
}
if(!(wc & ~0xffffu)) {
*str++ = (char) ((wc >> 12) | 0xe0);
*str++ = (char) (((wc >> 6) & 0x3f) | 0x80);
*str++ = (char) ((wc & 0x3f) | 0x80);
return 3;
}
if(!(wc & ~0x1fffffu)) {
*str++ = (char) ((wc >> 18) | 0xf0);
*str++ = (char) (((wc >> 12) & 0x3f) | 0x80);
*str++ = (char) (((wc >> 6) & 0x3f) | 0x80);
*str++ = (char) ((wc & 0x3f) | 0x80);
return 4;
}
if(!(wc & ~0x3ffffffu)) {
*str++ = (char) ((wc >> 24) | 0xf8);
*str++ = (char) (((wc >> 18) & 0x3f) | 0x80);
*str++ = (char) (((wc >> 12) & 0x3f) | 0x80);
*str++ = (char) (((wc >> 6) & 0x3f) | 0x80);
*str++ = (char) ((wc & 0x3f) | 0x80);
return 5;
}
if(!(wc & ~0x7fffffffu)) {
*str++ = (char) ((wc >> 30) | 0xfc);
*str++ = (char) (((wc >> 24) & 0x3f) | 0x80);
*str++ = (char) (((wc >> 18) & 0x3f) | 0x80);
*str++ = (char) (((wc >> 12) & 0x3f) | 0x80);
*str++ = (char) (((wc >> 6) & 0x3f) | 0x80);
*str++ = (char) ((wc & 0x3f) | 0x80);
return 6;
}
return 0;
}
// Unescape C-style strings, destination d must hold enough space (and can be source s)
unsigned char *cfg_unescapeu(unsigned char *d, const unsigned char *s) {
unsigned char *ret = d;
int n, k;
while(*s) {
switch (*s) {
case '\\':
switch (*++s) {
case '\n': // String continuation over new line
#if '\n' != '\r'
case '\r':
#endif
--d;
break;
case 'n':
*d = '\n';
break;
case 't':
*d = '\t';
break;
case 'a':
*d = '\a';
break;
case 'b':
*d = '\b';
break;
case 'e': // Non-standard ESC
*d = 27;
break;
case 'f':
*d = '\f';
break;
case 'r':
*d = '\r';
break;
case 'v':
*d = '\v';
break;
case '?':
*d = '?';
break;
case '`':
*d = '`';
break;
case '"':
*d = '"';
break;
case '\'':
*d = '\'';
break;
case '\\':
*d = '\\';
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7': // 1-3 octal digits
n = *s - '0';
for(k = 0; k < 2 && s[1] >= '0' && s[1] <= '7'; k++) // Max 2 more octal characters
n *= 8, n += s[1] - '0', s++;
*d = n;
break;
case 'x': // Unlimited hex digits
for(k = 0; isxdigit(s[k + 1]); k++)
continue;
if(k > 0) {
*d = tohex(s + 1, k);
s += k;
} else { // No hex digits after \x? copy \x
*d++ = '\\';
*d = 'x';
}
break;
case 'u': // Exactly 4 hex digits and valid unicode
if(isxdigit(s[1]) && isxdigit(s[2]) && isxdigit(s[3]) && isxdigit(s[4]) &&
(n = wc_to_utf8str(tohex(s+1, 4), d))) {
d += n - 1;
s += 4;
} else { // Invalid \u sequence? copy \u
*d++ = '\\';
*d = 'u';
}
break;
case 'U': // Exactly 6 hex digits and valid unicode
if(isxdigit(s[1]) && isxdigit(s[2]) && isxdigit(s[3]) && isxdigit(s[4]) && isxdigit(s[5]) && isxdigit(s[6]) &&
(n = wc_to_utf8str(tohex(s+1, 6), d))) {
d += n - 1;
s += 6;
} else { // Invalid \U sequence? copy \U
*d++ = '\\';
*d = 'U';
}
break;
default: // Keep the escape sequence (C would warn and remove \)
*d++ = '\\';
*d = *s;
}
break;
default: // Not an escape sequence: just copy the character
*d = *s;
}
d++;
s++;
}
*d = *s; // Terminate
return ret;
}
// Unescape C-style strings, destination d must hold enough space (and can be source s)
char *cfg_unescape(char *d, const char *s) {
return (char *) cfg_unescapeu((unsigned char *) d, (const unsigned char *) s);
}
// Return an escaped string that looks like a C-style input string incl quotes, memory is malloc'd
char *cfg_escape(const char *s) {
char buf[50*1024], *d = buf;
*d++ = '"';
for(; *s && d-buf < sizeof buf-7; s++) {
switch(*s) {
case '\n':
*d++ = '\\'; *d++ = 'n';
break;
case '\t':
*d++ = '\\'; *d++ = 't';
break;
case '\a':
*d++ = '\\'; *d++ = 'a';
break;
case '\b':
*d++ = '\\'; *d++ = 'b';
break;
case '\f':
*d++ = '\\'; *d++ = 'f';
break;
#if '\r' != '\n'
case '\r':
*d++ = '\\'; *d++ = 'r';
break;
#endif
case '\v':
*d++ = '\\'; *d++ = 'v';
break;
case '\"':
*d++ = '\\'; *d++ = '\"';
break;
default:
if(*s == 0x7f || (*s >= 0 && *s < 32)) {
sprintf(d, "\\%03o", *s);
d += strlen(d);
} else
*d++ = *s;
}
}
*d++ = '"';
*d = 0;
return cfg_strdup("cfg_escape()", buf);
}
static int cmp_comp(const void *v1, const void *v2) {
const Component_t *c1 = v1, *c2 = v2;
int ret = strcmp(c1->name, c2->name);
return ret? ret: c1->strct - c2->strct;
}
Component_t *cfg_comp_search(const char *name, int strct) {
static int init;
Component_t key;
if(!init++)
qsort(avr_comp, sizeof avr_comp/sizeof*avr_comp, sizeof(Component_t), cmp_comp);
key.name = name;
key.strct = strct;
return bsearch(&key, avr_comp, sizeof avr_comp/sizeof*avr_comp, sizeof(Component_t), cmp_comp);
}
const char *cfg_strct_name(int strct) {
switch(strct) {
case COMP_CONFIG_MAIN: return "avrdude.conf main";
case COMP_AVRPART: return "AVRPART";
case COMP_AVRMEM: return "AVRMEM";
case COMP_PROGRAMMER: return "PROGRAMMER";
}
return "unknown struct";
}
const char *cfg_v_type(int type) {
switch(type) {
case V_NONE: return "void";
case V_NUM: return "number";
case V_NUM_REAL: return "real";
case V_STR: return "string";
case V_COMPONENT: return "component";
}
return "unknown v type";
}
const char *cfg_comp_type(int type) {
switch(type) {
case COMP_INT: return "number";
case COMP_SHORT: return "short";
case COMP_CHAR: return "char";
case COMP_STRING: return "string";
case COMP_CHAR_ARRAY: return "byte array";
case COMP_INT_LISTID: return "number list";
case COMP_STRING_LISTID: return "string list";
case COMP_OPCODE: return "opcode";
case COMP_PIN: return "pin";
case COMP_PIN_LIST: return "pin list";
}
return "unknown comp type";
}
// Used by config_gram.y to assign a component in one of the relevant structures with a value
void cfg_assign(char *sp, int strct, Component_t *cp, VALUE *v) {
const char *str;
int num;
switch(cp->type) {
case COMP_CHAR:
case COMP_SHORT:
case COMP_INT:
if(v->type != V_NUM) {
yywarning("%s in %s expects a %s but is assigned a %s",
cp->name, cfg_strct_name(strct), cfg_comp_type(cp->type), cfg_v_type(v->type));
return;
}
// TODO: consider endianess (code currently assumes little endian)
num = v->number;
memcpy(sp+cp->offset, &num, cp->size);
break;
case COMP_STRING:
if(v->type != V_STR) {
yywarning("%s in %s expects a string but is assigned a %s",
cp->name, cfg_strct_name(strct), cfg_v_type(v->type));
return;
}
str = cache_string(v->string);
memcpy(sp+cp->offset, &str, cp->size);
break;
// TODO: implement COMP_CHAR_ARRAY, COMP_INT_LISTID, COMP_STRING_LISTID, ...
default:
yywarning("%s in %s expects a %s but that is not implemented",
cp->name, cfg_strct_name(strct), cfg_comp_type(cp->type));
}
}
// Automatically assign an mcuid if known from avrintel.c table
void cfg_update_mcuid(AVRPART *part) {
// Don't assign an mcuid for template parts that has a space in desc
if(!part->desc || *part->desc == 0 || strchr(part->desc, ' '))
return;
// Don't assign an mcuid for template parts where id starts with "."
if(!part->id || !*part->id || *part->id == '.')
return;
// Don't assign an mcuid for 32-bit AVR parts
if(part->prog_modes & PM_aWire)
return;
// Find an entry that shares the same name, overwrite mcuid with known, existing mcuid
for(int i=0; i < sizeof uP_table/sizeof *uP_table; i++) {
if(strcasecmp(part->desc, uP_table[i].name) == 0) {
if(part->mcuid != (int) uP_table[i].mcuid) {
if(part->mcuid >= 0 && verbose >= MSG_DEBUG)
yywarning("overwriting mcuid of part %s to be %d", part->desc, uP_table[i].mcuid);
part->mcuid = uP_table[i].mcuid;
}
return;
}
}
// None have the same name: an entry with part->mcuid might be an error
for(int i=0; i < sizeof uP_table/sizeof *uP_table; i++)
if(part->mcuid == (int) uP_table[i].mcuid) {
// Complain unless it can be considered a variant, eg, ATmega32L and ATmega32
AVRMEM *flash = avr_locate_mem(part, "flash");
if(flash) {
size_t l1 = strlen(part->desc), l2 = strlen(uP_table[i].name);
if(strncasecmp(part->desc, uP_table[i].name, l1 < l2? l1: l2) ||
flash->size != uP_table[i].flashsize ||
flash->page_size != uP_table[i].pagesize ||
part->n_interrupts != uP_table[i].ninterrupts)
yywarning("mcuid %d is reserved for %s, use a free number >= %d",
part->mcuid, uP_table[i].name, sizeof uP_table/sizeof *uP_table);
}
return;
}
// Range check
if(part->mcuid < 0 || part->mcuid >= UB_N_MCU)
yywarning("mcuid %d for %s is out of range [0..%d], use a free number >= %d",
part->mcuid, part->desc, UB_N_MCU-1, sizeof uP_table/sizeof *uP_table);
}

View File

@@ -25,17 +25,61 @@
#include "libavrdude.h"
#if defined(WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
#define realpath(N,R) _fullpath((R), (N), PATH_MAX)
#endif
#define MAX_STR_CONST 1024
enum { V_NONE, V_NUM, V_NUM_REAL, V_STR };
typedef struct {
char *kw; // Keyword near the comments
LISTID comms; // Chained list of comments
int rhs; // Comments to print rhs of keyword line
} COMMENT;
enum { // Which structures a component can occur in
COMP_CONFIG_MAIN,
COMP_PROGRAMMER,
COMP_AVRPART,
COMP_AVRMEM,
};
enum { // Component types in structure
COMP_INT,
COMP_SHORT,
COMP_CHAR,
COMP_STRING,
COMP_CHAR_ARRAY, // This and below are not yet implemented
COMP_INT_LISTID,
COMP_STRING_LISTID,
COMP_OPCODE,
COMP_PIN, // Pins may never be implemented
COMP_PIN_LIST
};
typedef struct { // Description of a component in a structure
const char *name; // Component name
int strct; // Structure, eg, COMP_AVRPART
int offset, size, type; // Location, size and type within structure
} Component_t;
enum { // Value types for VALUE struct
V_NONE,
V_NUM,
V_NUM_REAL,
V_STR,
V_COMPONENT,
};
typedef struct value_t {
int type;
/*union { TODO: use an anonymous union here ? */
union {
int number;
double number_real;
char * string;
/*};*/
Component_t *comp;
};
} VALUE;
@@ -50,8 +94,9 @@ extern FILE * yyin;
extern PROGRAMMER * current_prog;
extern AVRPART * current_part;
extern AVRMEM * current_mem;
extern int lineno;
extern const char * infile;
extern int current_strct;
extern int cfg_lineno;
extern char * cfg_infile;
extern LISTID string_list;
extern LISTID number_list;
extern bool is_alias; // current entry is alias
@@ -62,40 +107,61 @@ extern bool is_alias; // current entry is alias
#endif
extern YYSTYPE yylval;
extern char string_buf[MAX_STR_CONST];
extern char *string_buf_ptr;
#ifdef __cplusplus
extern "C" {
#endif
int yyparse(void);
int yyerror(char * errmsg, ...);
int yyerror(char *errmsg, ...);
int yywarning(char * errmsg, ...);
int yywarning(char *errmsg, ...);
TOKEN * new_token(int primary);
TOKEN *new_token(int primary);
void free_token(TOKEN * tkn);
void free_token(TOKEN *tkn);
void free_tokens(int n, ...);
TOKEN * number(char * text);
TOKEN *new_number(const char *text);
TOKEN * number_real(char * text);
TOKEN *new_number_real(const char *text);
TOKEN * hexnumber(char * text);
TOKEN *new_hexnumber(const char *text);
TOKEN * string(char * text);
TOKEN *new_constant(const char *text);
TOKEN * keyword(int primary);
TOKEN *new_string(const char *text);
void print_token(TOKEN * tkn);
TOKEN *new_keyword(int primary);
void print_token(TOKEN *tkn);
void pyytext(void);
char * dup_string(const char * str);
COMMENT *locate_comment(const LISTID comments, const char *where, int rhs);
void cfg_capture_prologue(void);
LISTID cfg_get_prologue(void);
void capture_comment_str(const char *com, int lineno);
void capture_lvalue_kw(const char *kw, int lineno);
LISTID cfg_move_comments(void);
void cfg_pop_comms(void);
Component_t *cfg_comp_search(const char *name, int strct);
const char *cfg_v_type(int type);
const char *cfg_strct_name(int strct);
void cfg_assign(char *sp, int strct, Component_t *cp, VALUE *v);
void cfg_update_mcuid(AVRPART *part);
#ifdef __cplusplus
}

File diff suppressed because it is too large Load Diff

35
src/configure.cmake Normal file
View File

@@ -0,0 +1,35 @@
#
# configure.cmake - autoconf like multi-line configure
# Copyright (C) 2022 Marius Greuel
#
# 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/>.
#
# Do a multi-line replace based on @<OPTION>_BEGIN@ and @<OPTION>_END@ tags.
macro(configure_option option)
if(${${option}})
string(REGEX REPLACE "(.*)@${option}_BEGIN@(.*)@${option}_END@(.*)" "\\1\\2\\3" CONTENTS "${CONTENTS}")
else()
string(REGEX REPLACE "(.*)@${option}_BEGIN@(.*)@${option}_END@(.*)" "\\1\\3" CONTENTS "${CONTENTS}")
endif()
endmacro()
# Perform autoconf like multi-line configure
file(READ avrdude.conf.in CONTENTS)
configure_option(HAVE_PARPORT)
configure_option(HAVE_LINUXSPI)
configure_option(HAVE_LINUXGPIO)
file(WRITE avrdude.conf.in "${CONTENTS}")
configure_file(avrdude.conf.in avrdude.conf)

1401
src/developer_opts.c Normal file

File diff suppressed because it is too large Load Diff

26
src/developer_opts.h Normal file
View File

@@ -0,0 +1,26 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2022, Stefan Rueger <stefan.rueger@urclocks.com>
*
* 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/>.
*/
#ifndef developer_opts_h
#define developer_opts_h
void dev_output_pgm_part(int dev_opt_c, char *programmer, int dev_opt_p, char *partdesc);
void dev_output_part_defs(char *partdesc);
void dev_output_pgm_defs(char *programmer);
#endif

View File

@@ -0,0 +1,140 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2022, Stefan Rueger <stefan.rueger@urclocks.com>
*
* 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/>.
*/
#ifndef developer_opts_private_h
#define developer_opts_private_h
#define DEV_SPI_EN_CE_SIG 1
#define DEV_SPI_PROGMEM 2
#define DEV_SPI_PROGMEM_PAGED 4
#define DEV_SPI_LOAD_EXT_ADDR 8
#define DEV_SPI_EEPROM 16
#define DEV_SPI_EEPROM_PAGED 32
#define DEV_SPI_LOCK 64
#define DEV_SPI_CALIBRATION 128
#define DEV_SPI_LFUSE 256
#define DEV_SPI_HFUSE 512
#define DEV_SPI_EFUSE 1024
static int dev_message(int msglvl, const char *fmt, ...);
#ifndef DEV_INFO
#define DEV_INFO MSG_INFO
#endif
#ifndef DEV_NOTICE
#define DEV_NOTICE MSG_NOTICE
#endif
#ifndef DEV_NOTICE
#define DEV_NOTICE2 MSG_NOTICE2
#endif
#define dev_info(...) dev_message(DEV_INFO, __VA_ARGS__)
#define dev_notice(...) dev_message(DEV_NOTICE, __VA_ARGS__)
#define dev_notice2(...) dev_message(DEV_NOTICE2, __VA_ARGS__)
#define _pgmout(fmt, component) \
dev_part_strct_entry(tsv, ".prog", id, NULL, #component, dev_sprintf(fmt, pgm->component), pgm->comments)
#define _pgmout_fmt(name, fmt, what) \
dev_part_strct_entry(tsv, ".prog", id, NULL, name, dev_sprintf(fmt, what), pgm->comments)
#define _if_pgmout(cmp, fmt, component) do { \
if(!base || cmp(base->component, pgm->component)) \
dev_part_strct_entry(tsv, ".prog", id, NULL, #component, dev_sprintf(fmt, pgm->component), pgm->comments); \
} while(0)
// Result must be a malloc'd string
#define _if_pgmout_str(cmp, result, component) do { \
if(!base || cmp(base->component, pgm->component)) \
dev_part_strct_entry(tsv, ".prog", id, NULL, #component, result, pgm->comments); \
} while(0)
#define _partout(fmt, component) \
dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, dev_sprintf(fmt, p->component), p->comments)
#define _if_partout(cmp, fmt, component) do { \
if(!base || cmp(base->component, p->component)) \
dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, dev_sprintf(fmt, p->component), p->comments); \
} while(0)
#define _if_n_partout(cmp, n, fmt, component) do { \
if(!base || cmp(base->component, p->component, n)) \
dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, dev_sprintf(fmt, p->component), p->comments); \
} while(0)
// Result must be a malloc'd string
#define _partout_str(result, component) \
dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result, p->comments)
// Result must be a malloc'd string
#define _if_partout_str(cmp, result, component) do { \
if(!base || cmp(base->component, p->component)) \
dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result, p->comments); \
} while(0)
// Result must be a malloc'd string
#define _if_n_partout_str(cmp, n, result, component) do { \
if(!base || cmp(base->component, p->component, n)) \
dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result, p->comments); \
} while(0)
#define _memout(fmt, component) \
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, dev_sprintf(fmt, m->component), m->comments)
#define _if_memout(cmp, fmt, component) do { \
if(!bm || cmp(bm->component, m->component)) \
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, dev_sprintf(fmt, m->component), m->comments); \
} while(0)
// Result must be a malloc'd string
#define _memout_str(result, component) \
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, result, m->comments)
// Result must be a malloc'd string
#define _if_n_memout_str(cmp, n, result, component) do { \
if(!bm || cmp(bm->component, m->component, n)) \
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, result, m->comments); \
} while(0)
#define _memout_yn(component) \
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, cfg_strdup("_memout_yn()", m->component? "yes": "no"), m->comments)
#define _if_memout_yn(component) do { \
if(!bm || bm->component != m->component) \
dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, cfg_strdup("_if_memout_yn()", m->component? "yes": "no"), m->comments); \
} while(0)
#define _flagout(mask, name) \
_partout_str(cfg_strdup("_flagout()", p->flags & (mask)? "yes": "no"), name)
#define _if_flagout(mask, name) do { \
if(!base || (base->flags & (mask)) != (p->flags & (mask))) \
_partout_str(cfg_strdup("_if_flagout()", p->flags & (mask)? "yes": "no"), name); \
} while(0)
// Result must be a malloc'd string
#define _cmderr(result, component) \
dev_part_strct_entry(tsv, ".cmderr", p->desc, m->desc, #component, result, NULL)
#endif

112
src/dfu.c
View File

@@ -38,9 +38,8 @@
#ifndef HAVE_LIBUSB
struct dfu_dev *dfu_open(char *port_name) {
avrdude_message(MSG_INFO, "%s: Error: No USB support in this compile of avrdude\n",
progname);
struct dfu_dev *dfu_open(const char *port_name) {
pmsg_error("no USB support compiled for avrdude\n");
return NULL;
}
@@ -99,8 +98,7 @@ static char * get_usb_string(usb_dev_handle * dev_handle, int index);
/* EXPORTED FUNCTION DEFINITIONS
*/
struct dfu_dev * dfu_open(char *port_spec)
{
struct dfu_dev *dfu_open(const char *port_spec) {
struct dfu_dev *dfu;
char *bus_name = NULL;
char *dev_name = NULL;
@@ -112,16 +110,14 @@ struct dfu_dev * dfu_open(char *port_spec)
*/
if (strncmp(port_spec, "usb", 3) != 0) {
avrdude_message(MSG_INFO, "%s: Error: "
"Invalid port specification \"%s\" for USB device\n",
progname, port_spec);
pmsg_error("invalid port specification %s for USB device\n", port_spec);
return NULL;
}
if(':' == port_spec[3]) {
bus_name = strdup(port_spec + 3 + 1);
if (bus_name == NULL) {
avrdude_message(MSG_INFO, "%s: Out of memory in strdup\n", progname);
pmsg_error("out of memory in strdup\n");
return NULL;
}
@@ -138,7 +134,7 @@ struct dfu_dev * dfu_open(char *port_spec)
if (dfu == NULL)
{
avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
pmsg_error("out of memory\n");
free(bus_name);
return NULL;
}
@@ -172,9 +168,7 @@ int dfu_init(struct dfu_dev *dfu, unsigned short vid, unsigned short pid)
*/
if (pid == 0 && dfu->dev_name == NULL) {
avrdude_message(MSG_INFO, "%s: Error: No DFU support for part; "
"specify PID in config or USB address (via -P) to override.\n",
progname);
pmsg_error("no DFU support for part; specify PID in config or USB address (via -P) to override\n");
return -1;
}
@@ -209,20 +203,18 @@ int dfu_init(struct dfu_dev *dfu, unsigned short vid, unsigned short pid)
* why the match failed, and if we came across another DFU-capable part.
*/
avrdude_message(MSG_INFO, "%s: Error: No matching USB device found\n", progname);
pmsg_error("no matching USB device found\n");
return -1;
}
if(verbose)
avrdude_message(MSG_INFO, "%s: Found VID=0x%04x PID=0x%04x at %s:%s\n",
progname, found->descriptor.idVendor, found->descriptor.idProduct,
found->bus->dirname, found->filename);
pmsg_notice("found VID=0x%04x PID=0x%04x at %s:%s\n",
found->descriptor.idVendor, found->descriptor.idProduct,
found->bus->dirname, found->filename);
dfu->dev_handle = usb_open(found);
if (dfu->dev_handle == NULL) {
avrdude_message(MSG_INFO, "%s: Error: USB device at %s:%s: %s\n",
progname, found->bus->dirname, found->filename, usb_strerror());
pmsg_error("USB device at %s:%s: %s\n", found->bus->dirname, found->filename, usb_strerror());
return -1;
}
@@ -272,37 +264,32 @@ int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status)
{
int result;
avrdude_message(MSG_TRACE, "%s: dfu_getstatus(): issuing control IN message\n",
progname);
pmsg_trace("dfu_getstatus(): issuing control IN message\n");
result = usb_control_msg(dfu->dev_handle,
0x80 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_GETSTATUS, 0, 0,
(char*) status, sizeof(struct dfu_status), dfu->timeout);
if (result < 0) {
avrdude_message(MSG_INFO, "%s: Error: Failed to get DFU status: %s\n",
progname, usb_strerror());
pmsg_error("unable to get DFU status: %s\n", usb_strerror());
return -1;
}
if (result < sizeof(struct dfu_status)) {
avrdude_message(MSG_INFO, "%s: Error: Failed to get DFU status: %s\n",
progname, "short read");
pmsg_error("unable to get DFU status: %s\n", "short read");
return -1;
}
if (result > sizeof(struct dfu_status)) {
avrdude_message(MSG_INFO, "%s: Error: Oversize read (should not happen); "
"exiting\n", progname);
pmsg_error("oversize read (should not happen); exiting\n");
exit(1);
}
avrdude_message(MSG_TRACE, "%s: dfu_getstatus(): bStatus 0x%02x, bwPollTimeout %d, bState 0x%02x, iString %d\n",
progname,
status->bStatus,
status->bwPollTimeout[0] | (status->bwPollTimeout[1] << 8) | (status->bwPollTimeout[2] << 16),
status->bState,
status->iString);
pmsg_trace("dfu_getstatus(): bStatus 0x%02x, bwPollTimeout %d, bState 0x%02x, iString %d\n",
status->bStatus,
status->bwPollTimeout[0] | (status->bwPollTimeout[1] << 8) | (status->bwPollTimeout[2] << 16),
status->bState,
status->iString);
return 0;
}
@@ -311,16 +298,14 @@ int dfu_clrstatus(struct dfu_dev *dfu)
{
int result;
avrdude_message(MSG_TRACE, "%s: dfu_clrstatus(): issuing control OUT message\n",
progname);
pmsg_trace("dfu_clrstatus(): issuing control OUT message\n");
result = usb_control_msg(dfu->dev_handle,
USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_CLRSTATUS, 0, 0,
NULL, 0, dfu->timeout);
if (result < 0) {
avrdude_message(MSG_INFO, "%s: Error: Failed to clear DFU status: %s\n",
progname, usb_strerror());
pmsg_error("unable to clear DFU status: %s\n", usb_strerror());
return -1;
}
@@ -331,16 +316,14 @@ int dfu_abort(struct dfu_dev *dfu)
{
int result;
avrdude_message(MSG_TRACE, "%s: dfu_abort(): issuing control OUT message\n",
progname);
pmsg_trace("dfu_abort(): issuing control OUT message\n");
result = usb_control_msg(dfu->dev_handle,
USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_ABORT, 0, 0,
NULL, 0, dfu->timeout);
if (result < 0) {
avrdude_message(MSG_INFO, "%s: Error: Failed to reset DFU state: %s\n",
progname, usb_strerror());
pmsg_error("unable to reset DFU state: %s\n", usb_strerror());
return -1;
}
@@ -352,29 +335,26 @@ int dfu_dnload(struct dfu_dev *dfu, void *ptr, int size)
{
int result;
avrdude_message(MSG_TRACE, "%s: dfu_dnload(): issuing control OUT message, wIndex = %d, ptr = %p, size = %d\n",
progname, wIndex, ptr, size);
pmsg_trace("dfu_dnload(): issuing control OUT message, wIndex = %d, ptr = %p, size = %d\n",
wIndex, ptr, size);
result = usb_control_msg(dfu->dev_handle,
USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_DNLOAD, wIndex++, 0,
ptr, size, dfu->timeout);
if (result < 0) {
avrdude_message(MSG_INFO, "%s: Error: DFU_DNLOAD failed: %s\n",
progname, usb_strerror());
pmsg_error("DFU_DNLOAD failed: %s\n", usb_strerror());
return -1;
}
if (result < size) {
avrdude_message(MSG_INFO, "%s: Error: DFU_DNLOAD failed: %s\n",
progname, "short write");
pmsg_error("DFU_DNLOAD failed: short write\n");
return -1;
}
if (result > size) {
avrdude_message(MSG_INFO, "%s: Error: Oversize write (should not happen); " \
"exiting\n", progname);
exit(1);
pmsg_error("DFU_DNLOAD failed: oversize write (should not happen)\n");
return -1;
}
return 0;
@@ -384,28 +364,25 @@ int dfu_upload(struct dfu_dev *dfu, void *ptr, int size)
{
int result;
avrdude_message(MSG_TRACE, "%s: dfu_upload(): issuing control IN message, wIndex = %d, ptr = %p, size = %d\n",
progname, wIndex, ptr, size);
pmsg_trace("dfu_upload(): issuing control IN message, wIndex = %d, ptr = %p, size = %d\n",
wIndex, ptr, size);
result = usb_control_msg(dfu->dev_handle,
0x80 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_UPLOAD, wIndex++, 0,
ptr, size, dfu->timeout);
if (result < 0) {
avrdude_message(MSG_INFO, "%s: Error: DFU_UPLOAD failed: %s\n",
progname, usb_strerror());
pmsg_error("DFU_UPLOAD failed: %s\n", usb_strerror());
return -1;
}
if (result < size) {
avrdude_message(MSG_INFO, "%s: Error: DFU_UPLOAD failed: %s\n",
progname, "short read");
pmsg_error("DFU_UPLOAD failed: %s\n", "short read");
return -1;
}
if (result > size) {
avrdude_message(MSG_INFO, "%s: Error: Oversize read (should not happen); "
"exiting\n", progname);
pmsg_error("oversize read (should not happen); exiting\n");
exit(1);
}
@@ -415,26 +392,26 @@ int dfu_upload(struct dfu_dev *dfu, void *ptr, int size)
void dfu_show_info(struct dfu_dev *dfu)
{
if (dfu->manf_str != NULL)
avrdude_message(MSG_INFO, " USB Vendor : %s (0x%04hX)\n",
msg_info(" USB Vendor : %s (0x%04hX)\n",
dfu->manf_str, (unsigned short) dfu->dev_desc.idVendor);
else
avrdude_message(MSG_INFO, " USB Vendor : 0x%04hX\n",
msg_info(" USB Vendor : 0x%04hX\n",
(unsigned short) dfu->dev_desc.idVendor);
if (dfu->prod_str != NULL)
avrdude_message(MSG_INFO, " USB Product : %s (0x%04hX)\n",
msg_info(" USB Product : %s (0x%04hX)\n",
dfu->prod_str, (unsigned short) dfu->dev_desc.idProduct);
else
avrdude_message(MSG_INFO, " USB Product : 0x%04hX\n",
msg_info(" USB Product : 0x%04hX\n",
(unsigned short) dfu->dev_desc.idProduct);
avrdude_message(MSG_INFO, " USB Release : %hu.%hu.%hu\n",
msg_info(" USB Release : %hu.%hu.%hu\n",
((unsigned short) dfu->dev_desc.bcdDevice >> 8) & 0xFF,
((unsigned short) dfu->dev_desc.bcdDevice >> 4) & 0xF,
((unsigned short) dfu->dev_desc.bcdDevice >> 0) & 0xF);
if (dfu->serno_str != NULL)
avrdude_message(MSG_INFO, " USB Serial No : %s\n", dfu->serno_str);
msg_info(" USB Serial No : %s\n", dfu->serno_str);
}
/* INTERNAL FUNCTION DEFINITIONS
@@ -451,15 +428,14 @@ char * get_usb_string(usb_dev_handle * dev_handle, int index) {
result = usb_get_string_simple(dev_handle, index, buffer, sizeof(buffer)-1);
if (result < 0) {
avrdude_message(MSG_INFO, "%s: Warning: Failed to read USB device string %d: %s\n",
progname, index, usb_strerror());
pmsg_error("unable to read USB device string %d: %s\n", index, usb_strerror());
return NULL;
}
str = malloc(result+1);
if (str == NULL) {
avrdude_message(MSG_INFO, "%s: Out of memory allocating a string\n", progname);
pmsg_error("out of memory allocating a string\n");
return 0;
}

View File

@@ -114,7 +114,7 @@ struct dfu_status {
// FUNCTIONS
extern struct dfu_dev * dfu_open(char *port_spec);
extern struct dfu_dev *dfu_open(const char *port_spec);
extern int dfu_init(struct dfu_dev *dfu,
unsigned short vid, unsigned short pid);
extern void dfu_close(struct dfu_dev *dfu);

179
src/doc/CMakeLists.txt Normal file
View File

@@ -0,0 +1,179 @@
#
# CMakeLists.txt - CMake project for AVRDUDE documentation
# Copyright (C) 2022 Marius Greuel
#
# 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/>.
#
set(AVRDUDE_CONF "${PROJECT_BINARY_DIR}/src/avrdude.conf")
set(TEXINFOS "${CMAKE_CURRENT_SOURCE_DIR}/avrdude.texi")
set(GENERATED_TEXINFOS
programmers.texi
programmer_types.texi
parts.texi
version.texi
)
string(TIMESTAMP TODAY "%d %B %Y")
set(DOCS_VERSION ${PROJECT_VERSION})
set(DOCS_UPDATED ${TODAY})
find_program(MAKEINFO_EXECUTABLE NAMES makeinfo)
find_program(TEXI2HTML_EXECUTABLE NAMES texi2html)
# =====================================
# Custom rules for auto-generated texi
# =====================================
add_custom_target(avrdude_binaries DEPENDS avrdude conf)
add_custom_command(
OUTPUT programmers.txt
DEPENDS avrdude_binaries
COMMAND $<TARGET_FILE:avrdude> -C ${AVRDUDE_CONF} -c ? 2>&1 | more > programmers.txt
VERBATIM
)
add_custom_command(
OUTPUT programmer_types.txt
DEPENDS avrdude_binaries
COMMAND $<TARGET_FILE:avrdude> -C ${AVRDUDE_CONF} -c ?type 2>&1 | more > programmer_types.txt
VERBATIM
)
add_custom_command(
OUTPUT parts.txt
DEPENDS avrdude_binaries
COMMAND $<TARGET_FILE:avrdude> -C ${AVRDUDE_CONF} -p ? 2>&1 | more > parts.txt
VERBATIM
)
add_custom_command(
OUTPUT programmers.texi
DEPENDS programmers.txt
COMMAND ${CMAKE_COMMAND}
-D TXT_FILE=programmers.txt
-D TEXI_FILE=programmers.texi
-P "${CMAKE_CURRENT_SOURCE_DIR}/programmers.cmake"
VERBATIM
)
add_custom_command(
OUTPUT programmer_types.texi
DEPENDS programmer_types.txt
COMMAND ${CMAKE_COMMAND}
-D TXT_FILE=programmer_types.txt
-D TEXI_FILE=programmer_types.texi
-P "${CMAKE_CURRENT_SOURCE_DIR}/programmer_types.cmake"
VERBATIM
)
add_custom_command(
OUTPUT parts.texi
DEPENDS parts.txt
COMMAND ${CMAKE_COMMAND}
-D TXT_FILE=parts.txt
-D TEXI_FILE=parts.texi
-D COMMENTS_FILE=${CMAKE_CURRENT_SOURCE_DIR}/parts_comments.txt
-P "${CMAKE_CURRENT_SOURCE_DIR}/parts.cmake"
VERBATIM
)
add_custom_command(
OUTPUT version.texi
COMMAND ${CMAKE_COMMAND} -E echo "@set EDITION ${DOCS_VERSION}" > version.texi
COMMAND ${CMAKE_COMMAND} -E echo "@set VERSION ${DOCS_VERSION}" >> version.texi
COMMAND ${CMAKE_COMMAND} -E echo "@set UPDATED ${DOCS_UPDATED}" >> version.texi
VERBATIM
)
# =====================================
# Custom rules for output files
# =====================================
add_custom_command(
OUTPUT avrdude.info
COMMAND ${MAKEINFO_EXECUTABLE} -o avrdude.info ${TEXINFOS}
DEPENDS ${TEXINFOS} ${GENERATED_TEXINFOS}
VERBATIM
)
add_custom_command(
OUTPUT avrdude.dvi
COMMAND ${MAKEINFO_EXECUTABLE}
--dvi
--Xopt=--quiet
--Xopt=--build-dir=dvi
-o avrdude.dvi
${TEXINFOS}
DEPENDS ${TEXINFOS} ${GENERATED_TEXINFOS}
VERBATIM
)
add_custom_command(
OUTPUT avrdude.pdf
COMMAND ${MAKEINFO_EXECUTABLE}
--pdf
--Xopt=--quiet
--Xopt=--build-dir=pdf
-o avrdude.pdf
${TEXINFOS}
DEPENDS ${TEXINFOS} ${GENERATED_TEXINFOS}
VERBATIM
)
add_custom_command(
OUTPUT avrdude.ps
COMMAND ${MAKEINFO_EXECUTABLE}
--ps
--Xopt=--quiet
--Xopt=--build-dir=ps
-o avrdude.ps
${TEXINFOS}
DEPENDS ${TEXINFOS} ${GENERATED_TEXINFOS}
VERBATIM
)
add_custom_command(
OUTPUT avrdude-html/avrdude.html
COMMAND ${TEXI2HTML_EXECUTABLE}
--split=node
--css-include=avrdude.css
--output=avrdude-html
-I ${CMAKE_CURRENT_BINARY_DIR}
${TEXINFOS}
DEPENDS ${TEXINFOS} ${GENERATED_TEXINFOS} avrdude.css
VERBATIM
)
# =====================================
# Custom targets for output files
# =====================================
add_custom_target(info ALL DEPENDS avrdude.info)
add_custom_target(dvi ALL DEPENDS avrdude.dvi)
add_custom_target(pdf ALL DEPENDS avrdude.pdf)
add_custom_target(ps ALL DEPENDS avrdude.ps)
add_custom_target(html ALL DEPENDS avrdude-html/avrdude.html)
# =====================================
# Install
# =====================================
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/avrdude.info" DESTINATION ${CMAKE_INSTALL_INFODIR})
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/avrdude.dvi" DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/avrdude.pdf" DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/avrdude.ps" DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/avrdude-html" DESTINATION ${CMAKE_INSTALL_DOCDIR})

View File

@@ -250,7 +250,8 @@ See below for the limitations of debugWire.
For ATxmega devices, the JTAG ICE mkII/3 is supported in PDI mode, provided it
has a revision 1 hardware and firmware version of at least 5.37 (decimal).
The Atmel-ICE (ARM/AVR) is supported (JTAG, PDI for Xmega, debugWIRE, ISP modes).
The Atmel-ICE (ARM/AVR) is supported (JTAG, PDI for Xmega, debugWIRE, ISP,
UPDI).
Atmel's XplainedPro boards, using EDBG protocol (CMSIS-DAP compliant), are
supported by the ``jtag3'' programmer type.
@@ -321,13 +322,13 @@ via a serial link (@url{https://github.com/ElTangas/jtag2updi}).
The Micronucleus bootloader is supported for both protocol version V1
and V2. As the bootloader does not support reading from flash memory,
use the @code{-V} option to prevent AVRDUDE from verifing the flash memory.
use the @code{-V} option to prevent AVRDUDE from verifying the flash memory.
See the section on @emph{extended parameters}
below for Micronucleus specific options.
The Teensy bootloader is supported for all AVR boards.
As the bootloader does not support reading from flash memory,
use the @code{-V} option to prevent AVRDUDE from verifing the flash memory.
use the @code{-V} option to prevent AVRDUDE from verifying the flash memory.
See the section on @emph{extended parameters}
below for Teensy specific options.
@@ -398,14 +399,19 @@ following options are recognized:
@table @code
@item -p @var{partno}
This is the only mandatory option and it tells AVRDUDE what type of part
(MCU) that is connected to the programmer. The @var{partno} parameter
is the part's id listed in the configuration file. Specify -p ? to list
all parts in the configuration file. If a part is unknown
to AVRDUDE, it means that there is no config file entry for that part,
but it can be added to the configuration file if you have the Atmel
datasheet so that you can enter the programming specifications.
Currently, the following MCU types are understood:
This option tells AVRDUDE what part (MCU) is connected to the programmer.
The @var{partno} parameter is the part's id listed in the configuration file.
For currently supported MCU types use ? as partno, which will print a list of
partno ids and official part names on the terminal. Both can be used with the
-p option. If a part is unknown to AVRDUDE, it means that there is no config
file entry for that part, but it can be added to the configuration file if
you have the Atmel datasheet so that you can enter the programming
specifications. If @code{-p ?} is specified with a specific programmer, see
@code{-c} below, then only those parts are output that the programmer expects
to be able to handle, together with the programming interface(s) that can be
used in that combination. In reality there can be deviations from this list,
particularly if programming is directly via a bootloader. Currently, the
following MCU types are understood:
@cindex Device support
@@ -458,7 +464,12 @@ AVRDUDE, and the programmer is controlled via the PC parallel port,
there's a good chance that it can be easily added to the configuration
file without any code changes to AVRDUDE. Simply copy an existing entry
and change the pin definitions to match that of the unknown programmer.
Currently, the following programmer ids are understood and supported:
If @code{-c ?} is specified with a specific part, see @code{-p} above, then
only those programmers are output that expect to be able to handle this part,
together with the programming interface(s) that can be used in that
combination. In reality there can be deviations from this list, particularly
if programming is directly via a bootloader. Currently, the following
programmer ids are understood and supported:
@cindex Programmer support
@@ -495,6 +506,16 @@ without patching your system wide configuration file. It can be used
several times, the files are read in same order as given on the command
line.
@item -A
Disable the automatic removal of trailing-0xFF sequences in file
input that is to be programmed to flash and in AVR reads from
flash memory. Normally, trailing 0xFFs can be discarded, as flash
programming requires the memory be erased to 0xFF beforehand. -A
should be used when the programmer hardware, or bootloader
software for that matter, does not carry out chip erase and
instead handles the memory erase on a page level. The popular
Arduino bootloader exhibits this behaviour; for this reason -A is
engaged by default when specifying -c arduino.
@item -D
Disable auto erase for flash. When the -U option with flash memory is
@@ -506,6 +527,7 @@ use page erase before writing each page so no explicit chip erase
is required.
Note however that any page not affected by the current operation
will retain its previous contents.
Setting -D implies -A.
@item -e
Causes a chip erase to be executed. This will reset the contents of the
@@ -534,12 +556,16 @@ Note in particular that the programming algorithm for the AT90S1200
device mandates that the `/RESET' signal is active before powering up
the MCU, so in case an external power supply is used for this MCU type,
a previous invocation of AVRDUDE with this option specified is one of
the possible ways to guarantee this condition.
the possible ways to guarantee this condition. @code{reset} is supported
by the @code{linuxspi} and @code{flip2} programmer options, as well as
all parallel port based programmers.
@item noreset
The `/RESET' line will be deactivated at program exit, thus allowing the
MCU target program to run while the programming hardware remains
connected.
connected. @code{noreset} is supported by the @code{linuxspi} and
@code{flip2} programmer options, as well as all parallel port based
programmers.
@item vcc
This option will leave those parallel port pins active (i. e. high) that
@@ -682,6 +708,10 @@ Posix systems (by now).
Disable (or quell) output of the progress bar while reading or writing
to the device. Specify it a second time for even quieter operation.
@item -s, -u
These options used to control the obsolete "safemode" feature which
is no longer present. They are silently ignored for backwards compatibility.
@item -t
Tells AVRDUDE to enter the interactive ``terminal'' mode instead of up-
or downloading files. See below for a detailed description of the
@@ -757,6 +787,9 @@ the file to read or write. Possible values are:
@item i
Intel Hex
@item I
Intel Hex with comments on download and tolerance of checksum errors on upload
@item s
Motorola S-record
@@ -790,13 +823,16 @@ fuse bit settings.
@item h
hexadecimal; each value will get the string @emph{0x} prepended.
Only valid on output.
@item o
octal; each value will get a @emph{0}
prepended unless it is less than 8 in which case it gets no prefix.
Only valid on output.
@item b
binary; each value will get the string @emph{0b} prepended.
Only valid on output.
@end table
@@ -843,10 +879,15 @@ accepting extended parameters.
@table @code
@item JTAG ICE mkII/3
@itemx Atmel-ICE
@itemx PICkit 4
@itemx MPLAB SNAP
@itemx Power Debugger
@itemx AVR Dragon
When using the JTAG ICE mkII/3 or AVR Dragon in JTAG mode, the
following extended parameter is accepted:
When using the JTAG ICE mkII, JTAGICE3, Atmel-ICE, PICkit 4, MPLAB SNAP,
Power Debugger or AVR Dragon in JTAG mode, the following extended parameter
is accepted:
@table @code
@item @samp{jtagchain=UB,UA,BB,BA}
Setup the JTAG scan chain for @var{UB} units before, @var{UA} units
@@ -856,6 +897,14 @@ Each AVR unit within the chain shifts by 4 bits.
Other JTAG units might require a different bit shift count.
@end table
The PICkit 4 and the Power Debugger also supports high-voltage UPDI programming.
This is used to enable a UPDI pin that has previously been set to RESET or
GPIO mode. High-voltage UPDI can be utilized by using an extended parameter:
@table @code
@item @samp{hvupdi}
Enable high-voltage UPDI initialization for targets that supports this.
@end table
@cindex @code{-x} AVR910
@item AVR910
@@ -1076,6 +1125,16 @@ specific.
When not provided, driver/OS default value will be used.
@end table
@cindex @code{-x} linuxspi
@item linuxspi
Extended parameter:
@table @code
@item @samp{disable_no_cs}
Ensures the programmer does not use the SPI_NO_CS bit for the SPI
driver. This parameter is useful for kernels that do not support
the CS line being managed outside the application.
@end table
@end table
@page
@@ -1270,120 +1329,161 @@ commands can be recalled and edited.
@section Terminal Mode Commands
@noindent
The following commands are implemented:
The following commands are implemented for all programmers:
@table @code
@item dump @var{memtype} [@var{start_addr} [@var{nbytes}]]
@item dump @var{memtype} @var{addr} @var{nbytes}
Read @var{nbytes} from the specified memory area, and display them in
the usual hexadecimal and ASCII form.
@item dump @var{memtype} [@var{start_addr}] @dots{}
Start reading from @var{start_addr}, all the way to the last memory address.
@item dump @var{memtype} @var{addr} @dots{}
Start reading from @var{addr}, all the way to the last memory address.
@item dump @var{memtype} @var{addr}
Read 256 bytes from the specified memory area, and display them.
@item dump @var{memtype} @dots{}
Read all bytes from the specified memory, and display them.
@item dump @var{memtype}
Continue dumping the memory contents for another @var{nbytes} where the
previous dump command left off.
@item write @var{memtype} @var{start_addr} @var{data1} @var{data2} @dots{} @var{dataN}
Manually program the respective memory cells, starting at address @var{start_addr},
using the values @var{data1} through @var{dataN}. This feature is not
implemented for bank-addressed memories such as the flash memory of
ATMega devices.
@item read
Can be used as an alias for dump.
Items @var{dataN} can have the following formats:
@item write @var{memtype} @var{addr} @var{data[,]} @{@var{data[,]}@}
Manually program the respective memory cells, starting at address
@var{addr}, using the data items provided. The terminal implements
reading from and writing to flash and EEPROM type memories normally
through a cache and paged access functions. All other memories are
directly written to without use of a cache. Some older parts without paged
access will also have flash and EEPROM directly accessed without cache.
Items @var{data} can have the following formats:
@multitable @columnfractions .3 .4 .3
@item @strong{Type}
@tab @strong{Example}
@tab @strong{Size (bytes)}
@item String
@tab @code{"Hello, world\n"}
@tab varying
@item Character
@tab @code{'A'}
@tab 1
@item Decimal integer
@tab 12345
@tab 1, 2, 4, or 8 (see below)
@tab 1, 2, 4, or 8
@item Octal integer
@tab 012345
@tab 1, 2, 4, or 8 (see below)
@tab 1, 2, 4, or 8
@item Hexadecimal integer
@tab 0x12345
@tab 1, 2, 4, or 8 (see below)
@tab 1, 2, 4, or 8
@item Float
@tab 3.1415926
@tab 4
@item Double
@tab 3.141592653589793D
@tab 8
@end multitable
Integer constants can be 1, 2, 4, or 8 bytes long.
By default, the smallest possible size will be used where
the specified number just fits into.
A specific size can be denoted by appending one of these suffixes:
@var{data}
can be hexadecimal, octal or decimal integers, floating point numbers
or C-style strings and characters. For integers, an optional case-insensitive
suffix specifies the data size as in the table below:
@table @code
@item LL
@itemx ll
8 bytes / 64 bits
@item L
@itemx l
4 bytes / 32 bits
@item H
@itemx h
@itemx S
@itemx s
@item H or S
2 bytes / 16 bits
@item HH
@itemx hh
1 byte / 8 bits
@end table
Similarly, floating-point constants can have an @code{F} or @code{f}
appended, but only 32-bit floating-point values are supported.
Suffix @code{D} indicates a 64-bit double, @code{F} a 32-bit float, whilst a
floating point number without suffix defaults to 32-bit float. Hexadecimal
floating point notation is supported. An ambiguous trailing suffix, eg,
@code{0x1.8D}, is read as no-suffix float where @code{D} is part of the
mantissa; use a zero exponent @code{0x1.8p0D} to clarify.
@item write @var{memtype} @var{start_addr} @var{length} @var{data1} @var{data2} @var{dataN} @dots{}
An optional @code{U} suffix makes integers unsigned. Ordinary @code{0x} hex
integers are always treated as unsigned. @code{+0x} or @code{-0x} hex
numbers are treated as signed unless they have a @code{U} suffix. Unsigned
integers cannot be larger than 2^64-1. If @var{n} is an unsigned integer then @var{-n}
is also a valid unsigned integer as in C. Signed integers must fall into
the [-2^63, 2^63-1] range or a correspondingly smaller range when a suffix
specifies a smaller type. Out of range signed numbers trigger a warning.
Similar to the above, but @var{length} byte of the memory are written.
For that purpose, after writing the initial items, @var{dataN} is
replicated as many times as needed.
Ordinary @code{0x} hex integers with @var{n} hex digits (counting leading
zeros) use the smallest size of 1, 2, 4 and 8 bytes that can accommodate
any n-digit hex integer. If an integer suffix specifies a size explicitly
the corresponding number of least significant bytes are written.
Otherwise, signed and unsigned integers alike occupy the smallest of 1, 2,
4, or 8 bytes needed to accommodate them in their respective
representation.
One trailing comma at the end of data items is ignored to facilitate copy
and paste of lists.
@item write @var{memtype} @var{addr} @var{length} @var{data[,]} @{@var{data[,]}@} @dots{}
The ellipses form @dots{} of write is similar to above, but @var{length}
byte of the memory are written. For that purpose, after writing the
initial items, the last @var{data} item is replicated as many times as
needed.
@item flush
Synchronise with the device all pending cached writes to EEPROM or flash.
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 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 command should be used sparingly.
@item abort
Normally, caches are only ever actually written to the device when using
@code{flush}, at the end of the terminal session after typing @code{quit},
or after EOF on input is encountered. The @code{abort} command resets the
cache discarding all previous writes to the flash and EEPROM cache.
@item erase
Perform a chip erase.
@item send @var{b1} @var{b2} @var{b3} @var{b4}
Send raw instruction codes to the AVR device. If you need access to a
feature of an AVR part that is not directly supported by AVRDUDE, this
command allows you to use it, even though AVRDUDE does not implement the
command. When using direct SPI mode, up to 3 bytes
can be omitted.
Perform a chip erase and discard all pending writes to EEPROM and flash.
@item sig
Display the device signature bytes.
@item spi
Enter direct SPI mode. The @emph{pgmled} pin acts as slave select.
@emph{Only supported on parallel bitbang programmers, and partially by USBtiny.}
Slave Select must be externally held low for direct SPI when
using USBtinyISP, and send must be a multiple of four bytes.
@item part
Display the current part settings and parameters. Includes chip
specific information including all memory types supported by the
device, read/write timing, etc.
@item pgm
Return to programming mode (from direct SPI mode).
@item verbose [@var{level}]
Change (when @var{level} is provided), or display the verbosity
level.
The initial verbosity level is controlled by the number of @code{-v} options
given on the command line.
@item quell [@var{level}]
Change (when @var{level} is provided), or display the quell
level. 1 is used to suppress progress reports. 2 or higher yields
progressively quieter operations. The initial quell level is controlled
by the number of @code{-q} options given on the command line.
@item ?
@itemx help
Give a short on-line summary of the available commands.
@@ -1394,11 +1494,29 @@ Leave terminal mode and thus AVRDUDE.
@end table
@noindent
In addition, the following commands are supported on the STK500
and STK600 programmer:
In addition, the following commands are supported on some programmers:
@table @code
@item pgerase @var{memory} @var{addr}
Erase one page of the memory specified.
@item send @var{b1} @var{b2} @var{b3} @var{b4}
Send raw instruction codes to the AVR device. If you need access to a
feature of an AVR part that is not directly supported by AVRDUDE, this
command allows you to use it, even though AVRDUDE does not implement the
command. When using direct SPI mode, up to 3 bytes
can be omitted.
@item spi
Enter direct SPI mode. The @emph{pgmled} pin acts as slave select.
@emph{Only supported on parallel bitbang programmers, and partially by USBtiny.}
Slave Select must be externally held low for direct SPI when
using USBtinyISP, and send must be a multiple of four bytes.
@item pgm
Return to programming mode (from direct SPI mode).
@item vtarg @var{voltage}
Set the target's supply voltage to @var{voltage} Volts.
@@ -1421,7 +1539,6 @@ Turn the master oscillator off.
@item sck @var{period}
@emph{STK500 and STK600 only:}
Set the SCK clock period to @var{period} microseconds.
@emph{JTAG ICE only:}
Set the JTAG ICE bit clock period to @var{period} microseconds.
Note that unlike STK500 settings, this setting will be reverted to
@@ -1433,7 +1550,6 @@ ISP clock period when operating the ICE in ISP mode.
@item parms
@emph{STK500 and STK600 only:}
Display the current voltage and master oscillator parameters.
@emph{JTAG ICE only:}
Display the current target supply voltage and JTAG bit clock rate/period.
@@ -1659,28 +1775,32 @@ The format of the programmer definition is as follows:
@smallexample
programmer
parent <id> # <id> is a quoted string
id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
desc = <description> ; # quoted string
type = "par" | "stk500" | ... ; # programmer type (see below for a list)
baudrate = <num> ; # baudrate for serial ports
vcc = <num1> [, <num2> ... ] ; # pin number(s)
buff = <num1> [, <num2> ... ] ; # pin number(s)
reset = <num> ; # pin number
sck = <num> ; # pin number
mosi = <num> ; # pin number
miso = <num> ; # pin number
errled = <num> ; # pin number
rdyled = <num> ; # pin number
pgmled = <num> ; # pin number
vfyled = <num> ; # pin number
usbvid = <hexnum>; # USB VID (Vendor ID)
usbpid = <hexnum> [, <hexnum> ...]; # USB PID (Product ID)
usbdev = <interface>; # USB interface or other device info
usbvendor = <vendorname>; # USB Vendor Name
usbproduct = <productname>; # USB Product Name
usbsn = <serialno>; # USB Serial Number
;
parent <id> # optional parent
id = <id1> [, <id2> ... ] ; # <idN> are quoted strings
desc = <description> ; # quoted string
type = <type>; # programmer type, quoted string
# supported types can be listed by "-c ?type"
prog_modes = PM_<i/f> @{ | PM_<i/f> @} # interfaces, eg, PM_SPM|PM_PDI
connection_type = parallel | serial | usb | spi
baudrate = <num> ; # baudrate for avr910-programmer
vcc = <pin1> [, <pin2> ... ] ; # pin number(s)
buff = <pin1> [, <pin2> ... ] ; # pin number(s)
reset = <pin> ; # pin number
sck = <pin> ; # pin number
mosi = <pin> ; # pin number
miso = <pin> ; # pin number
errled = <pin> ; # pin number
rdyled = <pin> ; # pin number
pgmled = <pin> ; # pin number
vfyled = <pin> ; # pin number
usbvid = <hexnum> ; # USB VID (Vendor ID)
usbpid = <hexnum> [, <hexnum> ...] ; # USB PID (Product ID)
usbdev = <interface> ; # USB interface or other device info
usbvendor = <vendorname> ; # USB Vendor Name
usbproduct = <productname> ; # USB Product Name
usbsn = <serialno> ; # USB Serial Number
hvupdi_support = <num> [, <num>, ... ] ; # UPDI HV Variants Support
;
@end smallexample
@noindent
@@ -1688,13 +1808,32 @@ If a parent is specified, all settings of it (except its ids) are used for the n
programmer. These values can be changed by new setting them for the new programmer.
@noindent
To invert a bit in the pin definitions, use @code{= ~ <num>}.
Known programming modes are
@itemize @bullet
@item @code{PM_SPM}: Bootloaders, self-programming with SPM opcodes or NVM Controllers
@item @code{PM_TPI}: Tiny Programming Interface (t4, t5, t9, t10, t20, t40, t102, t104)
@item @code{PM_ISP}: SPI programming for In-System Programming (almost all classic parts)
@item @code{PM_PDI}: Program and Debug Interface (xmega parts)
@item @code{PM_UPDI}: Unified Program and Debug Interface
@item @code{PM_HVSP}: High Voltage Serial Programming (some classic parts)
@item @code{PM_HVPP}: High Voltage Parallel Programming (most non-HVSP classic parts)
@item @code{PM_debugWIRE}: Simpler alternative to JTAG (a subset of HVPP/HVSP parts)
@item @code{PM_JTAG}: Joint Test Action Group standard (some classic parts)
@item @code{PM_JTAGmkI}: Subset of @code{PM_JTAG}, older parts, Atmel ICE mkI
@item @code{PM_XMEGAJTAG}: JTAG, some XMEGA parts
@item @code{PM_AVR32JTAG}: JTAG for 32-bit AVRs
@item @code{PM_aWire}: AVR32 parts
@end itemize
@noindent
To invert a bit in the pin definitions, use @code{= ~ <num>}. To invert a pin list
(all pins get inverted) use @code{~ ( <num1> [, <num2> ... ] )}.
@noindent
Not all programmer types can handle a list of USB PIDs.
@noindent
Following programmer types are currently implemented:
The following programmer types are currently implemented:
@multitable @columnfractions .25 .6
@include programmer_types.texi
@@ -1708,30 +1847,36 @@ Following programmer types are currently implemented:
@smallexample
part
id = <id> ; # quoted string
desc = <description> ; # quoted string
family_id = <description> ; # quoted string
has_jtag = <yes/no> ; # part has JTAG i/f
has_debugwire = <yes/no> ; # part has debugWire i/f
has_pdi = <yes/no> ; # part has PDI i/f
has_updi = <yes/no> ; # part has UPDI i/f
has_tpi = <yes/no> ; # part has TPI i/f
devicecode = <num> ; # numeric
id = <id> ; # quoted string
family_id = <id> ; # quoted string, eg, "megaAVR" or "tinyAVR"
prog_modes = PM_<i/f> @{| PM_<i/f>@} # interfaces, eg, PM_SPM|PM_ISP|PM_HVPP|PM_debugWIRE
mcuid = <num>; # unique id in 0..2039 for 8-bit AVRs
n_interrupts = <num>; # number of interrupts, used for vector bootloaders
n_page_erase = <num>; # if set, number of pages erased during NVM erase
hvupdi_variant = <num> ; # numeric -1 (n/a) or 0..2
devicecode = <num> ; # deprecated, use stk500_devcode
stk500_devcode = <num> ; # numeric
avr910_devcode = <num> ; # numeric
has_jtag = <yes/no> ; # part has JTAG i/f (deprecated, use prog_modes)
has_debugwire = <yes/no> ; # part has debugWire i/f (deprecated, use prog_modes)
has_pdi = <yes/no> ; # part has PDI i/f (deprecated, use prog_modes)
has_updi = <yes/no> ; # part has UPDI i/f (deprecated, use prog_modes)
has_tpi = <yes/no> ; # part has TPI i/f (deprecated, use prog_modes)
is_avr32 = <yes/no> ; # AVR32 part (deprecated, use prog_modes)
is_at90s1200 = <yes/no> ; # AT90S1200 part
signature = <num> <num> <num> ; # signature bytes
usbpid = <num> ; # DFU USB PID
reset = dedicated | io;
retry_pulse = reset | sck;
pgm_enable = <instruction format> ;
chip_erase = <instruction format> ;
chip_erase_delay = <num> ; # micro-seconds
reset = dedicated | io ;
retry_pulse = reset | sck ;
chip_erase_delay = <num> ; # chip erase delay (us)
# STK500 parameters (parallel programming IO lines)
pagel = <num> ; # pin name in hex, i.e., 0xD7
bs2 = <num> ; # pin name in hex, i.e., 0xA0
serial = <yes/no> ; # can use serial downloading
parallel = <yes/no/pseudo>; # can use par. programming
# STK500v2 parameters, to be taken from Atmel's XML files
parallel = <yes/no/pseudo> ; # can use par. programming
# STK500v2 parameters, to be taken from Atmel's ATDF files
timeout = <num> ;
stabdelay = <num> ;
cmdexedelay = <num> ;
@@ -1742,52 +1887,60 @@ part
predelay = <num> ;
postdelay = <num> ;
pollmethod = <num> ;
mode = <num> ;
delay = <num> ;
blocksize = <num> ;
readsize = <num> ;
hvspcmdexedelay = <num> ;
# STK500v2 HV programming parameters, from XML
pp_controlstack = <num>, <num>, ...; # PP only
hvsp_controlstack = <num>, <num>, ...; # HVSP only
hventerstabdelay = <num>;
progmodedelay = <num>; # PP only
latchcycles = <num>;
togglevtg = <num>;
poweroffdelay = <num>;
resetdelayms = <num>;
resetdelayus = <num>;
hvleavestabdelay = <num>;
resetdelay = <num>;
synchcycles = <num>; # HVSP only
chiperasepulsewidth = <num>; # PP only
chiperasepolltimeout = <num>;
chiperasetime = <num>; # HVSP only
programfusepulsewidth = <num>; # PP only
programfusepolltimeout = <num>;
programlockpulsewidth = <num>; # PP only
programlockpolltimeout = <num>;
# JTAG ICE mkII parameters, also from XML files
# STK500v2 HV programming parameters, from ATDFs
pp_controlstack = <num>, <num>, ... ; # PP only
hvsp_controlstack = <num>, <num>, ... ; # HVSP only
flash_instr = <num>, <num>, <num> ;
eeprom_instr = <num>, <num>, ... ;
hventerstabdelay = <num> ;
progmodedelay = <num> ; # PP only
latchcycles = <num> ;
togglevtg = <num> ;
poweroffdelay = <num> ;
resetdelayms = <num> ;
resetdelayus = <num> ;
hvleavestabdelay = <num> ;
resetdelay = <num> ;
synchcycles = <num> ; # HVSP only
chiperasepulsewidth = <num> ; # PP only
chiperasepolltimeout = <num> ;
chiperasetime = <num> ; # HVSP only
programfusepulsewidth = <num> ; # PP only
programfusepolltimeout = <num> ;
programlockpulsewidth = <num> ; # PP only
programlockpolltimeout = <num> ;
# JTAG ICE mkII parameters, also from ATDF files
allowfullpagebitstream = <yes/no> ;
enablepageprogramming = <yes/no> ;
idr = <num> ; # IO addr of IDR (OCD) reg.
rampz = <num> ; # IO addr of RAMPZ reg.
spmcr = <num> ; # mem addr of SPMC[S]R reg.
eecr = <num> ; # mem addr of EECR reg.
# (only when != 0x3c)
is_at90s1200 = <yes/no> ; # AT90S1200 part
is_avr32 = <yes/no> ; # AVR32 part
idr = <num> ; # IO addr of IDR (OCD) reg
rampz = <num> ; # IO addr of RAMPZ reg
spmcr = <num> ; # mem addr of SPMC[S]R reg
eecr = <num> ; # mem addr of EECR reg only when != 0x3f
mcu_base = <num> ;
nvm_base = <num> ;
ocd_base = <num> ;
ocdrev = <num> ;
pgm_enable = <instruction format> ;
chip_erase = <instruction format> ;
memory <memtype>
paged = <yes/no> ; # yes / no
paged = <yes/no> ; # yes/no (flash only, do not use for EEPROM)
offset = <num> ; # memory offset
size = <num> ; # bytes
page_size = <num> ; # bytes
num_pages = <num> ; # numeric
n_word_writes = <num> ; # TPI only: if set, number of words to write
min_write_delay = <num> ; # micro-seconds
max_write_delay = <num> ; # micro-seconds
readback_p1 = <num> ; # byte value
readback_p2 = <num> ; # byte value
pwroff_after_write = <yes/no> ; # yes / no
readback = <num> <num> ; # pair of byte values
readback_p1 = <num> ; # byte value (first component)
readback_p2 = <num> ; # byte value (second component)
pwroff_after_write = <yes/no> ; # yes/no
mode = <num> ; # STK500 v2 file parameter from ATDF files
delay = <num> ; # "
blocksize = <num> ; # "
readsize = <num> ; # "
read = <instruction format> ;
write = <instruction format> ;
read_lo = <instruction format> ;
@@ -1797,10 +1950,20 @@ part
loadpage_lo = <instruction format> ;
loadpage_hi = <instruction format> ;
writepage = <instruction format> ;
;
;
;
;
@end smallexample
@noindent
If any of the above parameters are not specified, the default value
of 0 is used for numerics (except for @code{mcuid}, @code{hvupdi_variant} and @code{ocdrev},
where the default value is -1) or the empty string @code{""} for string
values. If a required parameter is left empty, AVRDUDE will complain.
Almost all occurrences of numbers (with the exception of pin numbers
and where they are separated by space, eg, in signature and readback)
can also be given as simple expressions involving arithemtic and
bitwise operators.
@menu
* Parent Part::
* Instruction Format::
@@ -1813,11 +1976,19 @@ part
@subsection Parent Part
@noindent
Parts can also inherit parameters from previously defined parts
using the following syntax. In this case specified integer and
string values override parameter values from the parent part. New
memory definitions are added to the definitions inherited from the
parent.
Parts can also inherit parameters from previously defined parts using
the following syntax. In this case specified integer and string values
override parameter values from the parent part. New memory definitions
are added to the definitions inherited from the parent. If, however, a
new memory definition refers to an existing one of the same name for
that part then, from v7.1, the existing memory definition is extended,
and components overwritten with new values. Assigning @code{NULL}
removes an inherited SPI instruction format, memory definition, control
stack, eeprom or flash instruction, eg, as in @code{memory "efuse" =
NULL;}
@noindent
Example format for part inheritance:
@smallexample
part parent <id> # quoted string
@@ -1879,7 +2050,22 @@ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
@end smallexample
As the address bit numbers in the SPI opcodes are highly systematic, they
don't really need to be specified. A compact version of the format
specification neither uses bit-numbers for address lines nor spaces. If such
a string is longer than 7 characters, then the characters @code{0}, @code{1},
@code{x}, @code{a}, @code{i} and @code{o} will be recognised as the
corresponding bit, whilst any of the characters @code{.}, @code{-}, @code{_}
or @code{/} can act as arbitrary visual separators, which are ignored.
Examples:
@smallexample
loadpage_lo = "0100.0000--000x.xxxx--xxaa.aaaa--iiii.iiii";
loadpage_lo = "0100.0000", "000x.xxxx", "xxaa.aaaa", "iiii.iiii";
@end smallexample
@c
@c Node

37
src/doc/parts.cmake Normal file
View File

@@ -0,0 +1,37 @@
#
# programmers.cmake - create parts.texi from parts.txt
# Copyright (C) 2022 Marius Greuel
#
# 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/>.
#
file(STRINGS ${COMMENTS_FILE} COMMENTS_CONTENTS)
file(STRINGS ${TXT_FILE} TXT_CONTENTS REGEX "=")
set(TEXI_CONTENTS "")
foreach(TXT_LINE IN LISTS TXT_CONTENTS)
string(REGEX REPLACE "^[ \t]*([^ \t]+)[ \t]*=[ \t]*(.*)$" "@item @code{\\1} @tab \\2" TEXI_LINE "${TXT_LINE}")
foreach(COMMENTS_LINE IN LISTS COMMENTS_CONTENTS)
string(REGEX MATCH "^([^ \t]*)(.*)$" DUMMY "${COMMENTS_LINE}")
set(PART_REGEX "${CMAKE_MATCH_1}")
set(COMMENT "${CMAKE_MATCH_2}")
string(REGEX REPLACE "(${PART_REGEX})" "\\1${COMMENT}" TEXI_LINE "${TEXI_LINE}")
endforeach()
set(TEXI_CONTENTS "${TEXI_CONTENTS}${TEXI_LINE}\n")
endforeach()
file(WRITE ${TEXI_FILE} "${TEXI_CONTENTS}")

View File

@@ -0,0 +1,28 @@
#
# programmer_types.cmake - create programmer_types.texi from programmer_types.txt
# Copyright (C) 2022 Marius Greuel
#
# 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/>.
#
file(STRINGS ${TXT_FILE} TXT_CONTENTS REGEX "=")
SET(TEXI_CONTENTS "")
foreach(TXT_LINE IN LISTS TXT_CONTENTS)
string(REGEX REPLACE "^[ \t]*([^ \t]+)[ \t]*=[ \t]*(.*)$" "@item @code{\\1} @tab \\2" TEXI_LINE "${TXT_LINE}")
string(REGEX REPLACE "<?(http[s]?://[^ \t,>]+)>?" "@url{\\1}" TEXI_LINE "${TEXI_LINE}")
set(TEXI_CONTENTS "${TEXI_CONTENTS}${TEXI_LINE}\n")
endforeach()
file(WRITE ${TEXI_FILE} "${TEXI_CONTENTS}")

28
src/doc/programmers.cmake Normal file
View File

@@ -0,0 +1,28 @@
#
# programmers.cmake - create programmers.texi from programmers.txt
# Copyright (C) 2022 Marius Greuel
#
# 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/>.
#
file(STRINGS ${TXT_FILE} TXT_CONTENTS REGEX "=")
SET(TEXI_CONTENTS "")
foreach(TXT_LINE IN LISTS TXT_CONTENTS)
string(REGEX REPLACE "^[ \t]*([^ \t]+)[ \t]*=[ \t]*(.*)$" "@item @code{\\1} @tab \\2" TEXI_LINE "${TXT_LINE}")
string(REGEX REPLACE "[ \t>]*,?[ \t>]*<?(http[s]?://[^ \t>]+)>?" ",@*\n@url{\\1}" TEXI_LINE "${TEXI_LINE}")
set(TEXI_CONTENTS "${TEXI_CONTENTS}${TEXI_LINE}\n")
endforeach()
file(WRITE ${TEXI_FILE} "${TEXI_CONTENTS}")

View File

@@ -59,10 +59,11 @@ struct ihexrec {
static int b2ihex(unsigned char * inbuf, int bufsize,
int recsize, int startaddr,
char * outfile, FILE * outf);
char * outfile, FILE * outf, FILEFMT ffmt);
static int ihex2b(char * infile, FILE * inf,
AVRMEM * mem, int bufsize, unsigned int fileoffset);
AVRMEM * mem, int bufsize, unsigned int fileoffset,
FILEFMT ffmt);
static int b2srec(unsigned char * inbuf, int bufsize,
int recsize, int startaddr,
@@ -79,7 +80,8 @@ static int fileio_rbin(struct fioparms * fio,
char * filename, FILE * f, AVRMEM * mem, int size);
static int fileio_ihex(struct fioparms * fio,
char * filename, FILE * f, AVRMEM * mem, int size);
char * filename, FILE * f, AVRMEM * mem, int size,
FILEFMT ffmt);
static int fileio_srec(struct fioparms * fio,
char * filename, FILE * f, AVRMEM * mem, int size);
@@ -98,16 +100,14 @@ static int fileio_num(struct fioparms * fio,
char * filename, FILE * f, AVRMEM * mem, int size,
FILEFMT fmt);
static int fmt_autodetect(char * fname);
char * fmtstr(FILEFMT format)
char * fileio_fmtstr(FILEFMT format)
{
switch (format) {
case FMT_AUTO : return "auto-detect"; break;
case FMT_SREC : return "Motorola S-Record"; break;
case FMT_IHEX : return "Intel Hex"; break;
case FMT_IHXC : return "Intel Hex with comments"; break;
case FMT_RBIN : return "raw binary"; break;
case FMT_ELF : return "ELF"; break;
default : return "invalid format"; break;
@@ -115,10 +115,9 @@ char * fmtstr(FILEFMT format)
}
static int b2ihex(unsigned char * inbuf, int bufsize,
int recsize, int startaddr,
char * outfile, FILE * outf)
char * outfile, FILE * outf, FILEFMT ffmt)
{
unsigned char * buf;
unsigned int nextaddr;
@@ -127,8 +126,7 @@ static int b2ihex(unsigned char * inbuf, int bufsize,
unsigned char cksum;
if (recsize > 255) {
avrdude_message(MSG_INFO, "%s: recsize=%d, must be < 256\n",
progname, recsize);
pmsg_error("recsize=%d, must be < 256\n", recsize);
return -1;
}
@@ -154,8 +152,20 @@ static int b2ihex(unsigned char * inbuf, int bufsize,
cksum += buf[i];
}
cksum = -cksum;
fprintf(outf, "%02X\n", cksum);
fprintf(outf, "%02X", cksum);
if(ffmt == FMT_IHXC) { /* Print comment with address and ASCII dump */
for(i=n; i<recsize; i++)
fprintf(outf, " ");
fprintf(outf, " // %05x> ", n_64k*0x10000 + nextaddr);
for (i=0; i<n; i++) {
unsigned char c = buf[i] & 0x7f;
/* Print space as _ so that line is one word */
putc(c == ' '? '_': c < ' ' || c == 0x7f? '.': c, outf);
}
}
putc('\n', outf);
nextaddr += n;
nbytes += n;
}
@@ -283,7 +293,8 @@ static int ihex_readrec(struct ihexrec * ihex, char * rec)
*
* */
static int ihex2b(char * infile, FILE * inf,
AVRMEM * mem, int bufsize, unsigned int fileoffset)
AVRMEM * mem, int bufsize, unsigned int fileoffset,
FILEFMT ffmt)
{
char buffer [ MAX_LINE_LEN ];
unsigned int nextaddr, baseaddr, maxaddr;
@@ -307,29 +318,31 @@ static int ihex2b(char * infile, FILE * inf,
continue;
rc = ihex_readrec(&ihex, buffer);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: invalid record at line %d of \"%s\"\n",
progname, lineno, infile);
pmsg_error("invalid record at line %d of %s\n", lineno, infile);
return -1;
}
else if (rc != ihex.cksum) {
avrdude_message(MSG_INFO, "%s: ERROR: checksum mismatch at line %d of \"%s\"\n",
progname, lineno, infile);
avrdude_message(MSG_INFO, "%s: checksum=0x%02x, computed checksum=0x%02x\n",
progname, ihex.cksum, rc);
return -1;
if(ffmt == FMT_IHEX) {
pmsg_error("checksum mismatch at line %d of %s\n", lineno, infile);
imsg_error("checksum=0x%02x, computed checksum=0x%02x\n", ihex.cksum, rc);
return -1;
} else { /* Just warn with more permissive format FMT_IHXC */
pmsg_notice("checksum mismatch at line %d of %s\n", lineno, infile);
imsg_notice("checksum=0x%02x, computed checksum=0x%02x\n", ihex.cksum, rc);
}
}
switch (ihex.rectyp) {
case 0: /* data record */
if (fileoffset != 0 && baseaddr < fileoffset) {
avrdude_message(MSG_INFO, "%s: ERROR: address 0x%04x out of range (below fileoffset 0x%x) at line %d of %s\n",
progname, baseaddr, fileoffset, lineno, infile);
pmsg_error("address 0x%04x out of range (below fileoffset 0x%x) at line %d of %s\n",
baseaddr, fileoffset, lineno, infile);
return -1;
}
nextaddr = ihex.loadofs + baseaddr - fileoffset;
if (nextaddr + ihex.reclen > bufsize) {
avrdude_message(MSG_INFO, "%s: ERROR: address 0x%04x out of range at line %d of %s\n",
progname, nextaddr+ihex.reclen, lineno, infile);
if (nextaddr + ihex.reclen > (unsigned) bufsize) {
pmsg_error("address 0x%04x out of range at line %d of %s\n",
nextaddr+ihex.reclen, lineno, infile);
return -1;
}
for (i=0; i<ihex.reclen; i++) {
@@ -361,9 +374,8 @@ static int ihex2b(char * infile, FILE * inf,
break;
default:
avrdude_message(MSG_INFO, "%s: don't know how to deal with rectype=%d "
"at line %d of %s\n",
progname, ihex.rectyp, lineno, infile);
pmsg_error("do not know how to deal with rectype=%d "
"at line %d of %s\n", ihex.rectyp, lineno, infile);
return -1;
break;
}
@@ -371,16 +383,12 @@ static int ihex2b(char * infile, FILE * inf,
} /* while */
if (maxaddr == 0) {
avrdude_message(MSG_INFO, "%s: ERROR: No valid record found in Intel Hex "
"file \"%s\"\n",
progname, infile);
pmsg_error("no valid record found in Intel Hex file %s\n", infile);
return -1;
}
else {
avrdude_message(MSG_INFO, "%s: WARNING: no end of file record found for Intel Hex "
"file \"%s\"\n",
progname, infile);
pmsg_warning("no end of file record found for Intel Hex file %s\n", infile);
return maxaddr;
}
@@ -393,14 +401,12 @@ static int b2srec(unsigned char * inbuf, int bufsize,
unsigned char * buf;
unsigned int nextaddr;
int n, nbytes, addr_width;
int i;
unsigned char cksum;
char * tmpl=0;
if (recsize > 255) {
avrdude_message(MSG_INFO, "%s: ERROR: recsize=%d, must be < 256\n",
progname, recsize);
pmsg_error("recsize=%d, must be < 256\n", recsize);
return -1;
}
@@ -432,8 +438,7 @@ static int b2srec(unsigned char * inbuf, int bufsize,
tmpl="S3%02X%08X";
}
else {
avrdude_message(MSG_INFO, "%s: ERROR: address=%d, out of range\n",
progname, nextaddr);
pmsg_error("address=%d, out of range\n", nextaddr);
return -1;
}
@@ -441,10 +446,10 @@ static int b2srec(unsigned char * inbuf, int bufsize,
cksum += n + addr_width + 1;
for (i=addr_width; i>0; i--)
for (int i=addr_width; i>0; i--)
cksum += (nextaddr >> (i-1) * 8) & 0xff;
for (i=nextaddr; i<nextaddr + n; i++) {
for (unsigned i=nextaddr; i<nextaddr + n; i++) {
fprintf(outf, "%02X", buf[i]);
cksum += buf[i];
}
@@ -475,7 +480,7 @@ static int b2srec(unsigned char * inbuf, int bufsize,
addr_width = 3;
tmpl="S9%02X%06X";
}
else if (startaddr <= 0xffffffff) {
else if ((unsigned) startaddr <= 0xffffffff) {
addr_width = 4;
tmpl="S9%02X%08X";
}
@@ -483,7 +488,7 @@ static int b2srec(unsigned char * inbuf, int bufsize,
fprintf(outf, tmpl, n + addr_width + 1, nextaddr);
cksum += n + addr_width +1;
for (i=addr_width; i>0; i--)
for (int i=addr_width; i>0; i--)
cksum += (nextaddr >> (i - 1) * 8) & 0xff;
cksum = 0xff - cksum;
fprintf(outf, "%02X\n", cksum);
@@ -578,10 +583,10 @@ static int srec2b(char * infile, FILE * inf,
int len;
struct ihexrec srec;
int rc;
int reccount;
unsigned int reccount;
unsigned char datarec;
char * msg = 0;
char * msg = "";
lineno = 0;
maxaddr = 0;
@@ -597,15 +602,12 @@ static int srec2b(char * infile, FILE * inf,
rc = srec_readrec(&srec, buffer);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: ERROR: invalid record at line %d of \"%s\"\n",
progname, lineno, infile);
pmsg_error("invalid record at line %d of %s\n", lineno, infile);
return -1;
}
else if (rc != srec.cksum) {
avrdude_message(MSG_INFO, "%s: ERROR: checksum mismatch at line %d of \"%s\"\n",
progname, lineno, infile);
avrdude_message(MSG_INFO, "%s: checksum=0x%02x, computed checksum=0x%02x\n",
progname, srec.cksum, rc);
pmsg_error("checksum mismatch at line %d of %s\n", lineno, infile);
imsg_error("checksum=0x%02x, computed checksum=0x%02x\n", srec.cksum, rc);
return -1;
}
@@ -617,32 +619,27 @@ static int srec2b(char * infile, FILE * inf,
case 0x31: /* S1 - 16 bit address data record */
datarec=1;
msg="%s: ERROR: address 0x%04x out of range %sat line %d of %s\n";
msg="address 0x%04x out of range %sat line %d of %s\n";
break;
case 0x32: /* S2 - 24 bit address data record */
datarec=1;
msg="%s: ERROR: address 0x%06x out of range %sat line %d of %s\n";
msg="address 0x%06x out of range %sat line %d of %s\n";
break;
case 0x33: /* S3 - 32 bit address data record */
datarec=1;
msg="%s: ERROR: address 0x%08x out of range %sat line %d of %s\n";
msg="address 0x%08x out of range %sat line %d of %s\n";
break;
case 0x34: /* S4 - symbol record (LSI extension) */
avrdude_message(MSG_INFO, "%s: ERROR: not supported record at line %d of %s\n",
progname, lineno, infile);
pmsg_error("not supported record at line %d of %s\n", lineno, infile);
return -1;
case 0x35: /* S5 - count of S1,S2 and S3 records previously tx'd */
if (srec.loadofs != reccount){
avrdude_message(MSG_INFO, "%s: ERROR: count of transmitted data records mismatch "
"at line %d of \"%s\"\n",
progname, lineno, infile);
avrdude_message(MSG_INFO, "%s: transmitted data records= %d, expected "
"value= %d\n",
progname, reccount, srec.loadofs);
pmsg_error("count of transmitted data records mismatch at line %d of %s\n", lineno, infile);
imsg_error("transmitted data records= %d, expected value= %d\n", reccount, srec.loadofs);
return -1;
}
break;
@@ -653,24 +650,20 @@ static int srec2b(char * infile, FILE * inf,
return maxaddr;
default:
avrdude_message(MSG_INFO, "%s: ERROR: don't know how to deal with rectype S%d "
"at line %d of %s\n",
progname, srec.rectyp, lineno, infile);
pmsg_error("do not know how to deal with rectype S%d at line %d of %s\n",
srec.rectyp, lineno, infile);
return -1;
}
if (datarec == 1) {
nextaddr = srec.loadofs;
if (nextaddr < fileoffset) {
avrdude_message(MSG_INFO, msg, progname, nextaddr,
"(below fileoffset) ",
lineno, infile);
pmsg_error(msg, nextaddr, "(below fileoffset) ", lineno, infile);
return -1;
}
nextaddr -= fileoffset;
if (nextaddr + srec.reclen > bufsize) {
avrdude_message(MSG_INFO, msg, progname, nextaddr+srec.reclen, "",
lineno, infile);
if (nextaddr + srec.reclen > (unsigned) bufsize) {
pmsg_error(msg, nextaddr+srec.reclen, "", lineno, infile);
return -1;
}
for (i=0; i<srec.reclen; i++) {
@@ -684,9 +677,7 @@ static int srec2b(char * infile, FILE * inf,
}
avrdude_message(MSG_INFO, "%s: WARNING: no end of file record found for Motorola S-Records "
"file \"%s\"\n",
progname, infile);
pmsg_warning("no end of file record found for Motorola S-Records file %s\n", infile);
return maxaddr;
}
@@ -729,8 +720,7 @@ static Elf_Scn *elf_get_scn(Elf *e, Elf32_Phdr *ph, Elf32_Shdr **shptr)
Elf32_Shdr *sh;
size_t ndx = elf_ndxscn(s);
if ((sh = elf32_getshdr(s)) == NULL) {
avrdude_message(MSG_INFO, "%s: ERROR: Error reading section #%u header: %s\n",
progname, (unsigned int)ndx, elf_errmsg(-1));
pmsg_error("unable to read section #%u header: %s\n", (unsigned int)ndx, elf_errmsg(-1));
continue;
}
if ((sh->sh_flags & SHF_ALLOC) == 0 ||
@@ -747,9 +737,7 @@ static Elf_Scn *elf_get_scn(Elf *e, Elf32_Phdr *ph, Elf32_Shdr **shptr)
}
}
avrdude_message(MSG_INFO, "%s: ERROR: Cannot find a matching section for "
"program header entry @p_vaddr 0x%x\n",
progname, ph->p_vaddr);
pmsg_error("cannot find a matching section for program header entry @p_vaddr 0x%x\n", ph->p_vaddr);
return NULL;
}
@@ -760,7 +748,7 @@ static int elf_mem_limits(AVRMEM *mem, struct avrpart * p,
{
int rv = 0;
if (p->flags & AVRPART_AVR32) {
if (p->prog_modes & PM_aWire) { // AVR32
if (strcmp(mem->desc, "flash") == 0) {
*lowbound = 0x80000000;
*highbound = 0xffffffff;
@@ -820,8 +808,7 @@ static int elf2b(char * infile, FILE * inf,
unsigned int low, high, foff;
if (elf_mem_limits(mem, p, &low, &high, &foff) != 0) {
avrdude_message(MSG_INFO, "%s: ERROR: Cannot handle \"%s\" memory region from ELF file\n",
progname, mem->desc);
pmsg_error("cannot handle %s memory region from ELF file\n", mem->desc);
return -1;
}
@@ -832,15 +819,13 @@ static int elf2b(char * infile, FILE * inf,
* sections out of an ELF file that contains section data for more
* than one sub-segment.
*/
if ((p->flags & AVRPART_HAS_PDI) != 0 &&
if ((p->prog_modes & PM_PDI) != 0 &&
(strcmp(mem->desc, "boot") == 0 ||
strcmp(mem->desc, "application") == 0 ||
strcmp(mem->desc, "apptable") == 0)) {
AVRMEM *flashmem = avr_locate_mem(p, "flash");
if (flashmem == NULL) {
avrdude_message(MSG_INFO, "%s: ERROR: No \"flash\" memory region found, "
"cannot compute bounds of \"%s\" sub-region.\n",
progname, mem->desc);
pmsg_error("no flash memory region found, cannot compute bounds of %s sub-region\n", mem->desc);
return -1;
}
/* The config file offsets are PDI offsets, rebase to 0. */
@@ -849,18 +834,15 @@ static int elf2b(char * infile, FILE * inf,
}
if (elf_version(EV_CURRENT) == EV_NONE) {
avrdude_message(MSG_INFO, "%s: ERROR: ELF library initialization failed: %s\n",
progname, elf_errmsg(-1));
pmsg_error("ELF library initialization failed: %s\n", elf_errmsg(-1));
return -1;
}
if ((e = elf_begin(fileno(inf), ELF_C_READ, NULL)) == NULL) {
avrdude_message(MSG_INFO, "%s: ERROR: Cannot open \"%s\" as an ELF file: %s\n",
progname, infile, elf_errmsg(-1));
pmsg_error("cannot open %s as an ELF file: %s\n", infile, elf_errmsg(-1));
return -1;
}
if (elf_kind(e) != ELF_K_ELF) {
avrdude_message(MSG_INFO, "%s: ERROR: Cannot use \"%s\" as an ELF input file\n",
progname, infile);
pmsg_error("cannot use %s as an ELF input file\n", infile);
goto done;
}
@@ -868,14 +850,13 @@ static int elf2b(char * infile, FILE * inf,
const char *id = elf_getident(e, &isize);
if (id == NULL) {
avrdude_message(MSG_INFO, "%s: ERROR: Error reading ident area of \"%s\": %s\n",
progname, infile, elf_errmsg(-1));
pmsg_error("unable to read ident area of %s: %s\n", infile, elf_errmsg(-1));
goto done;
}
const char *endianname;
unsigned char endianess;
if (p->flags & AVRPART_AVR32) {
if (p->prog_modes & PM_aWire) { // AVR32
endianess = ELFDATA2MSB;
endianname = "little";
} else {
@@ -884,28 +865,25 @@ static int elf2b(char * infile, FILE * inf,
}
if (id[EI_CLASS] != ELFCLASS32 ||
id[EI_DATA] != endianess) {
avrdude_message(MSG_INFO, "%s: ERROR: ELF file \"%s\" is not a "
"32-bit, %s-endian file that was expected\n",
progname, infile, endianname);
pmsg_error("ELF file %s is not a 32-bit, %s-endian file that was expected\n",
infile, endianname);
goto done;
}
Elf32_Ehdr *eh;
if ((eh = elf32_getehdr(e)) == NULL) {
avrdude_message(MSG_INFO, "%s: ERROR: Error reading ehdr of \"%s\": %s\n",
progname, infile, elf_errmsg(-1));
pmsg_error("unable to read ehdr of %s: %s\n", infile, elf_errmsg(-1));
goto done;
}
if (eh->e_type != ET_EXEC) {
avrdude_message(MSG_INFO, "%s: ERROR: ELF file \"%s\" is not an executable file\n",
progname, infile);
pmsg_error("ELF file %s is not an executable file\n", infile);
goto done;
}
const char *mname;
uint16_t machine;
if (p->flags & AVRPART_AVR32) {
if (p->prog_modes & PM_aWire) {
machine = EM_AVR32;
mname = "AVR32";
} else {
@@ -913,28 +891,23 @@ static int elf2b(char * infile, FILE * inf,
mname = "AVR";
}
if (eh->e_machine != machine) {
avrdude_message(MSG_INFO, "%s: ERROR: ELF file \"%s\" is not for machine %s\n",
progname, infile, mname);
pmsg_error("ELF file %s is not for machine %s\n", infile, mname);
goto done;
}
if (eh->e_phnum == 0xffff /* PN_XNUM */) {
avrdude_message(MSG_INFO, "%s: ERROR: ELF file \"%s\" uses extended "
"program header numbers which are not expected\n",
progname, infile);
pmsg_error("ELF file %s uses extended program header numbers which are not expected\n", infile);
goto done;
}
Elf32_Phdr *ph;
if ((ph = elf32_getphdr(e)) == NULL) {
avrdude_message(MSG_INFO, "%s: ERROR: Error reading program header table of \"%s\": %s\n",
progname, infile, elf_errmsg(-1));
pmsg_error("unable to read program header table of %s: %s\n", infile, elf_errmsg(-1));
goto done;
}
size_t sndx;
if (elf_getshdrstrndx(e, &sndx) != 0) {
avrdude_message(MSG_INFO, "%s: ERROR: Error obtaining section name string table: %s\n",
progname, elf_errmsg(-1));
pmsg_error("unable to obtain section name string table: %s\n", elf_errmsg(-1));
sndx = 0;
}
@@ -947,9 +920,8 @@ static int elf2b(char * infile, FILE * inf,
ph[i].p_filesz == 0)
continue;
avrdude_message(MSG_NOTICE2, "%s: Considering PT_LOAD program header entry #%d:\n"
" p_vaddr 0x%x, p_paddr 0x%x, p_filesz %d\n",
progname, i, ph[i].p_vaddr, ph[i].p_paddr, ph[i].p_filesz);
pmsg_notice2("considering PT_LOAD program header entry #%d:\n"
" p_vaddr 0x%x, p_paddr 0x%x, p_filesz %d\n", (int) i, ph[i].p_vaddr, ph[i].p_paddr, ph[i].p_filesz);
Elf32_Shdr *sh;
Elf_Scn *s = elf_get_scn(e, ph + i, &sh);
@@ -968,15 +940,13 @@ static int elf2b(char * infile, FILE * inf,
unsigned int lma;
lma = ph[i].p_paddr + sh->sh_offset - ph[i].p_offset;
avrdude_message(MSG_NOTICE2, "%s: Found section \"%s\", LMA 0x%x, sh_size %u\n",
progname, sname, lma, sh->sh_size);
pmsg_notice2("found section %s, LMA 0x%x, sh_size %u\n", sname, lma, sh->sh_size);
if (lma >= low &&
lma + sh->sh_size < high) {
/* OK */
} else {
avrdude_message(MSG_NOTICE2, " => skipping, inappropriate for \"%s\" memory region\n",
mem->desc);
msg_notice2(" => skipping, inappropriate for %s memory region\n", mem->desc);
continue;
}
/*
@@ -987,28 +957,23 @@ static int elf2b(char * infile, FILE * inf,
* ELF file region for these, and extract the actual byte to write
* from it, using the "foff" offset obtained above.
*/
if (mem->size != 1 &&
sh->sh_size > mem->size) {
avrdude_message(MSG_INFO, "%s: ERROR: section \"%s\" does not fit into \"%s\" memory:\n"
" 0x%x + %u > %u\n",
progname, sname, mem->desc,
lma, sh->sh_size, mem->size);
if (mem->size != 1 && sh->sh_size > (unsigned) mem->size) {
pmsg_error("section %s does not fit into %s memory:\n"
" 0x%x + %u > %u\n", sname, mem->desc, lma, sh->sh_size, mem->size);
continue;
}
Elf_Data *d = NULL;
while ((d = elf_getdata(s, d)) != NULL) {
avrdude_message(MSG_NOTICE2, " Data block: d_buf %p, d_off 0x%x, d_size %d\n",
d->d_buf, (unsigned int)d->d_off, d->d_size);
msg_notice2(" Data block: d_buf %p, d_off 0x%x, d_size %ld\n",
d->d_buf, (unsigned int)d->d_off, (long) d->d_size);
if (mem->size == 1) {
if (d->d_off != 0) {
avrdude_message(MSG_INFO, "%s: ERROR: unexpected data block at offset != 0\n",
progname);
pmsg_error("unexpected data block at offset != 0\n");
} else if (foff >= d->d_size) {
avrdude_message(MSG_INFO, "%s: ERROR: ELF file section does not contain byte at offset %d\n",
progname, foff);
pmsg_error("ELF file section does not contain byte at offset %d\n", foff);
} else {
avrdude_message(MSG_NOTICE2, " Extracting one byte from file offset %d\n",
msg_notice2(" Extracting one byte from file offset %d\n",
foff);
mem->buf[0] = ((unsigned char *)d->d_buf)[foff];
mem->tags[0] = TAG_ALLOCATED;
@@ -1020,8 +985,8 @@ static int elf2b(char * infile, FILE * inf,
idx = lma - low + d->d_off;
if ((int)(idx + d->d_size) > rv)
rv = idx + d->d_size;
avrdude_message(MSG_DEBUG, " Writing %d bytes to mem offset 0x%x\n",
d->d_size, idx);
msg_debug(" Writing %ld bytes to mem offset 0x%x\n",
(long) d->d_size, idx);
memcpy(mem->buf + idx, d->d_buf, d->d_size);
memset(mem->tags + idx, TAG_ALLOCATED, d->d_size);
}
@@ -1090,15 +1055,13 @@ static int fileio_rbin(struct fioparms * fio,
rc = fwrite(buf, 1, size, f);
break;
default:
avrdude_message(MSG_INFO, "%s: fileio: invalid operation=%d\n",
progname, fio->op);
pmsg_error("invalid fileio operation=%d\n", fio->op);
return -1;
}
if (rc < 0 || (fio->op == FIO_WRITE && rc < size)) {
avrdude_message(MSG_INFO, "%s: %s error %s %s: %s; %s %d of the expected %d bytes\n",
progname, fio->iodesc, fio->dir, filename, strerror(errno),
fio->rw, rc, size);
pmsg_ext_error("%s error %s %s: %s; %s %d of the expected %d bytes\n",
fio->iodesc, fio->dir, filename, strerror(errno), fio->rw, rc, size);
return -1;
}
@@ -1125,8 +1088,7 @@ static int fileio_imm(struct fioparms * fio,
strtoul (p, &e, 0):
strtoul (p + 2, &e, 2);
if (*e != 0) {
avrdude_message(MSG_INFO, "%s: invalid byte value (%s) specified for immediate mode\n",
progname, p);
pmsg_error("invalid byte value (%s) specified for immediate mode\n", p);
return -1;
}
mem->buf[loc] = b;
@@ -1135,16 +1097,19 @@ static int fileio_imm(struct fioparms * fio,
rc = loc;
}
break;
case FIO_WRITE:
pmsg_error("invalid file format 'immediate' for output\n");
return -1;
default:
avrdude_message(MSG_INFO, "%s: fileio: invalid operation=%d\n",
progname, fio->op);
pmsg_error("invalid operation=%d\n", fio->op);
return -1;
}
if (rc < 0 || (fio->op == FIO_WRITE && rc < size)) {
avrdude_message(MSG_INFO, "%s: %s error %s %s: %s; %s %d of the expected %d bytes\n",
progname, fio->iodesc, fio->dir, filename, strerror(errno),
fio->rw, rc, size);
pmsg_ext_error("%s error %s %s: %s; %s %d of the expected %d bytes\n",
fio->iodesc, fio->dir, filename, strerror(errno), fio->rw, rc, size);
return -1;
}
@@ -1152,28 +1117,28 @@ static int fileio_imm(struct fioparms * fio,
}
static int fileio_ihex(struct fioparms * fio,
char * filename, FILE * f, AVRMEM * mem, int size)
static int fileio_ihex(struct fioparms * fio,
char * filename, FILE * f, AVRMEM * mem, int size,
FILEFMT ffmt)
{
int rc;
switch (fio->op) {
case FIO_WRITE:
rc = b2ihex(mem->buf, size, 32, fio->fileoffset, filename, f);
rc = b2ihex(mem->buf, size, 32, fio->fileoffset, filename, f, ffmt);
if (rc < 0) {
return -1;
}
break;
case FIO_READ:
rc = ihex2b(filename, f, mem, size, fio->fileoffset);
rc = ihex2b(filename, f, mem, size, fio->fileoffset, ffmt);
if (rc < 0)
return -1;
break;
default:
avrdude_message(MSG_INFO, "%s: invalid Intel Hex file I/O operation=%d\n",
progname, fio->op);
pmsg_error("invalid Intel Hex file I/O operation=%d\n", fio->op);
return -1;
break;
}
@@ -1202,9 +1167,7 @@ static int fileio_srec(struct fioparms * fio,
break;
default:
avrdude_message(MSG_INFO, "%s: ERROR: invalid Motorola S-Records file I/O "
"operation=%d\n",
progname, fio->op);
pmsg_error("invalid Motorola S-Records file I/O operation=%d\n", fio->op);
return -1;
break;
}
@@ -1222,9 +1185,7 @@ static int fileio_elf(struct fioparms * fio,
switch (fio->op) {
case FIO_WRITE:
avrdude_message(MSG_INFO, "%s: ERROR: write operation not (yet) "
"supported for ELF\n",
progname);
pmsg_error("write operation not supported for ELF\n");
return -1;
break;
@@ -1233,9 +1194,7 @@ static int fileio_elf(struct fioparms * fio,
return rc;
default:
avrdude_message(MSG_INFO, "%s: ERROR: invalid ELF file I/O "
"operation=%d\n",
progname, fio->op);
pmsg_error("invalid ELF file I/O operation=%d\n", fio->op);
return -1;
break;
}
@@ -1248,27 +1207,32 @@ static int fileio_num(struct fioparms * fio,
FILEFMT fmt)
{
const char *prefix;
const char *name;
char cbuf[20];
int base, i, num;
switch (fmt) {
case FMT_HEX:
name = "hex";
prefix = "0x";
base = 16;
break;
default:
case FMT_DEC:
name = "decimal";
prefix = "";
base = 10;
break;
case FMT_OCT:
name = "octal";
prefix = "0";
base = 8;
break;
case FMT_BIN:
name = "binary";
prefix = "0b";
base = 2;
break;
@@ -1278,9 +1242,13 @@ static int fileio_num(struct fioparms * fio,
switch (fio->op) {
case FIO_WRITE:
break;
case FIO_READ:
pmsg_error("invalid file format '%s' for input\n", name);
return -1;
default:
avrdude_message(MSG_INFO, "%s: fileio: invalid operation=%d\n",
progname, fio->op);
pmsg_error("invalid operation=%d\n", fio->op);
return -1;
}
@@ -1309,8 +1277,7 @@ static int fileio_num(struct fioparms * fio,
return 0;
writeerr:
avrdude_message(MSG_INFO, "%s: error writing to %s: %s\n",
progname, filename, strerror(errno));
pmsg_ext_error("unable to write to %s: %s\n", filename, strerror(errno));
return -1;
}
@@ -1336,8 +1303,7 @@ int fileio_setparms(int op, struct fioparms * fp,
break;
default:
avrdude_message(MSG_INFO, "%s: invalid I/O operation %d\n",
progname, op);
pmsg_error("invalid I/O operation %d\n", op);
return -1;
break;
}
@@ -1346,21 +1312,14 @@ int fileio_setparms(int op, struct fioparms * fp,
* AVR32 devices maintain their load offset within the file itself,
* but AVRDUDE maintains all memory images 0-based.
*/
if ((p->flags & AVRPART_AVR32) != 0)
{
fp->fileoffset = m->offset;
}
else
{
fp->fileoffset = 0;
}
fp->fileoffset = p->prog_modes & PM_aWire? m->offset: 0;
return 0;
}
static int fmt_autodetect(char * fname)
int fileio_fmt_autodetect(const char * fname)
{
FILE * f;
unsigned char buf[MAX_LINE_LEN];
@@ -1375,8 +1334,7 @@ static int fmt_autodetect(char * fname)
f = fopen(fname, "rb");
#endif
if (f == NULL) {
avrdude_message(MSG_INFO, "%s: error opening %s: %s\n",
progname, fname, strerror(errno));
pmsg_ext_error("unable to open %s: %s\n", fname, strerror(errno));
return -1;
}
@@ -1446,20 +1404,20 @@ static int fmt_autodetect(char * fname)
int fileio(int op, char * filename, FILEFMT format,
int fileio(int oprwv, char * filename, FILEFMT format,
struct avrpart * p, char * memtype, int size)
{
int rc;
int op, rc;
FILE * f;
char * fname;
struct fioparms fio;
AVRMEM * mem;
int using_stdio;
op = oprwv == FIO_READ_FOR_VERIFY? FIO_READ: oprwv;
mem = avr_locate_mem(p, memtype);
if (mem == NULL) {
avrdude_message(MSG_INFO, "fileio(): memory type \"%s\" not configured for device \"%s\"\n",
memtype, p->desc);
pmsg_error("memory type %s not configured for device %s\n", memtype, p->desc);
return -1;
}
@@ -1467,7 +1425,7 @@ int fileio(int op, char * filename, FILEFMT format,
if (rc < 0)
return -1;
if (fio.op == FIO_READ)
if (size < 0 || fio.op == FIO_READ)
size = mem->size;
if (fio.op == FIO_READ) {
@@ -1498,24 +1456,21 @@ int fileio(int op, char * filename, FILEFMT format,
int format_detect;
if (using_stdio) {
avrdude_message(MSG_INFO, "%s: can't auto detect file format when using stdin/out.\n"
"%s Please specify a file format and try again.\n",
progname, progbuf);
pmsg_error("cannot auto detect file format when using stdin/out\n");
imsg_error("please specify a file format and try again\n");
return -1;
}
format_detect = fmt_autodetect(fname);
format_detect = fileio_fmt_autodetect(fname);
if (format_detect < 0) {
avrdude_message(MSG_INFO, "%s: can't determine file format for %s, specify explicitly\n",
progname, fname);
pmsg_error("cannot determine file format for %s, specify explicitly\n", fname);
return -1;
}
format = format_detect;
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: %s file %s auto detected as %s\n",
progname, fio.iodesc, fname, fmtstr(format));
}
if (quell_progress < 2)
pmsg_notice("%s file %s auto detected as %s\n",
fio.iodesc, fname, fileio_fmtstr(format));
}
#if defined(WIN32)
@@ -1537,8 +1492,7 @@ int fileio(int op, char * filename, FILEFMT format,
if (!using_stdio) {
f = fopen(fname, fio.mode);
if (f == NULL) {
avrdude_message(MSG_INFO, "%s: can't open %s file %s: %s\n",
progname, fio.iodesc, fname, strerror(errno));
pmsg_ext_error("cannot open %s file %s: %s\n", fio.iodesc, fname, strerror(errno));
return -1;
}
}
@@ -1546,7 +1500,8 @@ int fileio(int op, char * filename, FILEFMT format,
switch (format) {
case FMT_IHEX:
rc = fileio_ihex(&fio, fname, f, mem, size);
case FMT_IHXC:
rc = fileio_ihex(&fio, fname, f, mem, size, format);
break;
case FMT_SREC:
@@ -1561,9 +1516,7 @@ int fileio(int op, char * filename, FILEFMT format,
#ifdef HAVE_LIBELF
rc = fileio_elf(&fio, fname, f, mem, p, size);
#else
avrdude_message(MSG_INFO, "%s: can't handle ELF file %s, "
"ELF file support was not compiled in\n",
progname, fname);
pmsg_error("cannot handle ELF file %s, ELF file support was not compiled in\n", fname);
rc = -1;
#endif
break;
@@ -1580,23 +1533,18 @@ int fileio(int op, char * filename, FILEFMT format,
break;
default:
avrdude_message(MSG_INFO, "%s: invalid %s file format: %d\n",
progname, fio.iodesc, format);
pmsg_error("invalid %s file format: %d\n", fio.iodesc, format);
return -1;
}
if (rc > 0) {
if ((op == FIO_READ) && (strcasecmp(mem->desc, "flash") == 0 ||
strcasecmp(mem->desc, "application") == 0 ||
strcasecmp(mem->desc, "apptable") == 0 ||
strcasecmp(mem->desc, "boot") == 0)) {
/*
* if we are reading flash, just mark the size as being the
* highest non-0xff byte
*/
rc = avr_mem_hiaddr(mem);
}
/* on reading flash other than for verify set the size to location of highest non-0xff byte */
if (rc > 0 && oprwv == FIO_READ) {
int hiaddr = avr_mem_hiaddr(mem);
if(hiaddr < rc) /* if trailing-0xff not disabled */
rc = hiaddr;
}
if (format != FMT_IMM && !using_stdio) {
fclose(f);
}

View File

@@ -136,23 +136,23 @@ enum flip1_mem_unit {
/* EXPORTED PROGRAMMER FUNCTION PROTOTYPES */
static int flip1_open(PROGRAMMER *pgm, char *port_spec);
static int flip1_initialize(PROGRAMMER* pgm, AVRPART *part);
static int flip1_open(PROGRAMMER *pgm, const char *port_spec);
static int flip1_initialize(const PROGRAMMER *pgm, const AVRPART *part);
static void flip1_close(PROGRAMMER* pgm);
static void flip1_enable(PROGRAMMER* pgm);
static void flip1_disable(PROGRAMMER* pgm);
static void flip1_display(PROGRAMMER* pgm, const char *prefix);
static int flip1_program_enable(PROGRAMMER* pgm, AVRPART *part);
static int flip1_chip_erase(PROGRAMMER* pgm, AVRPART *part);
static int flip1_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
static void flip1_enable(PROGRAMMER *pgm, const AVRPART *p);
static void flip1_disable(const PROGRAMMER *pgm);
static void flip1_display(const PROGRAMMER *pgm, const char *prefix);
static int flip1_program_enable(const PROGRAMMER *pgm, const AVRPART *part);
static int flip1_chip_erase(const PROGRAMMER *pgm, const AVRPART *part);
static int flip1_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned long addr, unsigned char *value);
static int flip1_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
static int flip1_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned long addr, unsigned char value);
static int flip1_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
static int flip1_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned int page_size, unsigned int addr, unsigned int n_bytes);
static int flip1_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
static int flip1_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned int page_size, unsigned int addr, unsigned int n_bytes);
static int flip1_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem);
static int flip1_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem);
static void flip1_setup(PROGRAMMER * pgm);
static void flip1_teardown(PROGRAMMER * pgm);
@@ -162,7 +162,7 @@ static void flip1_teardown(PROGRAMMER * pgm);
static void flip1_show_info(struct flip1 *flip1);
static int flip1_read_memory(PROGRAMMER * pgm,
static int flip1_read_memory(const PROGRAMMER *pgm,
enum flip1_mem_unit mem_unit, uint32_t addr, void *ptr, int size);
static int flip1_write_memory(struct dfu_dev *dfu,
enum flip1_mem_unit mem_unit, uint32_t addr, const void *ptr, int size);
@@ -176,8 +176,7 @@ static enum flip1_mem_unit flip1_mem_unit(const char *name);
/* THE INITPGM FUNCTION DEFINITIONS */
void flip1_initpgm(PROGRAMMER *pgm)
{
void flip1_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "flip1");
/* Mandatory Functions */
@@ -201,14 +200,12 @@ void flip1_initpgm(PROGRAMMER *pgm)
#ifdef HAVE_LIBUSB
/* EXPORTED PROGRAMMER FUNCTION DEFINITIONS */
int flip1_open(PROGRAMMER *pgm, char *port_spec)
{
int flip1_open(PROGRAMMER *pgm, const char *port_spec) {
FLIP1(pgm)->dfu = dfu_open(port_spec);
return (FLIP1(pgm)->dfu != NULL) ? 0 : -1;
}
int flip1_initialize(PROGRAMMER* pgm, AVRPART *part)
{
int flip1_initialize(const PROGRAMMER *pgm, const AVRPART *part) {
unsigned short vid, pid;
int result;
struct dfu_dev *dfu = FLIP1(pgm)->dfu;
@@ -237,16 +234,13 @@ int flip1_initialize(PROGRAMMER* pgm, AVRPART *part)
if (usbpid) {
pid = *(int *)(ldata(usbpid));
if (lnext(usbpid))
avrdude_message(MSG_INFO, "%s: Warning: using PID 0x%04x, ignoring remaining PIDs in list\n",
progname, pid);
pmsg_warning("using PID 0x%04x, ignoring remaining PIDs in list\n", pid);
} else {
pid = part->usbpid;
}
if (!ovsigck && (part->flags & AVRPART_HAS_PDI)) {
avrdude_message(MSG_INFO, "%s: \"flip1\" (FLIP protocol version 1) is for AT90USB* and ATmega*U* devices.\n"
"%s For Xmega devices, use \"flip2\".\n"
"%s (Use -F to bypass this check.)\n",
progname, progbuf, progbuf);
if (!ovsigck && (part->prog_modes & PM_PDI)) {
pmsg_error("flip1 (FLIP protocol version 1) is for AT90USB* and ATmega*U* devices\n");
imsg_error("for Xmega devices, use flip2 (or use -F to bypass this check)\n");
return -1;
}
@@ -258,32 +252,25 @@ int flip1_initialize(PROGRAMMER* pgm, AVRPART *part)
/* Check if descriptor values are what we expect. */
if (dfu->dev_desc.idVendor != vid)
avrdude_message(MSG_INFO, "%s: Warning: USB idVendor = 0x%04X (expected 0x%04X)\n",
progname, dfu->dev_desc.idVendor, vid);
pmsg_warning("USB idVendor = 0x%04X (expected 0x%04X)\n", dfu->dev_desc.idVendor, vid);
if (pid != 0 && dfu->dev_desc.idProduct != pid)
avrdude_message(MSG_INFO, "%s: Warning: USB idProduct = 0x%04X (expected 0x%04X)\n",
progname, dfu->dev_desc.idProduct, pid);
pmsg_warning("USB idProduct = 0x%04X (expected 0x%04X)\n", dfu->dev_desc.idProduct, pid);
if (dfu->dev_desc.bNumConfigurations != 1)
avrdude_message(MSG_INFO, "%s: Warning: USB bNumConfigurations = %d (expected 1)\n",
progname, (int) dfu->dev_desc.bNumConfigurations);
pmsg_warning("USB bNumConfigurations = %d (expected 1)\n", (int) dfu->dev_desc.bNumConfigurations);
if (dfu->conf_desc.bNumInterfaces != 1)
avrdude_message(MSG_INFO, "%s: Warning: USB bNumInterfaces = %d (expected 1)\n",
progname, (int) dfu->conf_desc.bNumInterfaces);
pmsg_warning("USB bNumInterfaces = %d (expected 1)\n", (int) dfu->conf_desc.bNumInterfaces);
if (dfu->dev_desc.bDeviceClass != 254)
avrdude_message(MSG_INFO, "%s: Warning: USB bDeviceClass = %d (expected 254)\n",
progname, (int) dfu->dev_desc.bDeviceClass);
pmsg_warning("USB bDeviceClass = %d (expected 254)\n", (int) dfu->dev_desc.bDeviceClass);
if (dfu->dev_desc.bDeviceSubClass != 1)
avrdude_message(MSG_INFO, "%s: Warning: USB bDeviceSubClass = %d (expected 1)\n",
progname, (int) dfu->dev_desc.bDeviceSubClass);
pmsg_warning("USB bDeviceSubClass = %d (expected 1)\n", (int) dfu->dev_desc.bDeviceSubClass);
if (dfu->dev_desc.bDeviceProtocol != 0)
avrdude_message(MSG_INFO, "%s: Warning: USB bDeviceProtocol = %d (expected 0)\n",
progname, (int) dfu->dev_desc.bDeviceProtocol);
pmsg_warning("USB bDeviceProtocol = %d (expected 0)\n", (int) dfu->dev_desc.bDeviceProtocol);
/*
* doc7618 claims an interface class of FEh and a subclas 01h.
@@ -293,21 +280,17 @@ int flip1_initialize(PROGRAMMER* pgm, AVRPART *part)
*/
if (0) {
if (dfu->intf_desc.bInterfaceClass != 254)
avrdude_message(MSG_INFO, "%s: Warning: USB bInterfaceClass = %d (expected 254)\n",
progname, (int) dfu->intf_desc.bInterfaceClass);
pmsg_warning("USB bInterfaceClass = %d (expected 254)\n", (int) dfu->intf_desc.bInterfaceClass);
if (dfu->intf_desc.bInterfaceSubClass != 1)
avrdude_message(MSG_INFO, "%s: Warning: USB bInterfaceSubClass = %d (expected 1)\n",
progname, (int) dfu->intf_desc.bInterfaceSubClass);
pmsg_warning("USB bInterfaceSubClass = %d (expected 1)\n", (int) dfu->intf_desc.bInterfaceSubClass);
if (dfu->intf_desc.bInterfaceProtocol != 0)
avrdude_message(MSG_INFO, "%s: Warning: USB bInterfaceSubClass = %d (expected 0)\n",
progname, (int) dfu->intf_desc.bInterfaceProtocol);
pmsg_warning("USB bInterfaceSubClass = %d (expected 0)\n", (int) dfu->intf_desc.bInterfaceProtocol);
}
if (dfu->dev_desc.bMaxPacketSize0 != 32)
avrdude_message(MSG_INFO, "%s: Warning: bMaxPacketSize0 (%d) != 32, things might go wrong\n",
progname, dfu->dev_desc.bMaxPacketSize0);
pmsg_warning("bMaxPacketSize0 (%d) != 32, things might go wrong\n", dfu->dev_desc.bMaxPacketSize0);
if (verbose)
flip1_show_info(FLIP1(pgm));
@@ -322,31 +305,26 @@ flip1_initialize_fail:
return 0;
}
void flip1_close(PROGRAMMER* pgm)
{
void flip1_close(PROGRAMMER *pgm) {
if (FLIP1(pgm)->dfu != NULL) {
dfu_close(FLIP1(pgm)->dfu);
FLIP1(pgm)->dfu = NULL;
}
}
void flip1_enable(PROGRAMMER* pgm)
{
void flip1_enable(PROGRAMMER *pgm, const AVRPART *p) {
/* Nothing to do. */
}
void flip1_disable(PROGRAMMER* pgm)
{
void flip1_disable(const PROGRAMMER *pgm) {
/* Nothing to do. */
}
void flip1_display(PROGRAMMER* pgm, const char *prefix)
{
void flip1_display(const PROGRAMMER *pgm, const char *prefix) {
/* Nothing to do. */
}
int flip1_program_enable(PROGRAMMER* pgm, AVRPART *part)
{
int flip1_program_enable(const PROGRAMMER *pgm, const AVRPART *part) {
/* I couldn't find anything that uses this function, although it is marked
* as "mandatory" in pgm.c. In case anyone does use it, we'll report an
* error if we failed to initialize.
@@ -355,14 +333,13 @@ int flip1_program_enable(PROGRAMMER* pgm, AVRPART *part)
return (FLIP1(pgm)->dfu != NULL) ? 0 : -1;
}
int flip1_chip_erase(PROGRAMMER* pgm, AVRPART *part)
{
int flip1_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) {
struct dfu_status status;
int cmd_result = 0;
int aux_result;
unsigned int default_timeout = FLIP1(pgm)->dfu->timeout;
avrdude_message(MSG_NOTICE2, "%s: flip_chip_erase()\n", progname);
pmsg_notice2("flip_chip_erase()\n");
struct flip1_cmd cmd = {
FLIP1_CMD_WRITE_COMMAND, { 0, 0xff }
@@ -377,8 +354,7 @@ int flip1_chip_erase(PROGRAMMER* pgm, AVRPART *part)
return -1;
if (status.bStatus != DFU_STATUS_OK) {
avrdude_message(MSG_INFO, "%s: failed to send chip erase command: %s\n",
progname, flip1_status_str(&status));
pmsg_error("unable to send chip erase command: %s\n", flip1_status_str(&status));
if (status.bState == STATE_dfuERROR)
dfu_clrstatus(FLIP1(pgm)->dfu);
return -1;
@@ -387,7 +363,7 @@ int flip1_chip_erase(PROGRAMMER* pgm, AVRPART *part)
return 0;
}
int flip1_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
int flip1_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned long addr, unsigned char *value)
{
enum flip1_mem_unit mem_unit;
@@ -395,12 +371,11 @@ int flip1_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
if (FLIP1(pgm)->dfu == NULL)
return -1;
if (strcasecmp(mem->desc, "signature") == 0) {
if (strcmp(mem->desc, "signature") == 0) {
if (flip1_read_sig_bytes(pgm, part, mem) < 0)
return -1;
if (addr > mem->size) {
avrdude_message(MSG_INFO, "%s: flip1_read_byte(signature): address %lu out of range\n",
progname, addr);
if (addr >= mem->size) {
pmsg_error("signature address %lu out of range [0, %d]\n", addr, mem->size-1);
return -1;
}
*value = mem->buf[addr];
@@ -410,10 +385,7 @@ int flip1_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
mem_unit = flip1_mem_unit(mem->desc);
if (mem_unit == FLIP1_MEM_UNIT_UNKNOWN) {
avrdude_message(MSG_INFO, "%s: Error: "
"\"%s\" memory not accessible using FLIP",
progname, mem->desc);
avrdude_message(MSG_INFO, "\n");
pmsg_error("%s memory not accessible using FLIP\n", mem->desc);
return -1;
}
@@ -424,7 +396,7 @@ int flip1_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
return flip1_read_memory(pgm, mem_unit, addr, value, 1);
}
int flip1_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
int flip1_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned long addr, unsigned char value)
{
enum flip1_mem_unit mem_unit;
@@ -435,17 +407,14 @@ int flip1_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
mem_unit = flip1_mem_unit(mem->desc);
if (mem_unit == FLIP1_MEM_UNIT_UNKNOWN) {
avrdude_message(MSG_INFO, "%s: Error: "
"\"%s\" memory not accessible using FLIP",
progname, mem->desc);
avrdude_message(MSG_INFO, "\n");
pmsg_error("%s memory not accessible using FLIP\n", mem->desc);
return -1;
}
return flip1_write_memory(FLIP1(pgm)->dfu, mem_unit, addr, &value, 1);
}
int flip1_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
int flip1_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned int page_size, unsigned int addr, unsigned int n_bytes)
{
enum flip1_mem_unit mem_unit;
@@ -456,10 +425,7 @@ int flip1_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
mem_unit = flip1_mem_unit(mem->desc);
if (mem_unit == FLIP1_MEM_UNIT_UNKNOWN) {
avrdude_message(MSG_INFO, "%s: Error: "
"\"%s\" memory not accessible using FLIP",
progname, mem->desc);
avrdude_message(MSG_INFO, "\n");
pmsg_error("%s memory not accessible using FLIP\n", mem->desc);
return -1;
}
@@ -470,7 +436,7 @@ int flip1_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
return flip1_read_memory(pgm, mem_unit, addr, mem->buf + addr, n_bytes);
}
int flip1_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
int flip1_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned int page_size, unsigned int addr, unsigned int n_bytes)
{
enum flip1_mem_unit mem_unit;
@@ -482,17 +448,13 @@ int flip1_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
mem_unit = flip1_mem_unit(mem->desc);
if (mem_unit == FLIP1_MEM_UNIT_UNKNOWN) {
avrdude_message(MSG_INFO, "%s: Error: "
"\"%s\" memory not accessible using FLIP",
progname, mem->desc);
avrdude_message(MSG_INFO, "\n");
pmsg_error("%s memory not accessible using FLIP\n", mem->desc);
return -1;
}
if (n_bytes > INT_MAX) {
/* This should never happen, unless the int type is only 16 bits. */
avrdude_message(MSG_INFO, "%s: Error: Attempting to read more than %d bytes\n",
progname, INT_MAX);
pmsg_error("attempting to read more than %d bytes\n", INT_MAX);
exit(1);
}
@@ -502,16 +464,14 @@ int flip1_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
return (result == 0) ? n_bytes : -1;
}
int flip1_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
{
avrdude_message(MSG_NOTICE2, "%s: flip1_read_sig_bytes(): ", progname);
int flip1_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem) {
pmsg_notice2("flip1_read_sig_bytes(): ");
if (FLIP1(pgm)->dfu == NULL)
return -1;
if (mem->size < sizeof(FLIP1(pgm)->part_sig)) {
avrdude_message(MSG_INFO, "%s: Error: Signature read must be at least %u bytes\n",
progname, (unsigned int) sizeof(FLIP1(pgm)->part_sig));
pmsg_error("signature read must be at least %u bytes\n", (unsigned int) sizeof(FLIP1(pgm)->part_sig));
return -1;
}
@@ -528,7 +488,7 @@ int flip1_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
FLIP1_CMD_READ_COMMAND, FLIP1_READ_FAMILY_CODE
};
avrdude_message(MSG_NOTICE2, "from device\n");
msg_notice2("from device\n");
for (i = 0; i < 3; i++)
{
@@ -545,8 +505,7 @@ int flip1_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
if (status.bStatus != DFU_STATUS_OK)
{
avrdude_message(MSG_INFO, "%s: failed to send cmd for signature byte %d: %s\n",
progname, i, flip1_status_str(&status));
pmsg_error("unable to send cmd for signature byte %d: %s\n", i, flip1_status_str(&status));
if (status.bState == STATE_dfuERROR)
dfu_clrstatus(FLIP1(pgm)->dfu);
return -1;
@@ -560,8 +519,7 @@ int flip1_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
if (status.bStatus != DFU_STATUS_OK)
{
avrdude_message(MSG_INFO, "%s: failed to read signature byte %d: %s\n",
progname, i, flip1_status_str(&status));
pmsg_error("unable to read signature byte %d: %s\n", i, flip1_status_str(&status));
if (status.bState == STATE_dfuERROR)
dfu_clrstatus(FLIP1(pgm)->dfu);
return -1;
@@ -570,7 +528,7 @@ int flip1_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
}
else
{
avrdude_message(MSG_NOTICE2, "cached\n");
msg_notice2("cached\n");
}
memcpy(mem->buf, FLIP1(pgm)->part_sig, sizeof(FLIP1(pgm)->part_sig));
@@ -583,8 +541,7 @@ void flip1_setup(PROGRAMMER * pgm)
pgm->cookie = calloc(1, sizeof(struct flip1));
if (pgm->cookie == NULL) {
avrdude_message(MSG_INFO, "%s: Out of memory allocating private data structure\n",
progname);
pmsg_error("out of memory allocating private data structure\n");
exit(1);
}
}
@@ -601,11 +558,10 @@ void flip1_teardown(PROGRAMMER * pgm)
void flip1_show_info(struct flip1 *flip1)
{
dfu_show_info(flip1->dfu);
avrdude_message(MSG_INFO, " USB max packet size : %hu\n",
(unsigned short) flip1->dfu->dev_desc.bMaxPacketSize0);
msg_info(" USB max packet size : %hu\n", (unsigned short) flip1->dfu->dev_desc.bMaxPacketSize0);
}
int flip1_read_memory(PROGRAMMER * pgm,
int flip1_read_memory(const PROGRAMMER *pgm,
enum flip1_mem_unit mem_unit, uint32_t addr, void *ptr, int size)
{
struct dfu_dev *dfu = FLIP1(pgm)->dfu;
@@ -619,8 +575,7 @@ int flip1_read_memory(PROGRAMMER * pgm,
unsigned int default_timeout = dfu->timeout;
avrdude_message(MSG_NOTICE2, "%s: flip_read_memory(%s, 0x%04x, %d)\n",
progname, flip1_mem_unit_str(mem_unit), addr, size);
pmsg_notice2("flip_read_memory(%s, 0x%04x, %d)\n", flip1_mem_unit_str(mem_unit), addr, size);
/*
* As this function is called once per page, no need to handle 64
@@ -650,9 +605,8 @@ int flip1_read_memory(PROGRAMMER * pgm,
if (status.bStatus != DFU_STATUS_OK)
{
avrdude_message(MSG_INFO, "%s: failed to read %u bytes of %s memory @%u: %s\n",
progname, size, flip1_mem_unit_str(mem_unit), addr,
flip1_status_str(&status));
pmsg_error("unable to read %u bytes of %s memory @%u: %s\n", size,
flip1_mem_unit_str(mem_unit), addr, flip1_status_str(&status));
if (status.bState == STATE_dfuERROR)
dfu_clrstatus(dfu);
return -1;
@@ -663,13 +617,14 @@ int flip1_read_memory(PROGRAMMER * pgm,
if (cmd_result < 0 && aux_result == 0 &&
status.bStatus == DFU_STATUS_ERR_WRITE) {
if (FLIP1(pgm)->security_mode_flag == 0)
avrdude_message(MSG_INFO, "\n%s:\n"
"%s***********************************************************************\n"
"%sMaybe the device is in ``security mode´´, and needs a chip erase first?\n"
"%s***********************************************************************\n"
"\n",
progname, progbuf, progbuf, progbuf);
if (FLIP1(pgm)->security_mode_flag == 0) {
msg_error("\n");
pmsg_error("\n");
imsg_error("***********************************************************************\n");
imsg_error("Maybe the device is in ``security mode´´, and needs a chip erase first?\n");
imsg_error("***********************************************************************\n");
msg_error("\n");
}
FLIP1(pgm)->security_mode_flag = 1;
}
@@ -678,9 +633,8 @@ int flip1_read_memory(PROGRAMMER * pgm,
if (status.bStatus != DFU_STATUS_OK)
{
avrdude_message(MSG_INFO, "%s: failed to read %u bytes of %s memory @%u: %s\n",
progname, size, flip1_mem_unit_str(mem_unit), addr,
flip1_status_str(&status));
pmsg_error("unable to read %u bytes of %s memory @%u: %s\n", size,
flip1_mem_unit_str(mem_unit), addr, flip1_status_str(&status));
if (status.bState == STATE_dfuERROR)
dfu_clrstatus(dfu);
return -1;
@@ -712,14 +666,14 @@ int flip1_write_memory(struct dfu_dev *dfu,
unsigned int default_timeout = dfu->timeout;
unsigned char *buf;
avrdude_message(MSG_NOTICE2, "%s: flip_write_memory(%s, 0x%04x, %d)\n",
progname, flip1_mem_unit_str(mem_unit), addr, size);
pmsg_notice2("flip_write_memory(%s, 0x%04x, %d)\n",
flip1_mem_unit_str(mem_unit), addr, size);
if (size < 32) {
/* presumably single-byte updates; must be padded to USB endpoint size */
if ((addr + size - 1) / 32 != addr / 32) {
avrdude_message(MSG_INFO, "%s: flip_write_memory(): begin (0x%x) and end (0x%x) not within same 32-byte block\n",
progname, addr, addr + size - 1);
pmsg_error("begin 0x%x and end 0x%x not within same 32-byte block\n",
addr, addr + size - 1);
return -1;
}
write_size = 32;
@@ -730,7 +684,7 @@ int flip1_write_memory(struct dfu_dev *dfu,
if ((buf = malloc(sizeof(struct flip1_cmd_header) +
write_size +
sizeof(struct flip1_prog_footer))) == 0) {
avrdude_message(MSG_INFO, "%s: Out of memory\n", progname);
pmsg_error("out of memory\n");
return -1;
}
@@ -779,9 +733,8 @@ int flip1_write_memory(struct dfu_dev *dfu,
if (status.bStatus != DFU_STATUS_OK)
{
avrdude_message(MSG_INFO, "%s: failed to write %u bytes of %s memory @%u: %s\n",
progname, size, flip1_mem_unit_str(mem_unit), addr,
flip1_status_str(&status));
pmsg_error("unable to write %u bytes of %s memory @%u: %s\n", size,
flip1_mem_unit_str(mem_unit), addr, flip1_status_str(&status));
if (status.bState == STATE_dfuERROR)
dfu_clrstatus(dfu);
return -1;
@@ -810,8 +763,7 @@ int flip1_set_mem_page(struct dfu_dev *dfu,
if (status.bStatus != DFU_STATUS_OK)
{
avrdude_message(MSG_INFO, "%s: failed to set memory page: %s\n",
progname, flip1_status_str(&status));
pmsg_error("unable to set memory page: %s\n", flip1_status_str(&status));
if (status.bState == STATE_dfuERROR)
dfu_clrstatus(dfu);
return -1;
@@ -856,23 +808,20 @@ const char * flip1_mem_unit_str(enum flip1_mem_unit mem_unit)
}
enum flip1_mem_unit flip1_mem_unit(const char *name) {
if (strcasecmp(name, "flash") == 0)
if (strcmp(name, "flash") == 0)
return FLIP1_MEM_UNIT_FLASH;
if (strcasecmp(name, "eeprom") == 0)
if (strcmp(name, "eeprom") == 0)
return FLIP1_MEM_UNIT_EEPROM;
return FLIP1_MEM_UNIT_UNKNOWN;
}
#else /* HAVE_LIBUSB */
// Dummy functions
int flip1_open(PROGRAMMER *pgm, char *port_spec)
{
fprintf(stderr, "%s: Error: No USB support in this compile of avrdude\n",
progname);
int flip1_open(PROGRAMMER *pgm, const char *port_spec) {
pmsg_error("no USB support compiled for avrdude\n");
return -1;
}
int flip1_initialize(PROGRAMMER* pgm, AVRPART *part)
{
int flip1_initialize(const PROGRAMMER *pgm, const AVRPART *part) {
return -1;
}
@@ -880,54 +829,48 @@ void flip1_close(PROGRAMMER* pgm)
{
}
void flip1_enable(PROGRAMMER* pgm)
{
void flip1_enable(PROGRAMMER *pgm, const AVRPART *p) {
}
void flip1_disable(PROGRAMMER* pgm)
{
void flip1_disable(const PROGRAMMER *pgm) {
}
void flip1_display(PROGRAMMER* pgm, const char *prefix)
{
void flip1_display(const PROGRAMMER *pgm, const char *prefix) {
}
int flip1_program_enable(PROGRAMMER* pgm, AVRPART *part)
{
int flip1_program_enable(const PROGRAMMER *pgm, const AVRPART *part) {
return -1;
}
int flip1_chip_erase(PROGRAMMER* pgm, AVRPART *part)
{
int flip1_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) {
return -1;
}
int flip1_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
int flip1_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned long addr, unsigned char *value)
{
return -1;
}
int flip1_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
int flip1_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned long addr, unsigned char value)
{
return -1;
}
int flip1_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
int flip1_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned int page_size, unsigned int addr, unsigned int n_bytes)
{
return -1;
}
int flip1_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
int flip1_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned int page_size, unsigned int addr, unsigned int n_bytes)
{
return -1;
}
int flip1_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
{
int flip1_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem) {
return -1;
}

View File

@@ -26,7 +26,7 @@ extern "C" {
#endif
extern const char flip1_desc[];
extern void flip1_initpgm(PROGRAMMER * pgm);
extern void flip1_initpgm(PROGRAMMER *pgm);
#ifdef __cplusplus
}

View File

@@ -123,23 +123,25 @@ enum flip2_mem_unit {
/* EXPORTED PROGRAMMER FUNCTION PROTOTYPES */
static int flip2_open(PROGRAMMER *pgm, char *port_spec);
static int flip2_initialize(PROGRAMMER* pgm, AVRPART *part);
static int flip2_open(PROGRAMMER *pgm, const char *port_spec);
static int flip2_initialize(const PROGRAMMER *pgm, const AVRPART *part);
static void flip2_close(PROGRAMMER* pgm);
static void flip2_enable(PROGRAMMER* pgm);
static void flip2_disable(PROGRAMMER* pgm);
static void flip2_display(PROGRAMMER* pgm, const char *prefix);
static int flip2_program_enable(PROGRAMMER* pgm, AVRPART *part);
static int flip2_chip_erase(PROGRAMMER* pgm, AVRPART *part);
static int flip2_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
static void flip2_enable(PROGRAMMER *pgm, const AVRPART *p);
static void flip2_disable(const PROGRAMMER *pgm);
static void flip2_display(const PROGRAMMER *pgm, const char *prefix);
static int flip2_program_enable(const PROGRAMMER *pgm, const AVRPART *part);
static int flip2_chip_erase(const PROGRAMMER *pgm, const AVRPART *part);
static int flip2_start_app(const PROGRAMMER *pgm);
static int flip2_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned long addr, unsigned char *value);
static int flip2_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
static int flip2_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned long addr, unsigned char value);
static int flip2_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
static int flip2_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned int page_size, unsigned int addr, unsigned int n_bytes);
static int flip2_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
static int flip2_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned int page_size, unsigned int addr, unsigned int n_bytes);
static int flip2_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem);
static int flip2_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem);
static int flip2_parseexitspecs(PROGRAMMER* pgm, const char *s);
static void flip2_setup(PROGRAMMER * pgm);
static void flip2_teardown(PROGRAMMER * pgm);
@@ -166,12 +168,7 @@ static const char * flip2_status_str(const struct dfu_status *status);
static const char * flip2_mem_unit_str(enum flip2_mem_unit mem_unit);
static enum flip2_mem_unit flip2_mem_unit(const char *name);
#endif /* HAVE_LIBUSB */
/* THE INITPGM FUNCTION DEFINITIONS */
void flip2_initpgm(PROGRAMMER *pgm)
{
void flip2_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "flip2");
/* Mandatory Functions */
@@ -188,21 +185,19 @@ void flip2_initpgm(PROGRAMMER *pgm)
pgm->read_byte = flip2_read_byte;
pgm->write_byte = flip2_write_byte;
pgm->read_sig_bytes = flip2_read_sig_bytes;
pgm->parseexitspecs = flip2_parseexitspecs;
pgm->setup = flip2_setup;
pgm->teardown = flip2_teardown;
}
#ifdef HAVE_LIBUSB
/* EXPORTED PROGRAMMER FUNCTION DEFINITIONS */
int flip2_open(PROGRAMMER *pgm, char *port_spec)
{
int flip2_open(PROGRAMMER *pgm, const char *port_spec) {
FLIP2(pgm)->dfu = dfu_open(port_spec);
return (FLIP2(pgm)->dfu != NULL) ? 0 : -1;
}
int flip2_initialize(PROGRAMMER* pgm, AVRPART *part)
{
int flip2_initialize(const PROGRAMMER *pgm, const AVRPART *part) {
unsigned short vid, pid;
int result;
struct dfu_dev *dfu = FLIP2(pgm)->dfu;
@@ -231,17 +226,15 @@ int flip2_initialize(PROGRAMMER* pgm, AVRPART *part)
if (usbpid) {
pid = *(int *)(ldata(usbpid));
if (lnext(usbpid))
avrdude_message(MSG_INFO, "%s: Warning: using PID 0x%04x, ignoring remaining PIDs in list\n",
progname, pid);
pmsg_warning("using PID 0x%04x, ignoring remaining PIDs in list\n", pid);
} else {
pid = part->usbpid;
}
if (!ovsigck && !(part->flags & AVRPART_HAS_PDI)) {
avrdude_message(MSG_INFO, "%s: \"flip2\" (FLIP protocol version 2) is for Xmega devices.\n"
"%s For AT90USB* or ATmega*U* devices, use \"flip1\".\n"
"%s (Use -F to bypass this check.)\n",
progname, progbuf, progbuf);
if (!ovsigck && !(part->prog_modes & PM_PDI)) {
pmsg_error("flip2 (FLIP protocol version 2) is for Xmega devices\n");
imsg_error("for AT90USB* or ATmega*U* devices, use flip1\n");
imsg_error("(or use -F to bypass this check)\n");
return -1;
}
@@ -253,44 +246,44 @@ int flip2_initialize(PROGRAMMER* pgm, AVRPART *part)
/* Check if descriptor values are what we expect. */
if (dfu->dev_desc.idVendor != vid)
avrdude_message(MSG_INFO, "%s: Warning: USB idVendor = 0x%04X (expected 0x%04X)\n",
progname, dfu->dev_desc.idVendor, vid);
pmsg_warning("USB idVendor = 0x%04X (expected 0x%04X)\n",
dfu->dev_desc.idVendor, vid);
if (pid != 0 && dfu->dev_desc.idProduct != pid)
avrdude_message(MSG_INFO, "%s: Warning: USB idProduct = 0x%04X (expected 0x%04X)\n",
progname, dfu->dev_desc.idProduct, pid);
pmsg_warning("USB idProduct = 0x%04X (expected 0x%04X)\n",
dfu->dev_desc.idProduct, pid);
if (dfu->dev_desc.bNumConfigurations != 1)
avrdude_message(MSG_INFO, "%s: Warning: USB bNumConfigurations = %d (expected 1)\n",
progname, (int) dfu->dev_desc.bNumConfigurations);
pmsg_error("USB bNumConfigurations = %d (expected 1)\n",
(int) dfu->dev_desc.bNumConfigurations);
if (dfu->conf_desc.bNumInterfaces != 1)
avrdude_message(MSG_INFO, "%s: Warning: USB bNumInterfaces = %d (expected 1)\n",
progname, (int) dfu->conf_desc.bNumInterfaces);
pmsg_error("USB bNumInterfaces = %d (expected 1)\n",
(int) dfu->conf_desc.bNumInterfaces);
if (dfu->dev_desc.bDeviceClass != 0)
avrdude_message(MSG_INFO, "%s: Warning: USB bDeviceClass = %d (expected 0)\n",
progname, (int) dfu->dev_desc.bDeviceClass);
pmsg_error("USB bDeviceClass = %d (expected 0)\n",
(int) dfu->dev_desc.bDeviceClass);
if (dfu->dev_desc.bDeviceSubClass != 0)
avrdude_message(MSG_INFO, "%s: Warning: USB bDeviceSubClass = %d (expected 0)\n",
progname, (int) dfu->dev_desc.bDeviceSubClass);
pmsg_error("USB bDeviceSubClass = %d (expected 0)\n",
(int) dfu->dev_desc.bDeviceSubClass);
if (dfu->dev_desc.bDeviceProtocol != 0)
avrdude_message(MSG_INFO, "%s: Warning: USB bDeviceProtocol = %d (expected 0)\n",
progname, (int) dfu->dev_desc.bDeviceProtocol);
pmsg_error("USB bDeviceProtocol = %d (expected 0)\n",
(int) dfu->dev_desc.bDeviceProtocol);
if (dfu->intf_desc.bInterfaceClass != 0xFF)
avrdude_message(MSG_INFO, "%s: Warning: USB bInterfaceClass = %d (expected 255)\n",
progname, (int) dfu->intf_desc.bInterfaceClass);
pmsg_error("USB bInterfaceClass = %d (expected 255)\n",
(int) dfu->intf_desc.bInterfaceClass);
if (dfu->intf_desc.bInterfaceSubClass != 0)
avrdude_message(MSG_INFO, "%s: Warning: USB bInterfaceSubClass = %d (expected 0)\n",
progname, (int) dfu->intf_desc.bInterfaceSubClass);
pmsg_error("USB bInterfaceSubClass = %d (expected 0)\n",
(int) dfu->intf_desc.bInterfaceSubClass);
if (dfu->intf_desc.bInterfaceProtocol != 0)
avrdude_message(MSG_INFO, "%s: Warning: USB bInterfaceSubClass = %d (expected 0)\n",
progname, (int) dfu->intf_desc.bInterfaceProtocol);
pmsg_error("USB bInterfaceSubClass = %d (expected 0)\n",
(int) dfu->intf_desc.bInterfaceProtocol);
result = flip2_read_memory(FLIP2(pgm)->dfu,
FLIP2_MEM_UNIT_SIGNATURE, 0, FLIP2(pgm)->part_sig, 4);
@@ -318,28 +311,27 @@ flip2_initialize_fail:
void flip2_close(PROGRAMMER* pgm)
{
if (FLIP2(pgm)->dfu != NULL) {
if (pgm->exit_reset == EXIT_RESET_ENABLED)
flip2_start_app(pgm);
dfu_close(FLIP2(pgm)->dfu);
FLIP2(pgm)->dfu = NULL;
}
}
void flip2_enable(PROGRAMMER* pgm)
{
void flip2_enable(PROGRAMMER *pgm, const AVRPART *p) {
/* Nothing to do. */
}
void flip2_disable(PROGRAMMER* pgm)
{
void flip2_disable(const PROGRAMMER *pgm) {
/* Nothing to do. */
}
void flip2_display(PROGRAMMER* pgm, const char *prefix)
{
void flip2_display(const PROGRAMMER *pgm, const char *prefix) {
/* Nothing to do. */
}
int flip2_program_enable(PROGRAMMER* pgm, AVRPART *part)
{
int flip2_program_enable(const PROGRAMMER *pgm, const AVRPART *part) {
/* I couldn't find anything that uses this function, although it is marked
* as "mandatory" in pgm.c. In case anyone does use it, we'll report an
* error if we failed to initialize.
@@ -348,13 +340,12 @@ int flip2_program_enable(PROGRAMMER* pgm, AVRPART *part)
return (FLIP2(pgm)->dfu != NULL) ? 0 : -1;
}
int flip2_chip_erase(PROGRAMMER* pgm, AVRPART *part)
{
int flip2_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) {
struct dfu_status status;
int cmd_result = 0;
int aux_result;
avrdude_message(MSG_NOTICE2, "%s: flip_chip_erase()\n", progname);
pmsg_notice2("flip_chip_erase()\n");
struct flip2_cmd cmd = {
FLIP2_CMD_GROUP_EXEC, FLIP2_CMD_CHIP_ERASE, { 0xFF, 0, 0, 0 }
@@ -372,9 +363,8 @@ int flip2_chip_erase(PROGRAMMER* pgm, AVRPART *part)
status.bState == ((FLIP2_STATUS_ERASE_ONGOING >> 0) & 0xFF))
{
continue;
} else
avrdude_message(MSG_INFO, "%s: Error: DFU status %s\n", progname,
flip2_status_str(&status));
}
pmsg_error("DFU status %s\n", flip2_status_str(&status));
dfu_clrstatus(FLIP2(pgm)->dfu);
} else
break;
@@ -383,7 +373,23 @@ int flip2_chip_erase(PROGRAMMER* pgm, AVRPART *part)
return cmd_result;
}
int flip2_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
int flip2_start_app(const PROGRAMMER *pgm) {
pmsg_info("starting application\n");
struct flip2_cmd cmd = {
FLIP2_CMD_GROUP_EXEC, FLIP2_CMD_START_APP, { 0x00, 0, 0, 0 }
};
// queue command
int cmd_result = dfu_dnload(FLIP2(pgm)->dfu, &cmd, sizeof(cmd));
// repeat dnload to actually execute
dfu_dnload(FLIP2(pgm)->dfu, &cmd, sizeof(cmd));
return cmd_result;
}
int flip2_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned long addr, unsigned char *value)
{
enum flip2_mem_unit mem_unit;
@@ -394,19 +400,17 @@ int flip2_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
mem_unit = flip2_mem_unit(mem->desc);
if (mem_unit == FLIP2_MEM_UNIT_UNKNOWN) {
avrdude_message(MSG_INFO, "%s: Error: "
"\"%s\" memory not accessible using FLIP",
progname, mem->desc);
pmsg_error("%s memory not accessible using FLIP", mem->desc);
if (strcmp(mem->desc, "flash") == 0)
avrdude_message(MSG_INFO, " (did you mean \"application\"?)");
avrdude_message(MSG_INFO, "\n");
msg_error(" (did you mean \"application\"?)");
msg_error("\n");
return -1;
}
return flip2_read_memory(FLIP2(pgm)->dfu, mem_unit, addr, value, 1);
}
int flip2_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
int flip2_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned long addr, unsigned char value)
{
enum flip2_mem_unit mem_unit;
@@ -417,19 +421,17 @@ int flip2_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
mem_unit = flip2_mem_unit(mem->desc);
if (mem_unit == FLIP2_MEM_UNIT_UNKNOWN) {
avrdude_message(MSG_INFO, "%s: Error: "
"\"%s\" memory not accessible using FLIP",
progname, mem->desc);
pmsg_error("%s memory not accessible using FLIP", mem->desc);
if (strcmp(mem->desc, "flash") == 0)
avrdude_message(MSG_INFO, " (did you mean \"application\"?)");
avrdude_message(MSG_INFO, "\n");
msg_error(" (did you mean \"application\"?)");
msg_error("\n");
return -1;
}
return flip2_write_memory(FLIP2(pgm)->dfu, mem_unit, addr, &value, 1);
}
int flip2_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
int flip2_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned int page_size, unsigned int addr, unsigned int n_bytes)
{
enum flip2_mem_unit mem_unit;
@@ -441,19 +443,16 @@ int flip2_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
mem_unit = flip2_mem_unit(mem->desc);
if (mem_unit == FLIP2_MEM_UNIT_UNKNOWN) {
avrdude_message(MSG_INFO, "%s: Error: "
"\"%s\" memory not accessible using FLIP",
progname, mem->desc);
pmsg_error("%s memory not accessible using FLIP", mem->desc);
if (strcmp(mem->desc, "flash") == 0)
avrdude_message(MSG_INFO, " (did you mean \"application\"?)");
avrdude_message(MSG_INFO, "\n");
msg_error(" (did you mean \"application\"?)");
msg_error("\n");
return -1;
}
if (n_bytes > INT_MAX) {
/* This should never happen, unless the int type is only 16 bits. */
avrdude_message(MSG_INFO, "%s: Error: Attempting to read more than %d bytes\n",
progname, INT_MAX);
pmsg_error("attempting to read more than %d bytes\n", INT_MAX);
exit(1);
}
@@ -463,7 +462,7 @@ int flip2_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
return (result == 0) ? n_bytes : -1;
}
int flip2_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
int flip2_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
unsigned int page_size, unsigned int addr, unsigned int n_bytes)
{
enum flip2_mem_unit mem_unit;
@@ -475,19 +474,16 @@ int flip2_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
mem_unit = flip2_mem_unit(mem->desc);
if (mem_unit == FLIP2_MEM_UNIT_UNKNOWN) {
avrdude_message(MSG_INFO, "%s: Error: "
"\"%s\" memory not accessible using FLIP",
progname, mem->desc);
pmsg_error("%s memory not accessible using FLIP", mem->desc);
if (strcmp(mem->desc, "flash") == 0)
avrdude_message(MSG_INFO, " (did you mean \"application\"?)");
avrdude_message(MSG_INFO, "\n");
msg_error(" (did you mean \"application\"?)");
msg_error("\n");
return -1;
}
if (n_bytes > INT_MAX) {
/* This should never happen, unless the int type is only 16 bits. */
avrdude_message(MSG_INFO, "%s: Error: Attempting to read more than %d bytes\n",
progname, INT_MAX);
pmsg_error("attempting to read more than %d bytes\n", INT_MAX);
exit(1);
}
@@ -497,14 +493,35 @@ int flip2_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
return (result == 0) ? n_bytes : -1;
}
int flip2_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
{
// Parse the -E option flag
int flip2_parseexitspecs(PROGRAMMER *pgm, const char *sp) {
char *cp, *s, *str = cfg_strdup("flip2_parseextitspecs()", sp);
s = str;
while ((cp = strtok(s, ","))) {
s = NULL;
if (!strcmp(cp, "reset")) {
pgm->exit_reset = EXIT_RESET_ENABLED;
continue;
}
if (!strcmp(cp, "noreset")) {
pgm->exit_reset = EXIT_RESET_DISABLED;
continue;
}
free(str);
return -1;
}
free(str);
return 0;
}
int flip2_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem) {
if (FLIP2(pgm)->dfu == NULL)
return -1;
if (mem->size < sizeof(FLIP2(pgm)->part_sig)) {
avrdude_message(MSG_INFO, "%s: Error: Signature read must be at least %u bytes\n",
progname, (unsigned int) sizeof(FLIP2(pgm)->part_sig));
pmsg_error("signature read must be at least %u bytes\n", (unsigned int) sizeof(FLIP2(pgm)->part_sig));
return -1;
}
@@ -517,8 +534,7 @@ void flip2_setup(PROGRAMMER * pgm)
pgm->cookie = calloc(1, sizeof(struct flip2));
if (pgm->cookie == NULL) {
avrdude_message(MSG_INFO, "%s: Out of memory allocating private data structure\n",
progname);
pmsg_error("out of memory allocating private data structure\n");
exit(1);
}
}
@@ -536,24 +552,24 @@ void flip2_show_info(struct flip2 *flip2)
{
dfu_show_info(flip2->dfu);
avrdude_message(MSG_INFO, " Part signature : 0x%02X%02X%02X\n",
msg_info(" Part signature : 0x%02X%02X%02X\n",
(int) flip2->part_sig[0],
(int) flip2->part_sig[1],
(int) flip2->part_sig[2]);
if (flip2->part_rev < 26)
avrdude_message(MSG_INFO, " Part revision : %c\n",
msg_info(" Part revision : %c\n",
(char) (flip2->part_rev + 'A'));
else
avrdude_message(MSG_INFO, " Part revision : %c%c\n",
msg_info(" Part revision : %c%c\n",
(char) (flip2->part_rev / 26 - 1 + 'A'),
(char) (flip2->part_rev % 26 + 'A'));
avrdude_message(MSG_INFO, " Bootloader version : 2.%hu.%hu\n",
msg_info(" Bootloader version : 2.%hu.%hu\n",
((unsigned short) flip2->boot_ver >> 4) & 0xF,
((unsigned short) flip2->boot_ver >> 0) & 0xF);
avrdude_message(MSG_INFO, " USB max packet size : %hu\n",
msg_info(" USB max packet size : %hu\n",
(unsigned short) flip2->dfu->dev_desc.bMaxPacketSize0);
}
@@ -566,18 +582,15 @@ int flip2_read_memory(struct dfu_dev *dfu,
int read_size;
int result;
avrdude_message(MSG_NOTICE2, "%s: flip_read_memory(%s, 0x%04x, %d)\n",
progname, flip2_mem_unit_str(mem_unit), addr, size);
pmsg_notice2("flip_read_memory(%s, 0x%04x, %d)\n", flip2_mem_unit_str(mem_unit), addr, size);
result = flip2_set_mem_unit(dfu, mem_unit);
if (result != 0) {
if ((mem_name = flip2_mem_unit_str(mem_unit)) != NULL)
avrdude_message(MSG_INFO, "%s: Error: Failed to set memory unit 0x%02X (%s)\n",
progname, (int) mem_unit, mem_name);
pmsg_error("unable to set memory unit 0x%02X (%s)\n", (int) mem_unit, mem_name);
else
avrdude_message(MSG_INFO, "%s: Error: Failed to set memory unit 0x%02X\n",
progname, (int) mem_unit);
pmsg_error("unable to set memory unit 0x%02X\n", (int) mem_unit);
return -1;
}
@@ -585,8 +598,7 @@ int flip2_read_memory(struct dfu_dev *dfu,
result = flip2_set_mem_page(dfu, page_addr);
if (result != 0) {
avrdude_message(MSG_INFO, "%s: Error: Failed to set memory page 0x%04hX\n",
progname, page_addr);
pmsg_error("unable to set memory page 0x%04hX\n", page_addr);
return -1;
}
@@ -597,8 +609,7 @@ int flip2_read_memory(struct dfu_dev *dfu,
if (page_addr != prev_page_addr) {
result = flip2_set_mem_page(dfu, page_addr);
if (result != 0) {
avrdude_message(MSG_INFO, "%s: Error: Failed to set memory page 0x%04hX\n",
progname, page_addr);
pmsg_error("unable to set memory page 0x%04hX\n", page_addr);
return -1;
}
}
@@ -607,8 +618,7 @@ int flip2_read_memory(struct dfu_dev *dfu,
result = flip2_read_max1k(dfu, addr & 0xFFFF, ptr, read_size);
if (result != 0) {
avrdude_message(MSG_INFO, "%s: Error: Failed to read 0x%04X bytes at 0x%04lX\n",
progname, read_size, (unsigned long) addr);
pmsg_error("unable to read 0x%04X bytes at 0x%04lX\n", read_size, (unsigned long) addr);
return -1;
}
@@ -629,18 +639,15 @@ int flip2_write_memory(struct dfu_dev *dfu,
int write_size;
int result;
avrdude_message(MSG_NOTICE2, "%s: flip_write_memory(%s, 0x%04x, %d)\n",
progname, flip2_mem_unit_str(mem_unit), addr, size);
pmsg_notice2("flip_write_memory(%s, 0x%04x, %d)\n", flip2_mem_unit_str(mem_unit), addr, size);
result = flip2_set_mem_unit(dfu, mem_unit);
if (result != 0) {
if ((mem_name = flip2_mem_unit_str(mem_unit)) != NULL)
avrdude_message(MSG_INFO, "%s: Error: Failed to set memory unit 0x%02X (%s)\n",
progname, (int) mem_unit, mem_name);
pmsg_error("unable to set memory unit 0x%02X (%s)\n", (int) mem_unit, mem_name);
else
avrdude_message(MSG_INFO, "%s: Error: Failed to set memory unit 0x%02X\n",
progname, (int) mem_unit);
pmsg_error("unable to set memory unit 0x%02X\n", (int) mem_unit);
return -1;
}
@@ -648,8 +655,7 @@ int flip2_write_memory(struct dfu_dev *dfu,
result = flip2_set_mem_page(dfu, page_addr);
if (result != 0) {
avrdude_message(MSG_INFO, "%s: Error: Failed to set memory page 0x%04hX\n",
progname, page_addr);
pmsg_error("unable to set memory page 0x%04hX\n", page_addr);
return -1;
}
@@ -660,8 +666,7 @@ int flip2_write_memory(struct dfu_dev *dfu,
if (page_addr != prev_page_addr) {
result = flip2_set_mem_page(dfu, page_addr);
if (result != 0) {
avrdude_message(MSG_INFO, "%s: Error: Failed to set memory page 0x%04hX\n",
progname, page_addr);
pmsg_error("unable to set memory page 0x%04hX\n", page_addr);
return -1;
}
}
@@ -670,8 +675,7 @@ int flip2_write_memory(struct dfu_dev *dfu,
result = flip2_write_max1k(dfu, addr & 0xFFFF, ptr, write_size);
if (result != 0) {
avrdude_message(MSG_INFO, "%s: Error: Failed to write 0x%04X bytes at 0x%04lX\n",
progname, write_size, (unsigned long) addr);
pmsg_error("unable to write 0x%04X bytes at 0x%04lX\n", write_size, (unsigned long) addr);
return -1;
}
@@ -707,11 +711,9 @@ int flip2_set_mem_unit(struct dfu_dev *dfu, enum flip2_mem_unit mem_unit)
if (status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) &&
status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF))
{
avrdude_message(MSG_INFO, "%s: Error: Unknown memory unit (0x%02x)\n",
progname, (unsigned int) mem_unit);
pmsg_error("unknown memory unit (0x%02x)\n", (unsigned int) mem_unit);
} else
avrdude_message(MSG_INFO, "%s: Error: DFU status %s\n", progname,
flip2_status_str(&status));
pmsg_error("DFU status %s\n", flip2_status_str(&status));
dfu_clrstatus(dfu);
}
@@ -744,11 +746,9 @@ int flip2_set_mem_page(struct dfu_dev *dfu,
if (status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) &&
status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF))
{
avrdude_message(MSG_INFO, "%s: Error: Page address out of range (0x%04hx)\n",
progname, page_addr);
pmsg_error("page address out of range (0x%04hx)\n", page_addr);
} else
avrdude_message(MSG_INFO, "%s: Error: DFU status %s\n", progname,
flip2_status_str(&status));
pmsg_error("DFU status %s\n", flip2_status_str(&status));
dfu_clrstatus(dfu);
}
@@ -789,11 +789,9 @@ flip2_read_max1k_status:
if (status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) &&
status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF))
{
avrdude_message(MSG_INFO, "%s: Error: Address out of range [0x%04hX,0x%04hX]\n",
progname, offset, offset+size-1);
pmsg_error("address out of range [0x%04hX,0x%04hX]\n", offset, offset+size-1);
} else
avrdude_message(MSG_INFO, "%s: Error: DFU status %s\n", progname,
flip2_status_str(&status));
pmsg_error("DFU status %s\n", flip2_status_str(&status));
dfu_clrstatus(dfu);
}
@@ -819,8 +817,7 @@ int flip2_write_max1k(struct dfu_dev *dfu,
cmd.args[3] = ((offset+size-1) >> 0) & 0xFF;
if (size > 0x400) {
avrdude_message(MSG_INFO, "%s: Error: Write block too large (%hu > 1024)\n",
progname, size);
pmsg_error("erite block too large (%hu > 1024)\n", size);
return -1;
}
@@ -850,11 +847,9 @@ int flip2_write_max1k(struct dfu_dev *dfu,
if (status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) &&
status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF))
{
avrdude_message(MSG_INFO, "%s: Error: Address out of range [0x%04hX,0x%04hX]\n",
progname, offset, offset+size-1);
pmsg_error("address out of range [0x%04hX,0x%04hX]\n", offset, offset+size-1);
} else
avrdude_message(MSG_INFO, "%s: Error: DFU status %s\n", progname,
flip2_status_str(&status));
pmsg_error("DFU status %s\n", flip2_status_str(&status));
dfu_clrstatus(dfu);
}
@@ -905,93 +900,26 @@ const char * flip2_mem_unit_str(enum flip2_mem_unit mem_unit)
}
enum flip2_mem_unit flip2_mem_unit(const char *name) {
if (strcasecmp(name, "application") == 0)
if (strcmp(name, "application") == 0)
return FLIP2_MEM_UNIT_FLASH;
if (strcasecmp(name, "eeprom") == 0)
if (strcmp(name, "eeprom") == 0)
return FLIP2_MEM_UNIT_EEPROM;
if (strcasecmp(name, "signature") == 0)
if (strcmp(name, "signature") == 0)
return FLIP2_MEM_UNIT_SIGNATURE;
return FLIP2_MEM_UNIT_UNKNOWN;
}
#else /* HAVE_LIBUSB */
#else /* !HAVE_LIBUSB */
/* EXPORTED PROGRAMMER FUNCTION DEFINITIONS */
int flip2_open(PROGRAMMER *pgm, char *port_spec)
{
fprintf(stderr, "%s: Error: No USB support in this compile of avrdude\n",
progname);
return -1;
// Give a proper error if we were not compiled with libusb
static int flip2_nousb_open(PROGRAMMER* pgm, const char* name) {
pmsg_error("no USB support; please compile with libusb installed\n");
return -1;
}
int flip2_initialize(PROGRAMMER* pgm, AVRPART *part)
{
return -1;
void flip2_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "flip2");
pgm->open = flip2_nousb_open;
}
void flip2_close(PROGRAMMER* pgm)
{
}
void flip2_enable(PROGRAMMER* pgm)
{
}
void flip2_disable(PROGRAMMER* pgm)
{
}
void flip2_display(PROGRAMMER* pgm, const char *prefix)
{
}
int flip2_program_enable(PROGRAMMER* pgm, AVRPART *part)
{
return -1;
}
int flip2_chip_erase(PROGRAMMER* pgm, AVRPART *part)
{
return -1;
}
int flip2_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
unsigned long addr, unsigned char *value)
{
return -1;
}
int flip2_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
unsigned long addr, unsigned char value)
{
return -1;
}
int flip2_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
unsigned int page_size, unsigned int addr, unsigned int n_bytes)
{
return -1;
}
int flip2_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
unsigned int page_size, unsigned int addr, unsigned int n_bytes)
{
return -1;
}
int flip2_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
{
return -1;
}
void flip2_setup(PROGRAMMER * pgm)
{
}
void flip2_teardown(PROGRAMMER * pgm)
{
}
#endif /* HAVE_LIBUSB */

View File

@@ -26,7 +26,7 @@ extern "C" {
#endif
extern const char flip2_desc[];
extern void flip2_initpgm(PROGRAMMER * pgm);
extern void flip2_initpgm(PROGRAMMER *pgm);
#ifdef __cplusplus
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
#define ft245r_h
extern const char ft245r_desc[];
void ft245r_initpgm (PROGRAMMER * pgm);
void ft245r_initpgm(PROGRAMMER *pgm);
#endif /* ft245r_h */

File diff suppressed because it is too large Load Diff

View File

@@ -25,27 +25,29 @@
extern "C" {
#endif
int jtag3_open_common(PROGRAMMER * pgm, char * port);
int jtag3_send(PROGRAMMER * pgm, unsigned char * data, size_t len);
int jtag3_recv(PROGRAMMER * pgm, unsigned char **msg);
int jtag3_open_common(PROGRAMMER *pgm, const char *port);
int jtag3_send(const PROGRAMMER *pgm, unsigned char *data, size_t len);
int jtag3_recv(const PROGRAMMER *pgm, unsigned char **msg);
void jtag3_close(PROGRAMMER * pgm);
int jtag3_getsync(PROGRAMMER * pgm, int mode);
int jtag3_getparm(PROGRAMMER * pgm, unsigned char scope,
int jtag3_getsync(const PROGRAMMER *pgm, int mode);
int jtag3_getparm(const PROGRAMMER *pgm, unsigned char scope,
unsigned char section, unsigned char parm,
unsigned char *value, unsigned char length);
int jtag3_setparm(PROGRAMMER * pgm, unsigned char scope,
int jtag3_setparm(const PROGRAMMER *pgm, unsigned char scope,
unsigned char section, unsigned char parm,
unsigned char *value, unsigned char length);
int jtag3_command(PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
int jtag3_command(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
unsigned char **resp, const char *descr);
void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p);
int jtag3_set_vtarget(const PROGRAMMER *pgm, double voltage);
extern const char jtag3_desc[];
extern const char jtag3_dw_desc[];
extern const char jtag3_pdi_desc[];
extern const char jtag3_updi_desc[];
void jtag3_initpgm (PROGRAMMER * pgm);
void jtag3_dw_initpgm (PROGRAMMER * pgm);
void jtag3_pdi_initpgm (PROGRAMMER * pgm);
void jtag3_updi_initpgm (PROGRAMMER * pgm);
void jtag3_initpgm(PROGRAMMER *pgm);
void jtag3_dw_initpgm(PROGRAMMER *pgm);
void jtag3_pdi_initpgm(PROGRAMMER *pgm);
void jtag3_updi_initpgm(PROGRAMMER *pgm);
/*
* These functions are referenced from stk500v2.c for JTAGICE3 in

View File

@@ -184,16 +184,24 @@
* precedes each parameter address. There are distinct parameter
* sets for generic and AVR scope.
*/
#define PARM3_HW_VER 0x00 /* section 0, generic scope, 1 byte */
#define PARM3_FW_MAJOR 0x01 /* section 0, generic scope, 1 byte */
#define PARM3_FW_MINOR 0x02 /* section 0, generic scope, 1 byte */
#define PARM3_FW_RELEASE 0x03 /* section 0, generic scope, 1 byte;
* always asked for by Atmel Studio,
* but never displayed there */
#define PARM3_VTARGET 0x00 /* section 1, generic scope, 2 bytes, in millivolts */
#define PARM3_VBUF 0x01 /* section 1, generic scope, 2 bytes, bufferred target voltage reference */
#define PARM3_VUSB 0x02 /* section 1, generic scope, 2 bytes, USB voltage */
#define PARM3_VADJUST 0x20 /* section 1, generic scope, 2 bytes, set voltage */
#define PARM3_HW_VER 0x00 /* section 0, generic scope, 1 byte */
#define PARM3_FW_MAJOR 0x01 /* section 0, generic scope, 1 byte */
#define PARM3_FW_MINOR 0x02 /* section 0, generic scope, 1 byte */
#define PARM3_FW_RELEASE 0x03 /* section 0, generic scope, 1 byte;
* always asked for by Atmel Studio,
* but never displayed there */
#define PARM3_VTARGET 0x00 /* section 1, generic scope, 2 bytes, in millivolts */
#define PARM3_VBUF 0x01 /* section 1, generic scope, 2 bytes, bufferred target voltage reference */
#define PARM3_VUSB 0x02 /* section 1, generic scope, 2 bytes, USB voltage */
#define PARM3_ANALOG_A_CURRENT 0x10 /* section 1, generic scope, 2 bytes, Ch A current in milliamps, Powerdebugger only */
#define PARM3_ANALOG_A_VOLTAGE 0x11 /* section 1, generic scope, 2 bytes, Ch A voltage in millivolts, Powerdebugger only */
#define PARM3_ANALOG_B_CURRENT 0x12 /* section 1, generic scope, 2 bytes, Ch B current in milliamps, Powerdebugger only */
#define PARM3_ANALOG_B_VOLTAGE 0x13 /* section 1, generic scope, 2 bytes, Ch V voltage in millivolts, Powerdebugger only */
#define PARM3_TSUP_VOLTAGE_MEAS 0x14 /* section 1, generic scope, 2 bytes, target voltage measurement in millivolts */
#define PARM3_USB_VOLTAGE_MEAS 0x15 /* section 1, generic scope, 2 bytes, USB voltage measurement in millivolts */
#define PARM3_VADJUST 0x20 /* section 1, generic scope, 2 bytes, set voltage in millivolts */
#define PARM3_ANALOG_STATUS 0x30 /* section 1, generic scope, 2 bytes, analog status */
#define PARM3_DEVICEDESC 0x00 /* section 2, memory etc. configuration,
* 31 bytes for tiny/mega AVR, 47 bytes
@@ -237,6 +245,14 @@
#define PARM3_OPT_12V_UPDI_ENABLE 0x06
#define PARM3_OPT_CHIP_ERASE_TO_ENTER 0x07
/*
* UPDI high-voltage enable modes
*/
#define PARM3_UPDI_HV_NONE 0x00 /* Do not use high-voltage */
#define PARM3_UPDI_HV_SIMPLE_PULSE 0x01 /* Issue a single high-voltage pulse immediately*/
#define PARM3_UPDI_HV_AUTO_POWER_TOGGLE 0x02 /* Toggle power automatically and then apply a high-voltage pulse */
#define PARM3_UPDI_HV_USER_POWER_TOGGLE 0x03 /* The user toggles power, and the tool applies a high-voltage pulse on power-up */
/* Xmega erase memory types, for CMND_XMEGA_ERASE */
#define XMEGA_ERASE_CHIP 0x00
#define XMEGA_ERASE_APP 0x01
@@ -393,5 +409,7 @@ struct updi_device_desc {
unsigned char flash_page_size_msb; // Extends flash_page_size, used in 24-bit mode
unsigned char address_mode; // 0x00 = 16-bit mode, 0x01 = 24-bit mode
unsigned char hvupdi_variant; // Indicates the target UPDI HV implementation
};
#endif /* JTAG3_PRIVATE_EXPORTED */

File diff suppressed because it is too large Load Diff

View File

@@ -26,7 +26,7 @@ extern "C" {
#endif
extern const char jtagmkI_desc[];
void jtagmkI_initpgm (PROGRAMMER * pgm);
void jtagmkI_initpgm(PROGRAMMER *pgm);
#ifdef __cplusplus
}

File diff suppressed because it is too large Load Diff

View File

@@ -25,27 +25,29 @@
extern "C" {
#endif
int jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len);
int jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg);
int jtagmkII_send(const PROGRAMMER *pgm, unsigned char *data, size_t len);
int jtagmkII_recv(const PROGRAMMER *pgm, unsigned char **msg);
void jtagmkII_close(PROGRAMMER * pgm);
int jtagmkII_getsync(PROGRAMMER * pgm, int mode);
int jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm,
int jtagmkII_getsync(const PROGRAMMER *pgm, int mode);
int jtagmkII_getparm(const PROGRAMMER *pgm, unsigned char parm,
unsigned char * value);
extern const char jtagmkII_desc[];
extern const char jtagmkII_avr32_desc[];
extern const char jtagmkII_dw_desc[];
extern const char jtagmkII_pdi_desc[];
extern const char jtagmkII_updi_desc[];
extern const char jtagmkII_dragon_desc[];
extern const char jtagmkII_dragon_dw_desc[];
extern const char jtagmkII_dragon_pdi_desc[];
void jtagmkII_initpgm (PROGRAMMER * pgm);
void jtagmkII_avr32_initpgm (PROGRAMMER * pgm);
void jtagmkII_dw_initpgm (PROGRAMMER * pgm);
void jtagmkII_pdi_initpgm (PROGRAMMER * pgm);
void jtagmkII_dragon_initpgm (PROGRAMMER * pgm);
void jtagmkII_dragon_dw_initpgm (PROGRAMMER * pgm);
void jtagmkII_dragon_pdi_initpgm (PROGRAMMER * pgm);
void jtagmkII_initpgm(PROGRAMMER *pgm);
void jtagmkII_avr32_initpgm(PROGRAMMER *pgm);
void jtagmkII_dw_initpgm(PROGRAMMER *pgm);
void jtagmkII_pdi_initpgm(PROGRAMMER *pgm);
void jtagmkII_updi_initpgm(PROGRAMMER *pgm);
void jtagmkII_dragon_initpgm(PROGRAMMER *pgm);
void jtagmkII_dragon_dw_initpgm(PROGRAMMER *pgm);
void jtagmkII_dragon_pdi_initpgm(PROGRAMMER *pgm);
/*
* These functions are referenced from stk500v2.c for JTAG ICE mkII

View File

@@ -39,15 +39,21 @@
#define YYERRCODE 256
#endif
/* capture lvalue keywords to associate comments with that assignment */
#define ccap() capture_lvalue_kw(yytext, cfg_lineno)
static void adjust_cfg_lineno(const char *p) {
while(*p)
if(*p++ == '\n')
cfg_lineno++;
}
%}
DIGIT [0-9]
HEXDIGIT [0-9a-fA-F]
SIGN [+-]
%x strng
%x incl
%x comment
%option nounput
/* Bump resources for classic lex. */
@@ -57,35 +63,47 @@ SIGN [+-]
%%
#{SIGN}*{DIGIT}+ { yylval = number(yytext); return TKN_NUMBER; }
#{SIGN}*{DIGIT}+"."{DIGIT}* { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
#{SIGN}*"."{DIGIT}* { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
{DIGIT}+ { yylval = number(yytext); return TKN_NUMBER; }
{DIGIT}+"."{DIGIT}* { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
"."{DIGIT}+ { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
{DIGIT}+ { yylval = new_number(yytext); return TKN_NUMBER; /* sign is treated in grammar */ }
{SIGN}?{DIGIT}+"."{DIGIT}* { yylval = new_number_real(yytext); return TKN_NUMBER_REAL; }
{SIGN}?"."{DIGIT}+ { yylval = new_number_real(yytext); return TKN_NUMBER_REAL; }
"\"" { string_buf_ptr = string_buf; BEGIN(strng); }
["]([^"\\\n]|\\.|\\\n)*["] {
char *str= cfg_strdup("lexer.l", yytext);
cfg_unescape(str, str+1);
size_t len = strlen(str);
if(len)
str[len-1] = 0;
yylval = new_string(str);
free(str);
return TKN_STRING;
}
0x{HEXDIGIT}+ { yylval = hexnumber(yytext); return TKN_NUMBER; }
0x{HEXDIGIT}+ { yylval = new_hexnumber(yytext); return TKN_NUMBER; }
#\n#\ PROGRAMMER\ DEFINITIONS\n#\n+ { /* Record comments so far as prologue and skip */
cfg_capture_prologue();
adjust_cfg_lineno(yytext);
}
#\n#\ PART\ DEFINITIONS\n#\n+ { /* Ignore part definions header */
adjust_cfg_lineno(yytext);
}
# { /* The following eats '#' style comments to end of line */
BEGIN(comment); }
<comment>[^\n] { /* eat comments */ }
<comment>\n { lineno++; BEGIN(INITIAL); }
[ \t]*#[^\n]*\n+ { /* Record and skip # comments including preceding white space */
capture_comment_str(yytext, cfg_lineno);
adjust_cfg_lineno(yytext);
}
"/*" { /* The following eats multiline C style comments */
"/*" { /* The following eats multiline C style comments, they are not captured */
int c;
int comment_start;
comment_start = lineno;
comment_start = cfg_lineno;
while (1) {
while (((c = input()) != '*') && (c != EOF)) {
/* eat up text of comment, but keep counting lines */
if (c == '\n')
lineno++;
cfg_lineno++;
}
if (c == '*') {
@@ -103,156 +121,175 @@ SIGN [+-]
}
<strng>\" { *string_buf_ptr = 0; string_buf_ptr = string_buf;
yylval = string(string_buf_ptr); BEGIN(INITIAL); return TKN_STRING; }
<strng>\\n *string_buf_ptr++ = '\n';
<strng>\\t *string_buf_ptr++ = '\t';
<strng>\\r *string_buf_ptr++ = '\r';
<strng>\\b *string_buf_ptr++ = '\b';
<strng>\\f *string_buf_ptr++ = '\f';
<strng>\\(.|\n) *(string_buf_ptr++) = yytext[1];
<strng>[^\\\n\"]+ { char *yptr = yytext; while (*yptr)
*(string_buf_ptr++) = *(yptr++); }
prog_modes|mcuid|n_interrupts|n_page_erase|n_word_writes { /* Components for assignment */
Component_t *cp = cfg_comp_search(yytext, current_strct);
if(!cp) {
yyerror("Unknown component %s in %s", yytext, cfg_strct_name(current_strct));
return YYERRCODE;
}
yylval = new_token(TKN_COMPONENT);
yylval->value.comp = cp;
ccap();
return TKN_COMPONENT;
}
<strng>\n { yyerror("unterminated character constant");
return YYERRCODE; }
PM_(SPM|TPI|ISP|PDI|UPDI|HVSP|HVPP|debugWIRE|JTAG|JTAGmkI|XMEGAJTAG|AVR32JTAG|aWire) { /* Constants */
yylval = new_constant(yytext);
return TKN_NUMBER;
}
alias { yylval=NULL; return K_ALIAS; }
allowfullpagebitstream { yylval=NULL; return K_ALLOWFULLPAGEBITSTREAM; }
avr910_devcode { yylval=NULL; return K_AVR910_DEVCODE; }
allowfullpagebitstream { yylval=NULL; ccap(); return K_ALLOWFULLPAGEBITSTREAM; }
avr910_devcode { yylval=NULL; ccap(); return K_AVR910_DEVCODE; }
bank_size { yylval=NULL; return K_PAGE_SIZE; }
banked { yylval=NULL; return K_PAGED; }
baudrate { yylval=NULL; return K_BAUDRATE; }
blocksize { yylval=NULL; return K_BLOCKSIZE; }
bs2 { yylval=NULL; return K_BS2; }
buff { yylval=NULL; return K_BUFF; }
bytedelay { yylval=NULL; return K_BYTEDELAY; }
chip_erase { yylval=new_token(K_CHIP_ERASE); return K_CHIP_ERASE; }
chip_erase_delay { yylval=NULL; return K_CHIP_ERASE_DELAY; }
chiperasepolltimeout { yylval=NULL; return K_CHIPERASEPOLLTIMEOUT; }
chiperasepulsewidth { yylval=NULL; return K_CHIPERASEPULSEWIDTH; }
chiperasetime { yylval=NULL; return K_CHIPERASETIME; }
cmdexedelay { yylval=NULL; return K_CMDEXEDELAY; }
connection_type { yylval=NULL; return K_CONNTYPE; }
baudrate { yylval=NULL; ccap(); return K_BAUDRATE; }
blocksize { yylval=NULL; ccap(); return K_BLOCKSIZE; }
bs2 { yylval=NULL; ccap(); return K_BS2; }
buff { yylval=NULL; ccap(); return K_BUFF; }
bytedelay { yylval=NULL; ccap(); return K_BYTEDELAY; }
chip_erase { yylval=new_token(K_CHIP_ERASE); ccap(); return K_CHIP_ERASE; }
chip_erase_delay { yylval=NULL; ccap(); return K_CHIP_ERASE_DELAY; }
chiperasepolltimeout { yylval=NULL; ccap(); return K_CHIPERASEPOLLTIMEOUT; }
chiperasepulsewidth { yylval=NULL; ccap(); return K_CHIPERASEPULSEWIDTH; }
chiperasetime { yylval=NULL; ccap(); return K_CHIPERASETIME; }
cmdexedelay { yylval=NULL; ccap(); return K_CMDEXEDELAY; }
connection_type { yylval=NULL; ccap(); return K_CONNTYPE; }
dedicated { yylval=new_token(K_DEDICATED); return K_DEDICATED; }
default_bitclock { yylval=NULL; return K_DEFAULT_BITCLOCK; }
default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
delay { yylval=NULL; return K_DELAY; }
desc { yylval=NULL; return K_DESC; }
family_id { yylval=NULL; return K_FAMILY_ID; }
devicecode { yylval=NULL; return K_DEVICECODE; }
eecr { yylval=NULL; return K_EECR; }
default_spi { yylval=NULL; return K_DEFAULT_SPI; }
delay { yylval=NULL; ccap(); return K_DELAY; }
desc { yylval=NULL; ccap(); return K_DESC; }
devicecode { yylval=NULL; ccap(); return K_DEVICECODE; }
eecr { yylval=NULL; ccap(); return K_EECR; }
eeprom { yylval=NULL; return K_EEPROM; }
eeprom_instr { yylval=NULL; return K_EEPROM_INSTR; }
enablepageprogramming { yylval=NULL; return K_ENABLEPAGEPROGRAMMING; }
errled { yylval=NULL; return K_ERRLED; }
eeprom_instr { yylval=NULL; ccap(); return K_EEPROM_INSTR; }
enablepageprogramming { yylval=NULL; ccap(); return K_ENABLEPAGEPROGRAMMING; }
errled { yylval=NULL; ccap(); return K_ERRLED; }
family_id { yylval=NULL; ccap(); return K_FAMILY_ID; }
flash { yylval=NULL; return K_FLASH; }
flash_instr { yylval=NULL; return K_FLASH_INSTR; }
has_debugwire { yylval=NULL; return K_HAS_DW; }
has_jtag { yylval=NULL; return K_HAS_JTAG; }
has_pdi { yylval=NULL; return K_HAS_PDI; }
has_tpi { yylval=NULL; return K_HAS_TPI; }
has_updi { yylval=NULL; return K_HAS_UPDI; }
hventerstabdelay { yylval=NULL; return K_HVENTERSTABDELAY; }
hvleavestabdelay { yylval=NULL; return K_HVLEAVESTABDELAY; }
hvsp_controlstack { yylval=NULL; return K_HVSP_CONTROLSTACK; }
hvspcmdexedelay { yylval=NULL; return K_HVSPCMDEXEDELAY; }
id { yylval=NULL; return K_ID; }
idr { yylval=NULL; return K_IDR; }
flash_instr { yylval=NULL; ccap(); return K_FLASH_INSTR; }
has_debugwire { yylval=NULL; ccap(); return K_HAS_DW; }
has_jtag { yylval=NULL; ccap(); return K_HAS_JTAG; }
has_pdi { yylval=NULL; ccap(); return K_HAS_PDI; }
has_tpi { yylval=NULL; ccap(); return K_HAS_TPI; }
has_updi { yylval=NULL; ccap(); return K_HAS_UPDI; }
hventerstabdelay { yylval=NULL; ccap(); return K_HVENTERSTABDELAY; }
hvleavestabdelay { yylval=NULL; ccap(); return K_HVLEAVESTABDELAY; }
hvsp_controlstack { yylval=NULL; ccap(); return K_HVSP_CONTROLSTACK; }
hvspcmdexedelay { yylval=NULL; ccap(); return K_HVSPCMDEXEDELAY; }
hvupdi_support { yylval=NULL; ccap(); return K_HVUPDI_SUPPORT; }
hvupdi_variant { yylval=NULL; ccap(); return K_HVUPDI_VARIANT; }
id { yylval=NULL; ccap(); return K_ID; }
idr { yylval=NULL; ccap(); return K_IDR; }
io { yylval=new_token(K_IO); return K_IO; }
is_at90s1200 { yylval=NULL; return K_IS_AT90S1200; }
is_avr32 { yylval=NULL; return K_IS_AVR32; }
latchcycles { yylval=NULL; return K_LATCHCYCLES; }
load_ext_addr { yylval=new_token(K_LOAD_EXT_ADDR); return K_LOAD_EXT_ADDR; }
loadpage_hi { yylval=new_token(K_LOADPAGE_HI); return K_LOADPAGE_HI; }
loadpage_lo { yylval=new_token(K_LOADPAGE_LO); return K_LOADPAGE_LO; }
max_write_delay { yylval=NULL; return K_MAX_WRITE_DELAY; }
mcu_base { yylval=NULL; return K_MCU_BASE; }
memory { yylval=NULL; return K_MEMORY; }
min_write_delay { yylval=NULL; return K_MIN_WRITE_DELAY; }
miso { yylval=NULL; return K_MISO; }
mode { yylval=NULL; return K_MODE; }
mosi { yylval=NULL; return K_MOSI; }
is_at90s1200 { yylval=NULL; ccap(); return K_IS_AT90S1200; }
is_avr32 { yylval=NULL; ccap(); return K_IS_AVR32; }
latchcycles { yylval=NULL; ccap(); return K_LATCHCYCLES; }
load_ext_addr { yylval=new_token(K_LOAD_EXT_ADDR); ccap(); return K_LOAD_EXT_ADDR; }
loadpage_hi { yylval=new_token(K_LOADPAGE_HI); ccap(); return K_LOADPAGE_HI; }
loadpage_lo { yylval=new_token(K_LOADPAGE_LO); ccap(); return K_LOADPAGE_LO; }
max_write_delay { yylval=NULL; ccap(); return K_MAX_WRITE_DELAY; }
mcu_base { yylval=NULL; ccap(); return K_MCU_BASE; }
memory { yylval=NULL; ccap(); return K_MEMORY; }
min_write_delay { yylval=NULL; ccap(); return K_MIN_WRITE_DELAY; }
miso { yylval=NULL; ccap(); return K_MISO; }
mode { yylval=NULL; ccap(); return K_MODE; }
mosi { yylval=NULL; ccap(); return K_MOSI; }
no { yylval=new_token(K_NO); return K_NO; }
NULL { yylval=NULL; return K_NULL; }
num_banks { yylval=NULL; return K_NUM_PAGES; }
num_pages { yylval=NULL; return K_NUM_PAGES; }
nvm_base { yylval=NULL; return K_NVM_BASE; }
ocd_base { yylval=NULL; return K_OCD_BASE; }
ocdrev { yylval=NULL; return K_OCDREV; }
offset { yylval=NULL; return K_OFFSET; }
page_size { yylval=NULL; return K_PAGE_SIZE; }
paged { yylval=NULL; return K_PAGED; }
pagel { yylval=NULL; return K_PAGEL; }
parallel { yylval=NULL; return K_PARALLEL; }
num_pages { yylval=NULL; ccap(); return K_NUM_PAGES; }
nvm_base { yylval=NULL; ccap(); return K_NVM_BASE; }
ocd_base { yylval=NULL; ccap(); return K_OCD_BASE; }
ocdrev { yylval=NULL; ccap(); return K_OCDREV; }
offset { yylval=NULL; ccap(); return K_OFFSET; }
paged { yylval=NULL; ccap(); return K_PAGED; }
pagel { yylval=NULL; ccap(); return K_PAGEL; }
page_size { yylval=NULL; ccap(); return K_PAGE_SIZE; }
parallel { yylval=NULL; ccap(); return K_PARALLEL; }
parent { yylval=NULL; return K_PARENT; }
part { yylval=NULL; return K_PART; }
pgm_enable { yylval=new_token(K_PGM_ENABLE); return K_PGM_ENABLE; }
pgmled { yylval=NULL; return K_PGMLED; }
pollindex { yylval=NULL; return K_POLLINDEX; }
pollmethod { yylval=NULL; return K_POLLMETHOD; }
pollvalue { yylval=NULL; return K_POLLVALUE; }
postdelay { yylval=NULL; return K_POSTDELAY; }
poweroffdelay { yylval=NULL; return K_POWEROFFDELAY; }
pp_controlstack { yylval=NULL; return K_PP_CONTROLSTACK; }
predelay { yylval=NULL; return K_PREDELAY; }
progmodedelay { yylval=NULL; return K_PROGMODEDELAY; }
programfusepolltimeout { yylval=NULL; return K_PROGRAMFUSEPOLLTIMEOUT; }
programfusepulsewidth { yylval=NULL; return K_PROGRAMFUSEPULSEWIDTH; }
programlockpolltimeout { yylval=NULL; return K_PROGRAMLOCKPOLLTIMEOUT; }
programlockpulsewidth { yylval=NULL; return K_PROGRAMLOCKPULSEWIDTH; }
programmer { yylval=NULL; return K_PROGRAMMER; }
part { yylval=NULL; ccap(); return K_PART; }
pgm_enable { yylval=new_token(K_PGM_ENABLE); ccap(); return K_PGM_ENABLE; }
pgmled { yylval=NULL; ccap(); return K_PGMLED; }
pollindex { yylval=NULL; ccap(); return K_POLLINDEX; }
pollmethod { yylval=NULL; ccap(); return K_POLLMETHOD; }
pollvalue { yylval=NULL; ccap(); return K_POLLVALUE; }
postdelay { yylval=NULL; ccap(); return K_POSTDELAY; }
poweroffdelay { yylval=NULL; ccap(); return K_POWEROFFDELAY; }
pp_controlstack { yylval=NULL; ccap(); return K_PP_CONTROLSTACK; }
predelay { yylval=NULL; ccap(); return K_PREDELAY; }
progmodedelay { yylval=NULL; ccap(); return K_PROGMODEDELAY; }
programfusepolltimeout { yylval=NULL; ccap(); return K_PROGRAMFUSEPOLLTIMEOUT; }
programfusepulsewidth { yylval=NULL; ccap(); return K_PROGRAMFUSEPULSEWIDTH; }
programlockpolltimeout { yylval=NULL; ccap(); return K_PROGRAMLOCKPOLLTIMEOUT; }
programlockpulsewidth { yylval=NULL; ccap(); return K_PROGRAMLOCKPULSEWIDTH; }
programmer { yylval=NULL; ccap(); return K_PROGRAMMER; }
pseudo { yylval=new_token(K_PSEUDO); return K_PSEUDO; }
pwroff_after_write { yylval=NULL; return K_PWROFF_AFTER_WRITE; }
rampz { yylval=NULL; return K_RAMPZ; }
rdyled { yylval=NULL; return K_RDYLED; }
read { yylval=new_token(K_READ); return K_READ; }
read_hi { yylval=new_token(K_READ_HI); return K_READ_HI; }
read_lo { yylval=new_token(K_READ_LO); return K_READ_LO; }
readback_p1 { yylval=NULL; return K_READBACK_P1; }
readback_p2 { yylval=NULL; return K_READBACK_P2; }
readsize { yylval=NULL; return K_READSIZE; }
reset { yylval=new_token(K_RESET); return K_RESET; }
resetdelay { yylval=NULL; return K_RESETDELAY; }
resetdelayms { yylval=NULL; return K_RESETDELAYMS; }
resetdelayus { yylval=NULL; return K_RESETDELAYUS; }
retry_pulse { yylval=NULL; return K_RETRY_PULSE; }
sck { yylval=new_token(K_SCK); return K_SCK; }
serial { yylval=NULL; return K_SERIAL; }
signature { yylval=NULL; return K_SIGNATURE; }
size { yylval=NULL; return K_SIZE; }
spmcr { yylval=NULL; return K_SPMCR; }
stabdelay { yylval=NULL; return K_STABDELAY; }
stk500_devcode { yylval=NULL; return K_STK500_DEVCODE; }
synchcycles { yylval=NULL; return K_SYNCHCYCLES; }
synchloops { yylval=NULL; return K_SYNCHLOOPS; }
timeout { yylval=NULL; return K_TIMEOUT; }
togglevtg { yylval=NULL; return K_TOGGLEVTG; }
type { yylval=NULL; return K_TYPE; }
pwroff_after_write { yylval=NULL; ccap(); return K_PWROFF_AFTER_WRITE; }
rampz { yylval=NULL; ccap(); return K_RAMPZ; }
rdyled { yylval=NULL; ccap(); return K_RDYLED; }
read { yylval=new_token(K_READ); ccap(); return K_READ; }
read_hi { yylval=new_token(K_READ_HI); ccap(); return K_READ_HI; }
read_lo { yylval=new_token(K_READ_LO); ccap(); return K_READ_LO; }
readback { yylval=NULL; ccap(); return K_READBACK; }
readback_p1 { yylval=NULL; ccap(); return K_READBACK_P1; }
readback_p2 { yylval=NULL; ccap(); return K_READBACK_P2; }
readsize { yylval=NULL; ccap(); return K_READSIZE; }
reset { yylval=new_token(K_RESET); ccap(); return K_RESET; }
resetdelay { yylval=NULL; ccap(); return K_RESETDELAY; }
resetdelayms { yylval=NULL; ccap(); return K_RESETDELAYMS; }
resetdelayus { yylval=NULL; ccap(); return K_RESETDELAYUS; }
retry_pulse { yylval=NULL; ccap(); return K_RETRY_PULSE; }
sck { yylval=new_token(K_SCK); ccap(); return K_SCK; }
serial { yylval=NULL; ccap(); return K_SERIAL; }
signature { yylval=NULL; ccap(); return K_SIGNATURE; }
size { yylval=NULL; ccap(); return K_SIZE; }
spi { yylval=NULL; return K_SPI; }
spmcr { yylval=NULL; ccap(); return K_SPMCR; }
stabdelay { yylval=NULL; ccap(); return K_STABDELAY; }
stk500_devcode { yylval=NULL; ccap(); return K_STK500_DEVCODE; }
synchcycles { yylval=NULL; ccap(); return K_SYNCHCYCLES; }
synchloops { yylval=NULL; ccap(); return K_SYNCHLOOPS; }
timeout { yylval=NULL; ccap(); return K_TIMEOUT; }
togglevtg { yylval=NULL; ccap(); return K_TOGGLEVTG; }
type { yylval=NULL; ccap(); return K_TYPE; }
usb { yylval=NULL; return K_USB; }
usbdev { yylval=NULL; return K_USBDEV; }
usbpid { yylval=NULL; return K_USBPID; }
usbproduct { yylval=NULL; return K_USBPRODUCT; }
usbsn { yylval=NULL; return K_USBSN; }
usbvendor { yylval=NULL; return K_USBVENDOR; }
usbvid { yylval=NULL; return K_USBVID; }
vcc { yylval=NULL; return K_VCC; }
vfyled { yylval=NULL; return K_VFYLED; }
write { yylval=new_token(K_WRITE); return K_WRITE; }
write_hi { yylval=new_token(K_WRITE_HI); return K_WRITE_HI; }
write_lo { yylval=new_token(K_WRITE_LO); return K_WRITE_LO; }
writepage { yylval=new_token(K_WRITEPAGE); return K_WRITEPAGE; }
usbdev { yylval=NULL; ccap(); return K_USBDEV; }
usbpid { yylval=NULL; ccap(); return K_USBPID; }
usbproduct { yylval=NULL; ccap(); return K_USBPRODUCT; }
usbsn { yylval=NULL; ccap(); return K_USBSN; }
usbvendor { yylval=NULL; ccap(); return K_USBVENDOR; }
usbvid { yylval=NULL; ccap(); return K_USBVID; }
vcc { yylval=NULL; ccap(); return K_VCC; }
vfyled { yylval=NULL; ccap(); return K_VFYLED; }
write { yylval=new_token(K_WRITE); ccap(); return K_WRITE; }
write_hi { yylval=new_token(K_WRITE_HI); ccap(); return K_WRITE_HI; }
write_lo { yylval=new_token(K_WRITE_LO); ccap(); return K_WRITE_LO; }
writepage { yylval=new_token(K_WRITEPAGE); ccap(); return K_WRITEPAGE; }
yes { yylval=new_token(K_YES); return K_YES; }
"," { yylval = NULL; pyytext(); return TKN_COMMA; }
"=" { yylval = NULL; pyytext(); return TKN_EQUAL; }
";" { yylval = NULL; pyytext(); return TKN_SEMI; }
"~" { yylval = NULL; pyytext(); return TKN_TILDE; }
"|" { yylval = NULL; pyytext(); return OP_OR; }
"^" { yylval = NULL; pyytext(); return OP_XOR; }
"&" { yylval = NULL; pyytext(); return OP_AND; }
"+" { yylval = NULL; pyytext(); return OP_PLUS; }
"-" { yylval = NULL; pyytext(); return OP_MINUS; }
"*" { yylval = NULL; pyytext(); return OP_TIMES; }
"/" { yylval = NULL; pyytext(); return OP_DIVIDE; }
"%" { yylval = NULL; pyytext(); return OP_MODULO; }
"~" { yylval = NULL; pyytext(); return OP_TILDE; }
"(" { yylval = NULL; pyytext(); return TKN_LEFT_PAREN; }
")" { yylval = NULL; pyytext(); return TKN_RIGHT_PAREN; }
"\n" { lineno++; }
"\n" { cfg_lineno++; }
[ \r\t]+ { /* ignore whitespace */ }
c: { yyerror("possible old-style config file entry\n"

View File

@@ -35,7 +35,7 @@ typedef uint32_t pinmask_t;
#define LIBAVRDUDE_SUCCESS 0
#define LIBAVRDUDE_GENERAL_FAILURE (-1)
#define LIBAVRDUDE_NOTSUPPORTED (-2) // operation not supported
#define LIBAVRDUDE_SOFTFAIL (-3) // returned by avr_signature() if caller
#define LIBAVRDUDE_SOFTFAIL (-3) // returned, eg, by avr_signature() if caller
// might proceed with chip erase
/* formerly lists.h */
@@ -169,6 +169,7 @@ enum ctl_stack_t {
CTL_STACK_HVSP /* high voltage serial programming control stack */
};
/*
* serial programming instruction bit specifications
*/
@@ -183,23 +184,33 @@ typedef struct opcode {
} OPCODE;
#define AVRPART_SERIALOK 0x0001 /* part supports serial programming */
#define AVRPART_PARALLELOK 0x0002 /* part supports parallel programming */
#define AVRPART_PSEUDOPARALLEL 0x0004 /* part has pseudo parallel support */
#define AVRPART_HAS_JTAG 0x0008 /* part has a JTAG i/f */
#define AVRPART_ALLOWFULLPAGEBITSTREAM 0x0010 /* JTAG ICE mkII param. */
#define AVRPART_ENABLEPAGEPROGRAMMING 0x0020 /* JTAG ICE mkII param. */
#define AVRPART_HAS_DW 0x0040 /* part has a debugWire i/f */
#define AVRPART_HAS_PDI 0x0080 /* part has PDI i/f rather than ISP (ATxmega) */
#define AVRPART_AVR32 0x0100 /* part is in AVR32 family */
#define AVRPART_INIT_SMC 0x0200 /* part will undergo chip erase */
#define AVRPART_WRITE 0x0400 /* at least one write operation specified */
#define AVRPART_HAS_TPI 0x0800 /* part has TPI i/f rather than ISP (ATtiny4/5/9/10) */
#define AVRPART_IS_AT90S1200 0x1000 /* part is an AT90S1200 (needs special treatment) */
#define AVRPART_HAS_UPDI 0x2000 /* part has UPDI i/f (AVR8X) */
// Any changes here, please also reflect in dev_part_strct() of developer_opts.c
#define AVRPART_SERIALOK 1 // Part supports serial programming
#define AVRPART_PARALLELOK 2 // Part supports parallel programming
#define AVRPART_PSEUDOPARALLEL 4 // Part has pseudo parallel support
#define AVRPART_ALLOWFULLPAGEBITSTREAM 8 // JTAG ICE mkII param
#define AVRPART_ENABLEPAGEPROGRAMMING 16 // JTAG ICE mkII param
#define AVRPART_IS_AT90S1200 32 // Part is an AT90S1200, needs special treatment
// Programming modes for parts and programmers: reflect changes in lexer.l, developer_opts.c and config.c
#define PM_SPM 1 // Bootloaders, self-programming with SPM opcodes or NVM Controllers
#define PM_TPI 2 // Tiny Programming Interface (t4, t5, t9, t10, t20, t40, t102, t104)
#define PM_ISP 4 // SPI programming for In-System Programming (almost all classic parts)
#define PM_PDI 8 // Program and Debug Interface (xmega parts)
#define PM_UPDI 16 // Unified Program and Debug Interface
#define PM_HVSP 32 // High Voltage Serial Programming (some classic parts)
#define PM_HVPP 64 // High Voltage Parallel Programming (most non-HVSP classic parts)
#define PM_debugWIRE 128 // Simpler alternative to JTAG (a subset of HVPP/HVSP parts)
#define PM_JTAG 256 // Joint Test Action Group standard (some classic parts)
#define PM_JTAGmkI 512 // Subset of PM_JTAG, older parts, Atmel ICE mkI
#define PM_XMEGAJTAG 1024 // JTAG, some XMEGA parts
#define PM_AVR32JTAG 2048 // JTAG for 32-bit AVRs
#define PM_aWire 4096 // For 32-bit AVRs
#define HV_UPDI_VARIANT_0 0 /* Shared UPDI/GPIO/RESET pin, HV on UPDI pin (tinyAVR0/1/2)*/
#define HV_UPDI_VARIANT_1 1 /* Dedicated UPDI pin, no HV (megaAVR0/AVR-Dx) */
#define HV_UPDI_VARIANT_2 2 /* Shared UPDI pin, HV on _RESET (AVR-Ex) */
#define AVR_DESCLEN 64
#define AVR_IDLEN 32
#define AVR_FAMILYIDLEN 7
#define AVR_SIBLEN 16
#define CTL_STACK_SIZE 32
@@ -208,10 +219,25 @@ typedef struct opcode {
#define TAG_ALLOCATED 1 /* memory byte is allocated */
/*
* Any changes in AVRPART or AVRMEM, please also ensure changes are made in
* - lexer.l
* - Either Component_t avr_comp[] of config.c or in config_gram.y
* - dev_part_strct() in developer_opts.c
* - avr_new_part() and/or avr_new_memtype() in avrpart.c for
* initialisation; note that all const char * must be initialised with ""
*/
typedef struct avrpart {
char desc[AVR_DESCLEN]; /* long part name */
char id[AVR_IDLEN]; /* short part name */
char family_id[AVR_FAMILYIDLEN+1]; /* family id in the SIB (avr8x) */
const char * desc; /* long part name */
const char * id; /* short part name */
LISTID comments; // Used by developer options -p*/[ASsr...]
const char * parent_id; /* Used by developer options */
const char * family_id; /* family id in the SIB (avr8x) */
int prog_modes; /* Programming interfaces, see #define PM_... */
int mcuid; /* Unique id in 0..2039 for urclock programmer */
int n_interrupts; /* Number of interrupts, used for vector bootloaders */
int n_page_erase; /* If set, number of pages erased during NVM erase */
int hvupdi_variant; /* HV pulse on UPDI pin, no pin or RESET pin */
int stk500_devcode; /* stk500 device code */
int avr910_devcode; /* avr910 device code */
int chip_erase_delay; /* microseconds */
@@ -257,12 +283,12 @@ typedef struct avrpart {
int programlockpulsewidth; /* stk500 v2 hv mode parameter */
int programlockpolltimeout; /* stk500 v2 hv mode parameter */
int synchcycles; /* stk500 v2 hv mode parameter */
int hvspcmdexedelay; /* stk500 v2 xml file parameter */
int hvspcmdexedelay; /* stk500 v2 hv mode file parameter */
unsigned char idr; /* JTAG ICE mkII XML file parameter */
unsigned char rampz; /* JTAG ICE mkII XML file parameter */
unsigned char spmcr; /* JTAG ICE mkII XML file parameter */
unsigned short eecr; /* JTAC ICE mkII XML file parameter */
unsigned char eecr; /* JTAC ICE mkII XML file parameter */
unsigned int mcu_base; /* Base address of MCU control block in ATxmega devices */
unsigned int nvm_base; /* Base address of NVM controller in ATxmega devices */
unsigned int ocd_base; /* Base address of OCD module in AVR8X/UPDI devices */
@@ -272,17 +298,18 @@ typedef struct avrpart {
LISTID mem; /* avr memory definitions */
LISTID mem_alias; /* memory alias definitions */
char config_file[PATH_MAX]; /* config file where defined */
int lineno; /* config file line number */
const char * config_file; /* config file where defined */
int lineno; /* config file line number */
} AVRPART;
#define AVR_MEMDESCLEN 64
typedef struct avrmem {
char desc[AVR_MEMDESCLEN]; /* memory description ("flash", "eeprom", etc) */
const char *desc; /* memory description ("flash", "eeprom", etc) */
LISTID comments; // Used by developer options -p*/[ASsr...]
int paged; /* page addressed (e.g. ATmega flash) */
int size; /* total memory size in bytes */
int page_size; /* size of memory page (if page addressed) */
int num_pages; /* number of pages (if page addressed) */
int n_word_writes; /* TPI only: number words to write at a time */
unsigned int offset; /* offset in IO memory (ATxmega) */
int min_write_delay; /* microseconds */
int max_write_delay; /* microseconds */
@@ -304,7 +331,7 @@ typedef struct avrmem {
} AVRMEM;
typedef struct avrmem_alias {
char desc[AVR_MEMDESCLEN]; /* alias name ("syscfg0" etc.) */
const char *desc; /* alias name ("syscfg0" etc.) */
AVRMEM *aliased_mem;
} AVRMEM_ALIAS;
@@ -312,38 +339,46 @@ typedef struct avrmem_alias {
extern "C" {
#endif
int intlog2(unsigned int n);
/* Functions for OPCODE structures */
OPCODE * avr_new_opcode(void);
void avr_free_opcode(OPCODE * op);
int avr_set_bits(OPCODE * op, unsigned char * cmd);
int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr);
int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data);
int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data);
int avr_get_output_index(OPCODE * op);
int avr_set_bits(const OPCODE *op, unsigned char *cmd);
int avr_set_addr(const OPCODE *op, unsigned char *cmd, unsigned long addr);
int avr_set_addr_mem(const AVRMEM *mem, int opnum, unsigned char *cmd, unsigned long addr);
int avr_set_input(const OPCODE *op, unsigned char *cmd, unsigned char data);
int avr_get_output(const OPCODE *op, const unsigned char *res, unsigned char *data);
int avr_get_output_index(const OPCODE *op);
char cmdbitchar(CMDBIT cb);
char *cmdbitstr(CMDBIT cb);
const char *opcodename(int opnum);
char *opcode2str(const OPCODE *op, int opnum, int detailed);
/* Functions for AVRMEM structures */
AVRMEM * avr_new_memtype(void);
AVRMEM_ALIAS * avr_new_memalias(void);
int avr_initmem(AVRPART * p);
AVRMEM * avr_dup_mem(AVRMEM * m);
int avr_initmem(const AVRPART *p);
AVRMEM * avr_dup_mem(const AVRMEM *m);
void avr_free_mem(AVRMEM * m);
void avr_free_memalias(AVRMEM_ALIAS * m);
AVRMEM * avr_locate_mem(AVRPART * p, char * desc);
AVRMEM * avr_locate_mem_noalias(AVRPART * p, char * desc);
AVRMEM_ALIAS * avr_locate_memalias(AVRPART * p, char * desc);
AVRMEM_ALIAS * avr_find_memalias(AVRPART * p, AVRMEM * m_orig);
void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, AVRPART * p,
int type, int verbose);
AVRMEM * avr_locate_mem(const AVRPART *p, const char *desc);
AVRMEM * avr_locate_mem_noalias(const AVRPART *p, const char *desc);
AVRMEM_ALIAS * avr_locate_memalias(const AVRPART *p, const char *desc);
AVRMEM_ALIAS * avr_find_memalias(const AVRPART *p, const AVRMEM *m_orig);
void avr_mem_display(const char *prefix, FILE *f, const AVRMEM *m,
const AVRPART *p, int verbose);
/* Functions for AVRPART structures */
AVRPART * avr_new_part(void);
AVRPART * avr_dup_part(AVRPART * d);
AVRPART * avr_dup_part(const AVRPART *d);
void avr_free_part(AVRPART * d);
AVRPART * locate_part(LISTID parts, char * partdesc);
AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode);
AVRPART * locate_part_by_signature(LISTID parts, unsigned char * sig,
AVRPART * locate_part(const LISTID parts, const char *partdesc);
AVRPART * locate_part_by_avr910_devcode(const LISTID parts, int devcode);
AVRPART * locate_part_by_signature(const LISTID parts, unsigned char *sig,
int sigsize);
void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose);
void avr_display(FILE *f, const AVRPART *p, const char *prefix, int verbose);
typedef void (*walk_avrparts_cb)(const char *name, const char *desc,
const char *cfgname, int cfglineno,
@@ -351,6 +386,8 @@ typedef void (*walk_avrparts_cb)(const char *name, const char *desc,
void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie);
void sort_avrparts(LISTID avrparts);
int part_match(const char *pattern, const char *string);
int compare_memory_masked(AVRMEM * m, uint8_t buf1, uint8_t buf2);
#ifdef __cplusplus
@@ -498,7 +535,15 @@ int pins_check(const struct programmer_t * const pgm, const struct pin_checklist
const char * avr_pin_name(int pinname);
/**
* This function returns a string representation of defined pins eg. ~1,2,~4,~5,7
* Returns the name of the pin as lowercase string.
*
* @param pinname the pinname which we want as string.
* @returns a lowercase string with the pinname, or <unknown> if pinname is invalid.
*/
const char * avr_pin_lcname(int pinname);
/**
* This function returns a string of defined pins, eg, ~1,2,~4,~5,7 or " (not used)"
* Another execution of this function will overwrite the previous result in the static buffer.
*
* @param[in] pindef the pin definition for which we want the string representation
@@ -507,9 +552,17 @@ const char * avr_pin_name(int pinname);
const char * pins_to_str(const struct pindef_t * const pindef);
/**
* This function returns a string representation of pins in the mask eg. 1,3,5-7,9,12
* This function returns a string of defined pins, eg, ~1, 2, ~4, ~5, 7 or ""
*
* @param[in] pindef the pin definition for which we want the string representation
* @returns a pointer to a string, which was created by strdup
*/
char *pins_to_strdup(const struct pindef_t * const pindef);
/**
* This function returns a string representation of pins in the mask, eg, 1,3,5-7,9,12
* Another execution of this function will overwrite the previous result in the static buffer.
* Consecutive pin number are representated as start-end.
* Consecutive pin number are represented as start-end.
*
* @param[in] pinmask the pin mask for which we want the string representation
* @returns pointer to a static string.
@@ -581,18 +634,17 @@ union pinfo
};
struct serial_device
{
struct serial_device {
// open should return -1 on error, other values on success
int (*open)(char * port, union pinfo pinfo, union filedescriptor *fd);
int (*setparams)(union filedescriptor *fd, long baud, unsigned long cflags);
int (*open)(const char *port, union pinfo pinfo, union filedescriptor *fd);
int (*setparams)(const union filedescriptor *fd, long baud, unsigned long cflags);
void (*close)(union filedescriptor *fd);
int (*send)(union filedescriptor *fd, const unsigned char * buf, size_t buflen);
int (*recv)(union filedescriptor *fd, unsigned char * buf, size_t buflen);
int (*drain)(union filedescriptor *fd, int display);
int (*send)(const union filedescriptor *fd, const unsigned char * buf, size_t buflen);
int (*recv)(const union filedescriptor *fd, unsigned char * buf, size_t buflen);
int (*drain)(const union filedescriptor *fd, int display);
int (*set_dtr_rts)(union filedescriptor *fd, int is_on);
int (*set_dtr_rts)(const union filedescriptor *fd, int is_on);
int flags;
#define SERDEV_FL_NONE 0x0000 /* no flags */
@@ -614,15 +666,21 @@ extern struct serial_device usbhid_serdev;
#define serial_drain (serdev->drain)
#define serial_set_dtr_rts (serdev->set_dtr_rts)
// See avrcache.c
typedef struct { // Memory cache for a subset of cached pages
int size, page_size; // Size of cache (flash or eeprom size) and page size
unsigned int offset; // Offset of flash/eeprom memory
unsigned char *cont, *copy; // current memory contens and device copy of it
unsigned char *iscached; // iscached[i] set when page i has been loaded
} AVR_Cache;
/* formerly pgm.h */
#define ON 1
#define OFF 0
#define PGM_DESCLEN 80
#define PGM_PORTLEN PATH_MAX
#define PGM_TYPELEN 32
#define PGM_USBSTRINGLEN 256
typedef enum {
EXIT_VCC_UNSPEC,
@@ -645,85 +703,116 @@ typedef enum {
typedef enum {
CONNTYPE_PARALLEL,
CONNTYPE_SERIAL,
CONNTYPE_USB
CONNTYPE_USB,
CONNTYPE_SPI
} conntype_t;
/*
* Any changes in PROGRAMMER, please also ensure changes are made in
* - lexer.l
* - Either Component_t avr_comp[] of config.c or config_gram.y
* - dev_pgm_strct() in developer_opts.c
* - pgm_new() in pgm.c for initialisation; note that all const char * must
* be initialised with ""
*/
typedef struct programmer_t {
LISTID id;
char desc[PGM_DESCLEN];
char type[PGM_TYPELEN];
char port[PGM_PORTLEN];
void (*initpgm)(struct programmer_t * pgm);
unsigned int pinno[N_PINS];
const char *desc;
void (*initpgm)(struct programmer_t *pgm); // Sets up the AVRDUDE programmer
LISTID comments; // Used by developer options -c*/[ASsr...]
const char *parent_id; // Used by developer options
int prog_modes; // Programming interfaces, see #define PM_...
struct pindef_t pin[N_PINS];
exit_vcc_t exit_vcc;
exit_reset_t exit_reset;
exit_datahigh_t exit_datahigh;
conntype_t conntype;
int ppidata;
int ppictrl;
int baudrate;
int usbvid;
LISTID usbpid;
char usbdev[PGM_USBSTRINGLEN], usbsn[PGM_USBSTRINGLEN];
char usbvendor[PGM_USBSTRINGLEN], usbproduct[PGM_USBSTRINGLEN];
double bitclock; /* JTAG ICE clock period in microseconds */
int ispdelay; /* ISP clock delay */
const char *usbdev;
const char *usbsn;
const char *usbvendor;
const char *usbproduct;
LISTID hvupdi_support; // List of UPDI HV variants the tool supports, see HV_UPDI_VARIANT_x
// Values below are not set by config_gram.y; ensure fd is first for dev_pgm_raw()
union filedescriptor fd;
int page_size; /* page size if the programmer supports paged write/load */
int (*rdy_led) (struct programmer_t * pgm, int value);
int (*err_led) (struct programmer_t * pgm, int value);
int (*pgm_led) (struct programmer_t * pgm, int value);
int (*vfy_led) (struct programmer_t * pgm, int value);
int (*initialize) (struct programmer_t * pgm, AVRPART * p);
void (*display) (struct programmer_t * pgm, const char * p);
void (*enable) (struct programmer_t * pgm);
void (*disable) (struct programmer_t * pgm);
void (*powerup) (struct programmer_t * pgm);
void (*powerdown) (struct programmer_t * pgm);
int (*program_enable) (struct programmer_t * pgm, AVRPART * p);
int (*chip_erase) (struct programmer_t * pgm, AVRPART * p);
int (*unlock) (struct programmer_t * pgm, AVRPART * p);
int (*cmd) (struct programmer_t * pgm, const unsigned char *cmd,
char type[PGM_TYPELEN];
char port[PGM_PORTLEN];
unsigned int pinno[N_PINS]; // TODO to be removed if old pin data no longer needed
exit_vcc_t exit_vcc; // Should these be set in avrdude.conf?
exit_reset_t exit_reset;
exit_datahigh_t exit_datahigh;
int ppidata;
int ppictrl;
int ispdelay; // ISP clock delay
int page_size; // Page size if the programmer supports paged write/load
double bitclock; // JTAG ICE clock period in microseconds
int (*rdy_led) (const struct programmer_t *pgm, int value);
int (*err_led) (const struct programmer_t *pgm, int value);
int (*pgm_led) (const struct programmer_t *pgm, int value);
int (*vfy_led) (const struct programmer_t *pgm, int value);
int (*initialize) (const struct programmer_t *pgm, const AVRPART *p); // Sets up the physical programmer
void (*display) (const struct programmer_t *pgm, const char *p);
void (*enable) (struct programmer_t *pgm, const AVRPART *p);
void (*disable) (const struct programmer_t *pgm);
void (*powerup) (const struct programmer_t *pgm);
void (*powerdown) (const struct programmer_t *pgm);
int (*program_enable) (const struct programmer_t *pgm, const AVRPART *p);
int (*chip_erase) (const struct programmer_t *pgm, const AVRPART *p);
int (*unlock) (const struct programmer_t *pgm, const AVRPART *p);
int (*cmd) (const struct programmer_t *pgm, const unsigned char *cmd,
unsigned char *res);
int (*cmd_tpi) (struct programmer_t * pgm, const unsigned char *cmd,
int (*cmd_tpi) (const struct programmer_t *pgm, const unsigned char *cmd,
int cmd_len, unsigned char res[], int res_len);
int (*spi) (struct programmer_t * pgm, const unsigned char *cmd,
int (*spi) (const struct programmer_t *pgm, const unsigned char *cmd,
unsigned char *res, int count);
int (*open) (struct programmer_t * pgm, char * port);
void (*close) (struct programmer_t * pgm);
int (*paged_write) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
int (*open) (struct programmer_t *pgm, const char *port);
void (*close) (struct programmer_t *pgm);
int (*paged_write) (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size, unsigned int baseaddr,
unsigned int n_bytes);
int (*paged_load) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
int (*paged_load) (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size, unsigned int baseaddr,
unsigned int n_bytes);
int (*page_erase) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
int (*page_erase) (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int baseaddr);
void (*write_setup) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
int (*write_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
void (*write_setup) (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m);
int (*write_byte) (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m,
unsigned long addr, unsigned char value);
int (*read_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
unsigned long addr, unsigned char * value);
int (*read_sig_bytes) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
int (*read_sib) (struct programmer_t * pgm, AVRPART * p, char *sib);
void (*print_parms) (struct programmer_t * pgm);
int (*set_vtarget) (struct programmer_t * pgm, double v);
int (*set_varef) (struct programmer_t * pgm, unsigned int chan, double v);
int (*set_fosc) (struct programmer_t * pgm, double v);
int (*set_sck_period) (struct programmer_t * pgm, double v);
int (*setpin) (struct programmer_t * pgm, int pinfunc, int value);
int (*getpin) (struct programmer_t * pgm, int pinfunc);
int (*highpulsepin) (struct programmer_t * pgm, int pinfunc);
int (*parseexitspecs) (struct programmer_t * pgm, char *s);
int (*perform_osccal) (struct programmer_t * pgm);
int (*parseextparams) (struct programmer_t * pgm, LISTID xparams);
void (*setup) (struct programmer_t * pgm);
void (*teardown) (struct programmer_t * pgm);
char config_file[PATH_MAX]; /* config file where defined */
int lineno; /* config file line number */
void *cookie; /* for private use by the programmer */
char flag; /* for private use of the programmer */
int (*read_byte) (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m,
unsigned long addr, unsigned char *value);
int (*read_sig_bytes) (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m);
int (*read_sib) (const struct programmer_t *pgm, const AVRPART *p, char *sib);
void (*print_parms) (const struct programmer_t *pgm);
int (*set_vtarget) (const struct programmer_t *pgm, double v);
int (*set_varef) (const struct programmer_t *pgm, unsigned int chan, double v);
int (*set_fosc) (const struct programmer_t *pgm, double v);
int (*set_sck_period) (const struct programmer_t *pgm, double v);
int (*setpin) (const struct programmer_t *pgm, int pinfunc, int value);
int (*getpin) (const struct programmer_t *pgm, int pinfunc);
int (*highpulsepin) (const struct programmer_t *pgm, int pinfunc);
int (*parseexitspecs) (struct programmer_t *pgm, const char *s);
int (*perform_osccal) (const struct programmer_t *pgm);
int (*parseextparams) (const struct programmer_t *pgm, const LISTID xparams);
void (*setup) (struct programmer_t *pgm);
void (*teardown) (struct programmer_t *pgm);
// Cached r/w API for terminal reads/writes
int (*write_byte_cached)(const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m,
unsigned long addr, unsigned char value);
int (*read_byte_cached)(const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m,
unsigned long addr, unsigned char *value);
int (*chip_erase_cached)(const struct programmer_t *pgm, const AVRPART *p);
int (*page_erase_cached)(const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int baseaddr);
int (*flush_cache) (const struct programmer_t *pgm, const AVRPART *p);
int (*reset_cache) (const struct programmer_t *pgm, const AVRPART *p);
AVR_Cache *cp_flash, *cp_eeprom;
const char *config_file; // Config file where defined
int lineno; // Config file line number
void *cookie; // For private use by the programmer
char flag; // For use by pgm->initpgm()
} PROGRAMMER;
#ifdef __cplusplus
@@ -731,8 +820,8 @@ extern "C" {
#endif
PROGRAMMER * pgm_new(void);
PROGRAMMER * pgm_dup(const PROGRAMMER * const src);
void pgm_free(PROGRAMMER * const p);
PROGRAMMER * pgm_dup(const PROGRAMMER *src);
void pgm_free(PROGRAMMER *p);
void programmer_display(PROGRAMMER * pgm, const char * p);
@@ -741,10 +830,10 @@ void programmer_display(PROGRAMMER * pgm, const char * p);
#define SHOW_PPI_PINS ((1<<PPI_AVR_VCC)|(1<<PPI_AVR_BUFF))
#define SHOW_AVR_PINS ((1<<PIN_AVR_RESET)|(1<<PIN_AVR_SCK)|(1<<PIN_AVR_MOSI)|(1<<PIN_AVR_MISO))
#define SHOW_LED_PINS ((1<<PIN_LED_ERR)|(1<<PIN_LED_RDY)|(1<<PIN_LED_PGM)|(1<<PIN_LED_VFY))
void pgm_display_generic_mask(PROGRAMMER * pgm, const char * p, unsigned int show);
void pgm_display_generic(PROGRAMMER * pgm, const char * p);
void pgm_display_generic_mask(const PROGRAMMER *pgm, const char *p, unsigned int show);
void pgm_display_generic(const PROGRAMMER *pgm, const char *p);
PROGRAMMER * locate_programmer(LISTID programmers, const char * configid);
PROGRAMMER *locate_programmer(const LISTID programmers, const char *configid);
typedef void (*walk_programmers_cb)(const char *name, const char *desc,
const char *cfgname, int cfglineno,
@@ -759,9 +848,10 @@ void sort_programmers(LISTID programmers);
/* formerly avr.h */
typedef void (*FP_UpdateProgress)(int percent, double etime, char *hdr);
typedef void (*FP_UpdateProgress)(int percent, double etime, const char *hdr, int finish);
extern struct avrpart parts[];
extern const char *avr_mem_order[100];
extern FP_UpdateProgress update_progress;
@@ -769,41 +859,71 @@ extern FP_UpdateProgress update_progress;
extern "C" {
#endif
int avr_tpi_poll_nvmbsy(PROGRAMMER *pgm);
int avr_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p);
int avr_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p, unsigned char guard_time);
int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
int avr_tpi_poll_nvmbsy(const PROGRAMMER *pgm);
int avr_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p);
int avr_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p, unsigned char guard_time);
int avr_read_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char * value);
int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, AVRPART * v);
int avr_read_mem(const PROGRAMMER * pgm, const AVRPART *p, const AVRMEM *mem, const AVRPART *v);
int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
int avr_read(const PROGRAMMER * pgm, const AVRPART *p, const char *memtype, const AVRPART *v);
int avr_write_page(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr);
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
int avr_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char data);
int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char data);
int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
int auto_erase);
int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int size, int auto_erase);
int avr_signature(PROGRAMMER * pgm, AVRPART * p);
int avr_write(const PROGRAMMER *pgm, const AVRPART *p, const char *memtype, int size, int auto_erase);
int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size);
int avr_signature(const PROGRAMMER *pgm, const AVRPART *p);
int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles);
int avr_verify(const AVRPART * p, const AVRPART * v, const char * memtype, int size);
int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);
int avr_get_cycle_count(const PROGRAMMER *pgm, const AVRPART *p, int *cycles);
int avr_mem_hiaddr(AVRMEM * mem);
int avr_put_cycle_count(const PROGRAMMER *pgm, const AVRPART *p, int cycles);
int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p);
void avr_add_mem_order(const char *str);
int avr_unlock(PROGRAMMER * pgm, AVRPART * p);
int avr_mem_is_flash_type(const AVRMEM *mem);
void report_progress (int completed, int total, char *hdr);
int avr_mem_is_eeprom_type(const AVRMEM *mem);
int avr_mem_is_known(const char *str);
int avr_mem_might_be_known(const char *str);
#define disable_trailing_ff_removal() avr_mem_hiaddr(NULL)
int avr_mem_hiaddr(const AVRMEM * mem);
int avr_chip_erase(const PROGRAMMER *pgm, const AVRPART *p);
int avr_unlock(const PROGRAMMER *pgm, const AVRPART *p);
void report_progress(int completed, int total, const char *hdr);
int avr_has_paged_access(const PROGRAMMER *pgm, const AVRMEM *m);
int avr_read_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int addr, unsigned char *buf);
int avr_write_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int addr, unsigned char *data);
int avr_is_and(const unsigned char *s1, const unsigned char *s2, const unsigned char *s3, size_t n);
// byte-wise cached 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_chip_erase_cached(const PROGRAMMER *pgm, const AVRPART *p);
int avr_page_erase_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned int baseaddr);
int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p);
int avr_reset_cache(const PROGRAMMER *pgm, const AVRPART *p);
#ifdef __cplusplus
}
@@ -821,7 +941,8 @@ typedef enum {
FMT_DEC,
FMT_OCT,
FMT_BIN,
FMT_ELF
FMT_ELF,
FMT_IHXC,
} FILEFMT;
struct fioparms {
@@ -835,16 +956,19 @@ struct fioparms {
enum {
FIO_READ,
FIO_WRITE
FIO_WRITE,
FIO_READ_FOR_VERIFY,
};
#ifdef __cplusplus
extern "C" {
#endif
char * fmtstr(FILEFMT format);
char * fileio_fmtstr(FILEFMT format);
int fileio(int op, char * filename, FILEFMT format,
int fileio_fmt_autodetect(const char * fname);
int fileio(int oprwv, char * filename, FILEFMT format,
struct avrpart * p, char * memtype, int size);
#ifdef __cplusplus
@@ -864,6 +988,7 @@ enum updateflags {
UF_NONE = 0,
UF_NOWRITE = 1,
UF_AUTO_ERASE = 2,
UF_VERIFY = 4,
};
@@ -874,6 +999,17 @@ typedef struct update_t {
int format;
} UPDATE;
typedef struct { // File reads for flash can exclude trailing 0xff, which are cut off
int nbytes, // Number of bytes set including 0xff but excluding cut off, trailing 0xff
nsections, // Number of consecutive sections in source excluding cut off, trailing 0xff
npages, // Number of memory pages needed excluding pages solely with trailing 0xff
nfill, // Number of fill bytes to make up full pages that are needed
ntrailing, // Number of trailing 0xff in source
firstaddr, // First address set in [0, mem->size-1]
lastaddr; // Highest address set by input file
} Filestats;
#ifdef __cplusplus
extern "C" {
#endif
@@ -886,6 +1022,22 @@ extern void free_update(UPDATE * upd);
extern int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd,
enum updateflags flags);
extern int memstats(struct avrpart *p, char *memtype, int size, Filestats *fsp);
// Convenience functions for printing
const char *update_plural(int x);
const char *update_inname(const char *fn);
const char *update_outname(const char *fn);
const char *update_interval(int a, int b);
// Helper functions for dry run to determine file access
int update_is_okfile(const char *fn);
int update_is_writeable(const char *fn);
int update_is_readable(const char *fn);
int update_dryrun(struct avrpart *p, UPDATE *upd);
#ifdef __cplusplus
}
#endif
@@ -897,7 +1049,7 @@ extern int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd,
typedef struct programmer_type_t {
const char * const id;
void (*initpgm)(struct programmer_t * pgm);
void (*initpgm)(struct programmer_t *pgm);
const char * const desc;
} PROGRAMMER_TYPE;
@@ -905,7 +1057,9 @@ typedef struct programmer_type_t {
extern "C" {
#endif
const PROGRAMMER_TYPE * locate_programmer_type(/*LISTID programmer_types, */const char * id);
const PROGRAMMER_TYPE *locate_programmer_type(const char *id);
const char *locate_programmer_type_id(void (*initpgm)(struct programmer_t *pgm));
typedef void (*walk_programmer_types_cb)(const char *id, const char *desc,
void *cookie);
@@ -919,9 +1073,10 @@ void walk_programmer_types(/*LISTID programmer_types,*/ walk_programmer_types_cb
extern LISTID part_list;
extern LISTID programmers;
extern char default_programmer[];
extern char default_parallel[];
extern char default_serial[];
extern const char *default_programmer;
extern const char *default_parallel;
extern const char *default_serial;
extern const char *default_spi;
extern double default_bitclock;
/* This name is fixed, it's only here for symmetry with
@@ -932,12 +1087,24 @@ extern double default_bitclock;
extern "C" {
#endif
void *cfg_malloc(const char *funcname, size_t n);
char *cfg_strdup(const char *funcname, const char *s);
int init_config(void);
void cleanup_config(void);
int read_config(const char * file);
const char *cache_string(const char *file);
unsigned char *cfg_unescapeu(unsigned char *d, const unsigned char *s);
char *cfg_unescape(char *d, const char *s);
char *cfg_escape(const char *s);
#ifdef __cplusplus
}
#endif

View File

@@ -31,18 +31,18 @@
#include <stdlib.h>
#define ppi_claim(fd) \
if (ioctl(fd, PPCLAIM)) { \
avrdude_message(MSG_INFO, "%s: can't claim device \"%s\": %s\n\n", \
progname, port, strerror(errno)); \
close(fd); \
return; \
#define ppi_claim(fd) \
if (ioctl(fd, PPCLAIM)) { \
pmsg_ext_error("cannot claim port %s: %s\n\n", \
port, strerror(errno)); \
close(fd); \
return; \
}
#define ppi_release(fd) \
if (ioctl(fd, PPRELEASE)) { \
avrdude_message(MSG_INFO, "%s: can't release device: %s\n\n", \
progname, strerror(errno)); \
#define ppi_release(fd) \
if (ioctl(fd, PPRELEASE)) { \
pmsg_ext_error("cannot release device: %s\n\n", \
strerror(errno)); \
}
#define DO_PPI_READ(fd, reg, valp) \

View File

@@ -27,6 +27,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include "avrdude.h"
#include "libavrdude.h"
@@ -62,7 +63,7 @@ static int linuxgpio_export(unsigned int gpio)
fd = open("/sys/class/gpio/export", O_WRONLY);
if (fd < 0) {
perror("Can't open /sys/class/gpio/export");
pmsg_ext_error("cannot open /sys/class/gpio/export: %s\n", strerror(errno));
return fd;
}
@@ -80,7 +81,7 @@ static int linuxgpio_unexport(unsigned int gpio)
fd = open("/sys/class/gpio/unexport", O_WRONLY);
if (fd < 0) {
perror("Can't open /sys/class/gpio/unexport");
pmsg_ext_error("cannot open /sys/class/gpio/unexport: %s\n", strerror(errno));
return fd;
}
@@ -108,7 +109,7 @@ static int linuxgpio_dir(unsigned int gpio, unsigned int dir)
fd = open(buf, O_WRONLY);
if (fd < 0) {
perror("Can't open gpioX/direction");
pmsg_ext_error("cannot open %s: %s\n", buf, strerror(errno));
return fd;
}
@@ -138,14 +139,18 @@ static int linuxgpio_dir_in(unsigned int gpio)
#define N_GPIO (PIN_MAX + 1)
/* Delay between checks for successful GPIO export (100ms) */
#define GPIO_SYSFS_OPEN_DELAY 100000
/* Number of retries to check for successful GPIO exports */
#define GPIO_SYSFS_OPEN_RETRIES 10
/*
* an array which holds open FDs to /sys/class/gpio/gpioXX/value for all needed pins
*/
static int linuxgpio_fds[N_GPIO] ;
static int linuxgpio_setpin(PROGRAMMER * pgm, int pinfunc, int value)
{
static int linuxgpio_setpin(const PROGRAMMER *pgm, int pinfunc, int value) {
int r;
int pin = pgm->pinno[pinfunc]; // TODO
@@ -171,8 +176,7 @@ static int linuxgpio_setpin(PROGRAMMER * pgm, int pinfunc, int value)
return 0;
}
static int linuxgpio_getpin(PROGRAMMER * pgm, int pinfunc)
{
static int linuxgpio_getpin(const PROGRAMMER *pgm, int pinfunc) {
unsigned char invert=0;
char c;
int pin = pgm->pinno[pinfunc]; // TODO
@@ -198,11 +202,9 @@ static int linuxgpio_getpin(PROGRAMMER * pgm, int pinfunc)
return 1-invert;
else
return -1;
}
static int linuxgpio_highpulsepin(PROGRAMMER * pgm, int pinfunc)
{
static int linuxgpio_highpulsepin(const PROGRAMMER *pgm, int pinfunc) {
int pin = pgm->pinno[pinfunc]; // TODO
if ( linuxgpio_fds[pin & PIN_MASK] < 0 )
@@ -216,35 +218,31 @@ static int linuxgpio_highpulsepin(PROGRAMMER * pgm, int pinfunc)
static void linuxgpio_display(PROGRAMMER *pgm, const char *p)
{
avrdude_message(MSG_INFO, "%sPin assignment : /sys/class/gpio/gpio{n}\n",p);
static void linuxgpio_display(const PROGRAMMER *pgm, const char *p) {
msg_info("%sPin assignment : /sys/class/gpio/gpio{n}\n",p);
pgm_display_generic_mask(pgm, p, SHOW_AVR_PINS);
}
static void linuxgpio_enable(PROGRAMMER *pgm)
{
static void linuxgpio_enable(PROGRAMMER *pgm, const AVRPART *p) {
/* nothing */
}
static void linuxgpio_disable(PROGRAMMER *pgm)
{
static void linuxgpio_disable(const PROGRAMMER *pgm) {
/* nothing */
}
static void linuxgpio_powerup(PROGRAMMER *pgm)
{
static void linuxgpio_powerup(const PROGRAMMER *pgm) {
/* nothing */
}
static void linuxgpio_powerdown(PROGRAMMER *pgm)
{
static void linuxgpio_powerdown(const PROGRAMMER *pgm) {
/* nothing */
}
static int linuxgpio_open(PROGRAMMER *pgm, char *port)
{
static int linuxgpio_open(PROGRAMMER *pgm, const char *port) {
int r, i, pin;
char gpio_path[60];
struct stat stat_buf;
if (bitbang_check_prerequisites(pgm) < 0)
return -1;
@@ -268,17 +266,53 @@ static int linuxgpio_open(PROGRAMMER *pgm, char *port)
i == PIN_AVR_MISO ) {
pin = pgm->pinno[i] & PIN_MASK;
if ((r=linuxgpio_export(pin)) < 0) {
avrdude_message(MSG_INFO, "Can't export GPIO %d, already exported/busy?: %s",
pmsg_ext_error("cannot export GPIO %d, already exported/busy?: %s",
pin, strerror(errno));
return r;
}
if (i == PIN_AVR_MISO)
r=linuxgpio_dir_in(pin);
else
r=linuxgpio_dir_out(pin);
if (r < 0)
/* Wait until GPIO directory appears */
snprintf(gpio_path, sizeof(gpio_path), "/sys/class/gpio/gpio%u", pin);
unsigned int retry_count;
for (retry_count = 0; retry_count < GPIO_SYSFS_OPEN_RETRIES; retry_count++) {
int ret = stat(gpio_path, &stat_buf);
if (ret == 0) {
break;
} else if (ret < 0 && errno != ENOENT) {
linuxgpio_unexport(pin);
return ret;
}
usleep(GPIO_SYSFS_OPEN_DELAY);
}
/* Write direction, looping in case of EACCES errors due to delayed
* udev permission rule application after export */
for (retry_count = 0; retry_count < GPIO_SYSFS_OPEN_RETRIES; retry_count++) {
usleep(GPIO_SYSFS_OPEN_DELAY);
if (i == PIN_AVR_MISO)
r=linuxgpio_dir_in(pin);
else
r=linuxgpio_dir_out(pin);
if (r >= 0)
break;
if (errno != EACCES) {
linuxgpio_unexport(pin);
return r;
}
}
if (retry_count)
pmsg_notice2("needed %d retr%s for linuxgpio_dir_%s(%s)\n",
retry_count, retry_count > 1? "ies": "y",
i == PIN_AVR_MISO? "in": "out", avr_pin_name(pin));
if (r < 0) {
linuxgpio_unexport(pin);
return r;
}
if ((linuxgpio_fds[pin]=linuxgpio_openfd(pin)) < 0)
return linuxgpio_fds[pin];
@@ -311,8 +345,7 @@ static void linuxgpio_close(PROGRAMMER *pgm)
}
}
void linuxgpio_initpgm(PROGRAMMER *pgm)
{
void linuxgpio_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "linuxgpio");
pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
@@ -344,10 +377,8 @@ const char linuxgpio_desc[] = "GPIO bitbanging using the Linux sysfs interface";
#else /* !HAVE_LINUXGPIO */
void linuxgpio_initpgm(PROGRAMMER * pgm)
{
avrdude_message(MSG_INFO, "%s: Linux sysfs GPIO support not available in this configuration\n",
progname);
void linuxgpio_initpgm(PROGRAMMER *pgm) {
pmsg_error("Linux sysfs GPIO support not available in this configuration\n");
}
const char linuxgpio_desc[] = "GPIO bitbanging using the Linux sysfs interface (not available)";

View File

@@ -27,7 +27,7 @@ extern "C" {
#endif
extern const char linuxgpio_desc[];
void linuxgpio_initpgm (PROGRAMMER * pgm);
void linuxgpio_initpgm(PROGRAMMER *pgm);
#ifdef __cplusplus
}

View File

@@ -62,14 +62,22 @@
#define LINUXSPI "linuxspi"
/*
* Private data for this programmer.
*/
struct pdata {
int disable_no_cs;
};
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
static int fd_spidev, fd_gpiochip, fd_linehandle;
/**
* @brief Sends/receives a message in full duplex mode
* @return -1 on failure, otherwise number of bytes sent/received
*/
static int linuxspi_spi_duplex(PROGRAMMER *pgm, const unsigned char *tx, unsigned char *rx, int len)
{
static int linuxspi_spi_duplex(const PROGRAMMER *pgm, const unsigned char *tx, unsigned char *rx, int len) {
struct spi_ioc_transfer tr;
int ret;
@@ -78,27 +86,33 @@ static int linuxspi_spi_duplex(PROGRAMMER *pgm, const unsigned char *tx, unsigne
.rx_buf = (unsigned long)rx,
.len = len,
.delay_usecs = 1,
.speed_hz = 1.0 / pgm->bitclock, // seconds to Hz
.speed_hz = 1.0 / pgm->bitclock,
.bits_per_word = 8,
};
errno = 0;
ret = ioctl(fd_spidev, SPI_IOC_MESSAGE(1), &tr);
if (ret != len)
avrdude_message(MSG_INFO, "\n%s: error: Unable to send SPI message\n", progname);
if (ret != len) {
int ioctl_errno = errno;
msg_error("\n");
pmsg_error("unable to send SPI message");
if (ioctl_errno)
msg_error("%s", strerror(ioctl_errno));
msg_error("\n");
}
return (ret == -1) ? -1 : 0;
return ret == -1? -1: 0;
}
static void linuxspi_setup(PROGRAMMER *pgm)
{
static void linuxspi_setup(PROGRAMMER *pgm) {
pgm->cookie = cfg_malloc("linuxspi_setup()", sizeof(struct pdata));
}
static void linuxspi_teardown(PROGRAMMER* pgm)
{
static void linuxspi_teardown(PROGRAMMER* pgm) {
free(pgm->cookie);
}
static int linuxspi_reset_mcu(PROGRAMMER *pgm, bool active)
{
static int linuxspi_reset_mcu(const PROGRAMMER *pgm, bool active) {
struct gpiohandle_data data;
int ret;
@@ -120,21 +134,20 @@ static int linuxspi_reset_mcu(PROGRAMMER *pgm, bool active)
#endif
if (ret == -1) {
ret = -errno;
avrdude_message(MSG_INFO, "%s error: Unable to set GPIO line %d value\n",
progname, pgm->pinno[PIN_AVR_RESET] & ~PIN_INVERSE);
pmsg_ext_error("unable to set GPIO line %d value: %s\n", pgm->pinno[PIN_AVR_RESET] & ~PIN_INVERSE, strerror(errno));
return ret;
}
return 0;
}
static int linuxspi_open(PROGRAMMER *pgm, char *port)
{
static int linuxspi_open(PROGRAMMER *pgm, const char *pt) {
const char *port_error =
"%s: error: Unknown port specification. "
"Please use the format /dev/spidev:/dev/gpiochip[:resetno]\n";
"unknown port specification, "
"please use the format /dev/spidev:/dev/gpiochip[:resetno]\n";
char port_default[] = "/dev/spidev0.0:/dev/gpiochip0";
char *spidev, *gpiochip, *reset_pin;
char *port = cfg_strdup("linuxspi_open()", pt);
struct gpiohandle_request req;
int ret;
@@ -144,13 +157,13 @@ static int linuxspi_open(PROGRAMMER *pgm, char *port)
spidev = strtok(port, ":");
if (!spidev) {
avrdude_message(MSG_INFO, port_error, progname);
pmsg_error("%s", port_error);
return -1;
}
gpiochip = strtok(NULL, ":");
if (!gpiochip) {
avrdude_message(MSG_INFO, port_error, progname);
pmsg_error("%s", port_error);
return -1;
}
@@ -162,20 +175,25 @@ static int linuxspi_open(PROGRAMMER *pgm, char *port)
strcpy(pgm->port, port);
fd_spidev = open(pgm->port, O_RDWR);
if (fd_spidev < 0) {
avrdude_message(MSG_INFO, "\n%s: error: Unable to open the spidev device %s", progname, pgm->port);
pmsg_ext_error("unable to open the spidev device %s: %s\n", pgm->port, strerror(errno));
return -1;
}
uint32_t mode = SPI_MODE_0 | SPI_NO_CS;
uint32_t mode = SPI_MODE_0;
if (!PDATA(pgm)->disable_no_cs)
mode |= SPI_NO_CS;
ret = ioctl(fd_spidev, SPI_IOC_WR_MODE32, &mode);
if (ret == -1) {
avrdude_message(MSG_INFO, "%s: error: Unable to set SPI mode %0X on %s\n",
progname, mode, spidev);
int ioctl_errno = errno;
pmsg_ext_error("unable to set SPI mode %02X on %s: %s\n", mode, spidev, strerror(errno));
if(ioctl_errno == EINVAL && !PDATA(pgm)->disable_no_cs)
pmsg_error("try -x disable_no_cs\n");
goto close_spidev;
}
fd_gpiochip = open(gpiochip, 0);
if (fd_gpiochip < 0) {
avrdude_message(MSG_INFO, "\n%s error: Unable to open the gpiochip %s", progname, gpiochip);
pmsg_ext_error("unable to open the gpiochip %s: %s\n", gpiochip, strerror(errno));
ret = -1;
goto close_spidev;
}
@@ -210,8 +228,7 @@ static int linuxspi_open(PROGRAMMER *pgm, char *port)
#endif
if (ret == -1) {
ret = -errno;
avrdude_message(MSG_INFO, "%s error: Unable to get GPIO line %d\n",
progname, pgm->pinno[PIN_AVR_RESET] & ~PIN_INVERSE);
pmsg_ext_error("unable to get GPIO line %d. %s\n", pgm->pinno[PIN_AVR_RESET] & ~PIN_INVERSE, strerror(errno));
goto close_gpiochip;
}
@@ -220,16 +237,12 @@ static int linuxspi_open(PROGRAMMER *pgm, char *port)
goto close_out;
if (pgm->baudrate != 0) {
avrdude_message(MSG_INFO,
"%s: obsolete use of -b <clock> option for bit clock; use -B <clock>\n",
progname);
pgm->bitclock = 1.0 / pgm->baudrate;
pmsg_warning("obsolete use of -b <clock> option for bit clock; use -B <clock>\n");
pgm->bitclock = 1.0 / pgm->baudrate;
}
if (pgm->bitclock == 0) {
avrdude_message(MSG_NOTICE,
"%s: defaulting bit clock to 200 kHz\n",
progname);
pgm->bitclock = 5E-6; // 200 kHz - 5 µs
pmsg_notice("defaulting bit clock to 200 kHz\n");
pgm->bitclock = 5E-6; // 200 kHz - 5 µs
}
return 0;
@@ -243,8 +256,7 @@ close_spidev:
return ret;
}
static void linuxspi_close(PROGRAMMER *pgm)
{
static void linuxspi_close(PROGRAMMER *pgm) {
switch (pgm->exit_reset) {
case EXIT_RESET_ENABLED:
linuxspi_reset_mcu(pgm, true);
@@ -263,25 +275,21 @@ static void linuxspi_close(PROGRAMMER *pgm)
close(fd_gpiochip);
}
static void linuxspi_disable(PROGRAMMER* pgm)
{
static void linuxspi_disable(const PROGRAMMER* pgm) {
}
static void linuxspi_enable(PROGRAMMER* pgm)
{
static void linuxspi_enable(PROGRAMMER *pgm, const AVRPART *p) {
}
static void linuxspi_display(PROGRAMMER* pgm, const char* p)
{
static void linuxspi_display(const PROGRAMMER* pgm, const char* p) {
}
static int linuxspi_initialize(PROGRAMMER *pgm, AVRPART *p)
{
static int linuxspi_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
int tries, ret;
if (p->flags & AVRPART_HAS_TPI) {
/* We do not support tpi. This is a dedicated SPI thing */
avrdude_message(MSG_INFO, "%s: error: Programmer " LINUXSPI " does not support TPI\n", progname);
if (p->prog_modes & PM_TPI) {
/* We do not support TPI. This is a dedicated SPI thing */
pmsg_error("programmer " LINUXSPI " does not support TPI\n");
return -1;
}
@@ -295,22 +303,21 @@ static int linuxspi_initialize(PROGRAMMER *pgm, AVRPART *p)
} while(tries++ < 65);
if (ret)
avrdude_message(MSG_INFO, "%s: error: AVR device not responding\n", progname);
pmsg_error("AVR device not responding\n");
return ret;
}
static int linuxspi_cmd(PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res)
static int linuxspi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res)
{
return linuxspi_spi_duplex(pgm, cmd, res, 4);
}
static int linuxspi_program_enable(PROGRAMMER *pgm, AVRPART *p)
{
static int linuxspi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char cmd[4], res[4];
if (!p->op[AVR_OP_PGM_ENABLE]) {
avrdude_message(MSG_INFO, "%s: error: program enable instruction not defined for part \"%s\"\n", progname, p->desc);
pmsg_error("program enable instruction not defined for part %s\n", p->desc);
return -1;
}
@@ -349,12 +356,11 @@ static int linuxspi_program_enable(PROGRAMMER *pgm, AVRPART *p)
return 0;
}
static int linuxspi_chip_erase(PROGRAMMER *pgm, AVRPART *p)
{
static int linuxspi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char cmd[4], res[4];
if (!p->op[AVR_OP_CHIP_ERASE]) {
avrdude_message(MSG_INFO, "%s: error: chip erase instruction not defined for part \"%s\"\n", progname, p->desc);
pmsg_error("chip erase instruction not defined for part %s\n", p->desc);
return -1;
}
@@ -367,12 +373,12 @@ static int linuxspi_chip_erase(PROGRAMMER *pgm, AVRPART *p)
return 0;
}
static int linuxspi_parseexitspecs(PROGRAMMER *pgm, char *s)
{
char *cp;
static int linuxspi_parseexitspecs(PROGRAMMER *pgm, const char *sp) {
char *cp, *s, *str = cfg_strdup("linuxspi_parseextitspecs()", sp);
s = str;
while ((cp = strtok(s, ","))) {
s = 0;
s = NULL;
if (!strcmp(cp, "reset")) {
pgm->exit_reset = EXIT_RESET_ENABLED;
continue;
@@ -381,14 +387,35 @@ static int linuxspi_parseexitspecs(PROGRAMMER *pgm, char *s)
pgm->exit_reset = EXIT_RESET_DISABLED;
continue;
}
free(str);
return -1;
}
free(str);
return 0;
}
void linuxspi_initpgm(PROGRAMMER *pgm)
{
static int linuxspi_parseextparams(const PROGRAMMER *pgm, const LISTID extparms) {
LNODEID ln;
const char *extended_param;
int rc = 0;
for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
extended_param = ldata(ln);
if (strcmp(extended_param, "disable_no_cs") == 0) {
PDATA(pgm)->disable_no_cs = 1;
continue;
}
pmsg_error("invalid extended parameter '%s'\n", extended_param);
rc = -1;
}
return rc;
}
void linuxspi_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, LINUXSPI);
pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
@@ -410,16 +437,15 @@ void linuxspi_initpgm(PROGRAMMER *pgm)
pgm->setup = linuxspi_setup;
pgm->teardown = linuxspi_teardown;
pgm->parseexitspecs = linuxspi_parseexitspecs;
pgm->parseextparams = linuxspi_parseextparams;
}
const char linuxspi_desc[] = "SPI using Linux spidev driver";
#else /* !HAVE_LINUXSPI */
void linuxspi_initpgm(PROGRAMMER * pgm)
{
avrdude_message(MSG_INFO, "%s: Linux SPI driver not available in this configuration\n",
progname);
void linuxspi_initpgm(PROGRAMMER *pgm) {
pmsg_error("Linux SPI driver not available in this configuration\n");
}
const char linuxspi_desc[] = "SPI using Linux spidev driver (not available)";

View File

@@ -25,7 +25,7 @@ extern "C" {
#endif
extern const char linuxspi_desc[];
void linuxspi_initpgm (PROGRAMMER * pgm);
void linuxspi_initpgm(PROGRAMMER *pgm);
#ifdef __cplusplus
}

File diff suppressed because it is too large Load Diff

View File

@@ -164,7 +164,7 @@ static int micronucleus_reconnect(pdata_t* pdata)
for (int i = 0; i < 25; i++)
{
avrdude_message(MSG_NOTICE, "%s: Trying to reconnect...\n", progname);
pmsg_notice("trying to reconnect ...\n");
pdata->usb_handle = usb_open(device);
if (pdata->usb_handle != NULL)
@@ -188,14 +188,12 @@ static int micronucleus_get_bootloader_info_v1(pdata_t* pdata)
MICRONUCLEUS_DEFAULT_TIMEOUT);
if (result < 0)
{
avrdude_message(MSG_INFO, "%s: WARNING: Failed to get bootloader info block: %s\n",
progname, usb_strerror());
pmsg_warning("unable to get bootloader info block: %s\n", usb_strerror());
return result;
}
else if (result < sizeof(buffer))
{
avrdude_message(MSG_INFO, "%s: WARNING: Received invalid bootloader info block size: %d\n",
progname, result);
pmsg_warning("received invalid bootloader info block size: %d\n", result);
return -1;
}
@@ -257,14 +255,12 @@ static int micronucleus_get_bootloader_info_v2(pdata_t* pdata)
MICRONUCLEUS_DEFAULT_TIMEOUT);
if (result < 0)
{
avrdude_message(MSG_INFO, "%s: WARNING: Failed to get bootloader info block: %s\n",
progname, usb_strerror());
pmsg_warning("unable to get bootloader info block: %s\n", usb_strerror());
return result;
}
else if (result < sizeof(buffer))
{
avrdude_message(MSG_INFO, "%s: WARNING: Received invalid bootloader info block size: %d\n",
progname, result);
pmsg_warning("received invalid bootloader info block size: %d\n", result);
return -1;
}
@@ -302,19 +298,19 @@ static int micronucleus_get_bootloader_info(pdata_t* pdata)
static void micronucleus_dump_device_info(pdata_t* pdata)
{
avrdude_message(MSG_NOTICE, "%s: Bootloader version: %d.%d\n", progname, pdata->major_version, pdata->minor_version);
avrdude_message(MSG_NOTICE, "%s: Available flash size: %u\n", progname, pdata->flash_size);
avrdude_message(MSG_NOTICE, "%s: Page size: %u\n", progname, pdata->page_size);
avrdude_message(MSG_NOTICE, "%s: Bootloader start: 0x%04X\n", progname, pdata->bootloader_start);
avrdude_message(MSG_NOTICE, "%s: Write sleep: %ums\n", progname, pdata->write_sleep);
avrdude_message(MSG_NOTICE, "%s: Erase sleep: %ums\n", progname, pdata->erase_sleep);
avrdude_message(MSG_NOTICE, "%s: Signature1: 0x%02X\n", progname, pdata->signature1);
avrdude_message(MSG_NOTICE, "%s: Signature2: 0x%02X\n", progname, pdata->signature2);
pmsg_notice("Bootloader version: %d.%d\n", pdata->major_version, pdata->minor_version);
imsg_notice("Available flash size: %u\n", pdata->flash_size);
imsg_notice("Page size: %u\n", pdata->page_size);
imsg_notice("Bootloader start: 0x%04X\n", pdata->bootloader_start);
imsg_notice("Write sleep: %ums\n", pdata->write_sleep);
imsg_notice("Erase sleep: %ums\n", pdata->erase_sleep);
imsg_notice("Signature1: 0x%02X\n", pdata->signature1);
imsg_notice("Signature2: 0x%02X\n", pdata->signature2);
}
static int micronucleus_erase_device(pdata_t* pdata)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_erase_device()\n", progname);
pmsg_debug("micronucleus_erase_device()\n");
int result = usb_control_msg(
pdata->usb_handle,
@@ -329,10 +325,10 @@ static int micronucleus_erase_device(pdata_t* pdata)
{
case -EIO:
case -EPIPE:
avrdude_message(MSG_NOTICE, "%s: Ignoring last error of erase command: %s\n", progname, usb_strerror());
pmsg_notice("ignoring last error of erase command: %s\n", usb_strerror());
break;
default:
avrdude_message(MSG_INFO, "%s: WARNING: Failed is issue erase command, code %d: %s\n", progname, result, usb_strerror());
pmsg_warning("erase command failed, code %d: %s\n", result, usb_strerror());
return result;
}
}
@@ -342,12 +338,12 @@ static int micronucleus_erase_device(pdata_t* pdata)
result = micronucleus_check_connection(pdata);
if (result < 0)
{
avrdude_message(MSG_NOTICE, "%s: Connection dropped, trying to reconnect...\n", progname);
pmsg_notice("connection dropped, trying to reconnect ...\n");
result = micronucleus_reconnect(pdata);
if (result < 0)
{
avrdude_message(MSG_INFO, "%s: WARNING: Failed to reconnect USB device: %s\n", progname, usb_strerror());
pmsg_warning("unable to reconnect USB device: %s\n", usb_strerror());
return result;
}
}
@@ -373,7 +369,7 @@ static int micronucleus_patch_reset_vector(pdata_t* pdata, uint8_t* buffer)
}
else
{
avrdude_message(MSG_INFO, "%s: The reset vector of the user program does not contain a branch instruction.\n", progname);
pmsg_error("the reset vector of the user program does not contain a branch instruction\n");
return -1;
}
@@ -431,7 +427,7 @@ static int micronucleus_write_page_v1(pdata_t* pdata, uint32_t address, uint8_t*
MICRONUCLEUS_DEFAULT_TIMEOUT);
if (result < 0)
{
avrdude_message(MSG_INFO, "%s: Failed to transfer page: %s\n", progname, usb_strerror());
pmsg_error("unable to transfer page: %s\n", usb_strerror());
return result;
}
@@ -449,7 +445,7 @@ static int micronucleus_write_page_v2(pdata_t* pdata, uint32_t address, uint8_t*
MICRONUCLEUS_DEFAULT_TIMEOUT);
if (result < 0)
{
avrdude_message(MSG_INFO, "%s: Failed to transfer page: %s\n", progname, usb_strerror());
pmsg_error("unable to transfer page: %s\n", usb_strerror());
return result;
}
@@ -466,7 +462,7 @@ static int micronucleus_write_page_v2(pdata_t* pdata, uint32_t address, uint8_t*
MICRONUCLEUS_DEFAULT_TIMEOUT);
if (result < 0)
{
avrdude_message(MSG_INFO, "%s: Failed to transfer page: %s\n", progname, usb_strerror());
pmsg_error("unable to transfer page: %s\n", usb_strerror());
return result;
}
}
@@ -476,7 +472,7 @@ static int micronucleus_write_page_v2(pdata_t* pdata, uint32_t address, uint8_t*
static int micronucleus_write_page(pdata_t* pdata, uint32_t address, uint8_t* buffer, uint32_t size)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_write_page(address=0x%04X, size=%d)\n", progname, address, size);
pmsg_debug("micronucleus_write_page(address=0x%04X, size=%d)\n", address, size);
if (address == 0)
{
@@ -528,7 +524,7 @@ static int micronucleus_write_page(pdata_t* pdata, uint32_t address, uint8_t* bu
static int micronucleus_start(pdata_t* pdata)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_start()\n", progname);
pmsg_debug("micronucleus_start()\n");
int result = usb_control_msg(
pdata->usb_handle,
@@ -539,7 +535,7 @@ static int micronucleus_start(pdata_t* pdata)
MICRONUCLEUS_DEFAULT_TIMEOUT);
if (result < 0)
{
avrdude_message(MSG_INFO, "%s: WARNING: Failed is issue start command: %s\n", progname, usb_strerror());
pmsg_warning("start command failed: %s\n", usb_strerror());
return result;
}
@@ -550,11 +546,11 @@ static int micronucleus_start(pdata_t* pdata)
static void micronucleus_setup(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_setup()\n", progname);
pmsg_debug("micronucleus_setup()\n");
if ((pgm->cookie = malloc(sizeof(pdata_t))) == 0)
{
avrdude_message(MSG_INFO, "%s: micronucleus_setup(): Out of memory allocating private data\n", progname);
pmsg_error("out of memory allocating private data\n");
exit(1);
}
@@ -563,13 +559,12 @@ static void micronucleus_setup(PROGRAMMER* pgm)
static void micronucleus_teardown(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_teardown()\n", progname);
pmsg_debug("micronucleus_teardown()\n");
free(pgm->cookie);
}
static int micronucleus_initialize(PROGRAMMER* pgm, AVRPART* p)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_initialize()\n", progname);
static int micronucleus_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
pmsg_debug("micronucleus_initialize()\n");
pdata_t* pdata = PDATA(pgm);
@@ -582,19 +577,16 @@ static int micronucleus_initialize(PROGRAMMER* pgm, AVRPART* p)
return 0;
}
static void micronucleus_display(PROGRAMMER* pgm, const char* prefix)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_display()\n", progname);
static void micronucleus_display(const PROGRAMMER *pgm, const char *prefix) {
pmsg_debug("micronucleus_display()\n");
}
static void micronucleus_powerup(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_powerup()\n", progname);
static void micronucleus_powerup(const PROGRAMMER *pgm) {
pmsg_debug("micronucleus_powerup()\n");
}
static void micronucleus_powerdown(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_powerdown()\n", progname);
static void micronucleus_powerdown(const PROGRAMMER *pgm) {
pmsg_debug("micronucleus_powerdown()\n");
pdata_t* pdata = PDATA(pgm);
if (pdata->write_last_page)
@@ -618,29 +610,25 @@ static void micronucleus_powerdown(PROGRAMMER* pgm)
}
}
static void micronucleus_enable(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_enable()\n", progname);
static void micronucleus_enable(PROGRAMMER *pgm, const AVRPART *p) {
pmsg_debug("micronucleus_enable()\n");
}
static void micronucleus_disable(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_disable()\n", progname);
static void micronucleus_disable(const PROGRAMMER *pgm) {
pmsg_debug("micronucleus_disable()\n");
}
static int micronucleus_program_enable(PROGRAMMER* pgm, AVRPART* p)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_program_enable()\n", progname);
static int micronucleus_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
pmsg_debug("micronucleus_program_enable()\n");
return 0;
}
static int micronucleus_read_sig_bytes(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_read_sig_bytes()\n", progname);
static int micronucleus_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem) {
pmsg_debug("micronucleus_read_sig_bytes()\n");
if (mem->size < 3)
{
avrdude_message(MSG_INFO, "%s: memory size too small for read_sig_bytes", progname);
pmsg_error("memory size %d < 3 too small for read_sig_bytes", mem->size);
return -1;
}
@@ -651,20 +639,18 @@ static int micronucleus_read_sig_bytes(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem)
return 0;
}
static int micronucleus_chip_erase(PROGRAMMER* pgm, AVRPART* p)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_chip_erase()\n", progname);
static int micronucleus_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
pmsg_debug("micronucleus_chip_erase()\n");
pdata_t* pdata = PDATA(pgm);
return micronucleus_erase_device(pdata);
}
static int micronucleus_open(PROGRAMMER* pgm, char* port)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_open(\"%s\")\n", progname, port);
static int micronucleus_open(PROGRAMMER* pgm, const char *port) {
pmsg_debug("micronucleus_open(\"%s\")\n", port);
pdata_t* pdata = PDATA(pgm);
char* bus_name = NULL;
const char *bus_name = NULL;
char* dev_name = NULL;
// if no -P was given or '-P usb' was given
@@ -689,8 +675,8 @@ static int micronucleus_open(PROGRAMMER* pgm, char* port)
if (port != NULL && dev_name == NULL)
{
avrdude_message(MSG_INFO, "%s: ERROR: Invalid -P value: '%s'\n", progname, port);
avrdude_message(MSG_INFO, "%sUse -P usb:bus:device\n", progbuf);
pmsg_error("invalid -P value %s\n", port);
imsg_error("use -P usb:bus:device\n");
return -1;
}
@@ -704,8 +690,7 @@ static int micronucleus_open(PROGRAMMER* pgm, char* port)
pid = *(int*)(ldata(usbpid));
if (lnext(usbpid))
{
avrdude_message(MSG_INFO, "%s: WARNING: using PID 0x%04x, ignoring remaining PIDs in list\n",
progname, pid);
pmsg_warning("using PID 0x%04x, ignoring remaining PIDs in list\n", pid);
}
}
@@ -738,8 +723,7 @@ static int micronucleus_open(PROGRAMMER* pgm, char* port)
{
if (show_unresponsive_device_message)
{
avrdude_message(MSG_INFO, "%s: WARNING: Unresponsive Micronucleus device detected, please reconnect...\n",
progname);
pmsg_warning("unresponsive Micronucleus device detected, please reconnect ...\n");
show_unresponsive_device_message = false;
}
@@ -747,8 +731,7 @@ static int micronucleus_open(PROGRAMMER* pgm, char* port)
continue;
}
avrdude_message(MSG_NOTICE, "%s: Found device with Micronucleus V%d.%d, bus:device: %s:%s\n",
progname,
pmsg_notice("found device with Micronucleus V%d.%d, bus:device: %s:%s\n",
pdata->major_version, pdata->minor_version,
bus->dirname, device->filename);
@@ -763,8 +746,7 @@ static int micronucleus_open(PROGRAMMER* pgm, char* port)
if (pdata->major_version > MICRONUCLEUS_MAX_MAJOR_VERSION)
{
avrdude_message(MSG_INFO, "%s: WARNING: device with unsupported version (V%d.%d) of Micronucleus detected.\n",
progname,
pmsg_warning("device with unsupported Micronucleus version V%d.%d\n",
pdata->major_version, pdata->minor_version);
continue;
}
@@ -772,7 +754,7 @@ static int micronucleus_open(PROGRAMMER* pgm, char* port)
pdata->usb_handle = usb_open(device);
if (pdata->usb_handle == NULL)
{
avrdude_message(MSG_INFO, "%s: ERROR: Failed to open USB device: %s\n", progname, usb_strerror());
pmsg_error("unable to open USB device: %s\n", usb_strerror());
}
}
}
@@ -784,16 +766,15 @@ static int micronucleus_open(PROGRAMMER* pgm, char* port)
{
if (pdata->wait_timout < 0)
{
avrdude_message(MSG_INFO, "%s: No device found, waiting for device to be plugged in...\n", progname);
pmsg_error("no device found, waiting for device to be plugged in ...\n");
}
else
{
avrdude_message(MSG_INFO, "%s: No device found, waiting %d seconds for device to be plugged in...\n",
progname,
pmsg_error("no device found, waiting %d seconds for device to be plugged in ...\n",
pdata->wait_timout);
}
avrdude_message(MSG_INFO, "%s: Press CTRL-C to terminate.\n", progname);
pmsg_error("press CTRL-C to terminate\n");
show_retry_message = false;
}
@@ -809,8 +790,7 @@ static int micronucleus_open(PROGRAMMER* pgm, char* port)
if (!pdata->usb_handle)
{
avrdude_message(MSG_INFO, "%s: ERROR: Could not find device with Micronucleus bootloader (%04X:%04X)\n",
progname, vid, pid);
pmsg_error("cannot find device with Micronucleus bootloader (%04X:%04X)\n", vid, pid);
return -1;
}
@@ -819,7 +799,7 @@ static int micronucleus_open(PROGRAMMER* pgm, char* port)
static void micronucleus_close(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_close()\n", progname);
pmsg_debug("micronucleus_close()\n");
pdata_t* pdata = PDATA(pgm);
if (pdata->usb_handle != NULL)
@@ -829,11 +809,10 @@ static void micronucleus_close(PROGRAMMER* pgm)
}
}
static int micronucleus_read_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
static int micronucleus_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char* value)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_read_byte(desc=%s, addr=0x%0X)\n",
progname, mem->desc, addr);
pmsg_debug("micronucleus_read_byte(desc=%s, addr=0x%04lX)\n", mem->desc, addr);
if (strcmp(mem->desc, "lfuse") == 0 ||
strcmp(mem->desc, "hfuse") == 0 ||
@@ -845,34 +824,31 @@ static int micronucleus_read_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
}
else
{
avrdude_message(MSG_INFO, "%s: Unsupported memory type: %s\n", progname, mem->desc);
pmsg_error("unsupported memory type %s\n", mem->desc);
return -1;
}
}
static int micronucleus_write_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
static int micronucleus_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char value)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_write_byte(desc=%s, addr=0x%0X)\n",
progname, mem->desc, addr);
pmsg_debug("micronucleus_write_byte(desc=%s, addr=0x%04lX)\n", mem->desc, addr);
return -1;
}
static int micronucleus_paged_load(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
static int micronucleus_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_paged_load(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n",
progname, page_size, addr, n_bytes);
pmsg_debug("micronucleus_paged_load(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n", page_size, addr, n_bytes);
return -1;
}
static int micronucleus_paged_write(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
static int micronucleus_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_paged_write(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n",
progname, page_size, addr, n_bytes);
pmsg_debug("micronucleus_paged_write(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n", page_size, addr, n_bytes);
if (strcmp(mem->desc, "flash") == 0)
{
@@ -880,20 +856,20 @@ static int micronucleus_paged_write(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
if (n_bytes > page_size)
{
avrdude_message(MSG_INFO, "%s: Buffer size (%u) exceeds page size (%u)\n", progname, n_bytes, page_size);
pmsg_error("buffer size %u exceeds page size %u\n", n_bytes, page_size);
return -1;
}
if (addr + n_bytes > pdata->flash_size)
{
avrdude_message(MSG_INFO, "%s: Program size (%u) exceeds flash size (%u)\n", progname, addr + n_bytes, pdata->flash_size);
pmsg_error("program size %u exceeds flash size %u\n", addr + n_bytes, pdata->flash_size);
return -1;
}
uint8_t* page_buffer = (uint8_t*)malloc(pdata->page_size);
if (page_buffer == NULL)
{
avrdude_message(MSG_INFO, "%s: Failed to allocate memory\n", progname);
pmsg_error("unable to allocate memory\n");
return -1;
}
@@ -921,14 +897,13 @@ static int micronucleus_paged_write(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
}
else
{
avrdude_message(MSG_INFO, "%s: Unsupported memory type: %s\n", progname, mem->desc);
pmsg_error("unsupported memory type: %s\n", mem->desc);
return -1;
}
}
static int micronucleus_parseextparams(PROGRAMMER* pgm, LISTID xparams)
{
avrdude_message(MSG_DEBUG, "%s: micronucleus_parseextparams()\n", progname);
static int micronucleus_parseextparams(const PROGRAMMER *pgm, const LISTID xparams) {
pmsg_debug("micronucleus_parseextparams()\n");
pdata_t* pdata = PDATA(pgm);
for (LNODEID node = lfirst(xparams); node != NULL; node = lnext(node))
@@ -947,7 +922,7 @@ static int micronucleus_parseextparams(PROGRAMMER* pgm, LISTID xparams)
}
else
{
avrdude_message(MSG_INFO, "%s: Invalid extended parameter '%s'\n", progname, param);
pmsg_error("invalid extended parameter '%s'\n", param);
return -1;
}
}
@@ -955,8 +930,7 @@ static int micronucleus_parseextparams(PROGRAMMER* pgm, LISTID xparams)
return 0;
}
void micronucleus_initpgm(PROGRAMMER* pgm)
{
void micronucleus_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "Micronucleus V2.0");
pgm->setup = micronucleus_setup;
@@ -983,14 +957,12 @@ void micronucleus_initpgm(PROGRAMMER* pgm)
#else /* !HAVE_LIBUSB */
// Give a proper error if we were not compiled with libusb
static int micronucleus_nousb_open(struct programmer_t* pgm, char* name)
{
avrdude_message(MSG_INFO, "%s: error: No usb support. Please compile again with libusb installed.\n", progname);
static int micronucleus_nousb_open(PROGRAMMER* pgm, const char* name) {
pmsg_error("no usb support; please compile again with libusb installed\n");
return -1;
}
void micronucleus_initpgm(PROGRAMMER* pgm)
{
void micronucleus_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "micronucleus");
pgm->open = micronucleus_nousb_open;
}

View File

@@ -26,7 +26,7 @@ extern "C" {
#endif
extern const char micronucleus_desc[];
void micronucleus_initpgm(PROGRAMMER* pgm);
void micronucleus_initpgm(PROGRAMMER *pgm);
#ifdef __cplusplus
}

View File

@@ -28,6 +28,11 @@
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "setupapi.lib")
#define strerror_r(errno,buf,len) strerror_s(buf,len,errno)
#define R_OK 4
#define W_OK 2
#define X_OK 1
#define F_OK 0
#define PATH_MAX _MAX_PATH

View File

@@ -73,8 +73,7 @@ static struct ppipins_t ppipins[] = {
#define NPINS (sizeof(ppipins)/sizeof(struct ppipins_t))
static int par_setpin_internal(PROGRAMMER * pgm, int pin, int value)
{
static int par_setpin_internal(const PROGRAMMER *pgm, int pin, int value) {
int inverted;
inverted = pin & PIN_INVERSE;
@@ -102,13 +101,11 @@ static int par_setpin_internal(PROGRAMMER * pgm, int pin, int value)
return 0;
}
static int par_setpin(PROGRAMMER * pgm, int pinfunc, int value)
{
static int par_setpin(const PROGRAMMER * pgm, int pinfunc, int value) {
return par_setpin_internal(pgm, pgm->pinno[pinfunc], value);
}
static void par_setmany(PROGRAMMER * pgm, int pinfunc, int value)
{
static void par_setmany(const PROGRAMMER *pgm, int pinfunc, int value) {
int pin, mask;
int pinset = pgm->pinno[pinfunc];
@@ -121,8 +118,7 @@ static void par_setmany(PROGRAMMER * pgm, int pinfunc, int value)
}
}
static int par_getpin(PROGRAMMER * pgm, int pinfunc)
{
static int par_getpin(const PROGRAMMER * pgm, int pinfunc) {
int value;
int inverted;
int pin = pgm->pinno[pinfunc];
@@ -150,8 +146,7 @@ static int par_getpin(PROGRAMMER * pgm, int pinfunc)
}
static int par_highpulsepin(PROGRAMMER * pgm, int pinfunc)
{
static int par_highpulsepin(const PROGRAMMER *pgm, int pinfunc) {
int inverted;
int pin = pgm->pinno[pinfunc];
@@ -190,8 +185,7 @@ static int par_highpulsepin(PROGRAMMER * pgm, int pinfunc)
/*
* apply power to the AVR processor
*/
static void par_powerup(PROGRAMMER * pgm)
{
static void par_powerup(const PROGRAMMER *pgm) {
par_setmany(pgm, PPI_AVR_VCC, 1); /* power up */
usleep(100000);
}
@@ -200,18 +194,15 @@ static void par_powerup(PROGRAMMER * pgm)
/*
* remove power from the AVR processor
*/
static void par_powerdown(PROGRAMMER * pgm)
{
static void par_powerdown(const PROGRAMMER *pgm) {
par_setmany(pgm, PPI_AVR_VCC, 0); /* power down */
}
static void par_disable(PROGRAMMER * pgm)
{
static void par_disable(const PROGRAMMER *pgm) {
par_setmany(pgm, PPI_AVR_BUFF, 1); /* turn off */
}
static void par_enable(PROGRAMMER * pgm)
{
static void par_enable(PROGRAMMER *pgm, const AVRPART *p) {
/*
* Prepare to start talking to the connected device - pull reset low
* first, delay a few milliseconds, then enable the buffer. This
@@ -232,8 +223,7 @@ static void par_enable(PROGRAMMER * pgm)
par_setmany(pgm, PPI_AVR_BUFF, 0);
}
static int par_open(PROGRAMMER * pgm, char * port)
{
static int par_open(PROGRAMMER *pgm, const char *port) {
int rc;
if (bitbang_check_prerequisites(pgm) < 0)
@@ -241,8 +231,7 @@ static int par_open(PROGRAMMER * pgm, char * port)
ppi_open(port, &pgm->fd);
if (pgm->fd.ifd < 0) {
avrdude_message(MSG_INFO, "%s: failed to open parallel port \"%s\"\n\n",
progname, port);
pmsg_error("unable to open parallel port %s\n\n", port);
return -1;
}
@@ -251,14 +240,14 @@ static int par_open(PROGRAMMER * pgm, char * port)
*/
rc = ppi_getall(&pgm->fd, PPIDATA);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: error reading status of ppi data port\n", progname);
pmsg_error("unable to read status of ppi data port\n");
return -1;
}
pgm->ppidata = rc;
rc = ppi_getall(&pgm->fd, PPICTRL);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: error reading status of ppi ctrl port\n", progname);
pmsg_error("unable to read status of ppi ctrl port\n");
return -1;
}
pgm->ppictrl = rc;
@@ -267,8 +256,7 @@ static int par_open(PROGRAMMER * pgm, char * port)
}
static void par_close(PROGRAMMER * pgm)
{
static void par_close(PROGRAMMER *pgm) {
/*
* Restore pin values before closing,
@@ -331,40 +319,41 @@ static void par_close(PROGRAMMER * pgm)
/*
* parse the -E string
*/
static int par_parseexitspecs(PROGRAMMER * pgm, char *s)
{
char *cp;
static int par_parseexitspecs(PROGRAMMER *pgm, const char *sp) {
char *cp, *s, *str = cfg_strdup("par_parseexitspecs()", sp);
while ((cp = strtok(s, ","))) {
if (strcmp(cp, "reset") == 0) {
s = str;
while((cp = strtok(s, ","))) {
if(strcmp(cp, "reset") == 0)
pgm->exit_reset = EXIT_RESET_ENABLED;
}
else if (strcmp(cp, "noreset") == 0) {
else if(strcmp(cp, "noreset") == 0)
pgm->exit_reset = EXIT_RESET_DISABLED;
}
else if (strcmp(cp, "vcc") == 0) {
else if(strcmp(cp, "vcc") == 0)
pgm->exit_vcc = EXIT_VCC_ENABLED;
}
else if (strcmp(cp, "novcc") == 0) {
else if(strcmp(cp, "novcc") == 0)
pgm->exit_vcc = EXIT_VCC_DISABLED;
}
else if (strcmp(cp, "d_high") == 0) {
else if(strcmp(cp, "d_high") == 0)
pgm->exit_datahigh = EXIT_DATAHIGH_ENABLED;
}
else if (strcmp(cp, "d_low") == 0) {
else if(strcmp(cp, "d_low") == 0)
pgm->exit_datahigh = EXIT_DATAHIGH_DISABLED;
}
else {
free(str);
return -1;
}
s = 0; /* strtok() should be called with the actual string only once */
s = NULL; // Only call strtok() once with the actual string
}
free(str);
return 0;
}
void par_initpgm(PROGRAMMER * pgm)
{
void par_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "PPI");
pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
@@ -400,10 +389,8 @@ void par_initpgm(PROGRAMMER * pgm)
#else /* !HAVE_PARPORT */
void par_initpgm(PROGRAMMER * pgm)
{
avrdude_message(MSG_INFO, "%s: parallel port access not available in this configuration\n",
progname);
void par_initpgm(PROGRAMMER *pgm) {
pmsg_error("parallel port access not available in this configuration\n");
}
#endif /* HAVE_PARPORT */

View File

@@ -26,7 +26,7 @@ extern "C" {
#endif
extern const char par_desc[];
void par_initpgm (PROGRAMMER * pgm);
void par_initpgm(PROGRAMMER *pgm);
#ifdef __cplusplus
}

289
src/pgm.c
View File

@@ -28,63 +28,67 @@
#include "avrdude.h"
#include "libavrdude.h"
static int pgm_default_2 (struct programmer_t *, AVRPART *);
static int pgm_default_3 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value);
static void pgm_default_4 (struct programmer_t *);
static int pgm_default_5 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data);
static void pgm_default_6 (struct programmer_t *, const char *);
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 (struct programmer_t *pgm, char * name)
{
avrdude_message(MSG_INFO, "\n%s: Fatal error: Programmer does not support open()",
progname);
static int pgm_default_open(PROGRAMMER *pgm, const char *name) {
pmsg_error("programmer does not support open()");
return -1;
}
static int pgm_default_led (struct programmer_t * pgm, int value)
{
/*
* If programmer has no LEDs, just do nothing.
*/
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;
}
static void pgm_default_powerup_powerdown (struct programmer_t * pgm)
{
/*
* If programmer does not support powerup/down, just do nothing.
*/
static void pgm_default_powerup_powerdown(const PROGRAMMER *pgm) {
// If programmer does not support powerup/down, just do nothing
}
PROGRAMMER * pgm_new(void)
{
int i;
PROGRAMMER * pgm;
pgm = (PROGRAMMER *)malloc(sizeof(*pgm));
if (pgm == NULL) {
avrdude_message(MSG_INFO, "%s: out of memory allocating programmer structure\n",
progname);
return NULL;
}
memset(pgm, 0, sizeof(*pgm));
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->desc[0] = 0;
pgm->type[0] = 0;
pgm->config_file[0] = 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;
// 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;
pgm->initpgm = NULL;
for (i=0; i<N_PINS; i++) {
// Clear pin array
for(int i=0; i<N_PINS; i++) {
pgm->pinno[i] = 0;
pin_clear_all(&(pgm->pin[i]));
}
@@ -95,14 +99,14 @@ PROGRAMMER * pgm_new(void)
*/
pgm->initialize = pgm_default_2;
pgm->display = pgm_default_6;
pgm->enable = pgm_default_4;
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;
pgm->close = pgm_default_4;
pgm->close = pgm_default_close;
pgm->read_byte = pgm_default_3;
pgm->write_byte = pgm_default_5;
@@ -115,172 +119,184 @@ PROGRAMMER * pgm_new(void)
pgm->err_led = pgm_default_led;
pgm->pgm_led = pgm_default_led;
pgm->vfy_led = pgm_default_led;
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;
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->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 * const p)
{
ldestroy_cb(p->id, free);
ldestroy_cb(p->usbpid, free);
p->id = NULL;
p->usbpid = NULL;
/* this is done by pgm_teardown, but usually cookie is not set to NULL */
/* if (p->cookie !=NULL) {
free(p->cookie);
p->cookie = NULL;
}*/
free(p);
}
PROGRAMMER * pgm_dup(const PROGRAMMER * const src)
{
PROGRAMMER * pgm;
LNODEID ln;
pgm = (PROGRAMMER *)malloc(sizeof(*pgm));
if (pgm == NULL) {
avrdude_message(MSG_INFO, "%s: out of memory allocating programmer structure\n",
progname);
return NULL;
}
memcpy(pgm, src, sizeof(*pgm));
pgm->id = lcreat(NULL, 0);
pgm->usbpid = lcreat(NULL, 0);
for (ln = lfirst(src->usbpid); ln; ln = lnext(ln)) {
int *ip = malloc(sizeof(int));
if (ip == NULL) {
avrdude_message(MSG_INFO, "%s: out of memory allocating programmer structure\n",
progname);
exit(1);
void pgm_free(PROGRAMMER *p) {
if(p) {
if(p->id) {
ldestroy_cb(p->id, free);
p->id = NULL;
}
*ip = *(int *) ldata(ln);
ladd(pgm->usbpid, ip);
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
// 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);
// 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));
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;
}
static void pgm_default(void)
{
avrdude_message(MSG_INFO, "%s: programmer operation not supported\n", progname);
static void pgm_default(void) {
pmsg_error("programmer operation not supported\n");
}
static int pgm_default_2 (struct programmer_t * pgm, AVRPART * p)
{
static int pgm_default_2 (const PROGRAMMER *pgm, const AVRPART *p) {
pgm_default();
return -1;
}
static int pgm_default_3 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char * value)
{
static int pgm_default_3 (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char * value) {
pgm_default();
return -1;
}
static void pgm_default_4 (struct programmer_t * pgm)
{
static void pgm_default_4 (const PROGRAMMER *pgm) {
pgm_default();
}
static int pgm_default_5 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
unsigned long addr, unsigned char data)
{
static int pgm_default_5 (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char data) {
pgm_default();
return -1;
}
static void pgm_default_6 (struct programmer_t * pgm, const char * p)
{
static void pgm_default_6 (const PROGRAMMER *pgm, const char *p) {
pgm_default();
}
void programmer_display(PROGRAMMER * pgm, const char * p)
{
avrdude_message(MSG_INFO, "%sProgrammer Type : %s\n", p, pgm->type);
avrdude_message(MSG_INFO, "%sDescription : %s\n", p, pgm->desc);
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(PROGRAMMER * pgm, const char * p, unsigned int show)
{
void pgm_display_generic_mask(const PROGRAMMER *pgm, const char *p, unsigned int show) {
if(show & (1<<PPI_AVR_VCC))
avrdude_message(MSG_INFO, "%s VCC = %s\n", p, pins_to_str(&pgm->pin[PPI_AVR_VCC]));
msg_info("%s VCC = %s\n", p, pins_to_str(&pgm->pin[PPI_AVR_VCC]));
if(show & (1<<PPI_AVR_BUFF))
avrdude_message(MSG_INFO, "%s BUFF = %s\n", p, pins_to_str(&pgm->pin[PPI_AVR_BUFF]));
msg_info("%s BUFF = %s\n", p, pins_to_str(&pgm->pin[PPI_AVR_BUFF]));
if(show & (1<<PIN_AVR_RESET))
avrdude_message(MSG_INFO, "%s RESET = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_RESET]));
msg_info("%s RESET = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_RESET]));
if(show & (1<<PIN_AVR_SCK))
avrdude_message(MSG_INFO, "%s SCK = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_SCK]));
msg_info("%s SCK = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_SCK]));
if(show & (1<<PIN_AVR_MOSI))
avrdude_message(MSG_INFO, "%s MOSI = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_MOSI]));
msg_info("%s MOSI = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_MOSI]));
if(show & (1<<PIN_AVR_MISO))
avrdude_message(MSG_INFO, "%s MISO = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_MISO]));
msg_info("%s MISO = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_MISO]));
if(show & (1<<PIN_LED_ERR))
avrdude_message(MSG_INFO, "%s ERR LED = %s\n", p, pins_to_str(&pgm->pin[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))
avrdude_message(MSG_INFO, "%s RDY LED = %s\n", p, pins_to_str(&pgm->pin[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))
avrdude_message(MSG_INFO, "%s PGM LED = %s\n", p, pins_to_str(&pgm->pin[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))
avrdude_message(MSG_INFO, "%s VFY LED = %s\n", p, pins_to_str(&pgm->pin[PIN_LED_VFY]));
msg_info("%s VFY LED = %s\n", p, pins_to_str(&pgm->pin[PIN_LED_VFY]));
}
void pgm_display_generic(PROGRAMMER * pgm, const char * p)
{
void pgm_display_generic(const PROGRAMMER *pgm, const char *p) {
pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS);
}
PROGRAMMER * locate_programmer(LISTID programmers, const char * configid)
{
LNODEID ln1, ln2;
PROGRAMMER * p = NULL;
const char * id;
int found;
PROGRAMMER *locate_programmer(const LISTID programmers, const char *configid) {
PROGRAMMER *p = NULL;
int found = 0;
found = 0;
for (ln1=lfirst(programmers); ln1 && !found; ln1=lnext(ln1)) {
for(LNODEID ln1=lfirst(programmers); ln1 && !found; ln1=lnext(ln1)) {
p = ldata(ln1);
for (ln2=lfirst(p->id); ln2 && !found; ln2=lnext(ln2)) {
id = ldata(ln2);
if (strcasecmp(configid, id) == 0)
for(LNODEID ln2=lfirst(p->id); ln2 && !found; ln2=lnext(ln2))
if(strcasecmp(configid, (const char *) ldata(ln2)) == 0)
found = 1;
}
}
if (found)
return p;
return NULL;
return found? p: NULL;
}
/*
@@ -310,16 +326,11 @@ void walk_programmers(LISTID programmers, walk_programmers_cb cb, void *cookie)
/*
* Compare function to sort the list of programmers
*/
static int sort_programmer_compare(PROGRAMMER * p1,PROGRAMMER * p2)
{
char* id1;
char* id2;
if(p1 == NULL || p2 == NULL) {
static int sort_programmer_compare(const PROGRAMMER *p1, const PROGRAMMER *p2) {
if(p1 == NULL || p1->id == NULL || p2 == NULL || p2->id == NULL)
return 0;
}
id1 = ldata(lfirst(p1->id));
id2 = ldata(lfirst(p2->id));
return strncasecmp(id1,id2,AVR_IDLEN);
return strcasecmp(ldata(lfirst(p1->id)), ldata(lfirst(p2->id)));
}
/*

View File

@@ -57,54 +57,55 @@
#include "xbee.h"
const PROGRAMMER_TYPE programmers_types[] = {
{"arduino", arduino_initpgm, arduino_desc},
{"avr910", avr910_initpgm, avr910_desc},
{"avrftdi", avrftdi_initpgm, avrftdi_desc},
{"buspirate", buspirate_initpgm, buspirate_desc},
{"buspirate_bb", buspirate_bb_initpgm, buspirate_bb_desc},
{"butterfly", butterfly_initpgm, butterfly_desc},
{"butterfly_mk", butterfly_mk_initpgm, butterfly_mk_desc},
{"dragon_dw", jtagmkII_dragon_dw_initpgm, jtagmkII_dragon_dw_desc},
{"dragon_hvsp", stk500v2_dragon_hvsp_initpgm, stk500v2_dragon_hvsp_desc},
{"dragon_isp", stk500v2_dragon_isp_initpgm, stk500v2_dragon_isp_desc},
{"dragon_jtag", jtagmkII_dragon_initpgm, jtagmkII_dragon_desc},
{"dragon_pdi", jtagmkII_dragon_pdi_initpgm, jtagmkII_dragon_pdi_desc},
{"dragon_pp", stk500v2_dragon_pp_initpgm, stk500v2_dragon_pp_desc},
{"flip1", flip1_initpgm, flip1_desc},
{"flip2", flip2_initpgm, flip2_desc},
{"ftdi_syncbb", ft245r_initpgm, ft245r_desc},
{"jtagmki", jtagmkI_initpgm, jtagmkI_desc},
{"jtagmkii", jtagmkII_initpgm, jtagmkII_desc},
{"jtagmkii_avr32", jtagmkII_avr32_initpgm, jtagmkII_avr32_desc},
{"jtagmkii_dw", jtagmkII_dw_initpgm, jtagmkII_dw_desc},
{"jtagmkii_isp", stk500v2_jtagmkII_initpgm, stk500v2_jtagmkII_desc},
{"jtagmkii_pdi", jtagmkII_pdi_initpgm, jtagmkII_pdi_desc},
{"jtagice3", jtag3_initpgm, jtag3_desc},
{"jtagice3_pdi", jtag3_pdi_initpgm, jtag3_pdi_desc},
{"jtagice3_updi", jtag3_updi_initpgm, jtag3_updi_desc},
{"jtagice3_dw", jtag3_dw_initpgm, jtag3_dw_desc},
{"jtagice3_isp", stk500v2_jtag3_initpgm, stk500v2_jtag3_desc},
{"linuxgpio", linuxgpio_initpgm, linuxgpio_desc},
{"linuxspi", linuxspi_initpgm, linuxspi_desc},
{"micronucleus", micronucleus_initpgm, micronucleus_desc},
{"par", par_initpgm, par_desc},
{"pickit2", pickit2_initpgm, pickit2_desc},
{"serbb", serbb_initpgm, serbb_desc},
{"serialupdi", serialupdi_initpgm, serialupdi_desc},
{"stk500", stk500_initpgm, stk500_desc},
{"stk500generic", stk500generic_initpgm, stk500generic_desc},
{"stk500v2", stk500v2_initpgm, stk500v2_desc},
{"stk500hvsp", stk500hvsp_initpgm, stk500hvsp_desc},
{"stk500pp", stk500pp_initpgm, stk500pp_desc},
{"stk600", stk600_initpgm, stk600_desc},
{"stk600hvsp", stk600hvsp_initpgm, stk600hvsp_desc},
{"stk600pp", stk600pp_initpgm, stk600pp_desc},
{"teensy", teensy_initpgm, teensy_desc},
{"usbasp", usbasp_initpgm, usbasp_desc},
{"usbtiny", usbtiny_initpgm, usbtiny_desc},
{"wiring", wiring_initpgm, wiring_desc},
{"xbee", xbee_initpgm, xbee_desc},
const PROGRAMMER_TYPE programmers_types[] = { // Name(s) the programmers call themselves
{"arduino", arduino_initpgm, arduino_desc}, // "Arduino"
{"avr910", avr910_initpgm, avr910_desc}, // "avr910"
{"avrftdi", avrftdi_initpgm, avrftdi_desc}, // "avrftdi"
{"buspirate", buspirate_initpgm, buspirate_desc}, // "BusPirate"
{"buspirate_bb", buspirate_bb_initpgm, buspirate_bb_desc}, // "BusPirate_BB"
{"butterfly", butterfly_initpgm, butterfly_desc}, // "butterfly"
{"butterfly_mk", butterfly_mk_initpgm, butterfly_mk_desc}, // "butterfly_mk"
{"dragon_dw", jtagmkII_dragon_dw_initpgm, jtagmkII_dragon_dw_desc}, // "DRAGON_DW"
{"dragon_hvsp", stk500v2_dragon_hvsp_initpgm, stk500v2_dragon_hvsp_desc}, // "DRAGON_HVSP"
{"dragon_isp", stk500v2_dragon_isp_initpgm, stk500v2_dragon_isp_desc}, // "DRAGON_ISP"
{"dragon_jtag", jtagmkII_dragon_initpgm, jtagmkII_dragon_desc}, // "DRAGON_JTAG"
{"dragon_pdi", jtagmkII_dragon_pdi_initpgm, jtagmkII_dragon_pdi_desc}, // "DRAGON_PDI"
{"dragon_pp", stk500v2_dragon_pp_initpgm, stk500v2_dragon_pp_desc}, // "DRAGON_PP"
{"flip1", flip1_initpgm, flip1_desc}, // "flip1"
{"flip2", flip2_initpgm, flip2_desc}, // "flip2"
{"ftdi_syncbb", ft245r_initpgm, ft245r_desc}, // "ftdi_syncbb"
{"jtagmki", jtagmkI_initpgm, jtagmkI_desc}, // "JTAGMKI"
{"jtagmkii", jtagmkII_initpgm, jtagmkII_desc}, // "JTAGMKII"
{"jtagmkii_avr32", jtagmkII_avr32_initpgm, jtagmkII_avr32_desc}, // "JTAGMKII_AVR32"
{"jtagmkii_dw", jtagmkII_dw_initpgm, jtagmkII_dw_desc}, // "JTAGMKII_DW"
{"jtagmkii_isp", stk500v2_jtagmkII_initpgm, stk500v2_jtagmkII_desc}, // "JTAGMKII_ISP"
{"jtagmkii_pdi", jtagmkII_pdi_initpgm, jtagmkII_pdi_desc}, // "JTAGMKII_PDI"
{"jtagmkii_updi", jtagmkII_updi_initpgm, jtagmkII_updi_desc}, // "JTAGMKII_UPDI"
{"jtagice3", jtag3_initpgm, jtag3_desc}, // "JTAGICE3"
{"jtagice3_pdi", jtag3_pdi_initpgm, jtag3_pdi_desc}, // "JTAGICE3_PDI"
{"jtagice3_updi", jtag3_updi_initpgm, jtag3_updi_desc}, // "JTAGICE3_UPDI"
{"jtagice3_dw", jtag3_dw_initpgm, jtag3_dw_desc}, // "JTAGICE3_DW"
{"jtagice3_isp", stk500v2_jtag3_initpgm, stk500v2_jtag3_desc}, // "JTAG3_ISP"
{"linuxgpio", linuxgpio_initpgm, linuxgpio_desc}, // "linuxgpio"
{"linuxspi", linuxspi_initpgm, linuxspi_desc}, // LINUXSPI
{"micronucleus", micronucleus_initpgm, micronucleus_desc}, // "micronucleus" or "Micronucleus V2.0"
{"par", par_initpgm, par_desc}, // "PPI"
{"pickit2", pickit2_initpgm, pickit2_desc}, // "pickit2"
{"serbb", serbb_initpgm, serbb_desc}, // "SERBB"
{"serialupdi", serialupdi_initpgm, serialupdi_desc}, // "serialupdi"
{"stk500", stk500_initpgm, stk500_desc}, // "STK500"
{"stk500generic", stk500generic_initpgm, stk500generic_desc}, // "STK500GENERIC"
{"stk500v2", stk500v2_initpgm, stk500v2_desc}, // "STK500V2"
{"stk500hvsp", stk500hvsp_initpgm, stk500hvsp_desc}, // "STK500HVSP"
{"stk500pp", stk500pp_initpgm, stk500pp_desc}, // "STK500PP"
{"stk600", stk600_initpgm, stk600_desc}, // "STK600"
{"stk600hvsp", stk600hvsp_initpgm, stk600hvsp_desc}, // "STK600HVSP"
{"stk600pp", stk600pp_initpgm, stk600pp_desc}, // "STK600PP"
{"teensy", teensy_initpgm, teensy_desc}, // "teensy"
{"usbasp", usbasp_initpgm, usbasp_desc}, // "usbasp"
{"usbtiny", usbtiny_initpgm, usbtiny_desc}, // "USBtiny" or "usbtiny"
{"wiring", wiring_initpgm, wiring_desc}, // "Wiring"
{"xbee", xbee_initpgm, xbee_desc}, // "XBee"
};
const PROGRAMMER_TYPE * locate_programmer_type(const char * id)
@@ -127,6 +128,16 @@ const PROGRAMMER_TYPE * locate_programmer_type(const char * id)
return NULL;
}
// Return type id given the init function or "" if not found
const char *locate_programmer_type_id(void (*initpgm)(PROGRAMMER *pgm)) {
for (int i=0; i < sizeof programmers_types/sizeof*programmers_types; i++)
if(programmers_types[i].initpgm == initpgm)
return programmers_types[i].id;
return "";
}
/*
* Iterate over the list of programmers given as "programmers", and
* call the callback function cb for each entry found. cb is being

View File

@@ -72,13 +72,13 @@
#endif
#if 0
#define DEBUG(...) do { avrdude_message(MSG_DEBUG, __VA_ARGS__); } while(0)
#define DEBUG(...) do { msg_debug(__VA_ARGS__); } while(0)
#else
#define DEBUG(...) ((void)0)
#endif
#if 0
#define DEBUGRECV(...) do { avrdude_message(MSG_DEBUG, __VA_ARGS__); } while(0)
#define DEBUGRECV(...) do { msg_debug(__VA_ARGS__); } while(0)
#else
#define DEBUGRECV(...) ((void)0)
#endif
@@ -104,8 +104,8 @@ static int usb_open_device(struct usb_dev_handle **dev, int vid, int pid);
#define USB_ERROR_IO 5
#endif // WIN32
static int pickit2_write_report(PROGRAMMER *pgm, const unsigned char report[65]);
static int pickit2_read_report(PROGRAMMER *pgm, unsigned char report[65]);
static int pickit2_write_report(const PROGRAMMER *pgm, const unsigned char report[65]);
static int pickit2_read_report(const PROGRAMMER *pgm, unsigned char report[65]);
#ifndef MIN
#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
@@ -164,8 +164,7 @@ static void pickit2_setup(PROGRAMMER * pgm)
{
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0)
{
avrdude_message(MSG_INFO, "%s: pickit2_setup(): Out of memory allocating private data\n",
progname);
pmsg_error("out of memory allocating private data\n");
exit(1);
}
memset(pgm->cookie, 0, sizeof(struct pdata));
@@ -179,37 +178,36 @@ static void pickit2_teardown(PROGRAMMER * pgm)
free(pgm->cookie);
}
static int pickit2_open(PROGRAMMER * pgm, char * port)
{
static int pickit2_open(PROGRAMMER *pgm, const char *port) {
#if (defined(WIN32) && defined(HAVE_LIBHID))
PDATA(pgm)->usb_handle = open_hid(PICKIT2_VID, PICKIT2_PID);
if (PDATA(pgm)->usb_handle == INVALID_HANDLE_VALUE)
{
/* no PICkit2 found */
avrdude_message(MSG_INFO, "%s: error: could not find PICkit2 with vid=0x%x pid=0x%x\n",
progname, PICKIT2_VID, PICKIT2_PID);
pmsg_error("cannot find PICkit2 with vid=0x%x pid=0x%x\n", PICKIT2_VID, PICKIT2_PID);
return -1;
}
else
{
// get the device description while we're at it
short buff[PGM_DESCLEN-1], i;
HidD_GetProductString(PDATA(pgm)->usb_handle, buff, PGM_DESCLEN-1);
// Get the device description while we're at it and overlay it on pgm->desc
short wbuf[80-1];
char *cbuf = cfg_malloc("pickit2_open()", sizeof wbuf/sizeof*wbuf + (pgm->desc? strlen(pgm->desc): 0) + 2);
HidD_GetProductString(PDATA(pgm)->usb_handle, wbuf, sizeof wbuf/sizeof*wbuf);
// convert from wide chars, but do not overwrite trailing '\0'
memset(&(pgm->desc), 0, PGM_DESCLEN);
for (i = 0; i < (PGM_DESCLEN-1) && buff[i]; i++)
{
pgm->desc[i] = (char)buff[i]; // TODO what about little/big endian???
}
if(pgm->desc && *pgm->desc)
strcpy(cbuf, pgm->desc);
// Convert from wide chars and overlay over initial part of desc
for (int i = 0; i < sizeof wbuf/sizeof*wbuf && wbuf[i]; i++)
cbuf[i] = (char) wbuf[i]; // TODO what about little/big endian???
pgm->desc = cache_string(cbuf);
}
#else
if (usb_open_device(&(PDATA(pgm)->usb_handle), PICKIT2_VID, PICKIT2_PID) < 0)
{
/* no PICkit2 found */
avrdude_message(MSG_INFO, "%s: error: could not find PICkit2 with vid=0x%x pid=0x%x\n",
progname, PICKIT2_VID, PICKIT2_PID);
pmsg_error("cannot find PICkit2 with vid=0x%x pid=0x%x\n", PICKIT2_VID, PICKIT2_PID);
return -1;
}
#endif
@@ -239,8 +237,7 @@ static void pickit2_close(PROGRAMMER * pgm)
}
static int pickit2_initialize(PROGRAMMER * pgm, AVRPART * p)
{
static int pickit2_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char temp[4];
memset(temp, 0, sizeof(temp));
@@ -258,7 +255,7 @@ static int pickit2_initialize(PROGRAMMER * pgm, AVRPART * p)
//memset(report, 0, sizeof(report));
if ((errorCode = pickit2_read_report(pgm, report)) >= 4)
{
avrdude_message(MSG_NOTICE, "%s: %s firmware version %d.%d.%d\n", progname, pgm->desc, (int)report[1], (int)report[2], (int)report[3]);
pmsg_notice("%s firmware version %d.%d.%d\n", pgm->desc, (int)report[1], (int)report[2], (int)report[3]);
// set the pins, apply reset,
// TO DO: apply vtarget (if requested though -x option)
@@ -293,19 +290,19 @@ static int pickit2_initialize(PROGRAMMER * pgm, AVRPART * p)
if (pickit2_write_report(pgm, report) < 0)
{
avrdude_message(MSG_INFO, "pickit2_read_report failed (ec %d). %s\n", errorCode, usb_strerror());
pmsg_error("pickit2_read_report failed (ec %d). %s\n", errorCode, usb_strerror());
return -1;
}
}
else
{
avrdude_message(MSG_INFO, "pickit2_read_report failed (ec %d). %s\n", errorCode, usb_strerror());
pmsg_error("pickit2_read_report failed (ec %d). %s\n", errorCode, usb_strerror());
return -1;
}
}
else
{
avrdude_message(MSG_INFO, "pickit2_write_report failed (ec %d). %s\n", errorCode, usb_strerror());
pmsg_error("pickit2_write_report failed (ec %d). %s\n", errorCode, usb_strerror());
return -1;
}
@@ -315,8 +312,7 @@ static int pickit2_initialize(PROGRAMMER * pgm, AVRPART * p)
return -1;
}
static void pickit2_disable(PROGRAMMER * pgm)
{
static void pickit2_disable(const PROGRAMMER *pgm) {
/* make sure all pins are floating & all voltages are off */
static const unsigned char report[65] =
{
@@ -337,16 +333,12 @@ static void pickit2_disable(PROGRAMMER * pgm)
return;
}
static void pickit2_enable(PROGRAMMER * pgm)
{
/* Do nothing. */
static void pickit2_enable(PROGRAMMER *pgm, const AVRPART *p) {
return;
}
static void pickit2_display(PROGRAMMER * pgm, const char * p)
{
DEBUG( "%s: Found \"%s\" version %d.%d.%d\n", progname, p, 1, 1, 1);
static void pickit2_display(const PROGRAMMER *pgm, const char *p) {
DEBUG("%s: found %s version %d.%d.%d\n", progname, p, 1, 1, 1);
return;
}
@@ -354,14 +346,12 @@ static void pickit2_display(PROGRAMMER * pgm, const char * p)
#define readReport(x) 0
#if 0
static int pickit2_rdy_led (struct programmer_t * pgm, int value)
{
static int pickit2_rdy_led(const PROGRAMMER *pgm, int value) {
// no rdy led
return 0;
}
static int pickit2_err_led(struct programmer_t * pgm, int value)
{
static int pickit2_err_led(const PROGRAMMER *pgm, int value) {
// there is no error led, so just flash the busy led a few times
uint8_t report[65] =
{
@@ -384,8 +374,7 @@ static int pickit2_err_led(struct programmer_t * pgm, int value)
}
#endif
static int pickit2_pgm_led (struct programmer_t * pgm, int value)
{
static int pickit2_pgm_led(const PROGRAMMER *pgm, int value) {
// script to set busy led appropriately
uint8_t report[65] = {0, CMD_EXEC_SCRIPT_2(1),
value ? SCR_BUSY_LED_ON : SCR_BUSY_LED_OFF,
@@ -395,33 +384,28 @@ static int pickit2_pgm_led (struct programmer_t * pgm, int value)
return pickit2_write_report(pgm, report) != -1;
}
static int pickit2_vfy_led (struct programmer_t * pgm, int value)
{
static int pickit2_vfy_led(const PROGRAMMER *pgm, int value) {
// no such thing - maybe just call pgm_led
return pgm->pgm_led(pgm, value);
}
static void pickit2_powerup(struct programmer_t * pgm)
{
static void pickit2_powerup(const PROGRAMMER *pgm) {
// turn vdd on?
}
static void pickit2_powerdown(struct programmer_t * pgm)
{
static void pickit2_powerdown(const PROGRAMMER *pgm) {
// do what?
pgm->disable(pgm);
}
static int pickit2_program_enable(struct programmer_t * pgm, AVRPART * p)
{
static int pickit2_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char cmd[4];
unsigned char res[4];
if (p->op[AVR_OP_PGM_ENABLE] == NULL)
{
avrdude_message(MSG_INFO, "program enable instruction not defined for part \"%s\"\n",
p->desc);
pmsg_error("program enable instruction not defined for part %s\n", p->desc);
return -1;
}
@@ -431,13 +415,13 @@ static int pickit2_program_enable(struct programmer_t * pgm, AVRPART * p)
{
int i;
avrdude_message(MSG_DEBUG, "program_enable(): sending command. Resp = ");
msg_debug("program_enable(): sending command. Resp = ");
for (i = 0; i < 4; i++)
{
avrdude_message(MSG_DEBUG, "%x ", (int)res[i]);
msg_debug("%x ", (int)res[i]);
}
avrdude_message(MSG_DEBUG, "\n");
msg_debug("\n");
}
// check for sync character
@@ -447,15 +431,13 @@ static int pickit2_program_enable(struct programmer_t * pgm, AVRPART * p)
return 0;
}
static int pickit2_chip_erase(struct programmer_t * pgm, AVRPART * p)
{
static int pickit2_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char cmd[4];
unsigned char res[4];
if (p->op[AVR_OP_CHIP_ERASE] == NULL)
{
avrdude_message(MSG_INFO, "chip erase instruction not defined for part \"%s\"\n",
p->desc);
pmsg_error("chip erase instruction not defined for part %s\n", p->desc);
return -1;
}
@@ -473,9 +455,9 @@ static int pickit2_chip_erase(struct programmer_t * pgm, AVRPART * p)
return 0;
}
static int pickit2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
unsigned int page_size, unsigned int addr, unsigned int n_bytes)
{
static int pickit2_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned int page_size, unsigned int addr, unsigned int n_bytes) {
// only supporting flash & eeprom page reads
if ((!mem->paged || page_size <= 1) || (strcmp(mem->desc, "flash") != 0 && strcmp(mem->desc, "eeprom") != 0))
{
@@ -491,18 +473,15 @@ static int pickit2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
pgm->pgm_led(pgm, ON);
if (lext) {
memset(cmd, 0, sizeof(cmd));
avr_set_bits(lext, cmd);
avr_set_addr(lext, cmd, addr/2);
pgm->cmd(pgm, cmd, res);
}
for (addr_base = addr; addr_base < max_addr; )
{
if ((addr_base == 0 || (addr_base % /*ext_address_boundary*/ 65536) == 0)
&& lext != NULL)
{
memset(cmd, 0, sizeof(cmd));
avr_set_bits(lext, cmd);
avr_set_addr(lext, cmd, addr_base);
pgm->cmd(pgm, cmd, res);
}
// bytes to send in the next packet -- not necessary as pickit2_spi() handles breaking up
// the data into packets -- but we need to keep transfers frequent so that we can update the
// status indicator bar
@@ -531,7 +510,7 @@ static int pickit2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
}
else
{
avrdude_message(MSG_INFO, "no read command specified\n");
pmsg_error("no read command specified\n");
return -1;
}
@@ -543,7 +522,7 @@ static int pickit2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
if (bytes_read < 0)
{
avrdude_message(MSG_INFO, "Failed @ pgm->spi()\n");
pmsg_error("failed @ pgm->spi()\n");
pgm->err_led(pgm, ON);
return -1;
}
@@ -569,7 +548,7 @@ static int pickit2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
}
static int pickit2_commit_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
static int pickit2_commit_page(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr)
{
OPCODE * wp, * lext;
@@ -577,8 +556,7 @@ static int pickit2_commit_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
wp = mem->op[AVR_OP_WRITEPAGE];
if (wp == NULL)
{
avrdude_message(MSG_INFO, "pickit2_commit_page(): memory \"%s\" not configured for page writes\n",
mem->desc);
pmsg_error("memory %s not configured for page writes\n", mem->desc);
return -1;
}
@@ -619,13 +597,13 @@ static int pickit2_commit_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
}
// not actually a paged write, but a bulk/batch write
static int pickit2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
static int pickit2_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned int page_size, unsigned int addr, unsigned int n_bytes)
{
// only paged write for flash implemented
if (strcmp(mem->desc, "flash") != 0 && strcmp(mem->desc, "eeprom") != 0)
{
avrdude_message(MSG_INFO, "Part does not support %d paged write of %s\n", page_size, mem->desc);
pmsg_error("part does not support %d paged write of %s\n", page_size, mem->desc);
return -1;
}
@@ -682,7 +660,7 @@ static int pickit2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
writeop = mem->op[AVR_OP_WRITE_LO];
caddr = addr; // maybe this should divide by 2 & use the write_high opcode also
avrdude_message(MSG_INFO, "Error AVR_OP_WRITE_LO defined only (where's the HIGH command?)\n");
pmsg_error("%s AVR_OP_WRITE_LO defined only (where is the HIGH command?)\n", mem->desc);
return -1;
}
else
@@ -707,7 +685,7 @@ static int pickit2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
if (bytes_read < 0)
{
avrdude_message(MSG_INFO, "Failed @ pgm->spi()\n");
pmsg_error("failed @ pgm->spi()\n");
pgm->err_led(pgm, ON);
return -1;
}
@@ -732,14 +710,14 @@ static int pickit2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
}
static int pickit2_cmd(struct programmer_t * pgm, const unsigned char *cmd,
static int pickit2_cmd(const PROGRAMMER *pgm, const unsigned char *cmd,
unsigned char *res)
{
return pgm->spi(pgm, cmd, res, 4);
}
// breaks up the cmd[] data into packets & sends to the pickit2. Data shifted in is stored in res[].
static int pickit2_spi(struct programmer_t * pgm, const unsigned char *cmd,
static int pickit2_spi(const PROGRAMMER *pgm, const unsigned char *cmd,
unsigned char *res, int n_bytes)
{
int retval = 0, temp1 = 0, temp2 = 0, count = n_bytes;
@@ -1059,8 +1037,7 @@ static HANDLE open_hid(unsigned short vid, unsigned short pid)
}
// simple read with timeout
static int usb_read_interrupt(PROGRAMMER *pgm, void *buff, int size, int timeout)
{
static int usb_read_interrupt(const PROGRAMMER *pgm, void *buff, int size, int timeout) {
OVERLAPPED ovr;
DWORD bytesRead = 0;
@@ -1085,8 +1062,7 @@ static int usb_read_interrupt(PROGRAMMER *pgm, void *buff, int size, int timeout
}
// simple write with timeout
static int usb_write_interrupt(PROGRAMMER *pgm, const void *buff, int size, int timeout)
{
static int usb_write_interrupt(const PROGRAMMER *pgm, const void *buff, int size, int timeout) {
OVERLAPPED ovr;
DWORD bytesWritten = 0;
@@ -1110,13 +1086,11 @@ static int usb_write_interrupt(PROGRAMMER *pgm, const void *buff, int size, int
return bytesWritten > 0 ? bytesWritten : -1;
}
static int pickit2_write_report(PROGRAMMER * pgm, const unsigned char report[65])
{
static int pickit2_write_report(const PROGRAMMER *pgm, const unsigned char report[65]) {
return usb_write_interrupt(pgm, report, 65, PDATA(pgm)->transaction_timeout); // XXX
}
static int pickit2_read_report(PROGRAMMER * pgm, unsigned char report[65])
{
static int pickit2_read_report(const PROGRAMMER *pgm, unsigned char report[65]) {
return usb_read_interrupt(pgm, report, 65, PDATA(pgm)->transaction_timeout);
}
@@ -1149,25 +1123,27 @@ static int usb_open_device(struct usb_dev_handle **device, int vendor, int produ
if (handle == NULL)
{
errorCode = USB_ERROR_ACCESS;
avrdude_message(MSG_INFO, "%s: Warning: cannot open USB device: %s\n", progname, usb_strerror());
pmsg_warning("cannot open USB device: %s\n", usb_strerror());
continue;
}
// return with opened device handle
else
{
avrdude_message(MSG_NOTICE, "Device %p seemed to open OK.\n", handle);
msg_notice("device %p seemed to open OK\n", handle);
if ((errorCode = usb_set_configuration(handle, 1)) < 0)
{
avrdude_message(MSG_INFO, "Could not set configuration. Error code %d, %s.\n"
"You may need to run avrdude as root or set up correct usb port permissions.", errorCode, usb_strerror());
pmsg_ext_error("cannot set configuration, error code %d, %s\n"
"you may need to run avrdude as root or set up correct usb port permissions",
errorCode, usb_strerror());
}
if ((errorCode = usb_claim_interface(handle, 0)) < 0)
{
avrdude_message(MSG_INFO, "Could not claim interface. Error code %d, %s\n"
"You may need to run avrdude as root or set up correct usb port permissions.", errorCode, usb_strerror());
pmsg_ext_error("cannot claim interface, error code %d, %s\n"
"You may need to run avrdude as root or set up correct usb port permissions.",
errorCode, usb_strerror());
}
errorCode = 0;
@@ -1181,21 +1157,18 @@ static int usb_open_device(struct usb_dev_handle **device, int vendor, int produ
return -1;
}
static int pickit2_write_report(PROGRAMMER * pgm, const unsigned char report[65])
{
static int pickit2_write_report(const PROGRAMMER *pgm, const unsigned char report[65]) {
// endpoint 1 OUT??
return usb_interrupt_write(PDATA(pgm)->usb_handle, USB_ENDPOINT_OUT | 1, (char*)(report+1), 64, PDATA(pgm)->transaction_timeout);
}
static int pickit2_read_report(PROGRAMMER * pgm, unsigned char report[65])
{
static int pickit2_read_report(const PROGRAMMER *pgm, unsigned char report[65]) {
// endpoint 1 IN??
return usb_interrupt_read(PDATA(pgm)->usb_handle, USB_ENDPOINT_IN | 1, (char*)(report+1), 64, PDATA(pgm)->transaction_timeout);
}
#endif // WIN32
static int pickit2_parseextparams(struct programmer_t * pgm, LISTID extparms)
{
static int pickit2_parseextparams(const PROGRAMMER *pgm, const LISTID extparms) {
LNODEID ln;
const char *extended_param;
int rv = 0;
@@ -1209,8 +1182,7 @@ static int pickit2_parseextparams(struct programmer_t * pgm, LISTID extparms)
int clock_rate;
if (sscanf(extended_param, "clockrate=%i", &clock_rate) != 1 || clock_rate <= 0)
{
avrdude_message(MSG_INFO, "%s: pickit2_parseextparms(): invalid clockrate '%s'\n",
progname, extended_param);
pmsg_error("invalid clockrate '%s'\n", extended_param);
rv = -1;
continue;
}
@@ -1218,8 +1190,7 @@ static int pickit2_parseextparams(struct programmer_t * pgm, LISTID extparms)
int clock_period = MIN(1000000 / clock_rate, 255); // max period is 255
clock_rate = (int)(1000000 / (clock_period + 5e-7)); // assume highest speed is 2MHz - should probably check this
avrdude_message(MSG_NOTICE2, "%s: pickit2_parseextparms(): clockrate set to 0x%02x\n",
progname, clock_rate);
pmsg_notice2("pickit2_parseextparms(): clockrate set to 0x%02x\n", clock_rate);
PDATA(pgm)->clock_period = clock_period;
continue;
@@ -1230,21 +1201,18 @@ static int pickit2_parseextparams(struct programmer_t * pgm, LISTID extparms)
int timeout;
if (sscanf(extended_param, "timeout=%i", &timeout) != 1 || timeout <= 0)
{
avrdude_message(MSG_INFO, "%s: pickit2_parseextparms(): invalid timeout '%s'\n",
progname, extended_param);
pmsg_error("invalid timeout '%s'\n", extended_param);
rv = -1;
continue;
}
avrdude_message(MSG_NOTICE2, "%s: pickit2_parseextparms(): usb timeout set to 0x%02x\n",
progname, timeout);
pmsg_notice2("pickit2_parseextparms(): usb timeout set to 0x%02x\n", timeout);
PDATA(pgm)->transaction_timeout = timeout;
continue;
}
avrdude_message(MSG_INFO, "%s: pickit2_parseextparms(): invalid extended parameter '%s'\n",
progname, extended_param);
pmsg_error("invalid extended parameter '%s'\n", extended_param);
rv = -1;
}
@@ -1252,8 +1220,7 @@ static int pickit2_parseextparams(struct programmer_t * pgm, LISTID extparms)
}
void pickit2_initpgm (PROGRAMMER * pgm)
{
void pickit2_initpgm(PROGRAMMER *pgm) {
/*
* mandatory functions - these are called without checking to see
* whether they are assigned or not
@@ -1303,25 +1270,24 @@ void pickit2_initpgm (PROGRAMMER * pgm)
pgm->setup = pickit2_setup;
pgm->teardown = pickit2_teardown;
// pgm->page_size = 256; // not sure what this does... maybe the max page size that the page read/write function can handle
// pgm->page_size = 256; // not sure what this does ... maybe the max page size that the page read/write function can handle
strncpy(pgm->type, "pickit2", sizeof(pgm->type));
}
#else
static int pickit2_nousb_open (struct programmer_t *pgm, char * name) {
avrdude_message(MSG_INFO,
static int pickit2_nousb_open(PROGRAMMER *pgm, const char *name) {
pmsg_error(
#ifdef WIN32
"%s: error: no usb or hid support. Please compile again with libusb or HID support from Win32 DDK installed.\n",
"no usb or hid support; please compile again with libusb or HID support from Win32 DDK installed\n"
#else
"%s: error: no usb support. Please compile again with libusb installed.\n",
"no usb support; please compile again with libusb installed\n"
#endif
progname);
);
return -1;
}
void pickit2_initpgm (PROGRAMMER * pgm)
{
void pickit2_initpgm(PROGRAMMER *pgm) {
/*
* mandatory functions - these are called without checking to see
* whether they are assigned or not

View File

@@ -26,7 +26,7 @@ extern "C" {
#endif
extern const char pickit2_desc[];
void pickit2_initpgm (PROGRAMMER * pgm);
void pickit2_initpgm(PROGRAMMER *pgm);
#ifdef __cplusplus
}

View File

@@ -64,7 +64,7 @@ static int pin_fill_old_pinno(const struct pindef_t * const pindef, unsigned int
for(i = 0; i < PIN_MAX; i++) {
if(pindef->mask[i / PIN_FIELD_ELEMENT_SIZE] & (1 << (i % PIN_FIELD_ELEMENT_SIZE))) {
if(found) {
avrdude_message(MSG_INFO, "Multiple pins found\n"); //TODO
pmsg_error("multiple pins found\n"); // TODO
return -1;
}
found = true;
@@ -89,7 +89,7 @@ static int pin_fill_old_pinlist(const struct pindef_t * const pindef, unsigned i
for(i = 0; i < PIN_FIELD_SIZE; i++) {
if(i == 0) {
if((pindef->mask[i] & ~PIN_MASK) != 0) {
avrdude_message(MSG_INFO, "Pins of higher index than max field size for old pinno found\n");
pmsg_error("pins of higher index than max field size for old pinno found\n");
return -1;
}
if (pindef->mask[i] == 0) {
@@ -101,11 +101,11 @@ static int pin_fill_old_pinlist(const struct pindef_t * const pindef, unsigned i
} else if(pindef->mask[i] == ((~pindef->inverse[i]) & pindef->mask[i])) { /* all set bits in mask are cleared in inverse */
*pinno = pindef->mask[i];
} else {
avrdude_message(MSG_INFO, "pins have different polarity set\n");
pmsg_error("pins have different polarity set\n");
return -1;
}
} else if(pindef->mask[i] != 0) {
avrdude_message(MSG_INFO, "Pins have higher number than fit in old format\n");
pmsg_error("pins have higher number than fit in old format\n");
return -1;
}
}
@@ -118,7 +118,7 @@ static int pin_fill_old_pinlist(const struct pindef_t * const pindef, unsigned i
*
* @param[inout] pgm programmer whose pins shall be converted.
*/
int pgm_fill_old_pins(struct programmer_t * const pgm) {
int pgm_fill_old_pins(PROGRAMMER * const pgm) {
if (pin_fill_old_pinlist(&(pgm->pin[PPI_AVR_VCC]), &(pgm->pinno[PPI_AVR_VCC])) < 0)
return -1;
@@ -218,7 +218,7 @@ const char * pinmask_to_str(const pinmask_t * const pinmask) {
* @param[in] size the number of entries in checklist
* @returns 0 if all pin definitions are valid, -1 otherwise
*/
int pins_check(const struct programmer_t * const pgm, const struct pin_checklist_t * const checklist, const int size, const bool output) {
int pins_check(const PROGRAMMER *const pgm, const struct pin_checklist_t *const checklist, const int size, const bool output) {
static const struct pindef_t no_valid_pins = {{0}, {0}}; // default value if check list does not contain anything else
int rv = 0; // return value
int pinname; // loop counter through pinnames
@@ -271,48 +271,46 @@ int pins_check(const struct programmer_t * const pgm, const struct pin_checklist
}
if(invalid) {
if(output) {
avrdude_message(MSG_INFO, "%s: %s: Following pins are not valid pins for this function: %s\n",
progname, avr_pin_name(pinname), pinmask_to_str(invalid_used));
avrdude_message(MSG_NOTICE2, "%s: %s: Valid pins for this function are: %s\n",
progname, avr_pin_name(pinname), pinmask_to_str(valid_pins->mask));
pmsg_error("%s: these pins are not valid pins for this function: %s\n",
avr_pin_name(pinname), pinmask_to_str(invalid_used));
pmsg_notice("%s: valid pins for this function are: %s\n",
avr_pin_name(pinname), pinmask_to_str(valid_pins->mask));
}
is_ok = false;
}
if(inverse) {
if(output) {
avrdude_message(MSG_INFO, "%s: %s: Following pins are not usable as inverse pins for this function: %s\n",
progname, avr_pin_name(pinname), pinmask_to_str(inverse_used));
avrdude_message(MSG_NOTICE2, "%s: %s: Valid inverse pins for this function are: %s\n",
progname, avr_pin_name(pinname), pinmask_to_str(valid_pins->inverse));
pmsg_error("%s: these pins are not usable as inverse pins for this function: %s\n",
avr_pin_name(pinname), pinmask_to_str(inverse_used));
pmsg_notice("%s: valid inverse pins for this function are: %s\n",
avr_pin_name(pinname), pinmask_to_str(valid_pins->inverse));
}
is_ok = false;
}
if(used) {
if(output) {
avrdude_message(MSG_INFO, "%s: %s: Following pins are set for other functions too: %s\n",
progname, avr_pin_name(pinname), pinmask_to_str(already_used));
pmsg_error("%s: these pins are set for other functions too: %s\n",
avr_pin_name(pinname), pinmask_to_str(already_used));
is_ok = false;
}
}
if(!mandatory_used && is_mandatory && !invalid) {
if(output) {
avrdude_message(MSG_INFO, "%s: %s: Mandatory pin is not defined.\n",
progname, avr_pin_name(pinname));
pmsg_error("%s: mandatory pin is not defined\n", avr_pin_name(pinname));
}
is_ok = false;
}
if(!is_ok) {
rv = -1;
} else if(output) {
avrdude_message(MSG_DEBUG, "%s: %s: Pin is ok.\n",
progname, avr_pin_name(pinname));
pmsg_debug("%s: pin is OK\n", avr_pin_name(pinname));
}
}
return rv;
}
/**
* This function returns a string representation of defined pins eg. ~1,2,~4,~5,7
* This function returns a string of defined pins, eg, ~1,2,~4,~5,7 or " (not used)"
* Another execution of this function will overwrite the previous result in the static buffer.
*
* @param[in] pindef the pin definition for which we want the string representation
@@ -346,6 +344,28 @@ const char * pins_to_str(const struct pindef_t * const pindef) {
return buf;
}
/**
* This function returns a string of defined pins, eg, ~1, 2, ~4, ~5, 7 or ""
*
* @param[in] pindef the pin definition for which we want the string representation
* @returns a pointer to a string, which was created by cfg_strdup()
*/
char *pins_to_strdup(const struct pindef_t * const pindef) {
char buf[6*(PIN_MAX+1)], *p = buf;
*buf = 0;
for(int pin = PIN_MIN; pin <= PIN_MAX; pin++) {
int index = pin / PIN_FIELD_ELEMENT_SIZE, bit = pin % PIN_FIELD_ELEMENT_SIZE;
if(pindef->mask[index] & (1 << bit)) {
if(*buf)
*p++ = ',', *p++=' ';
p += sprintf(p, pindef->inverse[index] & (1 << bit)? "~%d": "%d", pin);
}
}
return cfg_strdup("pins_to_strdup()", buf);
}
/**
* Returns the name of the pin as string.
*
@@ -369,3 +389,24 @@ const char * avr_pin_name(int pinname) {
}
/**
* Returns the name of the pin as string.
*
* @param pinname the pinname which we want as string.
* @returns a lowercase string with the pinname, or <unknown> if pinname is invalid.
*/
const char * avr_pin_lcname(int pinname) {
switch(pinname) {
case PPI_AVR_VCC : return "vcc";
case PPI_AVR_BUFF : return "buff";
case PIN_AVR_RESET : return "reset";
case PIN_AVR_SCK : return "sck";
case PIN_AVR_MOSI : return "mosi";
case PIN_AVR_MISO : return "miso";
case PIN_LED_ERR : return "errled";
case PIN_LED_RDY : return "rdyled";
case PIN_LED_PGM : return "pgmled";
case PIN_LED_VFY : return "vfyled";
default : return "<unknown>";
}
}

View File

@@ -51,7 +51,7 @@ enum {
PPI_SHADOWREAD
};
static int ppi_shadow_access(union filedescriptor *fdp, int reg,
static int ppi_shadow_access(const union filedescriptor *fdp, int reg,
unsigned char *v, unsigned char action)
{
static unsigned char shadow[3];
@@ -68,8 +68,7 @@ static int ppi_shadow_access(union filedescriptor *fdp, int reg,
shadow_num = 2;
break;
default:
avrdude_message(MSG_INFO, "%s: avr_set(): invalid register=%d\n",
progname, reg);
pmsg_error("invalid register=%d\n", reg);
return -1;
break;
}
@@ -93,8 +92,7 @@ static int ppi_shadow_access(union filedescriptor *fdp, int reg,
/*
* set the indicated bit of the specified register.
*/
int ppi_set(union filedescriptor *fdp, int reg, int bit)
{
int ppi_set(const union filedescriptor *fdp, int reg, int bit) {
unsigned char v;
int rc;
@@ -112,8 +110,7 @@ int ppi_set(union filedescriptor *fdp, int reg, int bit)
/*
* clear the indicated bit of the specified register.
*/
int ppi_clr(union filedescriptor *fdp, int reg, int bit)
{
int ppi_clr(const union filedescriptor *fdp, int reg, int bit) {
unsigned char v;
int rc;
@@ -131,8 +128,7 @@ int ppi_clr(union filedescriptor *fdp, int reg, int bit)
/*
* get the indicated bit of the specified register.
*/
int ppi_get(union filedescriptor *fdp, int reg, int bit)
{
int ppi_get(const union filedescriptor *fdp, int reg, int bit) {
unsigned char v;
int rc;
@@ -148,8 +144,7 @@ int ppi_get(union filedescriptor *fdp, int reg, int bit)
/*
* toggle the indicated bit of the specified register.
*/
int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
{
int ppi_toggle(const union filedescriptor *fdp, int reg, int bit) {
unsigned char v;
int rc;
@@ -167,8 +162,7 @@ int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
/*
* get all bits of the specified register.
*/
int ppi_getall(union filedescriptor *fdp, int reg)
{
int ppi_getall(const union filedescriptor *fdp, int reg) {
unsigned char v;
int rc;
@@ -183,8 +177,7 @@ int ppi_getall(union filedescriptor *fdp, int reg)
/*
* set all bits of the specified register to val.
*/
int ppi_setall(union filedescriptor *fdp, int reg, int val)
{
int ppi_setall(const union filedescriptor *fdp, int reg, int val) {
unsigned char v;
int rc;
@@ -198,15 +191,13 @@ int ppi_setall(union filedescriptor *fdp, int reg, int val)
}
void ppi_open(char * port, union filedescriptor *fdp)
{
void ppi_open(const char *port, union filedescriptor *fdp) {
int fd;
unsigned char v;
fd = open(port, O_RDWR);
if (fd < 0) {
avrdude_message(MSG_INFO, "%s: can't open device \"%s\": %s\n",
progname, port, strerror(errno));
pmsg_ext_error("cannot open port %s: %s\n", port, strerror(errno));
fdp->ifd = -1;
return;
}
@@ -225,8 +216,7 @@ void ppi_open(char * port, union filedescriptor *fdp)
}
void ppi_close(union filedescriptor *fdp)
{
void ppi_close(const union filedescriptor *fdp) {
ppi_release (fdp->ifd);
close(fdp->ifd);
}

View File

@@ -34,21 +34,21 @@ enum {
extern "C" {
#endif
int ppi_get (union filedescriptor *fdp, int reg, int bit);
int ppi_get (const union filedescriptor *fdp, int reg, int bit);
int ppi_set (union filedescriptor *fdp, int reg, int bit);
int ppi_set (const union filedescriptor *fdp, int reg, int bit);
int ppi_clr (union filedescriptor *fdp, int reg, int bit);
int ppi_clr (const union filedescriptor *fdp, int reg, int bit);
int ppi_getall (union filedescriptor *fdp, int reg);
int ppi_getall (const union filedescriptor *fdp, int reg);
int ppi_setall (union filedescriptor *fdp, int reg, int val);
int ppi_setall (const union filedescriptor *fdp, int reg, int val);
int ppi_toggle (union filedescriptor *fdp, int reg, int bit);
int ppi_toggle (const union filedescriptor *fdp, int reg, int bit);
void ppi_open (char * port, union filedescriptor *fdp);
void ppi_open (const char *port, union filedescriptor *fdp);
void ppi_close (union filedescriptor *fdp);
void ppi_close (const union filedescriptor *fdp);
#ifdef __cplusplus
}

View File

@@ -84,8 +84,7 @@ static void outb(unsigned char value, unsigned short port);
/* FUNCTION DEFINITIONS */
void ppi_open(char *port, union filedescriptor *fdp)
{
void ppi_open(const char *port, union filedescriptor *fdp) {
unsigned char i;
int fd;
@@ -93,7 +92,7 @@ void ppi_open(char *port, union filedescriptor *fdp)
if(fd < 0)
{
avrdude_message(MSG_INFO, "%s: can't open device \"giveio\"\n\n", progname);
pmsg_ext_error("cannot open device \"giveio\"\n\n"); // giveio?!? FIXME!
fdp->ifd = -1;
return;
}
@@ -121,14 +120,13 @@ void ppi_open(char *port, union filedescriptor *fdp)
fd = strtol(port, &cp, 0);
if(*port == '\0' || *cp != '\0')
{
avrdude_message(MSG_INFO, "%s: port name \"%s\" is neither lpt1/2/3 nor valid number\n",
progname, port);
pmsg_error("port %s is neither lpt1/2/3 nor valid number\n", port);
fd = -1;
}
}
if(fd < 0)
{
avrdude_message(MSG_INFO, "%s: can't open device \"%s\"\n\n", progname, port);
pmsg_ext_error("cannot open port %s\n\n", port);
fdp->ifd = -1;
return;
}
@@ -138,8 +136,7 @@ void ppi_open(char *port, union filedescriptor *fdp)
#define DRIVERNAME "\\\\.\\giveio"
static int winnt_pp_open(void)
{
static int winnt_pp_open(void) {
// Only try to use giveio under Windows NT/2000/XP.
OSVERSIONINFO ver_info;
@@ -178,8 +175,7 @@ static int winnt_pp_open(void)
void ppi_close(union filedescriptor *fdp)
{
void ppi_close(const union filedescriptor *fdp) {
return;
}
@@ -188,8 +184,7 @@ void ppi_close(union filedescriptor *fdp)
/*
* set the indicated bit of the specified register.
*/
int ppi_set(union filedescriptor *fdp, int reg, int bit)
{
int ppi_set(const union filedescriptor *fdp, int reg, int bit) {
unsigned char v;
unsigned short port;
@@ -204,8 +199,7 @@ int ppi_set(union filedescriptor *fdp, int reg, int bit)
/*
* clear the indicated bit of the specified register.
*/
int ppi_clr(union filedescriptor *fdp, int reg, int bit)
{
int ppi_clr(const union filedescriptor *fdp, int reg, int bit) {
unsigned char v;
unsigned short port;
@@ -221,8 +215,7 @@ int ppi_clr(union filedescriptor *fdp, int reg, int bit)
/*
* get the indicated bit of the specified register.
*/
int ppi_get(union filedescriptor *fdp, int reg, int bit)
{
int ppi_get(const union filedescriptor *fdp, int reg, int bit) {
unsigned char v;
v = inb(port_get(fdp, reg));
@@ -237,8 +230,7 @@ int ppi_get(union filedescriptor *fdp, int reg, int bit)
/*
* toggle the indicated bit of the specified register.
*/
int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
{
int ppi_toggle(const union filedescriptor *fdp, int reg, int bit) {
unsigned char v;
unsigned short port;
@@ -255,8 +247,7 @@ int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
/*
* get all bits of the specified register.
*/
int ppi_getall(union filedescriptor *fdp, int reg)
{
int ppi_getall(const union filedescriptor *fdp, int reg) {
unsigned char v;
v = inb(port_get(fdp, reg));
@@ -270,8 +261,7 @@ int ppi_getall(union filedescriptor *fdp, int reg)
/*
* set all bits of the specified register to val.
*/
int ppi_setall(union filedescriptor *fdp, int reg, int val)
{
int ppi_setall(const union filedescriptor *fdp, int reg, int val) {
outb((unsigned char)val, port_get(fdp, reg));
return 0;
}
@@ -280,15 +270,13 @@ int ppi_setall(union filedescriptor *fdp, int reg, int val)
/* Calculate port address to access. */
static unsigned short port_get(union filedescriptor *fdp, int reg)
{
static unsigned short port_get(const union filedescriptor *fdp, int reg) {
return((unsigned short)(fdp->ifd + reg2offset(reg)));
}
/* Convert register enum to offset of base address. */
static unsigned char reg2offset(int reg)
{
static unsigned char reg2offset(int reg) {
unsigned char offset = 0;
switch(reg)
@@ -315,8 +303,7 @@ static unsigned char reg2offset(int reg)
/* Read in value from port. */
static unsigned char inb(unsigned short port)
{
static unsigned char inb(unsigned short port) {
unsigned char t;
asm volatile ("in %1, %0"
@@ -328,8 +315,7 @@ static unsigned char inb(unsigned short port)
/* Write value to port. */
static void outb(unsigned char value, unsigned short port)
{
static void outb(unsigned char value, unsigned short port) {
asm volatile ("out %1, %0"
:
: "d" (port), "a" (value) );

View File

@@ -65,16 +65,15 @@ static int avrdoperRxPosition = 0; /* amount of bytes already consu
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
int product, char *productName, int doReportIDs)
static int usbOpenDevice(union filedescriptor *fdp, int vendor, const char *vendorName,
int product, const char *productName, int doReportIDs)
{
hid_device *dev;
dev = hid_open(vendor, product, NULL);
if (dev == NULL)
{
avrdude_message(MSG_INFO, "%s: usbOpenDevice(): No device found\n",
progname);
pmsg_ext_error("no device found\n");
return USB_ERROR_NOTFOUND;
}
fdp->usb.handle = dev;
@@ -96,8 +95,7 @@ static void usbCloseDevice(union filedescriptor *fdp)
/* ------------------------------------------------------------------------- */
static int usbSetReport(union filedescriptor *fdp, int reportType, char *buffer, int len)
{
static int usbSetReport(const union filedescriptor *fdp, int reportType, char *buffer, int len) {
hid_device *udev = (hid_device *)fdp->usb.handle;
int bytesSent = -1;
@@ -114,7 +112,7 @@ static int usbSetReport(union filedescriptor *fdp, int reportType, char *buffer,
if(bytesSent != len){
if(bytesSent < 0)
avrdude_message(MSG_INFO, "Error sending message: %s\n", hid_error(udev));
pmsg_error("unable to send message: %ls\n", hid_error(udev));
return USB_ERROR_IO;
}
return USB_ERROR_NONE;
@@ -122,7 +120,7 @@ static int usbSetReport(union filedescriptor *fdp, int reportType, char *buffer,
/* ------------------------------------------------------------------------- */
static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNumber,
static int usbGetReport(const union filedescriptor *fdp, int reportType, int reportNumber,
char *buffer, int *len)
{
hid_device *udev = (hid_device *)fdp->usb.handle;
@@ -139,7 +137,7 @@ static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNum
break;
}
if(bytesReceived < 0){
avrdude_message(MSG_INFO, "Error sending message: %s\n", hid_error(udev));
pmsg_error("unable to send message: %ls\n", hid_error(udev));
return USB_ERROR_IO;
}
*len = bytesReceived;
@@ -161,42 +159,30 @@ static void dumpBlock(const char *prefix, const unsigned char *buf, int len)
int i;
if(len <= 8){ /* more compact format for short blocks */
avrdude_message(MSG_INFO, "%s: %d bytes: ", prefix, len);
msg_info("%s: %d bytes: ", prefix, len);
for(i = 0; i < len; i++){
avrdude_message(MSG_INFO, "%02x ", buf[i]);
msg_info("%02x ", buf[i]);
}
avrdude_message(MSG_INFO, " \"");
for(i = 0; i < len; i++){
if(buf[i] >= 0x20 && buf[i] < 0x7f){
fputc(buf[i], stderr);
}else{
fputc('.', stderr);
}
}
avrdude_message(MSG_INFO, "\"\n");
msg_info(" \"");
for(i = 0; i < len; i++)
msg_info("%c", buf[i] >= 0x20 && buf[i] < 0x7f? buf[i]: '.');
msg_info("\"\n");
}else{
avrdude_message(MSG_INFO, "%s: %d bytes:\n", prefix, len);
msg_info("%s: %d bytes:\n", prefix, len);
while(len > 0){
for(i = 0; i < 16; i++){
if(i < len){
avrdude_message(MSG_INFO, "%02x ", buf[i]);
msg_info("%02x ", buf[i]);
}else{
avrdude_message(MSG_INFO, " ");
msg_info(" ");
}
if(i == 7)
fputc(' ', stderr);
msg_info(" ");
}
avrdude_message(MSG_INFO, " \"");
for(i = 0; i < 16; i++){
if(i < len){
if(buf[i] >= 0x20 && buf[i] < 0x7f){
fputc(buf[i], stderr);
}else{
fputc('.', stderr);
}
}
}
avrdude_message(MSG_INFO, "\"\n");
msg_info(" \"");
for(i = 0; i < 16 && i < len; i++)
msg_info("%c", buf[i] >= 0x20 && buf[i] < 0x7f? buf[i]: '.');
msg_info("\"\n");
buf += 16;
len -= 16;
}
@@ -208,20 +194,20 @@ static char *usbErrorText(int usbErrno)
static char buffer[32];
switch(usbErrno){
case USB_ERROR_NONE: return "Success.";
case USB_ERROR_ACCESS: return "Access denied.";
case USB_ERROR_NOTFOUND:return "Device not found.";
case USB_ERROR_BUSY: return "Device is busy.";
case USB_ERROR_IO: return "I/O Error.";
case USB_ERROR_NONE: return "Success";
case USB_ERROR_ACCESS: return "Access denied";
case USB_ERROR_NOTFOUND:return "Device not found";
case USB_ERROR_BUSY: return "Device is busy";
case USB_ERROR_IO: return "I/O Error";
default:
sprintf(buffer, "Unknown error %d.", usbErrno);
sprintf(buffer, "Unknown error %d", usbErrno);
return buffer;
}
}
/* ------------------------------------------------------------------------- */
static int avrdoper_open(char *port, union pinfo pinfo, union filedescriptor *fdp)
static int avrdoper_open(const char *port, union pinfo pinfo, union filedescriptor *fdp)
{
int rval;
char *vname = "obdev.at";
@@ -229,7 +215,7 @@ static int avrdoper_open(char *port, union pinfo pinfo, union filedescriptor *fd
rval = usbOpenDevice(fdp, USB_VENDOR_ID, vname, USB_PRODUCT_ID, devname, 1);
if(rval != 0){
avrdude_message(MSG_INFO, "%s: avrdoper_open(): %s\n", progname, usbErrorText(rval));
pmsg_ext_error("%s\n", usbErrorText(rval));
return -1;
}
return 0;
@@ -255,7 +241,7 @@ static int chooseDataSize(int len)
return i - 1;
}
static int avrdoper_send(union filedescriptor *fdp, const unsigned char *buf, size_t buflen)
static int avrdoper_send(const union filedescriptor *fdp, const unsigned char *buf, size_t buflen)
{
if(verbose > 3)
dumpBlock("Send", buf, buflen);
@@ -267,11 +253,11 @@ static int avrdoper_send(union filedescriptor *fdp, const unsigned char *buf, si
buffer[0] = lenIndex + 1; /* report ID */
buffer[1] = thisLen;
memcpy(buffer + 2, buf, thisLen);
avrdude_message(MSG_TRACE, "Sending %d bytes data chunk\n", thisLen);
msg_trace("Sending %d bytes data chunk\n", thisLen);
rval = usbSetReport(fdp, USB_HID_REPORT_TYPE_FEATURE, (char *)buffer,
reportDataSizes[lenIndex] + 2);
if(rval != 0){
avrdude_message(MSG_INFO, "%s: avrdoper_send(): %s\n", progname, usbErrorText(rval));
pmsg_error("%s\n", usbErrorText(rval));
return -1;
}
buflen -= thisLen;
@@ -282,8 +268,7 @@ static int avrdoper_send(union filedescriptor *fdp, const unsigned char *buf, si
/* ------------------------------------------------------------------------- */
static int avrdoperFillBuffer(union filedescriptor *fdp)
{
static int avrdoperFillBuffer(const union filedescriptor *fdp) {
int bytesPending = reportDataSizes[1]; /* guess how much data is buffered in device */
avrdoperRxPosition = avrdoperRxLength = 0;
@@ -297,17 +282,16 @@ static int avrdoperFillBuffer(union filedescriptor *fdp)
usbErr = usbGetReport(fdp, USB_HID_REPORT_TYPE_FEATURE, lenIndex + 1,
(char *)buffer, &len);
if(usbErr != 0){
avrdude_message(MSG_INFO, "%s: avrdoperFillBuffer(): %s\n", progname, usbErrorText(usbErr));
pmsg_error("%s\n", usbErrorText(usbErr));
return -1;
}
avrdude_message(MSG_TRACE, "Received %d bytes data chunk of total %d\n", len - 2, buffer[1]);
msg_trace("Received %d bytes data chunk of total %d\n", len - 2, buffer[1]);
len -= 2; /* compensate for report ID and length byte */
bytesPending = buffer[1] - len; /* amount still buffered */
if(len > buffer[1]) /* cut away padding */
len = buffer[1];
if(avrdoperRxLength + len > sizeof(avrdoperRxBuffer)){
avrdude_message(MSG_INFO, "%s: avrdoperFillBuffer(): internal error: buffer overflow\n",
progname);
pmsg_error("buffer overflow\n");
return -1;
}
memcpy(avrdoperRxBuffer + avrdoperRxLength, buffer + 2, len);
@@ -316,7 +300,7 @@ static int avrdoperFillBuffer(union filedescriptor *fdp)
return 0;
}
static int avrdoper_recv(union filedescriptor *fdp, unsigned char *buf, size_t buflen)
static int avrdoper_recv(const union filedescriptor *fdp, unsigned char *buf, size_t buflen)
{
unsigned char *p = buf;
int remaining = buflen;
@@ -341,7 +325,7 @@ static int avrdoper_recv(union filedescriptor *fdp, unsigned char *buf, size_t b
/* ------------------------------------------------------------------------- */
static int avrdoper_drain(union filedescriptor *fdp, int display)
static int avrdoper_drain(const union filedescriptor *fdp, int display)
{
do{
if (avrdoperFillBuffer(fdp) < 0)
@@ -352,9 +336,9 @@ static int avrdoper_drain(union filedescriptor *fdp, int display)
/* ------------------------------------------------------------------------- */
static int avrdoper_set_dtr_rts(union filedescriptor *fdp, int is_on)
static int avrdoper_set_dtr_rts(const union filedescriptor *fdp, int is_on)
{
avrdude_message(MSG_INFO, "%s: AVR-Doper doesn't support DTR/RTS setting\n", progname);
pmsg_error("AVR-Doper does not support DTR/RTS setting\n");
return -1;
}

View File

@@ -122,8 +122,7 @@ static struct baud_mapping baud_lookup_table [] = {
static struct termios original_termios;
static int saved_original_termios;
static speed_t serial_baud_lookup(long baud, bool *nonstandard)
{
static speed_t serial_baud_lookup(long baud, bool *nonstandard) {
struct baud_mapping *map = baud_lookup_table;
*nonstandard = false;
@@ -138,16 +137,14 @@ static speed_t serial_baud_lookup(long baud, bool *nonstandard)
* If a non-standard BAUD rate is used, issue
* a warning (if we are verbose) and return the raw rate
*/
avrdude_message(MSG_NOTICE, "%s: serial_baud_lookup(): Using non-standard baud rate: %ld\n",
progname, baud);
pmsg_notice("serial_baud_lookup(): using non-standard baud rate: %ld\n", baud);
*nonstandard = true;
return baud;
}
static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cflags)
{
static int ser_setparams(const union filedescriptor *fd, long baud, unsigned long cflags) {
int rc;
struct termios termios;
bool nonstandard;
@@ -161,9 +158,9 @@ static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cfla
*/
rc = tcgetattr(fd->ifd, &termios);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: ser_setparams(): tcgetattr() failed",
progname);
return -errno;
int ret = -errno;
pmsg_ext_error("tcgetattr() failed\n");
return ret;
}
/*
@@ -256,18 +253,18 @@ static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cfla
rc = tcsetattr(fd->ifd, TCSANOW, &termios);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: ser_setparams(): tcsetattr() failed\n",
progname);
return -errno;
int ret = -errno;
pmsg_ext_error("tcsetattr() failed\n");
return ret;
}
#ifdef __APPLE__
// handle nonstandard speed values the MacOS way
if (nonstandard) {
if (ioctl(fd->ifd, IOSSIOSPEED, &speed) < 0) {
avrdude_message(MSG_INFO, "%s: ser_setparams(): ioctrl(IOSSIOSPEED) failed\n",
progname);
return -errno;
int ret = -errno;
pmsg_ext_error("ioctrl(IOSSIOSPEED) failed\n");
return ret;
}
}
#endif // __APPLE__
@@ -283,17 +280,14 @@ static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cfla
* terminal/console server with serial parameters configured
* appropriately (e. g. 115200-8-N-1 for a STK500.)
*/
static int
net_open(const char *port, union filedescriptor *fdp)
{
static int net_open(const char *port, union filedescriptor *fdp) {
char *hp, *hstr, *pstr;
int s, fd, ret = -1;
struct addrinfo hints;
struct addrinfo *result, *rp;
if ((hstr = hp = strdup(port)) == NULL) {
avrdude_message(MSG_INFO, "%s: net_open(): Out of memory!\n",
progname);
pmsg_error("out of memory\n");
return -1;
}
@@ -303,8 +297,7 @@ net_open(const char *port, union filedescriptor *fdp)
* service name from the host or IP address.
*/
if (((pstr = strrchr(hstr, ':')) == NULL) || (pstr == hstr)) {
avrdude_message(MSG_INFO, "%s: net_open(): Mangled host:port string \"%s\"\n",
progname, hstr);
pmsg_error("mangled host:port string %s\n", hstr);
goto error;
}
@@ -327,10 +320,8 @@ net_open(const char *port, union filedescriptor *fdp)
s = getaddrinfo(hstr, pstr, &hints, &result);
if (s != 0) {
avrdude_message(MSG_INFO,
"%s: net_open(): Cannot resolve "
"host=\"%s\", port=\"%s\": %s\n",
progname, hstr, pstr, gai_strerror(s));
pmsg_ext_error("cannot resolve host=\"%s\", port=\"%s\": %s\n",
hstr, pstr, gai_strerror(s));
goto error;
}
for (rp = result; rp != NULL; rp = rp->ai_next) {
@@ -346,8 +337,7 @@ net_open(const char *port, union filedescriptor *fdp)
close(fd);
}
if (rp == NULL) {
avrdude_message(MSG_INFO, "%s: net_open(): Cannot connect: %s\n",
progname, strerror(errno));
pmsg_ext_error("cannot connect: %s\n", strerror(errno));
}
else {
fdp->ifd = fd;
@@ -361,14 +351,13 @@ error:
}
static int ser_set_dtr_rts(union filedescriptor *fdp, int is_on)
{
static int ser_set_dtr_rts(const union filedescriptor *fdp, int is_on) {
unsigned int ctl;
int r;
r = ioctl(fdp->ifd, TIOCMGET, &ctl);
if (r < 0) {
perror("ioctl(\"TIOCMGET\")");
pmsg_ext_error("ioctl(\"TIOCMGET\"): %s\n", strerror(errno));
return -1;
}
@@ -383,15 +372,14 @@ static int ser_set_dtr_rts(union filedescriptor *fdp, int is_on)
r = ioctl(fdp->ifd, TIOCMSET, &ctl);
if (r < 0) {
perror("ioctl(\"TIOCMSET\")");
pmsg_ext_error("ioctl(\"TIOCMSET\"): %s\n", strerror(errno));
return -1;
}
return 0;
}
static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
{
static int ser_open(const char *port, union pinfo pinfo, union filedescriptor *fdp) {
int rc;
int fd;
@@ -408,8 +396,7 @@ static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
*/
fd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd < 0) {
avrdude_message(MSG_INFO, "%s: ser_open(): can't open device \"%s\": %s\n",
progname, port, strerror(errno));
pmsg_ext_error("cannot open port %s: %s\n", port, strerror(errno));
return -1;
}
@@ -420,24 +407,21 @@ static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
*/
rc = ser_setparams(fdp, pinfo.serialinfo.baud, pinfo.serialinfo.cflags);
if (rc) {
avrdude_message(MSG_INFO, "%s: ser_open(): can't set attributes for device \"%s\": %s\n",
progname, port, strerror(-rc));
pmsg_ext_error("cannot set attributes for port %s: %s\n", port, strerror(-rc));
close(fd);
return -1;
}
return 0;
}
static void ser_close(union filedescriptor *fd)
{
static void ser_close(union filedescriptor *fd) {
/*
* restore original termios settings from ser_open
*/
if (saved_original_termios) {
int rc = tcsetattr(fd->ifd, TCSANOW | TCSADRAIN, &original_termios);
if (rc) {
avrdude_message(MSG_INFO, "%s: ser_close(): can't reset attributes for device: %s\n",
progname, strerror(errno));
pmsg_ext_error("cannot reset attributes for device: %s\n", strerror(errno));
}
saved_original_termios = 0;
}
@@ -446,8 +430,7 @@ static void ser_close(union filedescriptor *fd)
}
static int ser_send(union filedescriptor *fd, const unsigned char * buf, size_t buflen)
{
static int ser_send(const union filedescriptor *fd, const unsigned char * buf, size_t buflen) {
int rc;
const unsigned char * p = buf;
size_t len = buflen;
@@ -457,30 +440,29 @@ static int ser_send(union filedescriptor *fd, const unsigned char * buf, size_t
if (verbose > 3)
{
avrdude_message(MSG_TRACE, "%s: Send: ", progname);
pmsg_trace("send: ");
while (buflen) {
unsigned char c = *buf;
if (isprint(c)) {
avrdude_message(MSG_TRACE, "%c ", c);
msg_trace("%c ", c);
}
else {
avrdude_message(MSG_TRACE, ". ");
msg_trace(". ");
}
avrdude_message(MSG_TRACE, "[%02x] ", c);
msg_trace("[%02x] ", c);
buf++;
buflen--;
}
avrdude_message(MSG_TRACE, "\n");
msg_trace("\n");
}
while (len) {
rc = write(fd->ifd, p, (len > 1024) ? 1024 : len);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: ser_send(): write error: %s\n",
progname, strerror(errno));
pmsg_ext_error("unable to write: %s\n", strerror(errno));
return -1;
}
p += rc;
@@ -491,8 +473,7 @@ static int ser_send(union filedescriptor *fd, const unsigned char * buf, size_t
}
static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
{
static int ser_recv(const union filedescriptor *fd, unsigned char * buf, size_t buflen) {
struct timeval timeout, to2;
fd_set rfds;
int nfds;
@@ -511,27 +492,23 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &to2);
if (nfds == 0) {
avrdude_message(MSG_NOTICE2, "%s: ser_recv(): programmer is not responding\n",
progname);
pmsg_notice2("ser_recv(): programmer is not responding\n");
return -1;
}
else if (nfds == -1) {
if (errno == EINTR || errno == EAGAIN) {
avrdude_message(MSG_INFO, "%s: ser_recv(): programmer is not responding,reselecting\n",
progname);
pmsg_warning("programmer is not responding, reselecting\n");
goto reselect;
}
else {
avrdude_message(MSG_INFO, "%s: ser_recv(): select(): %s\n",
progname, strerror(errno));
pmsg_ext_error("select(): %s\n", strerror(errno));
return -1;
}
}
rc = read(fd->ifd, p, (buflen - len > 1024) ? 1024 : buflen - len);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: ser_recv(): read error: %s\n",
progname, strerror(errno));
pmsg_ext_error("unable to read: %s\n", strerror(errno));
return -1;
}
p += rc;
@@ -542,30 +519,29 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
if (verbose > 3)
{
avrdude_message(MSG_TRACE, "%s: Recv: ", progname);
pmsg_trace("recv: ");
while (len) {
unsigned char c = *p;
if (isprint(c)) {
avrdude_message(MSG_TRACE, "%c ", c);
msg_trace("%c ", c);
}
else {
avrdude_message(MSG_TRACE, ". ");
msg_trace(". ");
}
avrdude_message(MSG_TRACE, "[%02x] ", c);
msg_trace("[%02x] ", c);
p++;
len--;
}
avrdude_message(MSG_TRACE, "\n");
msg_trace("\n");
}
return 0;
}
static int ser_drain(union filedescriptor *fd, int display)
{
static int ser_drain(const union filedescriptor *fd, int display) {
struct timeval timeout;
fd_set rfds;
int nfds;
@@ -576,7 +552,7 @@ static int ser_drain(union filedescriptor *fd, int display)
timeout.tv_usec = 250000;
if (display) {
avrdude_message(MSG_INFO, "drain>");
msg_info("drain>");
}
while (1) {
@@ -587,7 +563,7 @@ static int ser_drain(union filedescriptor *fd, int display)
nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &timeout);
if (nfds == 0) {
if (display) {
avrdude_message(MSG_INFO, "<drain\n");
msg_info("<drain\n");
}
break;
@@ -597,20 +573,18 @@ static int ser_drain(union filedescriptor *fd, int display)
goto reselect;
}
else {
avrdude_message(MSG_INFO, "%s: ser_drain(): select(): %s\n",
progname, strerror(errno));
pmsg_ext_error("select(): %s\n", strerror(errno));
return -1;
}
}
rc = read(fd->ifd, &buf, 1);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: ser_drain(): read error: %s\n",
progname, strerror(errno));
pmsg_ext_error("unable to read: %s\n", strerror(errno));
return -1;
}
if (display) {
avrdude_message(MSG_INFO, "%02x ", buf);
msg_info("%02x ", buf);
}
}

View File

@@ -77,8 +77,7 @@ static DWORD serial_baud_lookup(long baud)
* If a non-standard BAUD rate is used, issue
* a warning (if we are verbose) and return the raw rate
*/
avrdude_message(MSG_NOTICE, "%s: serial_baud_lookup(): Using non-standard baud rate: %ld",
progname, baud);
pmsg_notice("serial_baud_lookup(): using non-standard baud rate: %ld", baud);
return baud;
}
@@ -95,8 +94,7 @@ static BOOL serial_w32SetTimeOut(HANDLE hComPort, DWORD timeout) // in ms
return SetCommTimeouts(hComPort, &ctmo);
}
static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cflags)
{
static int ser_setparams(const union filedescriptor *fd, long baud, unsigned long cflags) {
if (serial_over_ethernet) {
return -ENOTTY;
} else {
@@ -150,9 +148,7 @@ static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cfla
}
}
static int
net_open(const char *port, union filedescriptor *fdp)
{
static int net_open(const char *port, union filedescriptor *fdp) {
WSADATA wsaData;
LPVOID lpMsgBuf;
@@ -163,17 +159,17 @@ net_open(const char *port, union filedescriptor *fdp)
struct hostent *hp;
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {
avrdude_message(MSG_INFO, "%s: net_open(): WSAStartup() failed\n", progname);
pmsg_error("WSAStartup() failed\n");
return -1;
}
if ((hstr = strdup(port)) == NULL) {
avrdude_message(MSG_INFO, "%s: net_open(): Out of memory!\n", progname);
pmsg_error("out of memory\n");
return -1;
}
if (((pstr = strchr(hstr, ':')) == NULL) || (pstr == hstr)) {
avrdude_message(MSG_INFO, "%s: net_open(): Mangled host:port string \"%s\"\n", progname, hstr);
pmsg_error("mangled host:port string %s\n", hstr);
free(hstr);
return -1;
}
@@ -186,13 +182,13 @@ net_open(const char *port, union filedescriptor *fdp)
pnum = strtoul(pstr, &end, 10);
if ((*pstr == '\0') || (*end != '\0') || (pnum == 0) || (pnum > 65535)) {
avrdude_message(MSG_INFO, "%s: net_open(): Bad port number \"%s\"\n", progname, pstr);
pmsg_error("bad port number %s\n", pstr);
free(hstr);
return -1;
}
if ((hp = gethostbyname(hstr)) == NULL) {
avrdude_message(MSG_INFO, "%s: net_open(): unknown host \"%s\"\n", progname, hstr);
pmsg_error("unknown host %s\n", hstr);
free(hstr);
return -1;
}
@@ -210,7 +206,7 @@ net_open(const char *port, union filedescriptor *fdp)
(LPTSTR)&lpMsgBuf,
0,
NULL);
avrdude_message(MSG_INFO, "%s: net_open(): Cannot open socket: %s\n", progname, (char *)lpMsgBuf);
pmsg_error("cannot open socket: %s\n", (char *) lpMsgBuf);
LocalFree(lpMsgBuf);
return -1;
}
@@ -231,7 +227,7 @@ net_open(const char *port, union filedescriptor *fdp)
(LPTSTR)&lpMsgBuf,
0,
NULL);
avrdude_message(MSG_INFO, "%s: net_open(): Connect failed: %s\n", progname, (char *)lpMsgBuf);
pmsg_error("connect failed: %s\n", (char *) lpMsgBuf);
LocalFree(lpMsgBuf);
return -1;
}
@@ -243,8 +239,7 @@ net_open(const char *port, union filedescriptor *fdp)
}
static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
{
static int ser_open(const char *port, union pinfo pinfo, union filedescriptor *fdp) {
LPVOID lpMsgBuf;
HANDLE hComPort=INVALID_HANDLE_VALUE;
char *newname = 0;
@@ -263,8 +258,7 @@ static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
newname = malloc(strlen("\\\\.\\") + strlen(port) + 1);
if (newname == 0) {
avrdude_message(MSG_INFO, "%s: ser_open(): out of memory\n",
progname);
pmsg_error("out of memory\n");
exit(1);
}
strcpy(newname, "\\\\.\\");
@@ -287,8 +281,7 @@ static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
(LPTSTR) &lpMsgBuf,
0,
NULL);
avrdude_message(MSG_INFO, "%s: ser_open(): can't open device \"%s\": %s\n",
progname, port, (char*)lpMsgBuf);
pmsg_error("cannot open port %s: %s\n", port, (char*) lpMsgBuf);
LocalFree( lpMsgBuf );
return -1;
}
@@ -296,8 +289,7 @@ static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
if (!SetupComm(hComPort, W32SERBUFSIZE, W32SERBUFSIZE))
{
CloseHandle(hComPort);
avrdude_message(MSG_INFO, "%s: ser_open(): can't set buffers for \"%s\"\n",
progname, port);
pmsg_error("cannot set buffers for %s\n", port);
return -1;
}
@@ -305,16 +297,14 @@ static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
if (ser_setparams(fdp, pinfo.serialinfo.baud, pinfo.serialinfo.cflags) != 0)
{
CloseHandle(hComPort);
avrdude_message(MSG_INFO, "%s: ser_open(): can't set com-state for \"%s\"\n",
progname, port);
pmsg_error("cannot set com-state for %s\n", port);
return -1;
}
if (!serial_w32SetTimeOut(hComPort,0))
{
CloseHandle(hComPort);
avrdude_message(MSG_INFO, "%s: ser_open(): can't set initial timeout for \"%s\"\n",
progname, port);
pmsg_error("cannot set initial timeout for %s\n", port);
return -1;
}
@@ -325,8 +315,7 @@ static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
}
static void ser_close(union filedescriptor *fd)
{
static void ser_close(union filedescriptor *fd) {
if (serial_over_ethernet) {
closesocket(fd->ifd);
WSACleanup();
@@ -339,8 +328,7 @@ static void ser_close(union filedescriptor *fd)
}
}
static int ser_set_dtr_rts(union filedescriptor *fd, int is_on)
{
static int ser_set_dtr_rts(const union filedescriptor *fd, int is_on) {
if (serial_over_ethernet) {
return 0;
} else {
@@ -357,15 +345,14 @@ static int ser_set_dtr_rts(union filedescriptor *fd, int is_on)
}
}
static int net_send(union filedescriptor *fd, const unsigned char * buf, size_t buflen)
{
static int net_send(const union filedescriptor *fd, const unsigned char * buf, size_t buflen) {
LPVOID lpMsgBuf;
int rc;
const unsigned char *p = buf;
size_t len = buflen;
if (fd->ifd < 0) {
avrdude_message(MSG_NOTICE, "%s: net_send(): connection not open\n", progname);
pmsg_notice("net_send(): connection not open\n");
exit(1);
}
@@ -374,26 +361,26 @@ static int net_send(union filedescriptor *fd, const unsigned char * buf, size_t
}
if (verbose > 3) {
avrdude_message(MSG_TRACE, "%s: Send: ", progname);
pmsg_trace("send: ");
while (buflen) {
unsigned char c = *buf;
if (isprint(c)) {
avrdude_message(MSG_TRACE, "%c ", c);
msg_trace("%c ", c);
} else {
avrdude_message(MSG_TRACE, ". ");
msg_trace(". ");
}
avrdude_message(MSG_TRACE, "[%02x] ", c);
msg_trace("[%02x] ", c);
buf++;
buflen--;
}
avrdude_message(MSG_TRACE, "\n");
msg_trace("\n");
}
while (len) {
rc = send(fd->ifd, p, (len > 1024) ? 1024 : len, 0);
rc = send(fd->ifd, (const char *) p, (len > 1024)? 1024: len, 0);
if (rc < 0) {
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
@@ -405,7 +392,7 @@ static int net_send(union filedescriptor *fd, const unsigned char * buf, size_t
(LPTSTR)&lpMsgBuf,
0,
NULL);
avrdude_message(MSG_INFO, "%s: net_send(): send error: %s\n", progname, (char *)lpMsgBuf);
pmsg_error("unable to send: %s\n", (char *) lpMsgBuf);
LocalFree(lpMsgBuf);
exit(1);
}
@@ -417,8 +404,7 @@ static int net_send(union filedescriptor *fd, const unsigned char * buf, size_t
}
static int ser_send(union filedescriptor *fd, const unsigned char * buf, size_t buflen)
{
static int ser_send(const union filedescriptor *fd, const unsigned char * buf, size_t buflen) {
if (serial_over_ethernet) {
return net_send(fd, buf, buflen);
}
@@ -431,8 +417,7 @@ static int ser_send(union filedescriptor *fd, const unsigned char * buf, size_t
HANDLE hComPort=(HANDLE)fd->pfd;
if (hComPort == INVALID_HANDLE_VALUE) {
avrdude_message(MSG_INFO, "%s: ser_send(): port not open\n",
progname);
pmsg_error("port not open\n");
return -1;
}
@@ -441,34 +426,32 @@ static int ser_send(union filedescriptor *fd, const unsigned char * buf, size_t
if (verbose > 3)
{
avrdude_message(MSG_TRACE, "%s: Send: ", progname);
pmsg_trace("send: ");
while (len) {
c = *b;
if (isprint(c)) {
avrdude_message(MSG_TRACE, "%c ", c);
msg_trace("%c ", c);
}
else {
avrdude_message(MSG_TRACE, ". ");
msg_trace(". ");
}
avrdude_message(MSG_TRACE, "[%02x] ", c);
msg_trace("[%02x] ", c);
b++;
len--;
}
avrdude_message(MSG_INFO, "\n");
msg_trace("\n");
}
serial_w32SetTimeOut(hComPort,500);
if (!WriteFile (hComPort, buf, buflen, &written, NULL)) {
avrdude_message(MSG_INFO, "%s: ser_send(): write error: %s\n",
progname, "sorry no info avail"); // TODO
pmsg_error("unable to write: %s\n", "sorry no info avail"); // TODO
return -1;
}
if (written != buflen) {
avrdude_message(MSG_INFO, "%s: ser_send(): size/send mismatch\n",
progname);
pmsg_error("size/send mismatch\n");
return -1;
}
@@ -476,8 +459,7 @@ static int ser_send(union filedescriptor *fd, const unsigned char * buf, size_t
}
static int net_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
{
static int net_recv(const union filedescriptor *fd, unsigned char * buf, size_t buflen) {
LPVOID lpMsgBuf;
struct timeval timeout, to2;
fd_set rfds;
@@ -487,7 +469,7 @@ static int net_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
size_t len = 0;
if (fd->ifd < 0) {
avrdude_message(MSG_INFO, "%s: net_recv(): connection not open\n", progname);
pmsg_error("connection not open\n");
exit(1);
}
@@ -503,12 +485,12 @@ reselect:
nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &to2);
if (nfds == 0) {
if (verbose > 1) {
avrdude_message(MSG_NOTICE, "%s: ser_recv(): programmer is not responding\n", progname);
pmsg_notice("ser_recv(): programmer is not responding\n");
}
return -1;
} else if (nfds == -1) {
if (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEINPROGRESS) {
avrdude_message(MSG_NOTICE, "%s: ser_recv(): programmer is not responding, reselecting\n", progname);
pmsg_notice("ser_recv(): programmer is not responding, reselecting\n");
goto reselect;
} else {
FormatMessage(
@@ -521,13 +503,13 @@ reselect:
(LPTSTR)&lpMsgBuf,
0,
NULL);
avrdude_message(MSG_INFO, "%s: ser_recv(): select(): %s\n", progname, (char *)lpMsgBuf);
pmsg_error("select(): %s\n", (char *) lpMsgBuf);
LocalFree(lpMsgBuf);
exit(1);
}
}
rc = recv(fd->ifd, p, (buflen - len > 1024) ? 1024 : buflen - len, 0);
rc = recv(fd->ifd, (char *) p, (buflen - len > 1024)? 1024: buflen - len, 0);
if (rc < 0) {
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
@@ -539,7 +521,7 @@ reselect:
(LPTSTR)&lpMsgBuf,
0,
NULL);
avrdude_message(MSG_INFO, "%s: ser_recv(): read error: %s\n", progname, (char *)lpMsgBuf);
pmsg_error("unable to read: %s\n", (char *) lpMsgBuf);
LocalFree(lpMsgBuf);
exit(1);
}
@@ -550,28 +532,27 @@ reselect:
p = buf;
if (verbose > 3) {
avrdude_message(MSG_TRACE, "%s: Recv: ", progname);
pmsg_trace("Recv: ");
while (len) {
unsigned char c = *p;
if (isprint(c)) {
avrdude_message(MSG_TRACE, "%c ", c);
msg_trace("%c ", c);
} else {
avrdude_message(MSG_TRACE, ". ");
msg_trace(". ");
}
avrdude_message(MSG_TRACE, "[%02x] ", c);
msg_trace("[%02x] ", c);
p++;
len--;
}
avrdude_message(MSG_TRACE, "\n");
msg_trace("\n");
}
return 0;
}
static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
{
static int ser_recv(const union filedescriptor *fd, unsigned char * buf, size_t buflen) {
if (serial_over_ethernet) {
return net_recv(fd, buf, buflen);
}
@@ -583,8 +564,7 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
HANDLE hComPort=(HANDLE)fd->pfd;
if (hComPort == INVALID_HANDLE_VALUE) {
avrdude_message(MSG_INFO, "%s: ser_read(): port not open\n",
progname);
pmsg_error("port not open\n");
return -1;
}
@@ -602,16 +582,14 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
(LPTSTR) &lpMsgBuf,
0,
NULL );
avrdude_message(MSG_INFO, "%s: ser_recv(): read error: %s\n",
progname, (char*)lpMsgBuf);
pmsg_error("unable to read: %s\n", (char*) lpMsgBuf);
LocalFree( lpMsgBuf );
return -1;
}
/* time out detected */
if (read == 0) {
avrdude_message(MSG_NOTICE2, "%s: ser_recv(): programmer is not responding\n",
progname);
pmsg_notice2("ser_recv(): programmer is not responding\n");
return -1;
}
@@ -619,28 +597,27 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
if (verbose > 3)
{
avrdude_message(MSG_TRACE, "%s: Recv: ", progname);
pmsg_trace("recv: ");
while (read) {
c = *p;
if (isprint(c)) {
avrdude_message(MSG_TRACE, "%c ", c);
msg_trace("%c ", c);
}
else {
avrdude_message(MSG_TRACE, ". ");
msg_trace(". ");
}
avrdude_message(MSG_TRACE, "[%02x] ", c);
msg_trace("[%02x] ", c);
p++;
read--;
}
avrdude_message(MSG_INFO, "\n");
msg_trace("\n");
}
return 0;
}
static int net_drain(union filedescriptor *fd, int display)
{
static int net_drain(const union filedescriptor *fd, int display) {
LPVOID lpMsgBuf;
struct timeval timeout;
fd_set rfds;
@@ -649,12 +626,12 @@ static int net_drain(union filedescriptor *fd, int display)
int rc;
if (fd->ifd < 0) {
avrdude_message(MSG_INFO, "%s: ser_drain(): connection not open\n", progname);
pmsg_error("connection not open\n");
exit(1);
}
if (display) {
avrdude_message(MSG_INFO, "drain>");
msg_info("drain>");
}
timeout.tv_sec = 0;
@@ -668,13 +645,13 @@ static int net_drain(union filedescriptor *fd, int display)
nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &timeout);
if (nfds == 0) {
if (display) {
avrdude_message(MSG_INFO, "<drain\n");
msg_info("<drain\n");
}
break;
}
else if (nfds == -1) {
if (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEINPROGRESS) {
avrdude_message(MSG_NOTICE, "%s: ser_drain(): programmer is not responding, reselecting\n", progname);
pmsg_notice("ser_drain(): programmer is not responding, reselecting\n");
goto reselect;
} else {
FormatMessage(
@@ -687,13 +664,13 @@ static int net_drain(union filedescriptor *fd, int display)
(LPTSTR)&lpMsgBuf,
0,
NULL);
avrdude_message(MSG_INFO, "%s: ser_drain(): select(): %s\n", progname, (char *)lpMsgBuf);
pmsg_error("select(): %s\n", (char *) lpMsgBuf);
LocalFree(lpMsgBuf);
exit(1);
}
}
rc = recv(fd->ifd, &buf, 1, 0);
rc = recv(fd->ifd, (char *) &buf, 1, 0);
if (rc < 0) {
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
@@ -705,21 +682,20 @@ static int net_drain(union filedescriptor *fd, int display)
(LPTSTR)&lpMsgBuf,
0,
NULL);
avrdude_message(MSG_INFO, "%s: ser_drain(): read error: %s\n", progname, (char *)lpMsgBuf);
pmsg_error("unable to read: %s\n", (char *) lpMsgBuf);
LocalFree(lpMsgBuf);
exit(1);
}
if (display) {
avrdude_message(MSG_INFO, "%02x ", buf);
msg_info("%02x ", buf);
}
}
return 0;
}
static int ser_drain(union filedescriptor *fd, int display)
{
static int ser_drain(const union filedescriptor *fd, int display) {
if (serial_over_ethernet) {
return net_drain(fd, display);
}
@@ -732,15 +708,14 @@ static int ser_drain(union filedescriptor *fd, int display)
HANDLE hComPort=(HANDLE)fd->pfd;
if (hComPort == INVALID_HANDLE_VALUE) {
avrdude_message(MSG_INFO, "%s: ser_drain(): port not open\n",
progname);
pmsg_error("port not open\n");
return -1;
}
serial_w32SetTimeOut(hComPort,250);
if (display) {
avrdude_message(MSG_INFO, "drain>");
msg_info("drain>");
}
while (1) {
@@ -757,17 +732,18 @@ static int ser_drain(union filedescriptor *fd, int display)
(LPTSTR) &lpMsgBuf,
0,
NULL );
avrdude_message(MSG_INFO, "%s: ser_drain(): read error: %s\n",
progname, (char*)lpMsgBuf);
pmsg_error("unable to read: %s\n", (char*) lpMsgBuf);
LocalFree( lpMsgBuf );
return -1;
}
if (read) { // data avail
if (display) avrdude_message(MSG_INFO, "%02x ", buf[0]);
if (display)
msg_info("%02x ", buf[0]);
}
else { // no more data
if (display) avrdude_message(MSG_INFO, "<drain\n");
if (display)
msg_info("<drain\n");
break;
}
} // while

View File

@@ -26,7 +26,7 @@ extern "C" {
#endif
extern const char serbb_desc[];
void serbb_initpgm (PROGRAMMER * pgm);
void serbb_initpgm(PROGRAMMER *pgm);
#ifdef __cplusplus
}

View File

@@ -70,8 +70,7 @@ static char *serpins[DB9PINS + 1] =
{ "NONE", "CD", "RXD", "TXD", "DTR", "GND", "DSR", "RTS", "CTS", "RI" };
#endif
static int serbb_setpin(PROGRAMMER * pgm, int pinfunc, int value)
{
static int serbb_setpin(const PROGRAMMER *pgm, int pinfunc, int value) {
unsigned int ctl;
int r;
int pin = pgm->pinno[pinfunc]; // get its value
@@ -86,39 +85,39 @@ static int serbb_setpin(PROGRAMMER * pgm, int pinfunc, int value)
return -1;
#ifdef DEBUG
printf("%s to %d\n",serpins[pin],value);
msg_info("%s to %d\n", serpins[pin], value);
#endif
switch ( pin )
{
case 3: /* txd */
r = ioctl(pgm->fd.ifd, value ? TIOCSBRK : TIOCCBRK, 0);
if (r < 0) {
perror("ioctl(\"TIOCxBRK\")");
return -1;
}
break;
r = ioctl(pgm->fd.ifd, value ? TIOCSBRK : TIOCCBRK, 0);
if (r < 0) {
pmsg_ext_error("ioctl(\"TIOCxBRK\"): %s\n", strerror(errno));
return -1;
}
break;
case 4: /* dtr */
case 7: /* rts */
r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl);
if (r < 0) {
perror("ioctl(\"TIOCMGET\")");
return -1;
}
if ( value )
ctl |= serregbits[pin];
else
ctl &= ~(serregbits[pin]);
r = ioctl(pgm->fd.ifd, TIOCMSET, &ctl);
if (r < 0) {
perror("ioctl(\"TIOCMSET\")");
return -1;
}
break;
r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl);
if (r < 0) {
pmsg_ext_error("ioctl(\"TIOCMGET\"): %s\n", strerror(errno));
return -1;
}
if (value)
ctl |= serregbits[pin];
else
ctl &= ~(serregbits[pin]);
r = ioctl(pgm->fd.ifd, TIOCMSET, &ctl);
if (r < 0) {
pmsg_ext_error("ioctl(\"TIOCMSET\"): %s\n", strerror(errno));
return -1;
}
break;
default: /* impossible */
return -1;
return -1;
}
if (pgm->ispdelay > 1)
@@ -127,8 +126,7 @@ static int serbb_setpin(PROGRAMMER * pgm, int pinfunc, int value)
return 0;
}
static int serbb_getpin(PROGRAMMER * pgm, int pinfunc)
{
static int serbb_getpin(const PROGRAMMER *pgm, int pinfunc) {
unsigned int ctl;
unsigned char invert;
int r;
@@ -147,39 +145,38 @@ static int serbb_getpin(PROGRAMMER * pgm, int pinfunc)
switch ( pin )
{
case 2: /* rxd, currently not implemented, FIXME */
return(-1);
return(-1);
case 1: /* cd */
case 6: /* dsr */
case 8: /* cts */
case 9: /* ri */
r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl);
if (r < 0) {
perror("ioctl(\"TIOCMGET\")");
return -1;
}
if ( !invert )
{
r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl);
if (r < 0) {
pmsg_ext_error("ioctl(\"TIOCMGET\"): %s\n", strerror(errno));
return -1;
}
if ( !invert )
{
#ifdef DEBUG
printf("%s is %d\n",serpins[pin],(ctl & serregbits[pin]) ? 1 : 0 );
msg_info("%s is %d\n", serpins[pin], ctl & serregbits[pin]? 1: 0);
#endif
return ( (ctl & serregbits[pin]) ? 1 : 0 );
}
else
{
return ctl & serregbits[pin]? 1: 0;
}
else
{
#ifdef DEBUG
printf("%s is %d (~)\n",serpins[pin],(ctl & serregbits[pin]) ? 0 : 1 );
msg_info("%s is %d (~)\n", serpins[pin], ctl & serregbits[pin]? 0: 1);
#endif
return (( ctl & serregbits[pin]) ? 0 : 1 );
}
return ctl & serregbits[pin]? 0: 1;
}
default: /* impossible */
return(-1);
return(-1);
}
}
static int serbb_highpulsepin(PROGRAMMER * pgm, int pinfunc)
{
static int serbb_highpulsepin(const PROGRAMMER *pgm, int pinfunc) {
int pin = pgm->pinno[pinfunc]; // replace pin name by its value
if ( (pin & PIN_MASK) < 1 || (pin & PIN_MASK) > DB9PINS )
@@ -193,33 +190,27 @@ static int serbb_highpulsepin(PROGRAMMER * pgm, int pinfunc)
static void serbb_display(PROGRAMMER *pgm, const char *p)
{
static void serbb_display(const PROGRAMMER *pgm, const char *p) {
/* MAYBE */
}
static void serbb_enable(PROGRAMMER *pgm)
{
static void serbb_enable(PROGRAMMER *pgm, const AVRPART *p) {
/* nothing */
}
static void serbb_disable(PROGRAMMER *pgm)
{
static void serbb_disable(const PROGRAMMER *pgm) {
/* nothing */
}
static void serbb_powerup(PROGRAMMER *pgm)
{
static void serbb_powerup(const PROGRAMMER *pgm) {
/* nothing */
}
static void serbb_powerdown(PROGRAMMER *pgm)
{
static void serbb_powerdown(const PROGRAMMER *pgm) {
/* nothing */
}
static int serbb_open(PROGRAMMER *pgm, char *port)
{
static int serbb_open(PROGRAMMER *pgm, const char *port) {
struct termios mode;
int flags;
int r;
@@ -232,14 +223,13 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
pgm->fd.ifd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (pgm->fd.ifd < 0) {
perror(port);
pmsg_ext_error("%s: %s\n", port, strerror(errno));
return(-1);
}
r = tcgetattr(pgm->fd.ifd, &mode);
if (r < 0) {
avrdude_message(MSG_INFO, "%s: ", port);
perror("tcgetattr");
pmsg_ext_error("%s, tcgetattr(): %s\n", port, strerror(errno));
return(-1);
}
oldmode = mode;
@@ -252,8 +242,7 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
r = tcsetattr(pgm->fd.ifd, TCSANOW, &mode);
if (r < 0) {
avrdude_message(MSG_INFO, "%s: ", port);
perror("tcsetattr");
pmsg_ext_error("%s, tcsetattr(): %s", port, strerror(errno));
return(-1);
}
@@ -261,23 +250,20 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
flags = fcntl(pgm->fd.ifd, F_GETFL, 0);
if (flags == -1)
{
avrdude_message(MSG_INFO, "%s: Can not get flags: %s\n",
progname, strerror(errno));
pmsg_ext_error("cannot get flags: %s\n", strerror(errno));
return(-1);
}
flags &= ~O_NONBLOCK;
if (fcntl(pgm->fd.ifd, F_SETFL, flags) == -1)
{
avrdude_message(MSG_INFO, "%s: Can not clear nonblock flag: %s\n",
progname, strerror(errno));
pmsg_ext_error("cannot clear nonblock flag: %s\n", strerror(errno));
return(-1);
}
return(0);
}
static void serbb_close(PROGRAMMER *pgm)
{
static void serbb_close(PROGRAMMER *pgm) {
if (pgm->fd.ifd != -1)
{
(void)tcsetattr(pgm->fd.ifd, TCSANOW, &oldmode);
@@ -289,8 +275,7 @@ static void serbb_close(PROGRAMMER *pgm)
const char serbb_desc[] = "Serial port bitbanging";
void serbb_initpgm(PROGRAMMER *pgm)
{
void serbb_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "SERBB");
pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed

View File

@@ -61,8 +61,7 @@ static int dtr, rts, txd;
#define DB9PINS 9
static int serbb_setpin(PROGRAMMER * pgm, int pinfunc, int value)
{
static int serbb_setpin(const PROGRAMMER *pgm, int pinfunc, int value) {
int pin = pgm->pinno[pinfunc];
HANDLE hComPort = (HANDLE)pgm->fd.pfd;
LPVOID lpMsgBuf;
@@ -98,12 +97,10 @@ static int serbb_setpin(PROGRAMMER * pgm, int pinfunc, int value)
break;
default:
avrdude_message(MSG_NOTICE, "%s: serbb_setpin(): unknown pin %d\n",
progname, pin + 1);
pmsg_notice("serbb_setpin(): unknown pin %d\n", pin + 1);
return -1;
}
avrdude_message(MSG_TRACE2, "%s: serbb_setpin(): EscapeCommFunction(%s)\n",
progname, name);
pmsg_trace2("serbb_setpin(): EscapeCommFunction(%s)\n", name);
if (!EscapeCommFunction(hComPort, dwFunc))
{
FormatMessage(
@@ -116,8 +113,7 @@ static int serbb_setpin(PROGRAMMER * pgm, int pinfunc, int value)
(LPTSTR) &lpMsgBuf,
0,
NULL);
avrdude_message(MSG_INFO, "%s: serbb_setpin(): SetCommState() failed: %s\n",
progname, (char *)lpMsgBuf);
pmsg_error("SetCommState() failed: %s\n", (char *) lpMsgBuf);
CloseHandle(hComPort);
LocalFree(lpMsgBuf);
return -1;
@@ -129,8 +125,7 @@ static int serbb_setpin(PROGRAMMER * pgm, int pinfunc, int value)
return 0;
}
static int serbb_getpin(PROGRAMMER * pgm, int pinfunc)
{
static int serbb_getpin(const PROGRAMMER *pgm, int pinfunc) {
int pin = pgm->pinno[pinfunc];
HANDLE hComPort = (HANDLE)pgm->fd.pfd;
LPVOID lpMsgBuf;
@@ -162,14 +157,12 @@ static int serbb_getpin(PROGRAMMER * pgm, int pinfunc)
(LPTSTR) &lpMsgBuf,
0,
NULL);
avrdude_message(MSG_INFO, "%s: serbb_setpin(): GetCommModemStatus() failed: %s\n",
progname, (char *)lpMsgBuf);
pmsg_error("GetCommModemStatus() failed: %s\n", (char *) lpMsgBuf);
CloseHandle(hComPort);
LocalFree(lpMsgBuf);
return -1;
}
avrdude_message(MSG_TRACE2, "%s: serbb_getpin(): GetCommState() => 0x%lx\n",
progname, modemstate);
pmsg_trace2("serbb_getpin(): GetCommState() => 0x%lx\n", modemstate);
switch (pin)
{
case 1:
@@ -204,20 +197,17 @@ static int serbb_getpin(PROGRAMMER * pgm, int pinfunc)
name = "RTS";
break;
default:
avrdude_message(MSG_NOTICE, "%s: serbb_getpin(): unknown pin %d\n",
progname, pin + 1);
pmsg_notice("serbb_getpin(): unknown pin %d\n", pin + 1);
return -1;
}
avrdude_message(MSG_TRACE2, "%s: serbb_getpin(): return cached state for %s\n",
progname, name);
pmsg_trace2("serbb_getpin(): return cached state for %s\n", name);
if (invert)
rv = !rv;
return rv;
}
static int serbb_highpulsepin(PROGRAMMER * pgm, int pinfunc)
{
static int serbb_highpulsepin(const PROGRAMMER *pgm, int pinfunc) {
int pin = pgm->pinno[pinfunc];
if ( (pin & PIN_MASK) < 1 || (pin & PIN_MASK) > DB9PINS )
return -1;
@@ -229,33 +219,27 @@ static int serbb_highpulsepin(PROGRAMMER * pgm, int pinfunc)
}
static void serbb_display(PROGRAMMER *pgm, const char *p)
{
static void serbb_display(const PROGRAMMER *pgm, const char *p) {
/* MAYBE */
}
static void serbb_enable(PROGRAMMER *pgm)
{
static void serbb_enable(PROGRAMMER *pgm, const AVRPART *p) {
/* nothing */
}
static void serbb_disable(PROGRAMMER *pgm)
{
static void serbb_disable(const PROGRAMMER *pgm) {
/* nothing */
}
static void serbb_powerup(PROGRAMMER *pgm)
{
static void serbb_powerup(const PROGRAMMER *pgm) {
/* nothing */
}
static void serbb_powerdown(PROGRAMMER *pgm)
{
static void serbb_powerdown(const PROGRAMMER *pgm) {
/* nothing */
}
static int serbb_open(PROGRAMMER *pgm, char *port)
{
static int serbb_open(PROGRAMMER *pgm, const char *port) {
DCB dcb;
LPVOID lpMsgBuf;
HANDLE hComPort = INVALID_HANDLE_VALUE;
@@ -277,8 +261,7 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
(LPTSTR) &lpMsgBuf,
0,
NULL);
avrdude_message(MSG_INFO, "%s: ser_open(): can't open device \"%s\": %s\n",
progname, port, (char*)lpMsgBuf);
pmsg_error("cannot open port %s: %s\n", port, (char*) lpMsgBuf);
LocalFree(lpMsgBuf);
return -1;
}
@@ -286,8 +269,7 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
if (!SetupComm(hComPort, W32SERBUFSIZE, W32SERBUFSIZE))
{
CloseHandle(hComPort);
avrdude_message(MSG_INFO, "%s: ser_open(): can't set buffers for \"%s\"\n",
progname, port);
pmsg_error("cannot set buffers for %s\n", port);
return -1;
}
@@ -305,12 +287,10 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
if (!SetCommState(hComPort, &dcb))
{
CloseHandle(hComPort);
avrdude_message(MSG_INFO, "%s: ser_open(): can't set com-state for \"%s\"\n",
progname, port);
pmsg_error("cannot set com-state for %s\n", port);
return -1;
}
avrdude_message(MSG_DEBUG, "%s: ser_open(): opened comm port \"%s\", handle 0x%zx\n",
progname, port, (INT_PTR)hComPort);
pmsg_debug("ser_open(): opened comm port %s, handle 0x%zx\n", port, (INT_PTR) hComPort);
pgm->fd.pfd = (void *)hComPort;
@@ -319,24 +299,21 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
return 0;
}
static void serbb_close(PROGRAMMER *pgm)
{
static void serbb_close(PROGRAMMER *pgm) {
HANDLE hComPort=(HANDLE)pgm->fd.pfd;
if (hComPort != INVALID_HANDLE_VALUE)
{
pgm->setpin(pgm, PIN_AVR_RESET, 1);
CloseHandle (hComPort);
}
avrdude_message(MSG_DEBUG, "%s: ser_close(): closed comm port handle 0x%zx\n",
progname, (INT_PTR)hComPort);
pmsg_debug("ser_close(): closed comm port handle 0x%zx\n", (INT_PTR) hComPort);
hComPort = INVALID_HANDLE_VALUE;
}
const char serbb_desc[] = "Serial port bitbanging";
void serbb_initpgm(PROGRAMMER *pgm)
{
void serbb_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "SERBB");
pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed

View File

@@ -43,15 +43,13 @@
#include "updi_nvm.h"
#include "updi_constants.h"
static int serialupdi_enter_progmode(PROGRAMMER * pgm);
static int serialupdi_leave_progmode(PROGRAMMER * pgm);
static int serialupdi_enter_progmode(const PROGRAMMER *pgm);
static int serialupdi_leave_progmode(const PROGRAMMER *pgm);
static void serialupdi_setup(PROGRAMMER * pgm)
{
if ((pgm->cookie = malloc(sizeof(updi_state))) == 0) {
avrdude_message(MSG_INFO,
"%s: serialupdi_setup(): Out of memory allocating private data\n",
progname);
pmsg_error("out of memory allocating private data\n");
exit(1);
}
memset(pgm->cookie, 0, sizeof(updi_state));
@@ -64,8 +62,7 @@ static void serialupdi_teardown(PROGRAMMER * pgm)
free(pgm->cookie);
}
static int serialupdi_open(PROGRAMMER * pgm, char * port)
{
static int serialupdi_open(PROGRAMMER *pgm, const char *port) {
strcpy(pgm->port, port);
return updi_link_open(pgm);
}
@@ -75,8 +72,7 @@ typedef enum {
RELEASE_RESET
} reset_mode;
static int serialupdi_reset(PROGRAMMER * pgm, reset_mode mode)
{
static int serialupdi_reset(const PROGRAMMER *pgm, reset_mode mode) {
/*
def reset(self, apply_reset):
"""
@@ -93,36 +89,34 @@ static int serialupdi_reset(PROGRAMMER * pgm, reset_mode mode)
*/
switch (mode) {
case APPLY_RESET:
avrdude_message(MSG_DEBUG, "%s: Sending reset request\n", progname);
pmsg_debug("sending reset request\n");
return updi_write_cs(pgm, UPDI_ASI_RESET_REQ, UPDI_RESET_REQ_VALUE);
case RELEASE_RESET:
avrdude_message(MSG_DEBUG, "%s: Sending release reset request\n", progname);
pmsg_debug("sending release reset request\n");
return updi_write_cs(pgm, UPDI_ASI_RESET_REQ, 0x00);
}
return -1;
}
static int serialupdi_reset_connection(PROGRAMMER * pgm)
{
static int serialupdi_reset_connection(const PROGRAMMER *pgm) {
if (serialupdi_reset(pgm, APPLY_RESET) < 0) {
avrdude_message(MSG_INFO, "%s: Apply reset operation failed\n", progname);
pmsg_error("apply reset operation failed\n");
return -1;
}
if (serialupdi_reset(pgm, RELEASE_RESET) < 0) {
avrdude_message(MSG_INFO, "%s: Release reset operation failed\n", progname);
pmsg_error("release reset operation failed\n");
return -1;
}
return updi_link_init(pgm);
}
static int serialupdi_decode_sib(PROGRAMMER * pgm, updi_sib_info * sib_info)
{
static int serialupdi_decode_sib(const PROGRAMMER *pgm, updi_sib_info *sib_info) {
char * str_ptr;
sib_info->sib_string[SIB_INFO_STRING_LENGTH]=0;
avrdude_message(MSG_DEBUG, "%s: Received SIB: [%s]\n", progname, sib_info->sib_string);
pmsg_debug("received SIB: [%s]\n", sib_info->sib_string);
memset(sib_info->family_string, 0, SIB_INFO_FAMILY_LENGTH+1);
memset(sib_info->nvm_string, 0, SIB_INFO_NVM_LENGTH+1);
memset(sib_info->debug_string, 0, SIB_INFO_DEBUG_LENGTH+1);
@@ -138,41 +132,41 @@ static int serialupdi_decode_sib(PROGRAMMER * pgm, updi_sib_info * sib_info)
str_ptr = strstr(sib_info->nvm_string, ":");
if (!str_ptr) {
avrdude_message(MSG_INFO, "%s: Incorrect format of NVM string\n", progname);
pmsg_error("incorrect format of NVM string\n");
return -1;
}
sib_info->nvm_version = *(str_ptr+1);
str_ptr = strstr(sib_info->debug_string, ":");
if (!str_ptr) {
avrdude_message(MSG_INFO, "%s: Incorrect format of DEBUG string\n", progname);
pmsg_error("incorrect format of DEBUG string\n");
return -1;
}
sib_info->debug_version = *(str_ptr+1);
avrdude_message(MSG_DEBUG, "%s: Device family ID: %s\n", progname, sib_info->family_string);
avrdude_message(MSG_DEBUG, "%s: NVM interface: %s\n", progname, sib_info->nvm_string);
avrdude_message(MSG_DEBUG, "%s: Debug interface: %s\n", progname, sib_info->debug_string);
avrdude_message(MSG_DEBUG, "%s: PDI oscillator: %s\n", progname, sib_info->pdi_string);
avrdude_message(MSG_DEBUG, "%s: Extra information: %s\n", progname, sib_info->extra_string);
pmsg_debug("Device family ID: %s\n", sib_info->family_string);
pmsg_debug("NVM interface: %s\n", sib_info->nvm_string);
pmsg_debug("Debug interface: %s\n", sib_info->debug_string);
pmsg_debug("PDI oscillator: %s\n", sib_info->pdi_string);
pmsg_debug("Extra information: %s\n", sib_info->extra_string);
switch (sib_info->nvm_version) {
case '0':
avrdude_message(MSG_INFO, "%s: NVM type 0: 16-bit, page oriented write\n", progname);
pmsg_notice("NVM type 0: 16-bit, page oriented write\n");
updi_set_nvm_mode(pgm, UPDI_NVM_MODE_V0);
updi_set_datalink_mode(pgm, UPDI_LINK_MODE_16BIT);
break;
case '2':
avrdude_message(MSG_INFO, "%s: NVM type 2: 24-bit, word oriented write\n", progname);
pmsg_notice("NVM type 2: 24-bit, word oriented write\n");
updi_set_nvm_mode(pgm, UPDI_NVM_MODE_V2);
updi_set_datalink_mode(pgm, UPDI_LINK_MODE_24BIT);
break;
case '3':
avrdude_message(MSG_INFO, "%s: NVM type 3: 16-bit, page oriented\n", progname);
pmsg_notice("NVM type 3: 16-bit, page oriented\n");
updi_set_nvm_mode(pgm, UPDI_NVM_MODE_V3);
updi_set_datalink_mode(pgm, UPDI_LINK_MODE_16BIT);
break;
default:
avrdude_message(MSG_INFO, "%s: Unsupported NVM type: %c, please update software\n", progname, sib_info->nvm_version);
pmsg_warning("unsupported NVM type: %c, please update software\n", sib_info->nvm_version);
return -1;
}
return 0;
@@ -180,19 +174,19 @@ static int serialupdi_decode_sib(PROGRAMMER * pgm, updi_sib_info * sib_info)
static void serialupdi_close(PROGRAMMER * pgm)
{
avrdude_message(MSG_INFO, "%s: Leaving NVM programming mode\n", progname);
pmsg_notice("leaving NVM programming mode\n");
if (serialupdi_leave_progmode(pgm) < 0) {
avrdude_message(MSG_INFO, "%s: Unable to leave NVM programming mode\n", progname);
pmsg_error("unable to leave NVM programming mode\n");
}
if (updi_get_rts_mode(pgm) != RTS_MODE_DEFAULT) {
avrdude_message(MSG_INFO, "%s: Releasing DTR/RTS handshake lines\n", progname);
pmsg_warning("releasing DTR/RTS handshake lines\n");
}
updi_link_close(pgm);
}
static int serialupdi_wait_for_unlock(PROGRAMMER * pgm, unsigned int ms) {
static int serialupdi_wait_for_unlock(const PROGRAMMER *pgm, unsigned int ms) {
/*
def wait_unlocked(self, timeout_ms):
"""
@@ -227,7 +221,7 @@ static int serialupdi_wait_for_unlock(PROGRAMMER * pgm, unsigned int ms) {
current_time = (tv.tv_sec * 1000000) + tv.tv_usec;
} while ((current_time - start_time) < (ms * 1000));
avrdude_message(MSG_INFO, "%s: Timeout waiting for device to unlock\n", progname);
pmsg_error("timeout waiting for device to unlock\n");
return -1;
}
@@ -236,7 +230,7 @@ typedef enum {
WAIT_FOR_UROW_HIGH
} urow_wait_mode;
static int serialupdi_wait_for_urow(PROGRAMMER * pgm, unsigned int ms, urow_wait_mode mode) {
static int serialupdi_wait_for_urow(const PROGRAMMER *pgm, unsigned int ms, urow_wait_mode mode) {
/*
def wait_urow_prog(self, timeout_ms, wait_for_high):
"""
@@ -282,12 +276,11 @@ static int serialupdi_wait_for_urow(PROGRAMMER * pgm, unsigned int ms, urow_wait
current_time = (tv.tv_sec * 1000000) + tv.tv_usec;
} while ((current_time - start_time) < (ms * 1000));
avrdude_message(MSG_INFO, "%s: Timeout waiting for device to complete UROW WRITE\n", progname);
pmsg_error("timeout waiting for device to complete UROW WRITE\n");
return -1;
}
static int serialupdi_in_prog_mode(PROGRAMMER * pgm, uint8_t * in_prog_mode)
{
static int serialupdi_in_prog_mode(const PROGRAMMER *pgm, uint8_t *in_prog_mode) {
/*
def in_prog_mode(self):
"""
@@ -303,7 +296,7 @@ static int serialupdi_in_prog_mode(PROGRAMMER * pgm, uint8_t * in_prog_mode)
rc = updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &value);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: Read CS operation failed\n", progname);
pmsg_error("read CS operation failed\n");
return rc;
}
@@ -315,8 +308,7 @@ static int serialupdi_in_prog_mode(PROGRAMMER * pgm, uint8_t * in_prog_mode)
return 0;
}
static int serialupdi_enter_progmode(PROGRAMMER * pgm)
{
static int serialupdi_enter_progmode(const PROGRAMMER *pgm) {
/*
def enter_progmode(self):
"""
@@ -360,63 +352,62 @@ def enter_progmode(self):
uint8_t key_status;
if (serialupdi_in_prog_mode(pgm, &in_prog_mode) < 0) {
avrdude_message(MSG_INFO, "%s: Checking UPDI NVM prog mode failed\n", progname);
pmsg_error("checking UPDI NVM prog mode failed\n");
return -1;
}
if (in_prog_mode) {
avrdude_message(MSG_DEBUG, "%s: Already in prog mode\n", progname);
pmsg_debug("already in prog mode\n");
return 0;
}
memcpy(buffer, UPDI_KEY_NVM, sizeof(buffer));
if (updi_write_key(pgm, buffer, UPDI_KEY_64, sizeof(buffer)) < 0) {
avrdude_message(MSG_INFO, "%s: Writing NVM KEY failed\n", progname);
pmsg_error("writing NVM KEY failed\n");
return -1;
}
if (updi_read_cs(pgm, UPDI_ASI_KEY_STATUS, &key_status) < 0) {
avrdude_message(MSG_INFO, "%s: Checking KEY status failed\n", progname);
pmsg_error("checking KEY status failed\n");
return -1;
}
avrdude_message(MSG_DEBUG, "%s: Key status: 0x%02X\n", progname, key_status);
pmsg_debug("key status: 0x%02X\n", key_status);
if (!(key_status & (1 << UPDI_ASI_KEY_STATUS_NVMPROG))) {
avrdude_message(MSG_INFO, "%s: Key was not accepted\n", progname);
pmsg_error("key was not accepted\n");
return -1;
}
if (serialupdi_reset(pgm, APPLY_RESET) < 0) {
avrdude_message(MSG_INFO, "%s: Apply reset operation failed\n", progname);
pmsg_error("apply reset operation failed\n");
return -1;
}
if (serialupdi_reset(pgm, RELEASE_RESET) < 0) {
avrdude_message(MSG_INFO, "%s: Release reset operation failed\n", progname);
pmsg_error("release reset operation failed\n");
return -1;
}
if (serialupdi_wait_for_unlock(pgm, 100) < 0) {
avrdude_message(MSG_INFO, "%s: Failed to enter NVM programming mode: device is locked\n", progname);
pmsg_error("unable to enter NVM programming mode: device is locked\n");
return -1;
}
if (serialupdi_in_prog_mode(pgm, &in_prog_mode) < 0) {
avrdude_message(MSG_INFO, "%s: Checking UPDI NVM prog mode failed\n", progname);
pmsg_error("checking UPDI NVM prog mode failed\n");
return -1;
}
if (!in_prog_mode) {
avrdude_message(MSG_INFO, "%s: Failed to enter NVM programming mode\n", progname);
pmsg_error("unable to enter NVM programming mode\n");
return -1;
}
avrdude_message(MSG_DEBUG, "%s: Entered NVM programming mode\n", progname);
pmsg_debug("entered NVM programming mode\n");
return 0;
}
static int serialupdi_leave_progmode(PROGRAMMER * pgm)
{
static int serialupdi_leave_progmode(const PROGRAMMER *pgm) {
/*
def leave_progmode(self):
"""
@@ -429,19 +420,19 @@ static int serialupdi_leave_progmode(PROGRAMMER * pgm)
(1 << constants.UPDI_CTRLB_UPDIDIS_BIT) | (1 << constants.UPDI_CTRLB_CCDETDIS_BIT))
*/
if (serialupdi_reset(pgm, APPLY_RESET) < 0) {
avrdude_message(MSG_INFO, "%s: Apply reset operation failed\n", progname);
pmsg_error("apply reset operation failed\n");
return -1;
}
if (serialupdi_reset(pgm, RELEASE_RESET) < 0) {
avrdude_message(MSG_INFO, "%s: Release reset operation failed\n", progname);
pmsg_error("release reset operation failed\n");
return -1;
}
return updi_write_cs(pgm, UPDI_CS_CTRLB, (1 << UPDI_CTRLB_UPDIDIS_BIT) | (1 << UPDI_CTRLB_CCDETDIS_BIT));
}
static int serialupdi_write_userrow(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int serialupdi_write_userrow(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
@@ -498,74 +489,74 @@ static int serialupdi_write_userrow(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
memcpy(buffer, UPDI_KEY_UROW, sizeof(buffer));
if (updi_write_key(pgm, buffer, UPDI_KEY_64, sizeof(buffer)) < 0) {
avrdude_message(MSG_INFO, "%s: Writing USERROW KEY failed\n", progname);
pmsg_error("writing USERROW KEY failed\n");
return -1;
}
if (updi_read_cs(pgm, UPDI_ASI_KEY_STATUS, &key_status) < 0) {
avrdude_message(MSG_INFO, "%s: Checking KEY status failed\n", progname);
pmsg_error("checking KEY status failed\n");
return -1;
}
avrdude_message(MSG_DEBUG, "%s: Key status: 0x%02X\n", progname, key_status);
pmsg_debug("key status: 0x%02X\n", key_status);
if (!(key_status & (1 << UPDI_ASI_KEY_STATUS_UROWWRITE))) {
avrdude_message(MSG_INFO, "%s: Key was not accepted\n", progname);
pmsg_error("key was not accepted\n");
return -1;
}
if (serialupdi_reset(pgm, APPLY_RESET) < 0) {
avrdude_message(MSG_INFO, "%s: Apply reset operation failed\n", progname);
pmsg_error("apply reset operation failed\n");
return -1;
}
if (serialupdi_reset(pgm, RELEASE_RESET) < 0) {
avrdude_message(MSG_INFO, "%s: Release reset operation failed\n", progname);
pmsg_error("release reset operation failed\n");
return -1;
}
if (serialupdi_wait_for_urow(pgm, 500, WAIT_FOR_UROW_HIGH) < 0) {
avrdude_message(MSG_INFO, "%s: Failed to enter USERROW programming mode\n", progname);
pmsg_error("unable to enter USERROW programming mode\n");
return -1;
}
if (updi_write_data(pgm, m->offset+addr, m->buf + addr, n_bytes) < 0) {
avrdude_message(MSG_INFO, "%s: Writing USER ROW failed\n", progname);
pmsg_error("writing USER ROW failed\n");
return -1;
}
if (updi_write_cs(pgm, UPDI_ASI_SYS_CTRLA, (1 << UPDI_ASI_SYS_CTRLA_UROW_FINAL) |
(1 << UPDI_CTRLB_CCDETDIS_BIT)) < 0) {
avrdude_message(MSG_INFO, "%s: Failed trying to commit user row write\n", progname);
pmsg_error("unable to commit user row write\n");
return -1;
}
if (serialupdi_wait_for_urow(pgm, 500, WAIT_FOR_UROW_LOW) < 0) {
avrdude_message(MSG_DEBUG, "%s: Failed to exit USERROW programming mode\n", progname);
pmsg_debug("unable to exit USERROW programming mode\n");
if (serialupdi_reset(pgm, APPLY_RESET) < 0) {
avrdude_message(MSG_INFO, "%s: Apply reset operation failed\n", progname);
pmsg_error("apply reset operation failed\n");
return -1;
}
if (serialupdi_reset(pgm, RELEASE_RESET) < 0) {
avrdude_message(MSG_INFO, "%s: Release reset operation failed\n", progname);
pmsg_error("release reset operation failed\n");
return -1;
}
}
if (updi_write_cs(pgm, UPDI_ASI_KEY_STATUS, (1 << UPDI_ASI_KEY_STATUS_UROWWRITE) |
(1 << UPDI_CTRLB_CCDETDIS_BIT)) < 0) {
avrdude_message(MSG_INFO, "%s: Failed trying to complete user row write\n", progname);
pmsg_error("unable to complete user row write\n");
return -1;
}
if (serialupdi_reset(pgm, APPLY_RESET) < 0) {
avrdude_message(MSG_INFO, "%s: Apply reset operation failed\n", progname);
pmsg_error("apply reset operation failed\n");
return -1;
}
if (serialupdi_reset(pgm, RELEASE_RESET) < 0) {
avrdude_message(MSG_INFO, "%s: Release reset operation failed\n", progname);
pmsg_error("release reset operation failed\n");
return -1;
}
@@ -576,19 +567,18 @@ static int serialupdi_write_userrow(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
return 0;
}
static int serialupdi_initialize(PROGRAMMER * pgm, AVRPART * p)
{
static int serialupdi_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
uint8_t value;
uint8_t reset_link_required=0;
if (updi_link_init(pgm) < 0) {
avrdude_message(MSG_INFO, "%s: UPDI link initialization failed\n", progname);
pmsg_error("UPDI link initialization failed\n");
return -1;
}
avrdude_message(MSG_INFO, "%s: UPDI link initialization OK\n", progname);
pmsg_notice2("UPDI link initialization OK\n");
if (updi_get_rts_mode(pgm) != RTS_MODE_DEFAULT) {
avrdude_message(MSG_INFO, "%s: Forcing serial DTR/RTS handshake lines %s\n", progname, updi_get_rts_mode(pgm) == RTS_MODE_LOW ? "LOW" : "HIGH");
pmsg_warning("forcing serial DTR/RTS handshake lines %s\n", updi_get_rts_mode(pgm) == RTS_MODE_LOW ? "LOW" : "HIGH");
}
if (updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &value)<0) {
@@ -599,33 +589,33 @@ static int serialupdi_initialize(PROGRAMMER * pgm, AVRPART * p)
}
if (updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &value)<0) {
avrdude_message(MSG_INFO, "%s: Read CS operation during initialization failed\n", progname);
pmsg_error("read CS operation during initialization failed\n");
return -1;
}
}
if (value & (1 << UPDI_ASI_SYS_STATUS_LOCKSTATUS)) {
avrdude_message(MSG_INFO, "%s: Device is locked\n", progname);
pmsg_notice("device is locked\n");
}
if (value & (1 << UPDI_ASI_SYS_STATUS_UROWPROG)) {
avrdude_message(MSG_INFO, "%s: Device in USER ROW programming state, leaving programming mode\n", progname);
pmsg_notice("device in USER ROW programming state, leaving programming mode\n");
reset_link_required = 1;
}
if (value & (1 << UPDI_ASI_SYS_STATUS_NVMPROG)) {
avrdude_message(MSG_INFO, "%s: Device in NVM programming state, leaving programming mode\n", progname);
pmsg_notice("device in NVM programming state, leaving programming mode\n");
reset_link_required = 1;
}
if (value & (1 << UPDI_ASI_SYS_STATUS_INSLEEP)) {
avrdude_message(MSG_INFO, "%s: Device is in SLEEP mode\n", progname);
pmsg_notice("device is in SLEEP mode\n");
}
if (value & (1 << UPDI_ASI_SYS_STATUS_RSTSYS)) {
avrdude_message(MSG_INFO, "%s: Device in reset status, trying to release it\n", progname);
if (serialupdi_reset(pgm, RELEASE_RESET)<0) {
pmsg_notice("device in reset status, trying to release it\n");
if (serialupdi_reset(pgm, RELEASE_RESET) < 0) {
return -1;
}
}
if (reset_link_required) {
if (serialupdi_reset_connection(pgm) < 0) {
avrdude_message(MSG_INFO, "%s: UPDI link reset failed\n", progname);
pmsg_error("UPDI link reset failed\n");
return -1;
}
}
@@ -635,72 +625,66 @@ static int serialupdi_initialize(PROGRAMMER * pgm, AVRPART * p)
if (updi_read_sib(pgm, sib_info->sib_string, 32) < 0) {
/* this should never happen, let's try to reset connection and try again */
if (serialupdi_reset_connection(pgm) < 0) {
avrdude_message(MSG_INFO, "%s: SerialUPDI reset connection failed\n", progname);
pmsg_error("SerialUPDI reset connection failed\n");
return -1;
}
if (updi_read_sib(pgm, sib_info->sib_string, 32) < 0) {
avrdude_message(MSG_INFO, "%s: Read SIB operation failed\n", progname);
pmsg_error("read SIB operation failed\n");
return -1;
}
}
if (serialupdi_decode_sib(pgm, sib_info) < 0) {
avrdude_message(MSG_INFO, "%s: Decode SIB_INFO failed\n", progname);
pmsg_error("decode SIB_INFO failed\n");
return -1;
}
if (updi_link_init(pgm) < 0) {
avrdude_message(MSG_INFO, "%s: UPDI link initialization failed\n", progname);
pmsg_error("UPDI link initialization failed\n");
return -1;
}
avrdude_message(MSG_INFO, "%s: Entering NVM programming mode\n", progname);
pmsg_notice("entering NVM programming mode\n");
/* try, but ignore failure */
serialupdi_enter_progmode(pgm);
return 0;
}
static void serialupdi_disable(PROGRAMMER * pgm)
{
static void serialupdi_disable(const PROGRAMMER *pgm) {
/* Do nothing. */
return;
}
static void serialupdi_enable(PROGRAMMER * pgm)
{
static void serialupdi_enable(PROGRAMMER * pgm, const AVRPART *p) {
/* Do nothing. */
return;
}
static void serialupdi_display(PROGRAMMER * pgm, const char * p)
{
static void serialupdi_display(const PROGRAMMER *pgm, const char *p) {
return;
}
static int serialupdi_cmd(PROGRAMMER * pgm, const unsigned char * cmd,
static int serialupdi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd,
unsigned char * res)
{
avrdude_message(MSG_INFO, "%s: error: cmd %s[%s] not implemented yet\n",
progname, cmd, res);
pmsg_error("cmd %s[%s] not implemented yet\n", cmd, res);
return -1;
}
static int serialupdi_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
avrdude_message(MSG_INFO, "%s: error: program enable not implemented yet\n",
progname);
static int serialupdi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
pmsg_error("program enable not implemented yet\n");
return -1;
}
static int serialupdi_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
static int serialupdi_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char * value)
{
return updi_read_byte(pgm, mem->offset + addr, value);
}
static int serialupdi_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
static int serialupdi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char value)
{
if (strstr(mem->desc, "fuse") != 0) {
@@ -723,7 +707,7 @@ static int serialupdi_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
}
static int serialupdi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int serialupdi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
@@ -736,7 +720,7 @@ static int serialupdi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
rc = updi_read_data(pgm, m->offset + read_offset, m->buf + read_offset,
remaining_bytes > m->readsize ? m->readsize : remaining_bytes);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: Paged load operation failed\n", progname);
pmsg_error("paged load operation failed\n");
return rc;
} else {
read_bytes+=rc;
@@ -750,7 +734,7 @@ static int serialupdi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
}
}
static int serialupdi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int serialupdi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
@@ -771,15 +755,15 @@ static int serialupdi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
rc = serialupdi_write_userrow(pgm, p, m, page_size, write_offset,
remaining_bytes > m->page_size ? m->page_size : remaining_bytes);
} else if (strcmp(m->desc, "fuses")==0) {
avrdude_message(MSG_DEBUG, "%s: Page write operation requested for fuses, falling back to byte-level write\n", progname);
pmsg_debug("page write operation requested for fuses, falling back to byte-level write\n");
return -1;
} else {
avrdude_message(MSG_INFO, "%s: Invalid memory type: <%s:%d>, 0x%06X, %d (0x%04X)\n", progname, m->desc, page_size, addr, n_bytes, n_bytes);
pmsg_error("invalid memory type: <%s:%d>, 0x%06X, %d (0x%04X)\n", m->desc, page_size, addr, n_bytes, n_bytes);
rc = -1;
}
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: Paged write operation failed\n", progname);
pmsg_error("paged write operation failed\n");
return rc;
} else {
write_bytes+=rc;
@@ -796,18 +780,17 @@ static int serialupdi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
} else if (strcmp(m->desc, "userrow")==0) {
rc = serialupdi_write_userrow(pgm, p, m, page_size, addr, n_bytes);
} else if (strcmp(m->desc, "fuses")==0) {
avrdude_message(MSG_DEBUG, "%s: Page write operation requested for fuses, falling back to byte-level write\n", progname);
pmsg_debug("page write operation requested for fuses, falling back to byte-level write\n");
rc = -1;
} else {
avrdude_message(MSG_INFO, "%s: Invalid memory type: <%s:%d>, 0x%06X, %d (0x%04X)\n", progname, m->desc, page_size, addr, n_bytes, n_bytes);
pmsg_error("invalid memory type: <%s:%d>, 0x%06X, %d (0x%04X)\n", m->desc, page_size, addr, n_bytes, n_bytes);
rc = -1;
}
return rc;
}
}
static int serialupdi_unlock(PROGRAMMER * pgm, AVRPART * p)
{
static int serialupdi_unlock(const PROGRAMMER *pgm, const AVRPART *p) {
/*
def unlock(self):
"""
@@ -837,57 +820,56 @@ static int serialupdi_unlock(PROGRAMMER * pgm, AVRPART * p)
memcpy(buffer, UPDI_KEY_CHIPERASE, sizeof(buffer));
if (updi_write_key(pgm, buffer, UPDI_KEY_64, sizeof(buffer)) < 0) {
avrdude_message(MSG_INFO, "%s: Writing NVM KEY failed\n", progname);
pmsg_error("writing NVM KEY failed\n");
return -1;
}
if (updi_read_cs(pgm, UPDI_ASI_KEY_STATUS, &key_status) < 0) {
avrdude_message(MSG_INFO, "%s: Checking KEY status failed\n", progname);
pmsg_error("checking KEY status failed\n");
return -1;
}
avrdude_message(MSG_DEBUG, "%s: Key status: 0x%02X\n", progname, key_status);
pmsg_debug("key status: 0x%02X\n", key_status);
if (!(key_status & (1 << UPDI_ASI_KEY_STATUS_CHIPERASE))) {
avrdude_message(MSG_INFO, "%s: Key not accepted\n", progname);
pmsg_error("key not accepted\n");
return -1;
}
if (serialupdi_reset(pgm, APPLY_RESET) < 0) {
avrdude_message(MSG_INFO, "%s: Apply reset operation failed\n", progname);
pmsg_error("apply reset operation failed\n");
return -1;
}
if (serialupdi_reset(pgm, RELEASE_RESET) < 0) {
avrdude_message(MSG_INFO, "%s: Release reset operation failed\n", progname);
pmsg_error("release reset operation failed\n");
return -1;
}
if (serialupdi_wait_for_unlock(pgm, 500) < 0) {
avrdude_message(MSG_INFO, "%s: Waiting for unlock failed\n", progname);
pmsg_error("waiting for unlock failed\n");
return -1;
}
if (updi_link_init(pgm) < 0) {
avrdude_message(MSG_INFO, "%s: UPDI link reinitialization failed\n", progname);
pmsg_error("UPDI link reinitialization failed\n");
return -1;
}
return serialupdi_enter_progmode(pgm);
}
static int serialupdi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
static int serialupdi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
uint8_t value;
if (updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &value)<0) {
avrdude_message(MSG_INFO, "%s: Read CS operation during chip erase failed\n", progname);
pmsg_error("read CS operation during chip erase failed\n");
return -1;
}
if (value & (1 << UPDI_ASI_SYS_STATUS_LOCKSTATUS)) {
avrdude_message(MSG_INFO, "%s: Device is locked\n", progname);
pmsg_warning("device is locked\n");
if (ovsigck) {
avrdude_message(MSG_INFO, "%s: Attempting device erase\n", progname);
pmsg_warning("attempting device erase\n");
return serialupdi_unlock(pgm, p);
}
} else {
@@ -896,20 +878,19 @@ static int serialupdi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
return -1;
}
static int serialupdi_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int serialupdi_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int baseaddr)
{
avrdude_message(MSG_INFO, "%s: error: page erase not implemented yet\n",
progname);
pmsg_error("page erase not implemented yet\n");
return -1;
}
static int serialupdi_read_signature(PROGRAMMER * pgm, AVRPART *p, AVRMEM *m) {
static int serialupdi_read_signature(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m) {
uint8_t value;
if (updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &value)<0) {
avrdude_message(MSG_INFO, "%s: Read CS operation during signature read failed\n", progname);
pmsg_error("read CS operation during signature read failed\n");
return -1;
}
@@ -917,6 +898,7 @@ static int serialupdi_read_signature(PROGRAMMER * pgm, AVRPART *p, AVRMEM *m) {
m->buf[0]=0x00;
m->buf[1]=0x00;
m->buf[2]=0x00;
return LIBAVRDUDE_SOFTFAIL;
} else {
updi_read_byte(pgm, m->offset + 0, m->buf);
updi_read_byte(pgm, m->offset + 1, m->buf+1);
@@ -926,7 +908,7 @@ static int serialupdi_read_signature(PROGRAMMER * pgm, AVRPART *p, AVRMEM *m) {
return 3;
}
static int serialupdi_read_sib(PROGRAMMER * pgm, AVRPART *p, char *sib) {
static int serialupdi_read_sib(const PROGRAMMER *pgm, const AVRPART *p, char *sib) {
updi_sib_info * sib_info = updi_get_sib_info(pgm);
@@ -935,8 +917,7 @@ static int serialupdi_read_sib(PROGRAMMER * pgm, AVRPART *p, char *sib) {
return 0;
}
static int serialupdi_parseextparms(PROGRAMMER * pgm, LISTID extparms)
{
static int serialupdi_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
LNODEID ln;
const char *extended_param;
char rts_mode[5];
@@ -951,22 +932,20 @@ static int serialupdi_parseextparms(PROGRAMMER * pgm, LISTID extparms)
} else if (strcasecmp(rts_mode, "high") == 0) {
updi_set_rts_mode(pgm, RTS_MODE_HIGH);
} else {
avrdude_message(MSG_INFO, "%s: RTS/DTR mode must be LOW or HIGH\n", progname);
pmsg_error("RTS/DTR mode must be LOW or HIGH\n");
return -1;
}
continue;
}
avrdude_message(MSG_INFO, "%s: serialupdi_parseextparms(): invalid extended parameter '%s'\n",
progname, extended_param);
pmsg_error("invalid extended parameter '%s'\n", extended_param);
rv = -1;
}
return rv;
}
void serialupdi_initpgm(PROGRAMMER * pgm)
{
void serialupdi_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "serialupdi");
/*

View File

@@ -34,7 +34,7 @@ extern "C" {
#endif
extern const char serialupdi_desc[];
void serialupdi_initpgm (PROGRAMMER * pgm);
void serialupdi_initpgm(PROGRAMMER *pgm);
#ifdef __cplusplus
}

View File

@@ -45,54 +45,38 @@
#define STK500_XTAL 7372800U
#define MAX_SYNC_ATTEMPTS 10
struct pdata
{
unsigned char ext_addr_byte; // Record ext-addr byte set in the target device (if used)
int retry_attempts; // Number of connection attempts provided by the user
};
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
static int stk500_getparm(const PROGRAMMER *pgm, unsigned parm, unsigned *value);
static int stk500_setparm(const PROGRAMMER *pgm, unsigned parm, unsigned value);
static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p);
static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value);
static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value);
static void stk500_print_parms1(PROGRAMMER * pgm, const char * p);
static int stk500_send(PROGRAMMER * pgm, unsigned char * buf, size_t len)
{
static int stk500_send(const PROGRAMMER *pgm, unsigned char *buf, size_t len) {
return serial_send(&pgm->fd, buf, len);
}
static int stk500_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
{
static int stk500_recv(const PROGRAMMER *pgm, unsigned char *buf, size_t len) {
int rv;
rv = serial_recv(&pgm->fd, buf, len);
if (rv < 0) {
avrdude_message(MSG_INFO, "%s: stk500_recv(): programmer is not responding\n",
progname);
pmsg_error("programmer is not responding\n");
return -1;
}
return 0;
}
int stk500_drain(PROGRAMMER * pgm, int display)
{
int stk500_drain(const PROGRAMMER *pgm, int display) {
return serial_drain(&pgm->fd, display);
}
int stk500_getsync(PROGRAMMER * pgm)
{
int stk500_getsync(const PROGRAMMER *pgm) {
unsigned char buf[32], resp[32];
int attempt;
int max_sync_attempts;
/*
* get in sync */
buf[0] = Cmnd_STK_GET_SYNC;
buf[1] = Sync_CRC_EOP;
@@ -119,13 +103,13 @@ int stk500_getsync(PROGRAMMER * pgm)
usleep(50*1000);
stk500_drain(pgm, 0);
}
stk500_send(pgm, buf, 2);
stk500_recv(pgm, resp, 1);
if (resp[0] == Resp_STK_INSYNC){
resp[0] = 0;
if(stk500_recv(pgm, resp, 1) >= 0 && resp[0] == Resp_STK_INSYNC)
break;
}
avrdude_message(MSG_INFO, "%s: stk500_getsync() attempt %d of %d: not in sync: resp=0x%02x\n",
progname, attempt + 1, max_sync_attempts, resp[0]);
pmsg_warning("attempt %d of %d: not in sync: resp=0x%02x\n", attempt + 1, max_sync_attempts, resp[0]);
}
if (attempt == max_sync_attempts) {
stk500_drain(pgm, 0);
@@ -135,9 +119,7 @@ int stk500_getsync(PROGRAMMER * pgm)
if (stk500_recv(pgm, resp, 1) < 0)
return -1;
if (resp[0] != Resp_STK_OK) {
avrdude_message(MSG_INFO, "%s: stk500_getsync(): can't communicate with device: "
"resp=0x%02x\n",
progname, resp[0]);
pmsg_error("cannot communicate with device: resp=0x%02x\n", resp[0]);
return -1;
}
@@ -149,7 +131,7 @@ int stk500_getsync(PROGRAMMER * pgm)
* transmit an AVR device command and return the results; 'cmd' and
* 'res' must point to at least a 4 byte data buffer
*/
static int stk500_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
static int stk500_cmd(const PROGRAMMER *pgm, const unsigned char *cmd,
unsigned char *res)
{
unsigned char buf[32];
@@ -166,7 +148,7 @@ static int stk500_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
if (stk500_recv(pgm, buf, 1) < 0)
return -1;
if (buf[0] != Resp_STK_INSYNC) {
avrdude_message(MSG_INFO, "%s: stk500_cmd(): programmer is out of sync\n", progname);
pmsg_error("programmer is out of sync\n");
return -1;
}
@@ -179,7 +161,7 @@ static int stk500_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
if (stk500_recv(pgm, buf, 1) < 0)
return -1;
if (buf[0] != Resp_STK_OK) {
avrdude_message(MSG_INFO, "%s: stk500_cmd(): protocol error\n", progname);
pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]);
return -1;
}
@@ -191,28 +173,24 @@ static int stk500_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
/*
* issue the 'chip erase' command to the AVR device
*/
static int stk500_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
static int stk500_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char cmd[4];
unsigned char res[4];
if (pgm->cmd == NULL) {
avrdude_message(MSG_INFO, "%s: Error: %s programmer uses stk500_chip_erase() but does not\n"
"provide a cmd() method.\n",
progname, pgm->type);
pmsg_error("%s programmer uses stk500_chip_erase() but does not\n", pgm->type);
imsg_error("provide a cmd() method\n");
return -1;
}
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
avrdude_message(MSG_INFO, "chip erase instruction not defined for part \"%s\"\n",
p->desc);
pmsg_error("chip erase instruction not defined for part %s\n", p->desc);
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);
@@ -226,8 +204,7 @@ static int stk500_chip_erase(PROGRAMMER * pgm, AVRPART * p)
/*
* issue the 'program enable' command to the AVR device
*/
static int stk500_program_enable(PROGRAMMER * pgm, AVRPART * p)
{
static int stk500_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char buf[16];
int tries=0;
@@ -243,8 +220,7 @@ static int stk500_program_enable(PROGRAMMER * pgm, AVRPART * p)
return -1;
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
avrdude_message(MSG_INFO, "%s: stk500_program_enable(): can't get into sync\n",
progname);
pmsg_error("cannot get into sync\n");
return -1;
}
if (stk500_getsync(pgm) < 0)
@@ -252,9 +228,7 @@ static int stk500_program_enable(PROGRAMMER * pgm, AVRPART * p)
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
avrdude_message(MSG_INFO, "%s: stk500_program_enable(): protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
return -1;
}
@@ -264,28 +238,25 @@ static int stk500_program_enable(PROGRAMMER * pgm, AVRPART * p)
return 0;
}
else if (buf[0] == Resp_STK_NODEVICE) {
avrdude_message(MSG_INFO, "%s: stk500_program_enable(): no device\n",
progname);
pmsg_error("no device\n");
return -1;
}
if(buf[0] == Resp_STK_FAILED)
{
avrdude_message(MSG_INFO, "%s: stk500_program_enable(): failed to enter programming mode\n",
progname);
return -1;
pmsg_error("unable to enter programming mode\n");
return -1;
}
avrdude_message(MSG_INFO, "%s: stk500_program_enable(): unknown response=0x%02x\n",
progname, buf[0]);
pmsg_error("unknown response=0x%02x\n", buf[0]);
return -1;
}
static int stk500_set_extended_parms(PROGRAMMER * pgm, int n,
static int stk500_set_extended_parms(const PROGRAMMER *pgm, int n,
unsigned char * cmd)
{
unsigned char buf[16];
@@ -308,8 +279,7 @@ static int stk500_set_extended_parms(PROGRAMMER * pgm, int n,
return -1;
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
avrdude_message(MSG_INFO, "%s: stk500_set_extended_parms(): can't get into sync\n",
progname);
pmsg_error("cannot get into sync\n");
return -1;
}
if (stk500_getsync(pgm) < 0)
@@ -317,9 +287,7 @@ static int stk500_set_extended_parms(PROGRAMMER * pgm, int n,
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
avrdude_message(MSG_INFO, "%s: stk500_set_extended_parms(): protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
return -1;
}
@@ -329,22 +297,16 @@ static int stk500_set_extended_parms(PROGRAMMER * pgm, int n,
return 0;
}
else if (buf[0] == Resp_STK_NODEVICE) {
avrdude_message(MSG_INFO, "%s: stk500_set_extended_parms(): no device\n",
progname);
pmsg_error("no device\n");
return -1;
}
if(buf[0] == Resp_STK_FAILED)
{
avrdude_message(MSG_INFO, "%s: stk500_set_extended_parms(): failed to set extended "
"device programming parameters\n",
progname);
return -1;
if(buf[0] == Resp_STK_FAILED) {
pmsg_error("unable to set extended device programming parameters\n");
return -1;
}
avrdude_message(MSG_INFO, "%s: stk500_set_extended_parms(): unknown response=0x%02x\n",
progname, buf[0]);
pmsg_error("unknown response=0x%02x\n", buf[0]);
return -1;
}
@@ -353,8 +315,7 @@ static int stk500_set_extended_parms(PROGRAMMER * pgm, int n,
* Crossbow MIB510 initialization and shutdown. Use cmd = 1 to
* initialize, cmd = 0 to close.
*/
static int mib510_isp(PROGRAMMER * pgm, unsigned char cmd)
{
static int mib510_isp(const PROGRAMMER *pgm, unsigned char cmd) {
unsigned char buf[9];
int tries = 0;
@@ -378,8 +339,7 @@ static int mib510_isp(PROGRAMMER * pgm, unsigned char cmd)
return -1;
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
avrdude_message(MSG_INFO, "%s: mib510_isp(): can't get into sync\n",
progname);
pmsg_error("cannot get into sync\n");
return -1;
}
if (stk500_getsync(pgm) < 0)
@@ -387,9 +347,7 @@ static int mib510_isp(PROGRAMMER * pgm, unsigned char cmd)
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
avrdude_message(MSG_INFO, "%s: mib510_isp(): protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
return -1;
}
@@ -399,21 +357,18 @@ static int mib510_isp(PROGRAMMER * pgm, unsigned char cmd)
return 0;
}
else if (buf[0] == Resp_STK_NODEVICE) {
avrdude_message(MSG_INFO, "%s: mib510_isp(): no device\n",
progname);
pmsg_error("no device\n");
return -1;
}
if (buf[0] == Resp_STK_FAILED)
{
avrdude_message(MSG_INFO, "%s: mib510_isp(): command %d failed\n",
progname, cmd);
pmsg_error("command %d failed\n", cmd);
return -1;
}
avrdude_message(MSG_INFO, "%s: mib510_isp(): unknown response=0x%02x\n",
progname, buf[0]);
pmsg_error("unknown response=0x%02x\n", buf[0]);
return -1;
}
@@ -422,8 +377,7 @@ static int mib510_isp(PROGRAMMER * pgm, unsigned char cmd)
/*
* initialize the AVR device and prepare it to accept commands
*/
static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
{
static int stk500_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
unsigned char buf[32];
AVRMEM * m;
int tries;
@@ -473,8 +427,7 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
}
#if 0
avrdude_message(MSG_INFO, "%s: stk500_initialize(): n_extparms = %d\n",
progname, n_extparms);
pmsg_info("stk500_initialize(): n_extparms = %d\n", n_extparms);
#endif
buf[5] = 1; /* polling supported - XXX need this in config file */
@@ -547,8 +500,7 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
if (stk500_recv(pgm, buf, 1) < 0)
return -1;
if (buf[0] == Resp_STK_NOSYNC) {
avrdude_message(MSG_INFO, "%s: stk500_initialize(): programmer not in sync, resp=0x%02x\n",
progname, buf[0]);
pmsg_warning("programmer not in sync, resp=0x%02x\n", buf[0]);
if (tries > 33)
return -1;
if (stk500_getsync(pgm) < 0)
@@ -556,26 +508,21 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
avrdude_message(MSG_INFO, "%s: stk500_initialize(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
return -1;
}
if (stk500_recv(pgm, buf, 1) < 0)
return -1;
if (buf[0] != Resp_STK_OK) {
avrdude_message(MSG_INFO, "%s: stk500_initialize(): (b) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_OK, buf[0]);
pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]);
return -1;
}
if (n_extparms) {
if ((p->pagel == 0) || (p->bs2 == 0)) {
avrdude_message(MSG_NOTICE2, "%s: PAGEL and BS2 signals not defined in the configuration "
"file for part %s, using dummy values\n",
progname, p->desc);
pmsg_notice2("PAGEL and BS2 signals not defined in the configuration "
"file for part %s, using dummy values\n", p->desc);
buf[2] = 0xD7; /* they look somehow possible, */
buf[3] = 0xA0; /* don't they? ;) */
}
@@ -603,7 +550,7 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
rc = stk500_set_extended_parms(pgm, n_extparms+1, buf);
if (rc) {
avrdude_message(MSG_INFO, "%s: stk500_initialize(): failed\n", progname);
pmsg_error("failed to initialise programmer\n");
return -1;
}
}
@@ -611,7 +558,7 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
return pgm->program_enable(pgm, p);
}
static int stk500_parseextparms(PROGRAMMER * pgm, LISTID extparms)
static int stk500_parseextparms(const PROGRAMMER *pgm, const LISTID extparms)
{
LNODEID ln;
const char *extended_param;
@@ -623,21 +570,18 @@ static int stk500_parseextparms(PROGRAMMER * pgm, LISTID extparms)
if (sscanf(extended_param, "attempts=%2d", &attempts) == 1) {
PDATA(pgm)->retry_attempts = attempts;
avrdude_message(MSG_INFO, "%s: Setting number of retry attempts to %d\n",
progname, attempts);
pmsg_info("setting number of retry attempts to %d\n", attempts);
continue;
}
avrdude_message(MSG_INFO, "%s: stk500_parseextparms(): invalid extended parameter '%s'\n",
progname, extended_param);
pmsg_error("invalid extended parameter '%s'\n", extended_param);
rv = -1;
}
return rv;
}
static void stk500_disable(PROGRAMMER * pgm)
{
static void stk500_disable(const PROGRAMMER *pgm) {
unsigned char buf[16];
int tries=0;
@@ -653,8 +597,7 @@ static void stk500_disable(PROGRAMMER * pgm)
return;
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
avrdude_message(MSG_INFO, "%s: stk500_disable(): can't get into sync\n",
progname);
pmsg_error("cannot get into sync\n");
return;
}
if (stk500_getsync(pgm) < 0)
@@ -662,9 +605,7 @@ static void stk500_disable(PROGRAMMER * pgm)
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
avrdude_message(MSG_INFO, "%s: stk500_disable(): protocol error, expect=0x%02x, "
"resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
return;
}
@@ -674,25 +615,21 @@ static void stk500_disable(PROGRAMMER * pgm)
return;
}
else if (buf[0] == Resp_STK_NODEVICE) {
avrdude_message(MSG_INFO, "%s: stk500_disable(): no device\n",
progname);
pmsg_error("no device\n");
return;
}
avrdude_message(MSG_INFO, "%s: stk500_disable(): unknown response=0x%02x\n",
progname, buf[0]);
pmsg_error("unknown response=0x%02x\n", buf[0]);
return;
}
static void stk500_enable(PROGRAMMER * pgm)
{
static void stk500_enable(PROGRAMMER *pgm, const AVRPART *p) {
return;
}
static int stk500_open(PROGRAMMER * pgm, char * port)
{
static int stk500_open(PROGRAMMER *pgm, const char *port) {
union pinfo pinfo;
strcpy(pgm->port, port);
pinfo.serialinfo.baud = pgm->baudrate? pgm->baudrate: 115200;
@@ -729,8 +666,7 @@ static void stk500_close(PROGRAMMER * pgm)
}
static int stk500_loadaddr(PROGRAMMER * pgm, AVRMEM * mem, unsigned int addr)
{
static int stk500_loadaddr(const PROGRAMMER *pgm, const AVRMEM *mem, const unsigned int addr) {
unsigned char buf[16];
int tries;
unsigned char ext_byte;
@@ -745,8 +681,8 @@ static int stk500_loadaddr(PROGRAMMER * pgm, AVRMEM * mem, unsigned int addr)
if (lext != NULL) {
ext_byte = (addr >> 16) & 0xff;
if (ext_byte != PDATA(pgm)->ext_addr_byte) {
/* Either this is the first addr load, or a 64K word boundary is
* crossed, so set the ext addr byte */
/* Either this is the first addr load, or a different 64K word section */
memset(buf, 0, 4);
avr_set_bits(lext, buf);
avr_set_addr(lext, buf, addr);
stk500_cmd(pgm, buf, buf);
@@ -765,8 +701,7 @@ static int stk500_loadaddr(PROGRAMMER * pgm, AVRMEM * mem, unsigned int addr)
return -1;
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
avrdude_message(MSG_INFO, "%s: stk500_loadaddr(): can't get into sync\n",
progname);
pmsg_error("cannot get into sync\n");
return -1;
}
if (stk500_getsync(pgm) < 0)
@@ -774,27 +709,22 @@ static int stk500_loadaddr(PROGRAMMER * pgm, AVRMEM * mem, unsigned int addr)
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
avrdude_message(MSG_INFO, "%s: stk500_loadaddr(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
return -1;
}
if (stk500_recv(pgm, buf, 1) < 0)
return -1;
if (buf[0] == Resp_STK_OK) {
if (buf[0] == Resp_STK_OK)
return 0;
}
avrdude_message(MSG_INFO, "%s: loadaddr(): (b) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]);
return -1;
}
static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int stk500_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
@@ -808,27 +738,29 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
if (strcmp(m->desc, "flash") == 0) {
memtype = 'F';
}
else if (strcmp(m->desc, "eeprom") == 0) {
a_div = 2;
} else if (strcmp(m->desc, "eeprom") == 0) {
memtype = 'E';
}
else {
/*
* The STK original 500 v1 protocol actually expects a_div = 1, but the
* v1.x FW of the STK500 kit has been superseded by v2 FW in the mid
* 2000s. Since optiboot, arduino as ISP and others assume a_div = 2,
* better use that. See https://github.com/avrdudes/avrdude/issues/967
*/
a_div = 2;
} else {
return -2;
}
if ((m->op[AVR_OP_LOADPAGE_LO]) || (m->op[AVR_OP_READ_LO]))
a_div = 2;
else
a_div = 1;
n = addr + n_bytes;
#if 0
avrdude_message(MSG_INFO, "n_bytes = %d\n"
"n = %u\n"
"a_div = %d\n"
"page_size = %d\n",
n_bytes, n, a_div, page_size);
#endif
msg_info(
"n_bytes = %d\n"
"n = %u\n"
"a_div = %d\n"
"page_size = %d\n",
n_bytes, n, a_div, page_size);
#endif
for (; addr < n; addr += block_size) {
// MIB510 uses fixed blocks size of 256 bytes
@@ -861,27 +793,25 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
return -1;
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
avrdude_message(MSG_INFO, "\n%s: stk500_paged_write(): can't get into sync\n",
progname);
msg_error("\n");
pmsg_error("cannot get into sync\n");
return -3;
}
if (stk500_getsync(pgm) < 0)
return -1;
return -1;
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
avrdude_message(MSG_INFO, "\n%s: stk500_paged_write(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
msg_error("\n");
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
return -4;
}
if (stk500_recv(pgm, buf, 1) < 0)
return -1;
if (buf[0] != Resp_STK_OK) {
avrdude_message(MSG_INFO, "\n%s: stk500_paged_write(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
msg_error("\n");
pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]);
return -5;
}
}
@@ -889,7 +819,7 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
return n_bytes;
}
static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
static int stk500_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
@@ -902,19 +832,20 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
if (strcmp(m->desc, "flash") == 0) {
memtype = 'F';
}
else if (strcmp(m->desc, "eeprom") == 0) {
a_div = 2;
} else if (strcmp(m->desc, "eeprom") == 0) {
memtype = 'E';
}
else {
/*
* The STK original 500 v1 protocol actually expects a_div = 1, but the
* v1.x FW of the STK500 kit has been superseded by v2 FW in the mid
* 2000s. Since optiboot, arduino as ISP and others assume a_div = 2,
* better use that. See https://github.com/avrdudes/avrdude/issues/967
*/
a_div = 2;
} else {
return -2;
}
if ((m->op[AVR_OP_LOADPAGE_LO]) || (m->op[AVR_OP_READ_LO]))
a_div = 2;
else
a_div = 1;
n = addr + n_bytes;
for (; addr < n; addr += block_size) {
// MIB510 uses fixed blocks size of 256 bytes
@@ -942,18 +873,17 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
return -1;
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
avrdude_message(MSG_INFO, "\n%s: stk500_paged_load(): can't get into sync\n",
progname);
msg_error("\n");
pmsg_error("cannot get into sync\n");
return -3;
}
if (stk500_getsync(pgm) < 0)
return -1;
return -1;
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
avrdude_message(MSG_INFO, "\n%s: stk500_paged_load(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
msg_error("\n");
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
return -4;
}
@@ -965,17 +895,15 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
if(strcmp(ldata(lfirst(pgm->id)), "mib510") == 0) {
if (buf[0] != Resp_STK_INSYNC) {
avrdude_message(MSG_INFO, "\n%s: stk500_paged_load(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
return -5;
msg_error("\n");
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
return -5;
}
}
}
else {
if (buf[0] != Resp_STK_OK) {
avrdude_message(MSG_INFO, "\n%s: stk500_paged_load(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_OK, buf[0]);
msg_error("\n");
pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]);
return -5;
}
}
@@ -985,30 +913,26 @@ static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
}
static int stk500_set_vtarget(PROGRAMMER * pgm, double v)
{
static int stk500_set_vtarget(const PROGRAMMER *pgm, double v) {
unsigned uaref, utarg;
utarg = (unsigned)((v + 0.049) * 10);
if (stk500_getparm(pgm, Parm_STK_VADJUST, &uaref) != 0) {
avrdude_message(MSG_INFO, "%s: stk500_set_vtarget(): cannot obtain V[aref]\n",
progname);
pmsg_error("cannot obtain V[aref]\n");
return -1;
}
if (uaref > utarg) {
avrdude_message(MSG_INFO, "%s: stk500_set_vtarget(): reducing V[aref] from %.1f to %.1f\n",
progname, uaref / 10.0, v);
if (stk500_setparm(pgm, Parm_STK_VADJUST, utarg)
!= 0)
pmsg_error("reducing V[aref] from %.1f to %.1f\n", uaref / 10.0, v);
if (stk500_setparm(pgm, Parm_STK_VADJUST, utarg) != 0)
return -1;
}
return stk500_setparm(pgm, Parm_STK_VTARGET, utarg);
}
static int stk500_set_varef(PROGRAMMER * pgm, unsigned int chan /* unused */,
static int stk500_set_varef(const PROGRAMMER *pgm, unsigned int chan /* unused */,
double v)
{
unsigned uaref, utarg;
@@ -1016,28 +940,26 @@ static int stk500_set_varef(PROGRAMMER * pgm, unsigned int chan /* unused */,
uaref = (unsigned)((v + 0.049) * 10);
if (stk500_getparm(pgm, Parm_STK_VTARGET, &utarg) != 0) {
avrdude_message(MSG_INFO, "%s: stk500_set_varef(): cannot obtain V[target]\n",
progname);
pmsg_error("cannot obtain V[target]\n");
return -1;
}
if (uaref > utarg) {
avrdude_message(MSG_INFO, "%s: stk500_set_varef(): V[aref] must not be greater than "
"V[target] = %.1f\n",
progname, utarg / 10.0);
pmsg_error("V[aref] must not be greater than "
"V[target] = %.1f\n", utarg/10.0);
return -1;
}
return stk500_setparm(pgm, Parm_STK_VADJUST, uaref);
}
static int stk500_set_fosc(PROGRAMMER * pgm, double v)
{
static int stk500_set_fosc(const PROGRAMMER *pgm, double v) {
unsigned prescale, cmatch, fosc;
static unsigned ps[] = {
1, 8, 32, 64, 128, 256, 1024
};
int idx, rc;
size_t idx;
int rc;
prescale = cmatch = 0;
if (v > 0.0) {
@@ -1051,11 +973,10 @@ static int stk500_set_fosc(PROGRAMMER * pgm, double v)
unit = "kHz";
} else
unit = "Hz";
avrdude_message(MSG_INFO, "%s: stk500_set_fosc(): f = %.3f %s too high, using %.3f MHz\n",
progname, v, unit, STK500_XTAL / 2e6);
pmsg_warning("f = %.3f %s too high, using %.3f MHz\n", v, unit, STK500_XTAL/2e6);
fosc = STK500_XTAL / 2;
} else
fosc = (unsigned)v;
fosc = (unsigned) v;
for (idx = 0; idx < sizeof(ps) / sizeof(ps[0]); idx++) {
if (fosc >= STK500_XTAL / (256 * ps[idx] * 2)) {
@@ -1066,8 +987,7 @@ static int stk500_set_fosc(PROGRAMMER * pgm, double v)
}
}
if (idx == sizeof(ps) / sizeof(ps[0])) {
avrdude_message(MSG_INFO, "%s: stk500_set_fosc(): f = %u Hz too low, %u Hz min\n",
progname, fosc, STK500_XTAL / (256 * 1024 * 2));
pmsg_warning("f = %u Hz too low, %u Hz min\n", fosc, STK500_XTAL / (256 * 1024 * 2));
return -1;
}
}
@@ -1087,8 +1007,7 @@ static int stk500_set_fosc(PROGRAMMER * pgm, double v)
For small duration values, the actual SCK width is larger than
expected. As the duration value increases, the SCK width error
diminishes. */
static int stk500_set_sck_period(PROGRAMMER * pgm, double v)
{
static int stk500_set_sck_period(const PROGRAMMER *pgm, double v) {
int dur;
double min, max;
@@ -1098,20 +1017,19 @@ static int stk500_set_sck_period(PROGRAMMER * pgm, double v)
if (v < min) {
dur = 1;
avrdude_message(MSG_INFO, "%s: stk500_set_sck_period(): p = %.1f us too small, using %.1f us\n",
progname, v / 1e-6, dur * min / 1e-6);
pmsg_warning("p = %.1f us too small, using %.1f us\n",
v/1e-6, dur*min/1e-6);
} else if (v > max) {
dur = 255;
avrdude_message(MSG_INFO, "%s: stk500_set_sck_period(): p = %.1f us too large, using %.1f us\n",
progname, v / 1e-6, dur * min / 1e-6);
pmsg_warning("p = %.1f us too large, using %.1f us\n",
v/1e-6, dur*min/1e-6);
}
return stk500_setparm(pgm, Parm_STK_SCK_DURATION, dur);
}
static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
{
static int stk500_getparm(const PROGRAMMER *pgm, unsigned parm, unsigned *value) {
unsigned char buf[16];
unsigned v;
int tries = 0;
@@ -1128,8 +1046,8 @@ static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
return -1;
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
avrdude_message(MSG_INFO, "\n%s: stk500_getparm(): can't get into sync\n",
progname);
msg_error("\n");
pmsg_error("cannot get into sync\n");
return -1;
}
if (stk500_getsync(pgm) < 0)
@@ -1137,9 +1055,8 @@ static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
avrdude_message(MSG_INFO, "\n%s: stk500_getparm(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
msg_error("\n");
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
return -2;
}
@@ -1150,14 +1067,13 @@ static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
if (stk500_recv(pgm, buf, 1) < 0)
return -1;
if (buf[0] == Resp_STK_FAILED) {
avrdude_message(MSG_INFO, "\n%s: stk500_getparm(): parameter 0x%02x failed\n",
progname, v);
msg_error("\n");
pmsg_error("parameter 0x%02x failed\n", v);
return -3;
}
else if (buf[0] != Resp_STK_OK) {
avrdude_message(MSG_INFO, "\n%s: stk500_getparm(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_OK, buf[0]);
msg_error("\n");
pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]);
return -3;
}
@@ -1167,8 +1083,7 @@ static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
}
static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value)
{
static int stk500_setparm(const PROGRAMMER *pgm, unsigned parm, unsigned value) {
unsigned char buf[16];
int tries = 0;
@@ -1185,8 +1100,8 @@ static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value)
return -1;
if (buf[0] == Resp_STK_NOSYNC) {
if (tries > 33) {
avrdude_message(MSG_INFO, "\n%s: stk500_setparm(): can't get into sync\n",
progname);
msg_error("\n");
pmsg_error("cannot get into sync\n");
return -1;
}
if (stk500_getsync(pgm) < 0)
@@ -1194,9 +1109,8 @@ static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value)
goto retry;
}
else if (buf[0] != Resp_STK_INSYNC) {
avrdude_message(MSG_INFO, "\n%s: stk500_setparm(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
msg_error("\n");
pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]);
return -2;
}
@@ -1205,25 +1119,23 @@ static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value)
if (buf[0] == Resp_STK_OK)
return 0;
parm = buf[0]; /* if not STK_OK, we've been echoed parm here */
parm = buf[0]; /* if not STK_OK, we've been echoed parm here */
if (stk500_recv(pgm, buf, 1) < 0)
return -1;
if (buf[0] == Resp_STK_FAILED) {
avrdude_message(MSG_INFO, "\n%s: stk500_setparm(): parameter 0x%02x failed\n",
progname, parm);
msg_error("\n");
pmsg_error("parameter 0x%02x failed\n", parm);
return -3;
}
else {
avrdude_message(MSG_INFO, "\n%s: stk500_setparm(): (a) protocol error, "
"expect=0x%02x, resp=0x%02x\n",
progname, Resp_STK_INSYNC, buf[0]);
msg_error("\n");
pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]);
return -3;
}
}
static void stk500_display(PROGRAMMER * pgm, const char * p)
{
static void stk500_display(const PROGRAMMER *pgm, const char *p) {
unsigned maj, min, hdw, topcard;
stk500_getparm(pgm, Parm_STK_HW_VER, &hdw);
@@ -1231,21 +1143,21 @@ static void stk500_display(PROGRAMMER * pgm, const char * p)
stk500_getparm(pgm, Parm_STK_SW_MINOR, &min);
stk500_getparm(pgm, Param_STK500_TOPCARD_DETECT, &topcard);
avrdude_message(MSG_INFO, "%sHardware Version: %d\n", p, hdw);
avrdude_message(MSG_INFO, "%sFirmware Version: %d.%d\n", p, maj, min);
msg_info("%sHardware Version: %d\n", p, hdw);
msg_info("%sFirmware Version: %d.%d\n", p, maj, min);
if (topcard < 3) {
const char *n = "Unknown";
switch (topcard) {
case 1:
n = "STK502";
break;
n = "STK502";
break;
case 2:
n = "STK501";
break;
n = "STK501";
break;
}
avrdude_message(MSG_INFO, "%sTopcard : %s\n", p, n);
msg_info("%sTopcard : %s\n", p, n);
}
if(strcmp(pgm->type, "Arduino") != 0)
stk500_print_parms1(pgm, p);
@@ -1254,8 +1166,7 @@ static void stk500_display(PROGRAMMER * pgm, const char * p)
}
static void stk500_print_parms1(PROGRAMMER * pgm, const char * p)
{
static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p) {
unsigned vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration;
stk500_getparm(pgm, Parm_STK_VTARGET, &vtarget);
@@ -1264,11 +1175,11 @@ static void stk500_print_parms1(PROGRAMMER * pgm, const char * p)
stk500_getparm(pgm, Parm_STK_OSC_CMATCH, &osc_cmatch);
stk500_getparm(pgm, Parm_STK_SCK_DURATION, &sck_duration);
avrdude_message(MSG_INFO, "%sVtarget : %.1f V\n", p, vtarget / 10.0);
avrdude_message(MSG_INFO, "%sVaref : %.1f V\n", p, vadjust / 10.0);
avrdude_message(MSG_INFO, "%sOscillator : ", p);
msg_info("%sVtarget : %.1f V\n", p, vtarget / 10.0);
msg_info("%sVaref : %.1f V\n", p, vadjust / 10.0);
msg_info("%sOscillator : ", p);
if (osc_pscale == 0)
avrdude_message(MSG_INFO, "Off\n");
msg_info("Off\n");
else {
int prescale = 1;
double f = STK500_XTAL / 2;
@@ -1292,30 +1203,27 @@ static void stk500_print_parms1(PROGRAMMER * pgm, const char * p)
unit = "kHz";
} else
unit = "Hz";
avrdude_message(MSG_INFO, "%.3f %s\n", f, unit);
msg_info("%.3f %s\n", f, unit);
}
avrdude_message(MSG_INFO, "%sSCK period : %.1f us\n", p,
sck_duration * 8.0e6 / STK500_XTAL + 0.05);
msg_info("%sSCK period : %.1f us\n", p, sck_duration * 8.0e6 / STK500_XTAL + 0.05);
return;
}
static void stk500_print_parms(PROGRAMMER * pgm)
{
static void stk500_print_parms(const PROGRAMMER *pgm) {
stk500_print_parms1(pgm, "");
}
static void stk500_setup(PROGRAMMER * pgm)
{
if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
avrdude_message(MSG_INFO, "%s: stk500_setup(): Out of memory allocating private data\n",
progname);
pmsg_error("out of memory allocating private data\n");
return;
}
memset(pgm->cookie, 0, sizeof(struct pdata));
PDATA(pgm)->ext_addr_byte = 0xff; /* Ensures it is programmed before
* first memory address */
PDATA(pgm)->ext_addr_byte = 0xff;
PDATA(pgm)->xbeeResetPin = XBEE_DEFAULT_RESET_PIN;
}
static void stk500_teardown(PROGRAMMER * pgm)
@@ -1325,8 +1233,7 @@ static void stk500_teardown(PROGRAMMER * pgm)
const char stk500_desc[] = "Atmel STK500 Version 1.x firmware";
void stk500_initpgm(PROGRAMMER * pgm)
{
void stk500_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "STK500");
/*

View File

@@ -26,16 +26,26 @@ extern "C" {
#endif
extern const char stk500_desc[];
void stk500_initpgm (PROGRAMMER * pgm);
void stk500_initpgm(PROGRAMMER *pgm);
/* used by arduino.c to avoid duplicate code */
int stk500_getsync(PROGRAMMER * pgm);
int stk500_drain(PROGRAMMER * pgm, int display);
int stk500_getsync(const PROGRAMMER *pgm);
int stk500_drain(const PROGRAMMER *pgm, int display);
#ifdef __cplusplus
}
#endif
#include "xbee.h"
struct pdata {
unsigned char ext_addr_byte; // Record ext-addr byte set in the target device (if used)
int retry_attempts; // Number of connection attempts provided by the user
int xbeeResetPin; // Piggy back variable used by xbee programmmer
};
#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
#endif

View File

@@ -38,13 +38,11 @@
#include "stk500.h"
#include "stk500v2.h"
static int stk500generic_open(PROGRAMMER * pgm, char * port)
{
static int stk500generic_open(PROGRAMMER *pgm, const char *port) {
stk500_initpgm(pgm);
if (pgm->open(pgm, port) >= 0)
{
avrdude_message(MSG_INFO, "%s: successfully opened stk500v1 device -- please use -c stk500v1\n",
progname);
pmsg_info("successfully opened stk500v1 device -- please use -c stk500v1\n");
return 0;
}
@@ -53,13 +51,11 @@ static int stk500generic_open(PROGRAMMER * pgm, char * port)
stk500v2_initpgm(pgm);
if (pgm->open(pgm, port) >= 0)
{
avrdude_message(MSG_INFO, "%s: successfully opened stk500v2 device -- please use -c stk500v2\n",
progname);
pmsg_info("successfully opened stk500v2 device -- please use -c stk500v2\n");
return 0;
}
avrdude_message(MSG_INFO, "%s: cannot open either stk500v1 or stk500v2 programmer\n",
progname);
pmsg_error("cannot open either stk500v1 or stk500v2 programmer\n");
return -1;
}
@@ -80,8 +76,7 @@ static void stk500generic_teardown(PROGRAMMER * pgm)
const char stk500generic_desc[] = "Atmel STK500, autodetect firmware version";
void stk500generic_initpgm(PROGRAMMER * pgm)
{
void stk500generic_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "STK500GENERIC");
pgm->open = stk500generic_open;

View File

@@ -22,7 +22,7 @@
#define stk500generic_h__
extern const char stk500generic_desc[];
void stk500generic_initpgm (PROGRAMMER * pgm);
void stk500generic_initpgm(PROGRAMMER *pgm);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -37,22 +37,22 @@ extern const char stk500v2_jtag3_desc[];
extern const char stk600_desc[];
extern const char stk600hvsp_desc[];
extern const char stk600pp_desc[];
void stk500v2_initpgm (PROGRAMMER * pgm);
void stk500hvsp_initpgm (PROGRAMMER * pgm);
void stk500pp_initpgm (PROGRAMMER * pgm);
void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm);
void stk500v2_jtag3_initpgm(PROGRAMMER * pgm);
void stk500v2_dragon_hvsp_initpgm(PROGRAMMER * pgm);
void stk500v2_dragon_isp_initpgm(PROGRAMMER * pgm);
void stk500v2_dragon_pp_initpgm(PROGRAMMER * pgm);
void stk600_initpgm (PROGRAMMER * pgm);
void stk600hvsp_initpgm (PROGRAMMER * pgm);
void stk600pp_initpgm (PROGRAMMER * pgm);
void stk500v2_initpgm(PROGRAMMER *pgm);
void stk500hvsp_initpgm(PROGRAMMER *pgm);
void stk500pp_initpgm(PROGRAMMER *pgm);
void stk500v2_jtagmkII_initpgm(PROGRAMMER *pgm);
void stk500v2_jtag3_initpgm(PROGRAMMER *pgm);
void stk500v2_dragon_hvsp_initpgm(PROGRAMMER *pgm);
void stk500v2_dragon_isp_initpgm(PROGRAMMER *pgm);
void stk500v2_dragon_pp_initpgm(PROGRAMMER *pgm);
void stk600_initpgm(PROGRAMMER *pgm);
void stk600hvsp_initpgm(PROGRAMMER *pgm);
void stk600pp_initpgm(PROGRAMMER *pgm);
void stk500v2_setup(PROGRAMMER * pgm);
void stk500v2_teardown(PROGRAMMER * pgm);
int stk500v2_drain(PROGRAMMER * pgm, int display);
int stk500v2_getsync(PROGRAMMER * pgm);
int stk500v2_drain(const PROGRAMMER *pgm, int display);
int stk500v2_getsync(const PROGRAMMER *pgm);
#ifdef __cplusplus
}

View File

@@ -312,7 +312,7 @@ struct pdata
}
pgmtype;
AVRPART *lastpart;
const AVRPART *lastpart;
/* Start address of Xmega boot area */
unsigned long boot_start;

View File

@@ -86,8 +86,7 @@ static void delay_ms(uint32_t duration)
usleep(duration * 1000);
}
static int teensy_get_bootloader_info(pdata_t* pdata, AVRPART* p)
{
static int teensy_get_bootloader_info(pdata_t* pdata, const AVRPART* p) {
switch (pdata->hid_usage)
{
case 0x19:
@@ -128,12 +127,12 @@ static int teensy_get_bootloader_info(pdata_t* pdata, AVRPART* p)
// On Linux, libhidapi does not seem to return the HID usage from the report descriptor.
// We try to infer the board from the part information, until somebody fixes libhidapi.
// To use this workaround, the -F option is required.
avrdude_message(MSG_INFO, "%s: WARNING: Cannot detect board type (HID usage is 0)\n", progname);
pmsg_error("cannot detect board type (HID usage is 0)\n");
AVRMEM* mem = avr_locate_mem(p, "flash");
if (mem == NULL)
{
avrdude_message(MSG_INFO, "No flash memory for part %s\n", p->desc);
pmsg_error("no flash memory defined for part %s\n", p->desc);
return -1;
}
@@ -148,8 +147,7 @@ static int teensy_get_bootloader_info(pdata_t* pdata, AVRPART* p)
}
else
{
avrdude_message(MSG_INFO, "%s: ERROR: Teensy board not supported (HID usage 0x%02X)\n",
progname, pdata->hid_usage);
pmsg_error("Teensy board not supported (HID usage 0x%02X)\n", pdata->hid_usage);
return -1;
}
}
@@ -159,21 +157,21 @@ static int teensy_get_bootloader_info(pdata_t* pdata, AVRPART* p)
static void teensy_dump_device_info(pdata_t* pdata)
{
avrdude_message(MSG_NOTICE, "%s: HID usage: 0x%02X\n", progname, pdata->hid_usage);
avrdude_message(MSG_NOTICE, "%s: Board: %s\n", progname, pdata->board);
avrdude_message(MSG_NOTICE, "%s: Available flash size: %u\n", progname, pdata->flash_size);
avrdude_message(MSG_NOTICE, "%s: Page size: %u\n", progname, pdata->page_size);
avrdude_message(MSG_NOTICE, "%s: Signature: 0x%02X%02X%02X\n", progname,
pdata->sig_bytes[0], pdata->sig_bytes[1], pdata->sig_bytes[2]);
pmsg_notice("HID usage: 0x%02X\n", pdata->hid_usage);
pmsg_notice("Board: %s\n", pdata->board);
pmsg_notice("Available flash size: %u\n", pdata->flash_size);
pmsg_notice("Page size: %u\n", pdata->page_size);
pmsg_notice("Signature: 0x%02X%02X%02X\n",
pdata->sig_bytes[0], pdata->sig_bytes[1], pdata->sig_bytes[2]);
}
static int teensy_write_page(pdata_t* pdata, uint32_t address, const uint8_t* buffer, uint32_t size)
static int teensy_write_page(pdata_t* pdata, uint32_t address, const uint8_t* buffer, uint32_t size, bool suppress_warning)
{
avrdude_message(MSG_DEBUG, "%s: teensy_write_page(address=0x%06X, size=%d)\n", progname, address, size);
pmsg_debug("teensy_write_page(address=0x%06X, size=%d)\n", address, size);
if (size > pdata->page_size)
{
avrdude_message(MSG_INFO, "%s: ERROR: Invalid page size: %u\n", progname, pdata->page_size);
pmsg_error("invalid page size: %u\n", pdata->page_size);
return -1;
}
@@ -181,7 +179,7 @@ static int teensy_write_page(pdata_t* pdata, uint32_t address, const uint8_t* bu
uint8_t* report = (uint8_t*)malloc(report_size);
if (report == NULL)
{
avrdude_message(MSG_INFO, "%s: ERROR: Failed to allocate memory\n", progname);
pmsg_error("unable to allocate memory\n");
return -1;
}
@@ -208,8 +206,9 @@ static int teensy_write_page(pdata_t* pdata, uint32_t address, const uint8_t* bu
free(report);
if (result < 0)
{
avrdude_message(MSG_INFO, "%s: WARNING: Failed to write page: %ls\n",
progname, hid_error(pdata->hid_handle));
if (!suppress_warning)
pmsg_error("unable to write page: %ls\n", hid_error(pdata->hid_handle));
return result;
}
@@ -218,29 +217,29 @@ static int teensy_write_page(pdata_t* pdata, uint32_t address, const uint8_t* bu
static int teensy_erase_flash(pdata_t* pdata)
{
avrdude_message(MSG_DEBUG, "%s: teensy_erase_flash()\n", progname);
pmsg_debug("teensy_erase_flash()\n");
// Write a dummy page at address 0 to explicitly erase the flash.
return teensy_write_page(pdata, 0, NULL, 0);
return teensy_write_page(pdata, 0, NULL, 0, false);
}
static int teensy_reboot(pdata_t* pdata)
{
avrdude_message(MSG_DEBUG, "%s: teensy_reboot()\n", progname);
pmsg_debug("teensy_reboot()\n");
// Write a dummy page at address -1 to reboot the Teensy.
return teensy_write_page(pdata, 0xFFFFFFFF, NULL, 0);
return teensy_write_page(pdata, 0xFFFFFFFF, NULL, 0, true);
}
//-----------------------------------------------------------------------------
static void teensy_setup(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: teensy_setup()\n", progname);
pmsg_debug("teensy_setup()\n");
if ((pgm->cookie = malloc(sizeof(pdata_t))) == NULL)
{
avrdude_message(MSG_INFO, "%s: ERROR: Failed to allocate memory\n", progname);
pmsg_error("unable to allocate memory\n");
exit(1);
}
@@ -249,13 +248,12 @@ static void teensy_setup(PROGRAMMER* pgm)
static void teensy_teardown(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: teensy_teardown()\n", progname);
pmsg_debug("teensy_teardown()\n");
free(pgm->cookie);
}
static int teensy_initialize(PROGRAMMER* pgm, AVRPART* p)
{
avrdude_message(MSG_DEBUG, "%s: teensy_initialize()\n", progname);
static int teensy_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
pmsg_debug("teensy_initialize()\n");
pdata_t* pdata = PDATA(pgm);
@@ -268,19 +266,16 @@ static int teensy_initialize(PROGRAMMER* pgm, AVRPART* p)
return 0;
}
static void teensy_display(PROGRAMMER* pgm, const char* prefix)
{
avrdude_message(MSG_DEBUG, "%s: teensy_display()\n", progname);
static void teensy_display(const PROGRAMMER *pgm, const char *prefix) {
pmsg_debug("teensy_display()\n");
}
static void teensy_powerup(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: teensy_powerup()\n", progname);
static void teensy_powerup(const PROGRAMMER *pgm) {
pmsg_debug("teensy_powerup()\n");
}
static void teensy_powerdown(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: teensy_powerdown()\n", progname);
static void teensy_powerdown(const PROGRAMMER *pgm) {
pmsg_debug("teensy_powerdown()\n");
pdata_t* pdata = PDATA(pgm);
@@ -297,29 +292,25 @@ static void teensy_powerdown(PROGRAMMER* pgm)
}
}
static void teensy_enable(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: teensy_enable()\n", progname);
static void teensy_enable(PROGRAMMER* pgm, const AVRPART *p) {
pmsg_debug("teensy_enable()\n");
}
static void teensy_disable(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: teensy_disable()\n", progname);
static void teensy_disable(const PROGRAMMER *pgm) {
pmsg_debug("teensy_disable()\n");
}
static int teensy_program_enable(PROGRAMMER* pgm, AVRPART* p)
{
avrdude_message(MSG_DEBUG, "%s: teensy_program_enable()\n", progname);
static int teensy_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
pmsg_debug("teensy_program_enable()\n");
return 0;
}
static int teensy_read_sig_bytes(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem)
{
avrdude_message(MSG_DEBUG, "%s: teensy_read_sig_bytes()\n", progname);
static int teensy_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem) {
pmsg_debug("teensy_read_sig_bytes()\n");
if (mem->size < 3)
{
avrdude_message(MSG_INFO, "%s: memory size too small for read_sig_bytes\n", progname);
pmsg_error("memory size too small for read_sig_bytes\n");
return -1;
}
@@ -329,9 +320,8 @@ static int teensy_read_sig_bytes(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem)
return 0;
}
static int teensy_chip_erase(PROGRAMMER* pgm, AVRPART* p)
{
avrdude_message(MSG_DEBUG, "%s: teensy_chip_erase()\n", progname);
static int teensy_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
pmsg_debug("teensy_chip_erase()\n");
pdata_t* pdata = PDATA(pgm);
@@ -341,12 +331,11 @@ static int teensy_chip_erase(PROGRAMMER* pgm, AVRPART* p)
return 0;
}
static int teensy_open(PROGRAMMER* pgm, char* port)
{
avrdude_message(MSG_DEBUG, "%s: teensy_open(\"%s\")\n", progname, port);
static int teensy_open(PROGRAMMER *pgm, const char *port) {
pmsg_debug("teensy_open(\"%s\")\n", port);
pdata_t* pdata = PDATA(pgm);
char* bus_name = NULL;
const char *bus_name = NULL;
char* dev_name = NULL;
// if no -P was given or '-P usb' was given
@@ -371,8 +360,8 @@ static int teensy_open(PROGRAMMER* pgm, char* port)
if (port != NULL && dev_name == NULL)
{
avrdude_message(MSG_INFO, "%s: ERROR: Invalid -P value: '%s'\n", progname, port);
avrdude_message(MSG_INFO, "%sUse -P usb:bus:device\n", progbuf);
pmsg_error("invalid -P value: '%s'\n", port);
imsg_error("Use -P usb:bus:device\n");
return -1;
}
@@ -386,8 +375,7 @@ static int teensy_open(PROGRAMMER* pgm, char* port)
pid = *(int*)(ldata(usbpid));
if (lnext(usbpid))
{
avrdude_message(MSG_INFO, "%s: WARNING: using PID 0x%04x, ignoring remaining PIDs in list\n",
progname, pid);
pmsg_error("using PID 0x%04x, ignoring remaining PIDs in list\n", pid);
}
}
@@ -407,7 +395,7 @@ static int teensy_open(PROGRAMMER* pgm, char* port)
pdata->hid_handle = hid_open_path(device->path);
if (pdata->hid_handle == NULL)
{
avrdude_message(MSG_INFO, "%s: ERROR: Found HID device, but hid_open_path() failed.\n", progname);
pmsg_error("found HID device, but hid_open_path() failed\n");
}
else
{
@@ -427,16 +415,15 @@ static int teensy_open(PROGRAMMER* pgm, char* port)
{
if (pdata->wait_timout < 0)
{
avrdude_message(MSG_INFO, "%s: No device found, waiting for device to be plugged in...\n", progname);
pmsg_error("no device found, waiting for device to be plugged in ...\n");
}
else
{
avrdude_message(MSG_INFO, "%s: No device found, waiting %d seconds for device to be plugged in...\n",
progname,
pmsg_error("no device found, waiting %d seconds for device to be plugged in ...\n",
pdata->wait_timout);
}
avrdude_message(MSG_INFO, "%s: Press CTRL-C to terminate.\n", progname);
pmsg_error("press CTRL-C to terminate\n");
show_retry_message = false;
}
@@ -452,8 +439,7 @@ static int teensy_open(PROGRAMMER* pgm, char* port)
if (!pdata->hid_handle)
{
avrdude_message(MSG_INFO, "%s: ERROR: Could not find device with Teensy bootloader (%04X:%04X)\n",
progname, vid, pid);
pmsg_error("cannot find device with Teensy bootloader (%04X:%04X)\n", vid, pid);
return -1;
}
@@ -462,7 +448,7 @@ static int teensy_open(PROGRAMMER* pgm, char* port)
static void teensy_close(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: teensy_close()\n", progname);
pmsg_debug("teensy_close()\n");
pdata_t* pdata = PDATA(pgm);
if (pdata->hid_handle != NULL)
@@ -472,11 +458,10 @@ static void teensy_close(PROGRAMMER* pgm)
}
}
static int teensy_read_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
static int teensy_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char* value)
{
avrdude_message(MSG_DEBUG, "%s: teensy_read_byte(desc=%s, addr=0x%0X)\n",
progname, mem->desc, addr);
pmsg_debug("teensy_read_byte(desc=%s, addr=0x%04lX)\n", mem->desc, addr);
if (strcmp(mem->desc, "lfuse") == 0 ||
strcmp(mem->desc, "hfuse") == 0 ||
@@ -488,34 +473,31 @@ static int teensy_read_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
}
else
{
avrdude_message(MSG_INFO, "%s: Unsupported memory type: %s\n", progname, mem->desc);
pmsg_error("unsupported memory type: %s\n", mem->desc);
return -1;
}
}
static int teensy_write_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
static int teensy_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char value)
{
avrdude_message(MSG_DEBUG, "%s: teensy_write_byte(desc=%s, addr=0x%0X)\n",
progname, mem->desc, addr);
pmsg_debug("teensy_write_byte(desc=%s, addr=0x%04lX)\n", mem->desc, addr);
return -1;
}
static int teensy_paged_load(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
static int teensy_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
avrdude_message(MSG_DEBUG, "%s: teensy_paged_load(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n",
progname, page_size, addr, n_bytes);
pmsg_debug("teensy_paged_load(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n", page_size, addr, n_bytes);
return -1;
}
static int teensy_paged_write(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
static int teensy_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
avrdude_message(MSG_DEBUG, "%s: teensy_paged_write(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n",
progname, page_size, addr, n_bytes);
pmsg_debug("teensy_paged_write(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n", page_size, addr, n_bytes);
if (strcmp(mem->desc, "flash") == 0)
{
@@ -523,13 +505,13 @@ static int teensy_paged_write(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
if (n_bytes > page_size)
{
avrdude_message(MSG_INFO, "%s: Buffer size (%u) exceeds page size (%u)\n", progname, n_bytes, page_size);
pmsg_error("buffer size %u exceeds page size %u\n", n_bytes, page_size);
return -1;
}
if (addr + n_bytes > pdata->flash_size)
{
avrdude_message(MSG_INFO, "%s: Program size (%u) exceeds flash size (%u)\n", progname, addr + n_bytes, pdata->flash_size);
pmsg_error("program size %u exceeds flash size %u\n", addr + n_bytes, pdata->flash_size);
return -1;
}
@@ -549,7 +531,7 @@ static int teensy_paged_write(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
pdata->erase_flash = false;
}
int result = teensy_write_page(pdata, addr, mem->buf + addr, n_bytes);
int result = teensy_write_page(pdata, addr, mem->buf + addr, n_bytes, false);
if (result < 0)
{
return result;
@@ -562,14 +544,13 @@ static int teensy_paged_write(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
}
else
{
avrdude_message(MSG_INFO, "%s: Unsupported memory type: %s\n", progname, mem->desc);
pmsg_error("unsupported memory type: %s\n", mem->desc);
return -1;
}
}
static int teensy_parseextparams(PROGRAMMER* pgm, LISTID xparams)
{
avrdude_message(MSG_DEBUG, "%s: teensy_parseextparams()\n", progname);
static int teensy_parseextparams(const PROGRAMMER *pgm, const LISTID xparams) {
pmsg_debug("teensy_parseextparams()\n");
pdata_t* pdata = PDATA(pgm);
for (LNODEID node = lfirst(xparams); node != NULL; node = lnext(node))
@@ -588,7 +569,7 @@ static int teensy_parseextparams(PROGRAMMER* pgm, LISTID xparams)
}
else
{
avrdude_message(MSG_INFO, "%s: Invalid extended parameter '%s'\n", progname, param);
pmsg_error("invalid extended parameter '%s'\n", param);
return -1;
}
}
@@ -596,8 +577,7 @@ static int teensy_parseextparams(PROGRAMMER* pgm, LISTID xparams)
return 0;
}
void teensy_initpgm(PROGRAMMER* pgm)
{
void teensy_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "teensy");
pgm->setup = teensy_setup;
@@ -624,14 +604,12 @@ void teensy_initpgm(PROGRAMMER* pgm)
#else /* !HAVE_LIBHIDAPI */
// Give a proper error if we were not compiled with libhidapi
static int teensy_nousb_open(struct programmer_t* pgm, char* name)
{
avrdude_message(MSG_INFO, "%s: error: No HID support. Please compile again with libhidapi installed.\n", progname);
static int teensy_nousb_open(PROGRAMMER *pgm, const char *name) {
pmsg_error("no HID support; please compile again with libhidapi installed\n");
return -1;
}
void teensy_initpgm(PROGRAMMER* pgm)
{
void teensy_initpgm(PROGRAMMER *pgm) {
strcpy(pgm->type, "teensy");
pgm->open = teensy_nousb_open;
}

View File

@@ -26,7 +26,7 @@ extern "C" {
#endif
extern const char teensy_desc[];
void teensy_initpgm(PROGRAMMER* pgm);
void teensy_initpgm(PROGRAMMER *pgm);
#ifdef __cplusplus
}

1158
src/term.c

File diff suppressed because it is too large Load Diff

View File

@@ -34,6 +34,8 @@ typedef enum {
int terminal_mode(PROGRAMMER * pgm, struct avrpart * p);
char * terminal_get_input(const char *prompt);
void terminal_setup_update_progress();
int terminal_message(const int msglvl, const char *format, ...);
#ifdef __cplusplus
}

View File

@@ -24,6 +24,9 @@
#include <errno.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "ac_cfg.h"
#include "avrdude.h"
@@ -37,37 +40,23 @@ UPDATE * parse_op(char * s)
int i;
size_t fnlen;
upd = (UPDATE *)malloc(sizeof(UPDATE));
if (upd == NULL) {
avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
exit(1);
}
upd = (UPDATE *) cfg_malloc("parse_op()", sizeof(UPDATE));
i = 0;
p = s;
while ((i < (sizeof(buf)-1) && *p && (*p != ':')))
while (i < (int) sizeof(buf)-1 && *p && *p != ':')
buf[i++] = *p++;
buf[i] = 0;
if (*p != ':') {
upd->memtype = NULL; /* default memtype, "flash", or "application" */
upd->op = DEVICE_WRITE;
upd->filename = (char *)malloc(strlen(buf) + 1);
if (upd->filename == NULL) {
avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
exit(1);
}
strcpy(upd->filename, buf);
upd->filename = cfg_strdup("parse_op()", buf);
upd->format = FMT_AUTO;
return upd;
}
upd->memtype = (char *)malloc(strlen(buf)+1);
if (upd->memtype == NULL) {
avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
exit(1);
}
strcpy(upd->memtype, buf);
upd->memtype = cfg_strdup("parse_op()", buf);
p++;
if (*p == 'r') {
@@ -80,12 +69,11 @@ UPDATE * parse_op(char * s)
upd->op = DEVICE_VERIFY;
}
else {
avrdude_message(MSG_INFO, "%s: invalid I/O mode '%c' in update specification\n",
progname, *p);
avrdude_message(MSG_INFO, " allowed values are:\n"
" r = read device\n"
" w = write device\n"
" v = verify device\n");
pmsg_error("invalid I/O mode '%c' in update specification\n", *p);
msg_error(" allowed values are:\n"
" r = read device\n"
" w = write device\n"
" v = verify device\n");
free(upd->memtype);
free(upd);
return NULL;
@@ -94,7 +82,7 @@ UPDATE * parse_op(char * s)
p++;
if (*p != ':') {
avrdude_message(MSG_INFO, "%s: invalid update specification\n", progname);
pmsg_error("invalid update specification\n");
free(upd->memtype);
free(upd);
return NULL;
@@ -118,10 +106,10 @@ UPDATE * parse_op(char * s)
// and to binary for read operations:
upd->format = upd->op == DEVICE_READ? FMT_RBIN: FMT_AUTO;
fnlen = strlen(cp);
upd->filename = (char *)malloc(fnlen + 1);
upd->filename = (char *) cfg_malloc("parse_op()", fnlen + 1);
} else {
fnlen = p - cp;
upd->filename = (char *)malloc(fnlen +1);
upd->filename = (char *) cfg_malloc("parse_op()", fnlen +1);
c = *++p;
if (c && p[1])
/* More than one char - force failure below. */
@@ -130,6 +118,7 @@ UPDATE * parse_op(char * s)
case 'a': upd->format = FMT_AUTO; break;
case 's': upd->format = FMT_SREC; break;
case 'i': upd->format = FMT_IHEX; break;
case 'I': upd->format = FMT_IHXC; break;
case 'r': upd->format = FMT_RBIN; break;
case 'e': upd->format = FMT_ELF; break;
case 'm': upd->format = FMT_IMM; break;
@@ -138,20 +127,13 @@ UPDATE * parse_op(char * s)
case 'h': upd->format = FMT_HEX; break;
case 'o': upd->format = FMT_OCT; break;
default:
avrdude_message(MSG_INFO, "%s: invalid file format '%s' in update specifier\n",
progname, p);
pmsg_error("invalid file format '%s' in update specifier\n", p);
free(upd->memtype);
free(upd);
return NULL;
}
}
if (upd->filename == NULL) {
avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
free(upd->memtype);
free(upd);
return NULL;
}
memcpy(upd->filename, cp, fnlen);
upd->filename[fnlen] = 0;
@@ -162,19 +144,15 @@ UPDATE * dup_update(UPDATE * upd)
{
UPDATE * u;
u = (UPDATE *)malloc(sizeof(UPDATE));
if (u == NULL) {
avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
exit(1);
}
u = (UPDATE *) cfg_malloc("dup_update()", sizeof(UPDATE));
memcpy(u, upd, sizeof(UPDATE));
if (upd->memtype != NULL)
u->memtype = strdup(upd->memtype);
u->memtype = cfg_strdup("dup_update()", upd->memtype);
else
u->memtype = NULL;
u->filename = strdup(upd->filename);
u->filename = cfg_strdup("dup_update()", upd->filename);
return u;
}
@@ -183,14 +161,10 @@ UPDATE * new_update(int op, char * memtype, int filefmt, char * filename)
{
UPDATE * u;
u = (UPDATE *)malloc(sizeof(UPDATE));
if (u == NULL) {
avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
exit(1);
}
u = (UPDATE *) cfg_malloc("new_update()", sizeof(UPDATE));
u->memtype = strdup(memtype);
u->filename = strdup(filename);
u->memtype = cfg_strdup("new_update()", memtype);
u->filename = cfg_strdup("new_update()", filename);
u->op = op;
u->format = filefmt;
@@ -213,188 +187,420 @@ void free_update(UPDATE * u)
}
// Memory statistics considering holes after a file read returned size bytes
int memstats(struct avrpart *p, char *memtype, int size, Filestats *fsp) {
Filestats ret = { 0 };
AVRMEM *mem = avr_locate_mem(p, memtype);
if(!mem) {
pmsg_error("%s %s undefined\n", p->desc, memtype);
return LIBAVRDUDE_GENERAL_FAILURE;
}
if(!mem->buf || !mem->tags) {
pmsg_error("%s %s is not set\n", p->desc, memtype);
return LIBAVRDUDE_GENERAL_FAILURE;
}
int pgsize = mem->page_size;
if(pgsize < 1)
pgsize = 1;
if(size < 0 || size > mem->size) {
pmsg_error("size %d at odds with %s %s size %d\n", size, p->desc, memtype, mem->size);
return LIBAVRDUDE_GENERAL_FAILURE;
}
ret.lastaddr = -1;
int firstset = 0, insection = 0;
// Scan all memory
for(int addr = 0; addr < mem->size; ) {
int pageset = 0;
// Go page by page
for(int pgi = 0; pgi < pgsize; pgi++, addr++) {
if(mem->tags[addr] & TAG_ALLOCATED) {
if(!firstset) {
firstset = 1;
ret.firstaddr = addr;
}
ret.lastaddr = addr;
// size can be smaller than tags suggest owing to flash trailing-0xff
if(addr < size) {
ret.nbytes++;
if(!pageset) {
pageset = 1;
ret.nfill += pgi;
ret.npages++;
}
if(!insection) {
insection = 1;
ret.nsections++;
}
} else { // Now beyond size returned by input file read
ret.ntrailing++;
if(pageset)
ret.nfill++;
}
} else { // In a hole or beyond input file
insection = 0;
if(pageset)
ret.nfill++;
}
}
}
if(fsp)
*fsp = ret;
return LIBAVRDUDE_SUCCESS;
}
// Convenience functions for printing
const char *update_plural(int x) {
return x==1? "": "s";
}
const char *update_inname(const char *fn) {
return !fn? "???": strcmp(fn, "-")? fn: "<stdin>";
}
const char *update_outname(const char *fn) {
return !fn? "???": strcmp(fn, "-")? fn: "<stdout>";
}
// Return sth like "[0, 0x1ff]"
const char *update_interval(int a, int b) {
// Cyclic buffer for 20+ temporary interval strings each max 41 bytes at 64-bit int
static char space[20*41 + 80], *sp;
if(!sp || sp-space > (int) sizeof space - 80)
sp = space;
char *ret = sp;
sprintf(sp, a<16? "[%d": "[0x%x", a);
sp += strlen(sp);
sprintf(sp, b<16? ", %d]": ", 0x%x]", b);
// Advance beyond return string in temporary ring buffer
sp += strlen(sp)+1;
return ret;
}
// Helper functions for dry run to determine file access
int update_is_okfile(const char *fn) {
struct stat info;
// File exists and is a regular file or a character file, eg, /dev/urandom
return fn && *fn && stat(fn, &info) == 0 && !!(info.st_mode & (S_IFREG | S_IFCHR));
}
int update_is_writeable(const char *fn) {
if(!fn || !*fn)
return 0;
// Assume writing to stdout will be OK
if(!strcmp(fn, "-"))
return 1;
// File exists? If so return whether it's readable and an OK file type
if(access(fn, F_OK) == 0)
return access(fn, W_OK) == 0 && update_is_okfile(fn);
// File does not exist: try to create it
FILE *test = fopen(fn, "w");
if(test) {
unlink(fn);
fclose(test);
}
return !!test;
}
int update_is_readable(const char *fn) {
if(!fn || !*fn)
return 0;
// Assume reading from stdin will be OK
if(!strcmp(fn, "-"))
return 1;
// File exists, is readable by the process and an OK file type?
return access(fn, R_OK) == 0 && update_is_okfile(fn);
}
static void ioerror(const char *iotype, UPDATE *upd) {
int errnocp = errno;
pmsg_ext_error("file %s is not %s", update_outname(upd->filename), iotype);
if(errnocp)
msg_ext_error("memstats(): %s", strerror(errnocp));
else if(upd->filename && *upd->filename)
msg_ext_error(" (not a regular or character file?)");
msg_ext_error("\n");
}
// Basic checks to reveal serious failure before programming
int update_dryrun(struct avrpart *p, UPDATE *upd) {
static char **wrote;
static int nfwritten;
int known, format_detect, ret = LIBAVRDUDE_SUCCESS;
/*
* Reject an update if memory name is not known amongst any part (suspect a typo)
* but accept when the specific part does not have it (allow unifying i/faces)
*/
if(!avr_mem_might_be_known(upd->memtype)) {
pmsg_error("unknown memory type %s\n", upd->memtype);
ret = LIBAVRDUDE_GENERAL_FAILURE;
} else if(p && !avr_locate_mem(p, upd->memtype))
ret = LIBAVRDUDE_SOFTFAIL;
known = 0;
// Necessary to check whether the file is readable?
if(upd->op == DEVICE_VERIFY || upd->op == DEVICE_WRITE || upd->format == FMT_AUTO) {
if(upd->format != FMT_IMM) {
// Need to read the file: was it written before, so will be known?
for(int i = 0; i < nfwritten; i++)
if(!wrote || (upd->filename && !strcmp(wrote[i], upd->filename)))
known = 1;
errno = 0;
if(!known && !update_is_readable(upd->filename)) {
ioerror("readable", upd);
ret = LIBAVRDUDE_GENERAL_FAILURE;
known = 1; // Pretend we know it, so no auto detect needed
}
}
}
if(!known && upd->format == FMT_AUTO) {
if(!strcmp(upd->filename, "-")) {
pmsg_error("cannot auto detect file format for stdin/out, "
"specify explicitly\n");
ret = LIBAVRDUDE_GENERAL_FAILURE;
} else if((format_detect = fileio_fmt_autodetect(upd->filename)) < 0) {
pmsg_error("cannot determine file format for %s, specify explicitly\n", upd->filename);
ret = LIBAVRDUDE_GENERAL_FAILURE;
} else {
// Set format now, no need to repeat auto detection later
upd->format = format_detect;
if(quell_progress < 2)
pmsg_notice("%s file %s auto detected as %s\n",
upd->op == DEVICE_READ? "output": "input", upd->filename,
fileio_fmtstr(upd->format));
}
}
switch(upd->op) {
case DEVICE_READ:
if(upd->format == FMT_IMM) {
pmsg_error("invalid file format 'immediate' for output\n");
ret = LIBAVRDUDE_GENERAL_FAILURE;
} else {
errno = 0;
if(!update_is_writeable(upd->filename)) {
ioerror("writeable", upd);
ret = LIBAVRDUDE_GENERAL_FAILURE;
} else if(upd->filename) { // Record filename (other than stdout) is available for future reads
if(strcmp(upd->filename, "-") && (wrote = realloc(wrote, sizeof(*wrote) * (nfwritten+1))))
wrote[nfwritten++] = upd->filename;
}
}
break;
case DEVICE_VERIFY: // Already checked that file is readable
case DEVICE_WRITE:
break;
default:
pmsg_error("invalid update operation (%d) requested\n", upd->op);
ret = LIBAVRDUDE_GENERAL_FAILURE;
}
return ret;
}
int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags flags)
{
struct avrpart * v;
AVRMEM * mem;
int size, vsize;
int size;
int rc;
Filestats fs;
mem = avr_locate_mem(p, upd->memtype);
if (mem == NULL) {
avrdude_message(MSG_INFO, "\"%s\" memory type not defined for part \"%s\"\n",
upd->memtype, p->desc);
return -1;
pmsg_warning("skipping -U %s:... as memory not defined for part %s\n", upd->memtype, p->desc);
return LIBAVRDUDE_SOFTFAIL;
}
AVRMEM_ALIAS * alias_mem = avr_find_memalias(p, mem);
char alias_mem_desc[AVR_DESCLEN + 1] = "";
if(alias_mem) {
strcat(alias_mem_desc, "/");
strcat(alias_mem_desc, alias_mem->desc);
AVRMEM_ALIAS *alias_mem = avr_find_memalias(p, mem);
char *alias_mem_desc = cfg_malloc("do_op()", 2 + (alias_mem && alias_mem->desc? strlen(alias_mem->desc): 0));
if(alias_mem && alias_mem->desc && *alias_mem->desc) {
*alias_mem_desc = '/';
strcpy(alias_mem_desc+1, alias_mem->desc);
}
if (upd->op == DEVICE_READ) {
/*
* read out the specified device memory and write it to a file
*/
switch (upd->op) {
case DEVICE_READ:
// Read out the specified device memory and write it to a file
if (upd->format == FMT_IMM) {
avrdude_message(MSG_INFO,
"%s: Invalid file format 'immediate' for output\n",
progname, upd->filename);
return -1;
pmsg_error("invalid file format 'immediate' for output\n");
return LIBAVRDUDE_GENERAL_FAILURE;
}
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: reading %s%s memory:\n",
progname, mem->desc, alias_mem_desc);
}
report_progress(0,1,"Reading");
pmsg_info("reading %s%s memory ...\n", mem->desc, alias_mem_desc);
report_progress(0, 1, "Reading");
rc = avr_read(pgm, p, upd->memtype, 0);
report_progress(1, 1, NULL);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: failed to read all of %s%s memory, rc=%d\n",
progname, mem->desc, alias_mem_desc, rc);
return -1;
pmsg_error("unable to read all of %s%s memory, rc=%d\n", mem->desc, alias_mem_desc, rc);
return LIBAVRDUDE_GENERAL_FAILURE;
}
report_progress(1,1,NULL);
size = rc;
if (quell_progress < 2) {
if (rc == 0)
avrdude_message(MSG_INFO, "%s: Flash is empty, resulting file has no contents.\n",
progname);
avrdude_message(MSG_INFO, "%s: writing output file \"%s\"\n",
progname,
strcmp(upd->filename, "-")==0 ? "<stdout>" : upd->filename);
}
if (rc == 0)
pmsg_notice("flash is empty, resulting file has no contents\n");
pmsg_info("writing output file %s\n", update_outname(upd->filename));
rc = fileio(FIO_WRITE, upd->filename, upd->format, p, upd->memtype, size);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: write to file '%s' failed\n",
progname, upd->filename);
return -1;
}
}
else if (upd->op == DEVICE_WRITE) {
/*
* write the selected device memory using data from a file; first
* read the data from the specified file
*/
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: reading input file \"%s\"\n",
progname,
strcmp(upd->filename, "-")==0 ? "<stdin>" : upd->filename);
pmsg_error("write to file %s failed\n", update_outname(upd->filename));
return LIBAVRDUDE_GENERAL_FAILURE;
}
break;
case DEVICE_WRITE:
// Write the selected device memory using data from a file
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: read from file '%s' failed\n",
progname, upd->filename);
return -1;
pmsg_error("read from file %s failed\n", update_inname(upd->filename));
return LIBAVRDUDE_GENERAL_FAILURE;
}
size = rc;
pmsg_info("reading input file %s for %s%s\n",
update_inname(upd->filename), mem->desc, alias_mem_desc);
/*
* write the buffer contents to the selected memory type
*/
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: writing %s%s (%d bytes):\n",
progname, mem->desc, alias_mem_desc, size);
}
if(memstats(p, upd->memtype, size, &fs) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
imsg_info("with %d byte%s in %d section%s within %s\n",
fs.nbytes, update_plural(fs.nbytes),
fs.nsections, update_plural(fs.nsections),
update_interval(fs.firstaddr, fs.lastaddr));
if(mem->page_size > 1) {
imsg_info("using %d page%s and %d pad byte%s",
fs.npages, update_plural(fs.npages),
fs.nfill, update_plural(fs.nfill));
if(fs.ntrailing)
msg_info(", cutting off %d trailing 0xff byte%s",
fs.ntrailing, update_plural(fs.ntrailing));
msg_info("\n");
}
// Write the buffer contents to the selected memory type
pmsg_info("writing %d byte%s %s%s ...\n", fs.nbytes,
update_plural(fs.nbytes), mem->desc, alias_mem_desc);
if (!(flags & UF_NOWRITE)) {
report_progress(0,1,"Writing");
report_progress(0, 1, "Writing");
rc = avr_write(pgm, p, upd->memtype, size, (flags & UF_AUTO_ERASE) != 0);
report_progress(1,1,NULL);
}
else {
/*
* test mode, don't actually write to the chip, output the buffer
* to stdout in intel hex instead
*/
report_progress(1, 1, NULL);
} else {
// Test mode: write to stdout in intel hex rather than to the chip
rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, upd->memtype, size);
}
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: failed to write %s%s memory, rc=%d\n",
progname, mem->desc, alias_mem_desc, rc);
return -1;
pmsg_error("unable to write %s%s memory, rc=%d\n", mem->desc, alias_mem_desc, rc);
return LIBAVRDUDE_GENERAL_FAILURE;
}
vsize = rc;
pmsg_info("%d byte%s of %s%s written\n", fs.nbytes,
update_plural(fs.nbytes), mem->desc, alias_mem_desc);
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: %d bytes of %s%s written\n", progname,
vsize, mem->desc, alias_mem_desc);
}
// Fall through for (default) auto verify, ie, unless -V was specified
if (!(flags & UF_VERIFY))
break;
}
else if (upd->op == DEVICE_VERIFY) {
/*
* verify that the in memory file (p->mem[AVR_M_FLASH|AVR_M_EEPROM])
* is the same as what is on the chip
*/
case DEVICE_VERIFY:
// Verify that the in memory file is the same as what is on the chip
pgm->vfy_led(pgm, ON);
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: verifying %s%s memory against %s:\n",
progname, mem->desc, alias_mem_desc, upd->filename);
int userverify = upd->op == DEVICE_VERIFY; // Explicit -U :v by user
avrdude_message(MSG_NOTICE2, "%s: load data %s%s data from input file %s:\n",
progname, mem->desc, alias_mem_desc, upd->filename);
pmsg_info("verifying %s%s memory against %s\n", mem->desc,
alias_mem_desc, update_inname(upd->filename));
// No need to read file when fallen through from DEVICE_WRITE
if (userverify) {
pmsg_notice("load %s%s data from input file %s\n", mem->desc,
alias_mem_desc, update_inname(upd->filename));
rc = fileio(FIO_READ_FOR_VERIFY, upd->filename, upd->format, p, upd->memtype, -1);
if (rc < 0) {
pmsg_error("read from file %s failed\n", update_inname(upd->filename));
return LIBAVRDUDE_GENERAL_FAILURE;
}
size = rc;
if(memstats(p, upd->memtype, size, &fs) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
} else {
// Correct size of last read to include potentially cut off, trailing 0xff (flash)
size = fs.lastaddr+1;
}
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: read from file '%s' failed\n",
progname, upd->filename);
return -1;
}
v = avr_dup_part(p);
size = rc;
if (quell_progress < 2) {
avrdude_message(MSG_NOTICE2, "%s: input file %s contains %d bytes\n",
progname, upd->filename, size);
avrdude_message(MSG_NOTICE2, "%s: reading on-chip %s%s data:\n",
progname, mem->desc, alias_mem_desc);
if (userverify)
pmsg_notice("input file %s contains %d byte%s\n",
update_inname(upd->filename), fs.nbytes, update_plural(fs.nbytes));
pmsg_notice2("reading on-chip %s%s data ...\n", mem->desc, alias_mem_desc);
}
report_progress (0,1,"Reading");
rc = avr_read(pgm, p, upd->memtype, v);
report_progress (1,1,NULL);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: failed to read all of %s%s memory, rc=%d\n",
progname, mem->desc, alias_mem_desc, rc);
pmsg_error("unable to read all of %s%s memory, rc=%d\n", mem->desc, alias_mem_desc, rc);
pgm->err_led(pgm, ON);
avr_free_part(v);
return -1;
return LIBAVRDUDE_GENERAL_FAILURE;
}
report_progress (1,1,NULL);
if (quell_progress < 2)
pmsg_notice2("verifying ...\n");
if (quell_progress < 2) {
avrdude_message(MSG_NOTICE2, "%s: verifying ...\n", progname);
}
rc = avr_verify(p, v, upd->memtype, size);
if (rc < 0) {
avrdude_message(MSG_INFO, "%s: verification error; content mismatch\n",
progname);
pmsg_error("verification mismatch\n");
pgm->err_led(pgm, ON);
avr_free_part(v);
return -1;
return LIBAVRDUDE_GENERAL_FAILURE;
}
if (quell_progress < 2) {
avrdude_message(MSG_INFO, "%s: %d bytes of %s%s verified\n",
progname, rc, mem->desc, alias_mem_desc);
}
int verified = fs.nbytes+fs.ntrailing;
pmsg_info("%d byte%s of %s%s verified\n", verified, update_plural(verified), mem->desc, alias_mem_desc);
pgm->vfy_led(pgm, OFF);
avr_free_part(v);
}
else {
avrdude_message(MSG_INFO, "%s: invalid update operation (%d) requested\n",
progname, upd->op);
return -1;
break;
default:
pmsg_error("invalid update operation (%d) requested\n", upd->op);
return LIBAVRDUDE_GENERAL_FAILURE;
}
return 0;
return LIBAVRDUDE_SUCCESS;
}

View File

@@ -39,8 +39,7 @@
#include "updi_constants.h"
#include "updi_state.h"
static void updi_set_rtsdtr_mode(PROGRAMMER* pgm)
{
static void updi_set_rtsdtr_mode(const PROGRAMMER *pgm) {
updi_rts_mode rts_mode = updi_get_rts_mode(pgm);
if (rts_mode == RTS_MODE_DEFAULT) {
@@ -59,11 +58,11 @@ static int updi_physical_open(PROGRAMMER* pgm, int baudrate, unsigned long cflag
pinfo.serialinfo.baud = baudrate;
pinfo.serialinfo.cflags = cflags;
avrdude_message(MSG_DEBUG, "%s: Opening serial port...\n", progname);
pmsg_debug("opening serial port ...\n");
if (serial_open(pgm->port, pinfo, &pgm->fd)==-1) {
avrdude_message(MSG_DEBUG, "%s: Serial port open failed!\n", progname);
pmsg_debug("serial port open failed!\n");
return -1;
}
@@ -87,55 +86,50 @@ static void updi_physical_close(PROGRAMMER* pgm)
pgm->fd.ifd = -1;
}
static int updi_physical_send(PROGRAMMER * pgm, unsigned char * buf, size_t len)
{
static int updi_physical_send(const PROGRAMMER *pgm, unsigned char *buf, size_t len) {
size_t i;
int rv;
avrdude_message(MSG_DEBUG, "%s: Sending %lu bytes [", progname, len);
pmsg_debug("sending %lu bytes [", len);
for (i=0; i<len; i++) {
avrdude_message(MSG_DEBUG, "0x%02x", buf[i]);
msg_debug("0x%02x", buf[i]);
if (i<len-1) {
avrdude_message(MSG_DEBUG, ", ");
msg_debug(", ");
}
}
avrdude_message(MSG_DEBUG, "]\n");
msg_debug("]\n");
rv = serial_send(&pgm->fd, buf, len);
serial_recv(&pgm->fd, buf, len);
return rv;
}
static int updi_physical_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
{
static int updi_physical_recv(const PROGRAMMER *pgm, unsigned char *buf, size_t len) {
size_t i;
int rv;
rv = serial_recv(&pgm->fd, buf, len);
if (rv < 0) {
avrdude_message(MSG_DEBUG,
"%s: serialupdi_recv(): programmer is not responding\n",
progname);
pmsg_debug("serialupdi_recv(): programmer is not responding\n");
return -1;
}
avrdude_message(MSG_DEBUG, "%s: Received %lu bytes [", progname, len);
pmsg_debug("received %lu bytes [", len);
for (i=0; i<len; i++) {
avrdude_message(MSG_DEBUG, "0x%02x", buf[i]);
msg_debug("0x%02x", buf[i]);
if (i<len-1) {
avrdude_message(MSG_DEBUG, ", ");
msg_debug(", ");
}
}
avrdude_message(MSG_DEBUG, "]\n");
msg_debug("]\n");
return len;
}
static int updi_physical_send_double_break(PROGRAMMER * pgm)
{
static int updi_physical_send_double_break(const PROGRAMMER *pgm) {
unsigned char buffer[1];
avrdude_message(MSG_DEBUG, "%s: Sending double break\n", progname);
pmsg_debug("sending double break\n");
if (serial_setparams(&pgm->fd, 300, SERIAL_8E1) < 0) {
return -1;
@@ -171,8 +165,7 @@ static int updi_physical_send_double_break(PROGRAMMER * pgm)
return 0;
}
int updi_physical_sib(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size)
{
int updi_physical_sib(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size) {
/*
def sib(self):
"""
@@ -189,15 +182,14 @@ int updi_physical_sib(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size)
send_buffer[1] = UPDI_KEY | UPDI_KEY_SIB | UPDI_SIB_32BYTES;
if (updi_physical_send(pgm, send_buffer, 2) < 0) {
avrdude_message(MSG_DEBUG, "%s: SIB request send failed\n", progname);
pmsg_debug("SIB request send failed\n");
return -1;
}
return updi_physical_recv(pgm, buffer, size);
}
int updi_link_open(PROGRAMMER * pgm)
{
int updi_link_open(PROGRAMMER *pgm) {
unsigned char init_buffer[1];
if (updi_physical_open(pgm, pgm->baudrate? pgm->baudrate: 115200, SERIAL_8E2) < 0) {
@@ -208,13 +200,11 @@ int updi_link_open(PROGRAMMER * pgm)
return updi_physical_send(pgm, init_buffer, 1);
}
void updi_link_close(PROGRAMMER * pgm)
{
void updi_link_close(PROGRAMMER *pgm) {
updi_physical_close(pgm);
}
static int updi_link_init_session_parameters(PROGRAMMER * pgm)
{
static int updi_link_init_session_parameters(const PROGRAMMER *pgm) {
/*
def _init_session_parameters(self):
"""
@@ -234,8 +224,7 @@ static int updi_link_init_session_parameters(PROGRAMMER * pgm)
return 0;
}
static int updi_link_check(PROGRAMMER * pgm)
{
static int updi_link_check(const PROGRAMMER *pgm) {
/*
def _check_datalink(self):
"""
@@ -255,22 +244,21 @@ static int updi_link_check(PROGRAMMER * pgm)
uint8_t value;
result = updi_link_ldcs(pgm, UPDI_CS_STATUSA, &value);
if (result < 0) {
avrdude_message(MSG_DEBUG, "%s: Check failed\n", progname);
pmsg_debug("check failed\n");
return -1;
} else {
if (value > 0) {
avrdude_message(MSG_DEBUG, "%s: UDPI init OK\n", progname);
pmsg_debug("UDPI init OK\n");
return 0;
} else {
avrdude_message(MSG_DEBUG, "%s: UDPI not OK - reinitialisation required\n", progname);
pmsg_debug("UDPI not OK - reinitialisation required\n");
return -1;
}
}
}
int updi_link_init(PROGRAMMER * pgm)
{
int updi_link_init(const PROGRAMMER *pgm) {
/*
def init_datalink(self):
"""
@@ -286,30 +274,29 @@ int updi_link_init(PROGRAMMER * pgm)
raise PymcuprogError("UPDI initialisation failed")
*/
if (updi_link_init_session_parameters(pgm) < 0) {
avrdude_message(MSG_DEBUG, "%s: Session initialisation failed\n", progname);
pmsg_debug("session initialisation failed\n");
return -1;
}
if (updi_link_check(pgm) < 0) {
avrdude_message(MSG_DEBUG, "%s: Datalink not active, resetting...\n", progname);
pmsg_debug("datalink not active, resetting ...\n");
if (updi_physical_send_double_break(pgm) < 0) {
avrdude_message(MSG_DEBUG, "%s: Datalink initialisation failed\n", progname);
pmsg_debug("datalink initialisation failed\n");
return -1;
}
if (updi_link_init_session_parameters(pgm) < 0) {
avrdude_message(MSG_DEBUG, "%s: Session initialisation failed\n", progname);
pmsg_debug("session initialisation failed\n");
return -1;
}
if (updi_link_check(pgm) < 0) {
avrdude_message(MSG_DEBUG, "%s: Restoring datalink failed\n", progname);
pmsg_debug("restoring datalink failed\n");
return -1;
}
}
return 0;
}
int updi_link_ldcs(PROGRAMMER * pgm, uint8_t address, uint8_t * value)
{
int updi_link_ldcs(const PROGRAMMER *pgm, uint8_t address, uint8_t *value) {
/*
def ldcs(self, address):
"""
@@ -329,17 +316,17 @@ int updi_link_ldcs(PROGRAMMER * pgm, uint8_t address, uint8_t * value)
*/
unsigned char buffer[2];
int result;
avrdude_message(MSG_DEBUG, "%s: LDCS from 0x%02X\n", progname, address);
pmsg_debug("LDCS from 0x%02X\n", address);
buffer[0]=UPDI_PHY_SYNC;
buffer[1]=UPDI_LDCS | (address & 0x0F);
if (updi_physical_send(pgm, buffer, 2) < 0) {
avrdude_message(MSG_DEBUG, "%s: LDCS send operation failed\n", progname);
pmsg_debug("LDCS send operation failed\n");
return -1;
}
result = updi_physical_recv(pgm, buffer, 1);
if (result != 1) {
if (result >= 0) {
avrdude_message(MSG_DEBUG, "%s: Incorrect response size, received %d instead of %d bytes\n", progname, result, 1);
pmsg_debug("incorrect response size, received %d instead of %d bytes\n", result, 1);
}
return -1;
}
@@ -347,8 +334,7 @@ int updi_link_ldcs(PROGRAMMER * pgm, uint8_t address, uint8_t * value)
return 0;
}
int updi_link_stcs(PROGRAMMER * pgm, uint8_t address, uint8_t value)
{
int updi_link_stcs(const PROGRAMMER *pgm, uint8_t address, uint8_t value) {
/*
def stcs(self, address, value):
"""
@@ -361,15 +347,14 @@ int updi_link_stcs(PROGRAMMER * pgm, uint8_t address, uint8_t value)
self.updi_phy.send([constants.UPDI_PHY_SYNC, constants.UPDI_STCS | (address & 0x0F), value])
*/
unsigned char buffer[3];
avrdude_message(MSG_DEBUG, "%s: STCS 0x%02X to address 0x%02X\n", progname, value, address);
pmsg_debug("STCS 0x%02X to address 0x%02X\n", value, address);
buffer[0] = UPDI_PHY_SYNC;
buffer[1] = UPDI_STCS | (address & 0x0F);
buffer[2] = value;
return updi_physical_send(pgm, buffer, 3);
}
int updi_link_ld_ptr_inc(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size)
{
int updi_link_ld_ptr_inc(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size) {
/*
def ld_ptr_inc(self, size):
"""
@@ -384,18 +369,17 @@ int updi_link_ld_ptr_inc(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size
return self.updi_phy.receive(size)
*/
unsigned char send_buffer[2];
avrdude_message(MSG_DEBUG, "%s: LD8 from ptr++\n", progname);
pmsg_debug("LD8 from ptr++\n");
send_buffer[0] = UPDI_PHY_SYNC;
send_buffer[1] = UPDI_LD | UPDI_PTR_INC | UPDI_DATA_8;
if (updi_physical_send(pgm, send_buffer, 2) < 0) {
avrdude_message(MSG_DEBUG, "%s: LD_PTR_INC send operation failed\n", progname);
pmsg_debug("LD_PTR_INC send operation failed\n");
return -1;
}
return updi_physical_recv(pgm, buffer, size);
}
int updi_link_ld_ptr_inc16(PROGRAMMER * pgm, unsigned char * buffer, uint16_t words)
{
int updi_link_ld_ptr_inc16(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words) {
/*
def ld_ptr_inc16(self, words):
"""
@@ -410,18 +394,17 @@ int updi_link_ld_ptr_inc16(PROGRAMMER * pgm, unsigned char * buffer, uint16_t wo
return self.updi_phy.receive(words << 1)
*/
unsigned char send_buffer[2];
avrdude_message(MSG_DEBUG, "%s: LD16 from ptr++\n", progname);
pmsg_debug("LD16 from ptr++\n");
send_buffer[0] = UPDI_PHY_SYNC;
send_buffer[1] = UPDI_LD | UPDI_PTR_INC | UPDI_DATA_16;
if (updi_physical_send(pgm, send_buffer, 2) < 0) {
avrdude_message(MSG_DEBUG, "%s: LD_PTR_INC send operation failed\n", progname);
pmsg_debug("LD_PTR_INC send operation failed\n");
return -1;
}
return updi_physical_recv(pgm, buffer, words << 2);
}
int updi_link_st_ptr_inc(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size)
{
int updi_link_st_ptr_inc(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size) {
/*
def st_ptr_inc(self, data):
"""
@@ -450,32 +433,32 @@ int updi_link_st_ptr_inc(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size
unsigned char recv_buffer[1];
int response;
int num = 1;
avrdude_message(MSG_DEBUG, "%s: ST8 to *ptr++\n", progname);
pmsg_debug("ST8 to *ptr++\n");
send_buffer[0] = UPDI_PHY_SYNC;
send_buffer[1] = UPDI_ST | UPDI_PTR_INC | UPDI_DATA_8;
send_buffer[2] = buffer[0];
if (updi_physical_send(pgm, send_buffer, 3) < 0) {
avrdude_message(MSG_DEBUG, "%s: ST_PTR_INC send operation failed\n", progname);
pmsg_debug("ST_PTR_INC send operation failed\n");
return -1;
}
response = updi_physical_recv(pgm, recv_buffer, 1);
if (response != 1 || recv_buffer[0] != UPDI_PHY_ACK) {
avrdude_message(MSG_DEBUG, "%s: ACK was expected but not received\n", progname);
pmsg_debug("ACK was expected but not received\n");
return -1;
}
while (num < size) {
send_buffer[0]=buffer[num];
if (updi_physical_send(pgm, send_buffer, 1) < 0) {
avrdude_message(MSG_DEBUG, "%s: ST_PTR_INC data send operation failed\n", progname);
pmsg_debug("ST_PTR_INC data send operation failed\n");
return -1;
}
response = updi_physical_recv(pgm, recv_buffer, 1);
if (response != 1 || recv_buffer[0] != UPDI_PHY_ACK) {
avrdude_message(MSG_DEBUG, "%s: Data ACK was expected but not received\n", progname);
pmsg_debug("data ACK was expected but not received\n");
return -1;
}
num++;
@@ -484,8 +467,7 @@ int updi_link_st_ptr_inc(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size
return 0;
}
int updi_link_st_ptr_inc16(PROGRAMMER * pgm, unsigned char * buffer, uint16_t words)
{
int updi_link_st_ptr_inc16(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words) {
/*
def st_ptr_inc16(self, data):
"""
@@ -514,20 +496,20 @@ int updi_link_st_ptr_inc16(PROGRAMMER * pgm, unsigned char * buffer, uint16_t wo
unsigned char recv_buffer[1];
int response;
int num = 2;
avrdude_message(MSG_DEBUG, "%s: ST16 to *ptr++\n", progname);
pmsg_debug("ST16 to *ptr++\n");
send_buffer[0] = UPDI_PHY_SYNC;
send_buffer[1] = UPDI_ST | UPDI_PTR_INC | UPDI_DATA_16;
send_buffer[2] = buffer[0];
send_buffer[3] = buffer[1];
if (updi_physical_send(pgm, send_buffer, 4) < 0) {
avrdude_message(MSG_DEBUG, "%s: ST_PTR_INC16 send operation failed\n", progname);
pmsg_debug("ST_PTR_INC16 send operation failed\n");
return -1;
}
response = updi_physical_recv(pgm, recv_buffer, 1);
if (response != 1 || recv_buffer[0] != UPDI_PHY_ACK) {
avrdude_message(MSG_DEBUG, "%s: ACK was expected but not received\n", progname);
pmsg_debug("ACK was expected but not received\n");
return -1;
}
@@ -535,13 +517,13 @@ int updi_link_st_ptr_inc16(PROGRAMMER * pgm, unsigned char * buffer, uint16_t wo
send_buffer[0]=buffer[num];
send_buffer[1]=buffer[num+1];
if (updi_physical_send(pgm, send_buffer, 2) < 0) {
avrdude_message(MSG_DEBUG, "%s: ST_PTR_INC data send operation failed\n", progname);
pmsg_debug("ST_PTR_INC data send operation failed\n");
return -1;
}
response = updi_physical_recv(pgm, recv_buffer, 1);
if (response != 1 || recv_buffer[0] != UPDI_PHY_ACK) {
avrdude_message(MSG_DEBUG, "%s: Data ACK was expected but not received\n", progname);
pmsg_debug("data ACK was expected but not received\n");
return -1;
}
num+=2;
@@ -550,7 +532,7 @@ int updi_link_st_ptr_inc16(PROGRAMMER * pgm, unsigned char * buffer, uint16_t wo
return 0;
}
int updi_link_st_ptr_inc16_RSD(PROGRAMMER * pgm, unsigned char * buffer, uint16_t words, int blocksize) {
int updi_link_st_ptr_inc16_RSD(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words, int blocksize) {
/*
def st_ptr_inc16_RSD(self, data, blocksize):
"""
@@ -564,7 +546,7 @@ int updi_link_st_ptr_inc16_RSD(PROGRAMMER * pgm, unsigned char * buffer, uint16_
"""
self.logger.debug("ST16 to *ptr++ with RSD, data length: 0x%03X in blocks of: %d", len(data), blocksize)
#for performance we glob everything together into one USB transfer....
#for performance we glob everything together into one USB transfer ...
repnumber= ((len(data) >> 1) -1)
data = [*data, *[constants.UPDI_PHY_SYNC, constants.UPDI_STCS | constants.UPDI_CS_CTRLA, 0x06]]
@@ -593,14 +575,14 @@ int updi_link_st_ptr_inc16_RSD(PROGRAMMER * pgm, unsigned char * buffer, uint16_
self.updi_phy.send(data_slice)
num += len(data_slice)
*/
avrdude_message(MSG_DEBUG, "%s: ST16 to *ptr++ with RSD, data length: 0x%03X in blocks of: %d\n", progname, words * 2, blocksize);
pmsg_debug("ST16 to *ptr++ with RSD, data length: 0x%03X in blocks of: %d\n", words * 2, blocksize);
unsigned int temp_buffer_size = 3 + 3 + 2 + (words * 2) + 3;
unsigned int num=0;
unsigned char* temp_buffer = malloc(temp_buffer_size);
if (temp_buffer == 0) {
avrdude_message(MSG_DEBUG, "%s: Allocating temporary buffer failed\n", progname);
pmsg_debug("allocating temporary buffer failed\n");
return -1;
}
@@ -625,7 +607,7 @@ int updi_link_st_ptr_inc16_RSD(PROGRAMMER * pgm, unsigned char * buffer, uint16_
if (blocksize < 10) {
if (updi_physical_send(pgm, temp_buffer, 6) < 0) {
avrdude_message(MSG_DEBUG, "%s: Failed to send first package\n", progname);
pmsg_debug("unable to send first package\n");
free(temp_buffer);
return -1;
}
@@ -642,7 +624,7 @@ int updi_link_st_ptr_inc16_RSD(PROGRAMMER * pgm, unsigned char * buffer, uint16_
}
if (updi_physical_send(pgm, temp_buffer + num, next_package_size) < 0) {
avrdude_message(MSG_DEBUG, "%s: Failed to send package\n", progname);
pmsg_debug("unable to send package\n");
free(temp_buffer);
return -1;
}
@@ -653,8 +635,7 @@ int updi_link_st_ptr_inc16_RSD(PROGRAMMER * pgm, unsigned char * buffer, uint16_
return 0;
}
int updi_link_repeat(PROGRAMMER * pgm, uint16_t repeats)
{
int updi_link_repeat(const PROGRAMMER *pgm, uint16_t repeats) {
/*
def repeat(self, repeats):
"""
@@ -671,9 +652,9 @@ int updi_link_repeat(PROGRAMMER * pgm, uint16_t repeats)
repeats & 0xFF])
*/
unsigned char buffer[3];
avrdude_message(MSG_DEBUG, "%s: Repeat %d\n", progname, repeats);
pmsg_debug("repeat %d\n", repeats);
if ((repeats - 1) > UPDI_MAX_REPEAT_SIZE) {
avrdude_message(MSG_DEBUG, "%s: Invalid repeat count of %d\n", progname, repeats);
pmsg_debug("invalid repeat count of %d\n", repeats);
return -1;
}
repeats-=1;
@@ -683,8 +664,7 @@ int updi_link_repeat(PROGRAMMER * pgm, uint16_t repeats)
return updi_physical_send(pgm, buffer, 3);
}
int updi_link_read_sib(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size)
{
int updi_link_read_sib(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size) {
/*
def read_sib(self):
"""
@@ -695,8 +675,7 @@ int updi_link_read_sib(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size)
return updi_physical_sib(pgm, buffer, size);
}
int updi_link_key(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size_type, uint16_t size)
{
int updi_link_key(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size_type, uint16_t size) {
/*
def key(self, size, key):
"""
@@ -714,15 +693,15 @@ int updi_link_key(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size_type, u
unsigned char send_buffer[2];
unsigned char reversed_key[256];
int index;
avrdude_message(MSG_DEBUG, "%s: UPDI writing key\n", progname);
pmsg_debug("UPDI writing key\n");
if (size != (8 << size_type)) {
avrdude_message(MSG_DEBUG, "%s: Invalid key length\n", progname);
pmsg_debug("invalid key length\n");
return -1;
}
send_buffer[0] = UPDI_PHY_SYNC;
send_buffer[1] = UPDI_KEY | UPDI_KEY_KEY | size_type;
if (updi_physical_send(pgm, send_buffer, 2) < 0) {
avrdude_message(MSG_DEBUG, "%s: UPDI key send message failed\n", progname);
pmsg_debug("UPDI key send message failed\n");
return -1;
}
/* reverse key contents */
@@ -732,8 +711,7 @@ int updi_link_key(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size_type, u
return updi_physical_send(pgm, reversed_key, size);
}
int updi_link_ld(PROGRAMMER * pgm, uint32_t address, uint8_t * value)
{
int updi_link_ld(const PROGRAMMER *pgm, uint32_t address, uint8_t *value) {
/*
def ld(self, address):
"""
@@ -750,26 +728,25 @@ int updi_link_ld(PROGRAMMER * pgm, uint32_t address, uint8_t * value)
*/
unsigned char send_buffer[5];
unsigned char recv_buffer[1];
avrdude_message(MSG_DEBUG, "%s: LD from 0x%06X\n", progname, address);
pmsg_debug("LD from 0x%06X\n", address);
send_buffer[0] = UPDI_PHY_SYNC;
send_buffer[1] = UPDI_LDS | UPDI_DATA_8 | (updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? UPDI_ADDRESS_24 : UPDI_ADDRESS_16);
send_buffer[2] = address & 0xFF;
send_buffer[3] = (address >> 8) & 0xFF;
send_buffer[4] = (address >> 16) & 0xFF;
if (updi_physical_send(pgm, send_buffer, updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? 5 : 4) < 0) {
avrdude_message(MSG_DEBUG, "%s: LD operation send failed\n", progname);
pmsg_debug("LD operation send failed\n");
return -1;
}
if (updi_physical_recv(pgm, recv_buffer, 1) < 0) {
avrdude_message(MSG_DEBUG, "%s: LD operation recv failed\n", progname);
pmsg_debug("LD operation recv failed\n");
return -1;
}
* value = recv_buffer[0];
return 0;
}
int updi_link_ld16(PROGRAMMER * pgm, uint32_t address, uint16_t * value)
{
int updi_link_ld16(const PROGRAMMER *pgm, uint32_t address, uint16_t *value) {
/*
def ld16(self, address):
"""
@@ -786,26 +763,25 @@ int updi_link_ld16(PROGRAMMER * pgm, uint32_t address, uint16_t * value)
*/
unsigned char send_buffer[5];
unsigned char recv_buffer[2];
avrdude_message(MSG_DEBUG, "%s: LD16 from 0x%06X\n", progname, address);
pmsg_debug("LD16 from 0x%06X\n", address);
send_buffer[0] = UPDI_PHY_SYNC;
send_buffer[1] = UPDI_LDS | UPDI_DATA_16 | (updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? UPDI_ADDRESS_24 : UPDI_ADDRESS_16);
send_buffer[2] = address & 0xFF;
send_buffer[3] = (address >> 8) & 0xFF;
send_buffer[4] = (address >> 16) & 0xFF;
if (updi_physical_send(pgm, send_buffer, updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? 5 : 4) < 0) {
avrdude_message(MSG_DEBUG, "%s: LD16 operation send failed\n", progname);
pmsg_debug("LD16 operation send failed\n");
return -1;
}
if (updi_physical_recv(pgm, recv_buffer, 2) < 0) {
avrdude_message(MSG_DEBUG, "%s: LD16 operation recv failed\n", progname);
pmsg_debug("LD16 operation recv failed\n");
return -1;
}
* value = (recv_buffer[0] << 8 | recv_buffer[1]);
return 0;
}
static int updi_link_st_data_phase(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size)
{
static int updi_link_st_data_phase(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size) {
/*
def _st_data_phase(self, values):
"""
@@ -826,30 +802,29 @@ static int updi_link_st_data_phase(PROGRAMMER * pgm, unsigned char * buffer, uin
*/
unsigned char recv_buffer[1];
if (updi_physical_recv(pgm, recv_buffer, 1) < 0) {
avrdude_message(MSG_DEBUG, "%s: UPDI data phase recv failed on first ACK\n", progname);
pmsg_debug("UPDI data phase recv failed on first ACK\n");
return -1;
}
if (recv_buffer[0] != UPDI_PHY_ACK) {
avrdude_message(MSG_DEBUG, "%s: UPDI data phase expected first ACK\n", progname);
pmsg_debug("UPDI data phase expected first ACK\n");
return -1;
}
if (updi_physical_send(pgm, buffer, size) < 0) {
avrdude_message(MSG_DEBUG, "%s: UPDI data phase send failed\n", progname);
pmsg_debug("UPDI data phase send failed\n");
return -1;
}
if (updi_physical_recv(pgm, recv_buffer, 1) < 0) {
avrdude_message(MSG_DEBUG, "%s: UPDI data phase recv failed on second ACK\n", progname);
pmsg_debug("UPDI data phase recv failed on second ACK\n");
return -1;
}
if (recv_buffer[0] != UPDI_PHY_ACK) {
avrdude_message(MSG_DEBUG, "%s: UPDI data phase expected second ACK\n", progname);
pmsg_debug("UPDI data phase expected second ACK\n");
return -1;
}
return 0;
}
int updi_link_st(PROGRAMMER * pgm, uint32_t address, uint8_t value)
{
int updi_link_st(const PROGRAMMER *pgm, uint32_t address, uint8_t value) {
/*
def st(self, address, value):
"""
@@ -865,22 +840,21 @@ int updi_link_st(PROGRAMMER * pgm, uint32_t address, uint8_t value)
return self._st_data_phase([value & 0xFF])
*/
unsigned char send_buffer[5];
avrdude_message(MSG_DEBUG, "%s: ST to 0x%06X\n", progname, address);
pmsg_debug("ST to 0x%06X\n", address);
send_buffer[0] = UPDI_PHY_SYNC;
send_buffer[1] = UPDI_STS | UPDI_DATA_8 | (updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? UPDI_ADDRESS_24 : UPDI_ADDRESS_16);
send_buffer[2] = address & 0xFF;
send_buffer[3] = (address >> 8) & 0xFF;
send_buffer[4] = (address >> 16) & 0xFF;
if (updi_physical_send(pgm, send_buffer, updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? 5 : 4) < 0) {
avrdude_message(MSG_DEBUG, "%s: ST operation send failed\n", progname);
pmsg_debug("ST operation send failed\n");
return -1;
}
send_buffer[0] = value;
return updi_link_st_data_phase(pgm, send_buffer, 1);
}
int updi_link_st16(PROGRAMMER * pgm, uint32_t address, uint16_t value)
{
int updi_link_st16(const PROGRAMMER *pgm, uint32_t address, uint16_t value) {
/*
def st16(self, address, value):
"""
@@ -896,14 +870,14 @@ int updi_link_st16(PROGRAMMER * pgm, uint32_t address, uint16_t value)
return self._st_data_phase([value & 0xFF, (value >> 8) & 0xFF])
*/
unsigned char send_buffer[5];
avrdude_message(MSG_DEBUG, "%s: ST16 to 0x%06X\n", progname, address);
pmsg_debug("ST16 to 0x%06X\n", address);
send_buffer[0] = UPDI_PHY_SYNC;
send_buffer[1] = UPDI_STS | UPDI_DATA_16 | (updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? UPDI_ADDRESS_24 : UPDI_ADDRESS_16);
send_buffer[2] = address & 0xFF;
send_buffer[3] = (address >> 8) & 0xFF;
send_buffer[4] = (address >> 16) & 0xFF;
if (updi_physical_send(pgm, send_buffer, updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? 5 : 4) < 0) {
avrdude_message(MSG_DEBUG, "%s: ST16 operation send failed\n", progname);
pmsg_debug("ST16 operation send failed\n");
return -1;
}
send_buffer[0] = value & 0xFF;
@@ -911,8 +885,7 @@ int updi_link_st16(PROGRAMMER * pgm, uint32_t address, uint16_t value)
return updi_link_st_data_phase(pgm, send_buffer, 2);
}
int updi_link_st_ptr(PROGRAMMER * pgm, uint32_t address)
{
int updi_link_st_ptr(const PROGRAMMER *pgm, uint32_t address) {
/*
def st_ptr(self, address):
"""
@@ -930,22 +903,22 @@ int updi_link_st_ptr(PROGRAMMER * pgm, uint32_t address)
*/
unsigned char send_buffer[5];
unsigned char recv_buffer[1];
avrdude_message(MSG_DEBUG, "%s: ST_PTR to 0x%06X\n", progname, address);
pmsg_debug("ST_PTR to 0x%06X\n", address);
send_buffer[0] = UPDI_PHY_SYNC;
send_buffer[1] = UPDI_STS | UPDI_ST | UPDI_PTR_ADDRESS | (updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? UPDI_DATA_24 : UPDI_DATA_16);
send_buffer[2] = address & 0xFF;
send_buffer[3] = (address >> 8) & 0xFF;
send_buffer[4] = (address >> 16) & 0xFF;
if (updi_physical_send(pgm, send_buffer, updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? 5 : 4) < 0) {
avrdude_message(MSG_DEBUG, "%s: ST_PTR operation send failed\n", progname);
pmsg_debug("ST_PTR operation send failed\n");
return -1;
}
if (updi_physical_recv(pgm, recv_buffer, 1) < 0) {
avrdude_message(MSG_DEBUG, "%s: UPDI ST_PTR recv failed on ACK\n", progname);
pmsg_debug("UPDI ST_PTR recv failed on ACK\n");
return -1;
}
if (recv_buffer[0] != UPDI_PHY_ACK) {
avrdude_message(MSG_DEBUG, "%s: UPDI ST_PTR expected ACK\n", progname);
pmsg_debug("UPDI ST_PTR expected ACK\n");
return -1;
}
return 0;

View File

@@ -35,22 +35,22 @@ extern "C" {
int updi_link_open(PROGRAMMER * pgm);
void updi_link_close(PROGRAMMER * pgm);
int updi_link_init(PROGRAMMER * pgm);
int updi_link_ldcs(PROGRAMMER * pgm, uint8_t address, uint8_t * value);
int updi_link_stcs(PROGRAMMER * pgm, uint8_t address, uint8_t value);
int updi_link_ld_ptr_inc(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size);
int updi_link_ld_ptr_inc16(PROGRAMMER * pgm, unsigned char * buffer, uint16_t words);
int updi_link_st_ptr_inc(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size);
int updi_link_st_ptr_inc16(PROGRAMMER * pgm, unsigned char * buffer, uint16_t words);
int updi_link_st_ptr_inc16_RSD(PROGRAMMER * pgm, unsigned char * buffer, uint16_t words, int blocksize);
int updi_link_repeat(PROGRAMMER * pgm, uint16_t repeats);
int updi_link_read_sib(PROGRAMMER * pgm, unsigned char * buffer, uint16_t size);
int updi_link_key(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size_type, uint16_t size);
int updi_link_ld(PROGRAMMER * pgm, uint32_t address, uint8_t * value);
int updi_link_ld16(PROGRAMMER * pgm, uint32_t address, uint16_t * value);
int updi_link_st(PROGRAMMER * pgm, uint32_t address, uint8_t value);
int updi_link_st16(PROGRAMMER * pgm, uint32_t address, uint16_t value);
int updi_link_st_ptr(PROGRAMMER * pgm, uint32_t address);
int updi_link_init(const PROGRAMMER *pgm);
int updi_link_ldcs(const PROGRAMMER *pgm, uint8_t address, uint8_t *value);
int updi_link_stcs(const PROGRAMMER *pgm, uint8_t address, uint8_t value);
int updi_link_ld_ptr_inc(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size);
int updi_link_ld_ptr_inc16(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words);
int updi_link_st_ptr_inc(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size);
int updi_link_st_ptr_inc16(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words);
int updi_link_st_ptr_inc16_RSD(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words, int blocksize);
int updi_link_repeat(const PROGRAMMER *pgm, uint16_t repeats);
int updi_link_read_sib(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size);
int updi_link_key(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size_type, uint16_t size);
int updi_link_ld(const PROGRAMMER *pgm, uint32_t address, uint8_t *value);
int updi_link_ld16(const PROGRAMMER *pgm, uint32_t address, uint16_t *value);
int updi_link_st(const PROGRAMMER *pgm, uint32_t address, uint8_t value);
int updi_link_st16(const PROGRAMMER *pgm, uint32_t address, uint16_t value);
int updi_link_st_ptr(const PROGRAMMER *pgm, uint32_t address);
#ifdef __cplusplus
}

Some files were not shown because too many files have changed in this diff Show More