mirror of
https://github.com/mariusgreuel/avrdude.git
synced 2026-08-17 12:20:37 +00:00
Merge pull request #1 from avrdudes/main
Merge latest avrdudes/avrdude main branch
This commit is contained in:
10
.github/workflows/build.yml
vendored
10
.github/workflows/build.yml
vendored
@@ -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
|
||||
|
||||
@@ -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
134
NEWS
@@ -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:
|
||||
|
||||
2
build.sh
2
build.sh
@@ -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
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
@@ -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
491
src/avr.c
@@ -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. */
|
||||
}
|
||||
|
||||
123
src/avr910.c
123
src/avr910.c
@@ -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");
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
737
src/avrcache.c
Normal 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;
|
||||
}
|
||||
254
src/avrdude.1
254
src/avrdude.1
@@ -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
|
||||
|
||||
26803
src/avrdude.conf.in
26803
src/avrdude.conf.in
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
160
src/avrftdi.c
160
src/avrftdi.c
@@ -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");
|
||||
|
||||
/*
|
||||
|
||||
@@ -29,7 +29,7 @@ extern "C" {
|
||||
|
||||
|
||||
extern const char avrftdi_desc[];
|
||||
void avrftdi_initpgm (PROGRAMMER * pgm);
|
||||
void avrftdi_initpgm(PROGRAMMER *pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -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, ...);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
5458
src/avrintel.c
Normal file
File diff suppressed because it is too large
Load Diff
1477
src/avrintel.h
Normal file
1477
src/avrintel.h
Normal file
File diff suppressed because it is too large
Load Diff
857
src/avrpart.c
857
src/avrpart.c
File diff suppressed because it is too large
Load Diff
130
src/bitbang.c
130
src/bitbang.c
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
378
src/buspirate.c
378
src/buspirate.c
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
189
src/butterfly.c
189
src/butterfly.c
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
736
src/config.c
736
src/config.c
@@ -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);
|
||||
}
|
||||
|
||||
106
src/config.h
106
src/config.h
@@ -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
35
src/configure.cmake
Normal 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
1401
src/developer_opts.c
Normal file
File diff suppressed because it is too large
Load Diff
26
src/developer_opts.h
Normal file
26
src/developer_opts.h
Normal 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
|
||||
140
src/developer_opts_private.h
Normal file
140
src/developer_opts_private.h
Normal 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
112
src/dfu.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
179
src/doc/CMakeLists.txt
Normal 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})
|
||||
@@ -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
37
src/doc/parts.cmake
Normal 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}")
|
||||
28
src/doc/programmer_types.cmake
Normal file
28
src/doc/programmer_types.cmake
Normal 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
28
src/doc/programmers.cmake
Normal 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}")
|
||||
374
src/fileio.c
374
src/fileio.c
@@ -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);
|
||||
}
|
||||
|
||||
251
src/flip1.c
251
src/flip1.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
374
src/flip2.c
374
src/flip2.c
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
603
src/ft245r.c
603
src/ft245r.c
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
|
||||
869
src/jtag3.c
869
src/jtag3.c
File diff suppressed because it is too large
Load Diff
24
src/jtag3.h
24
src/jtag3.h
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
475
src/jtagmkI.c
475
src/jtagmkI.c
File diff suppressed because it is too large
Load Diff
@@ -26,7 +26,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char jtagmkI_desc[];
|
||||
void jtagmkI_initpgm (PROGRAMMER * pgm);
|
||||
void jtagmkI_initpgm(PROGRAMMER *pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
1332
src/jtagmkII.c
1332
src/jtagmkII.c
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
323
src/lexer.l
323
src/lexer.l
@@ -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"
|
||||
|
||||
469
src/libavrdude.h
469
src/libavrdude.h
@@ -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
|
||||
|
||||
@@ -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) \
|
||||
|
||||
101
src/linuxgpio.c
101
src/linuxgpio.c
@@ -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)";
|
||||
|
||||
@@ -27,7 +27,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char linuxgpio_desc[];
|
||||
void linuxgpio_initpgm (PROGRAMMER * pgm);
|
||||
void linuxgpio_initpgm(PROGRAMMER *pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
158
src/linuxspi.c
158
src/linuxspi.c
@@ -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)";
|
||||
|
||||
@@ -25,7 +25,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char linuxspi_desc[];
|
||||
void linuxspi_initpgm (PROGRAMMER * pgm);
|
||||
void linuxspi_initpgm(PROGRAMMER *pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
908
src/main.c
908
src/main.c
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char micronucleus_desc[];
|
||||
void micronucleus_initpgm(PROGRAMMER* pgm);
|
||||
void micronucleus_initpgm(PROGRAMMER *pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
85
src/par.c
85
src/par.c
@@ -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 */
|
||||
|
||||
@@ -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
289
src/pgm.c
@@ -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)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
107
src/pgm_type.c
107
src/pgm_type.c
@@ -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
|
||||
|
||||
212
src/pickit2.c
212
src/pickit2.c
@@ -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
|
||||
|
||||
@@ -26,7 +26,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char pickit2_desc[];
|
||||
void pickit2_initpgm (PROGRAMMER * pgm);
|
||||
void pickit2_initpgm(PROGRAMMER *pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -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>";
|
||||
}
|
||||
}
|
||||
|
||||
32
src/ppi.c
32
src/ppi.c
@@ -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);
|
||||
}
|
||||
|
||||
16
src/ppi.h
16
src/ppi.h
@@ -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
|
||||
}
|
||||
|
||||
46
src/ppiwin.c
46
src/ppiwin.c
@@ -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) );
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
124
src/ser_posix.c
124
src/ser_posix.c
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
172
src/ser_win32.c
172
src/ser_win32.c
@@ -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
|
||||
|
||||
@@ -26,7 +26,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char serbb_desc[];
|
||||
void serbb_initpgm (PROGRAMMER * pgm);
|
||||
void serbb_initpgm(PROGRAMMER *pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
263
src/serialupdi.c
263
src/serialupdi.c
@@ -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");
|
||||
|
||||
/*
|
||||
|
||||
@@ -34,7 +34,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char serialupdi_desc[];
|
||||
void serialupdi_initpgm (PROGRAMMER * pgm);
|
||||
void serialupdi_initpgm(PROGRAMMER *pgm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
439
src/stk500.c
439
src/stk500.c
@@ -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");
|
||||
|
||||
/*
|
||||
|
||||
16
src/stk500.h
16
src/stk500.h
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#define stk500generic_h__
|
||||
|
||||
extern const char stk500generic_desc[];
|
||||
void stk500generic_initpgm (PROGRAMMER * pgm);
|
||||
void stk500generic_initpgm(PROGRAMMER *pgm);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
1045
src/stk500v2.c
1045
src/stk500v2.c
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
}
|
||||
|
||||
@@ -312,7 +312,7 @@ struct pdata
|
||||
}
|
||||
pgmtype;
|
||||
|
||||
AVRPART *lastpart;
|
||||
const AVRPART *lastpart;
|
||||
|
||||
/* Start address of Xmega boot area */
|
||||
unsigned long boot_start;
|
||||
|
||||
172
src/teensy.c
172
src/teensy.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
1158
src/term.c
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
}
|
||||
|
||||
540
src/update.c
540
src/update.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
215
src/updi_link.c
215
src/updi_link.c
@@ -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;
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user