Merge branch 'avrdudes:main' into hv-updi
This commit is contained in:
commit
8159c46013
|
@ -20,7 +20,11 @@ name: Build
|
|||
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'onlinedocs'
|
||||
pull_request:
|
||||
branches-ignore:
|
||||
- 'onlinedocs'
|
||||
workflow_call:
|
||||
|
||||
env:
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
# cmake --build build
|
||||
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
project(avrdude VERSION 6.99)
|
||||
project(avrdude VERSION 7.0)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED True)
|
||||
|
@ -35,6 +35,13 @@ option(USE_LIBUSBWIN32 "Prefer libusb-win32 over libusb" OFF)
|
|||
option(DEBUG_CMAKE "Enable debugging output for this CMake project" OFF)
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
|
||||
|
||||
if(WIN32)
|
||||
# Prefer static libraries over DLLs on Windows
|
||||
option(USE_STATIC_LIBS "Use static libraries" ON)
|
||||
else()
|
||||
option(USE_STATIC_LIBS "Use static libraries" OFF)
|
||||
endif()
|
||||
|
||||
include(CheckIncludeFile)
|
||||
include(CheckSymbolExists)
|
||||
include(FetchContent)
|
||||
|
@ -110,14 +117,14 @@ endif()
|
|||
# Detect installed libraries
|
||||
# =====================================
|
||||
|
||||
# Prefer static libraries over DLLs on Windows
|
||||
if(WIN32)
|
||||
if(USE_STATIC_LIBS)
|
||||
set(PREFERRED_LIBELF libelf.a elf)
|
||||
set(PREFERRED_LIBUSB libusb.a usb)
|
||||
set(PREFERRED_LIBUSB_1_0 libusb-1.0.a usb-1.0)
|
||||
set(PREFERRED_LIBHIDAPI libhidapi.a libhidapi-libusb.a libhidapi-hidraw.a hidapi hidapi-libusb hidapi-hidraw)
|
||||
set(PREFERRED_LIBFTDI libftdi.a ftdi)
|
||||
set(PREFERRED_LIBFTDI1 libftdi1.a ftdi1)
|
||||
set(PREFERRED_LIBREADLINE libreadline.a)
|
||||
else()
|
||||
set(PREFERRED_LIBELF elf)
|
||||
set(PREFERRED_LIBUSB usb)
|
||||
|
@ -125,6 +132,7 @@ else()
|
|||
set(PREFERRED_LIBHIDAPI hidapi hidapi-libusb hidapi-hidraw)
|
||||
set(PREFERRED_LIBFTDI ftdi)
|
||||
set(PREFERRED_LIBFTDI1 ftdi1)
|
||||
set(PREFERRED_LIBREADLINE readline)
|
||||
endif()
|
||||
|
||||
# -------------------------------------
|
||||
|
@ -182,6 +190,9 @@ endif()
|
|||
# Find libhidapi
|
||||
|
||||
find_library(HAVE_LIBHID NAMES hid)
|
||||
if(HAVE_LIBHID)
|
||||
set(LIB_LIBHID ${HAVE_LIBHID})
|
||||
endif()
|
||||
|
||||
find_library(HAVE_LIBHIDAPI NAMES ${PREFERRED_LIBHIDAPI})
|
||||
if(HAVE_LIBHIDAPI)
|
||||
|
@ -209,7 +220,7 @@ endif()
|
|||
# -------------------------------------
|
||||
# Find libreadline
|
||||
|
||||
find_library(HAVE_LIBREADLINE NAMES readline)
|
||||
find_library(HAVE_LIBREADLINE NAMES ${PREFERRED_LIBREADLINE})
|
||||
if(HAVE_LIBREADLINE)
|
||||
set(LIB_LIBREADLINE ${HAVE_LIBREADLINE})
|
||||
endif()
|
||||
|
|
91
NEWS
91
NEWS
|
@ -5,7 +5,31 @@ Approximate change log for AVRDUDE by version.
|
|||
(For detailed changes, see the version control system logs.)
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Changes since version 6.4:
|
||||
Changes since version 7.0:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
|
||||
* New devices supported:
|
||||
|
||||
* New programmers supported:
|
||||
|
||||
* Issues fixed:
|
||||
|
||||
- Fix micronucleus bootloader to check for unresponsive USB
|
||||
devices #945
|
||||
- Fix src/CMakeLists.txt to honor CMAKE_INSTALL_LIBDIR #972
|
||||
|
||||
* Pull requests:
|
||||
|
||||
- Fix .Dd macro in manpage #949
|
||||
- fix M1 homebrew path #950
|
||||
- CMake Enhancements #962
|
||||
- Reduce programmer desc string length in avrdude.conf
|
||||
to < 80 characters #1000
|
||||
|
||||
* Internals:
|
||||
|
||||
Changes in version 7.0:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
|
||||
|
@ -13,6 +37,17 @@ Changes since version 6.4:
|
|||
- Started to add CMake (by now, parallel with autoconf/automake)
|
||||
- New-architecture devices (AVR8X mega and tiny) can access all
|
||||
fuses, and memory display shows meaningful alias names
|
||||
- The "safemode" feature has been removed. The major class of
|
||||
programmers it has been designed for (lowlevel bitbang
|
||||
programmers on parallel or serial ports) virtually doesn't exist
|
||||
anymore, and the fuse combination that was covered by it do not
|
||||
match the fuses of modern AVR devices anyway.
|
||||
- avrdude.conf is now being looked up in the location of the
|
||||
executable file first, before considering the configured default
|
||||
location; this eases a "portable use" where the entire suite is
|
||||
not installed into its configured default location. (Basically
|
||||
only relevant for unixoid systems; on Windows, this search order
|
||||
has been used for many years already.)
|
||||
|
||||
* New devices supported:
|
||||
|
||||
|
@ -30,6 +65,7 @@ Changes since version 6.4:
|
|||
- ATtiny3224, ATtiny3226 and ATtiny3227
|
||||
- AVR16DD14/20/28/32, AVR32DD14/20/28/32 and AVR64DD14/20/28/32
|
||||
- AVR8EA28/32, AVR16EA28/32/48, AVR32EA28/32/48 and AVR64EA28/32/64
|
||||
- ATmega16U4
|
||||
|
||||
|
||||
* New programmers supported:
|
||||
|
@ -40,6 +76,8 @@ Changes since version 6.4:
|
|||
- Teensy bootloader (PR #802)
|
||||
- Micronucleus bootloader (PR #786)
|
||||
- ft232h (generic variant, PR #842)
|
||||
- Kristech KT-LINK FT2232H interface with IO switching and voltage
|
||||
buffers (PR #930)
|
||||
|
||||
* Issues fixed:
|
||||
|
||||
|
@ -63,6 +101,22 @@ Changes since version 6.4:
|
|||
- Segmentation fault when writing ATtiny104 fuse #823
|
||||
- USBasp returns ERANGE for unknown error #848
|
||||
- Compiler warnings #856
|
||||
- Can't get serialupdi to work #874
|
||||
- Rework HID support for Windows #881
|
||||
- List of signing keys? #884
|
||||
- Pickit4 UPDI is writing at offset 0x4000 into flash instead of 0x0000. #892
|
||||
- SerialUPDI programmer can't write to usersig/userrow in terminal mode #889
|
||||
- Signature read command for ATmega165* was wrong (no-id)
|
||||
- Cannot use non-standard baud rates for uploading on MacOS #771
|
||||
- Wrong values in avrdude.conf #897
|
||||
- AVR-Eclipse plugin broken by missing -u commandline option #890
|
||||
- Timeout passed to hid_read_timeout() is too short for instances
|
||||
where the EDBG AVRISP 'Enter Programming Mode' command fails #900
|
||||
- Terminal write mode doesn't support string input (yet) #913
|
||||
- Terminal mode: memory fill with strings may cause Avrdude to crash. #922
|
||||
- Some parts have wrong or missing ISP commands #915
|
||||
- Incorrect -b conversion for linuxspi programmer #927
|
||||
- ATtiny43U calibration memory size #921
|
||||
|
||||
* Pull requests:
|
||||
|
||||
|
@ -119,10 +173,45 @@ Changes since version 6.4:
|
|||
- Fix libusb-1.0 error strings #850
|
||||
- Assign proper type to msg[] in errstr() #857
|
||||
- Fix Arduino retry attempts #855
|
||||
- CMake: use CMAKE_CURRENT_BINARY_DIR to locate avrdude.conf #858
|
||||
- Remove the "safemode" feature. #859
|
||||
- Add support for reading from more memory sections #863
|
||||
- Alias keyword #868
|
||||
- Add fuse name aliases to avrdude.conf + tweak update.c #869
|
||||
- Print JTAG3 clocks after configuration + string formatting #853
|
||||
- Tweak programmer info formatting strings #872
|
||||
- Remove libhid support in ser_avrdoper.c in favor of libhidapi #882
|
||||
- Reduce jtag3 output verbosity #877
|
||||
- Fix Curiosity Nano target voltage #878
|
||||
- Smallest possible fix for PL2303HX #885
|
||||
- Add missing USBtiny derived programmers #873
|
||||
- Cleanup of POSIX serial init code #886
|
||||
- Avrdude terminal write improvements #880
|
||||
- Add userrow and usersig aliases #888
|
||||
- For UPDI devices do not add offset when accessing flash. #895
|
||||
- Support both userrow and usersig names #893
|
||||
- Fix ugly terminal write bug #896
|
||||
- Improve terminal read functionality #894
|
||||
- Macos nonstandard baudrates #898
|
||||
- Fix errors in Avrdude.conf #899
|
||||
- Minor terminal write improvements #902
|
||||
- Term docs #903
|
||||
- Add progressbar for read and write command #912
|
||||
- Add MacOS serial/parallel port note #908
|
||||
- Add ATmega16U4 to avrdude.conf #910
|
||||
- Mask out unused ATmega32U4 efuse bits #909
|
||||
- Increased timeout passed to hid_read_timeout() #901
|
||||
- Add terminal write string functionality #914
|
||||
- Update documentation link to new URL #929
|
||||
- Fix terminal write buffer overflow issue #924
|
||||
- Fix linuxspi baud to clock period calculation #931
|
||||
- Added KT-LINK FT2232H interface with IO switching and voltage buffers. #930
|
||||
|
||||
* Internals:
|
||||
|
||||
- Development moved to Github
|
||||
- Addition of "alias" keyword to avrdude.conf.in syntax; used
|
||||
for fuse name aliases right now
|
||||
|
||||
|
||||
Version 6.4:
|
||||
|
|
|
@ -16,6 +16,10 @@ with the help of [various contributors](./AUTHORS).
|
|||
The latest version of AVRDUDE is always available here:\
|
||||
<https://github.com/avrdudes/avrdude>
|
||||
|
||||
## Documentation
|
||||
|
||||
Documentation for current and previous releases is [on Github Pages](https://avrdudes.github.io/avrdude/).
|
||||
|
||||
## Getting AVRDUDE for Windows
|
||||
|
||||
To get AVRDUDE for Windows, install the latest version from the [Releases](http://download.savannah.gnu.org/releases/avrdude/) page.
|
||||
|
@ -57,4 +61,4 @@ avrdude -c arduino -P COM1 -b 115200 -p atmega328p -D -U flash:w:objs/blink.hex:
|
|||
|
||||
There are many different programmers and options that may be required for the programming to succeed.
|
||||
|
||||
For more information, refer to the [AVRDUDE documentation](http://download.savannah.gnu.org/releases/avrdude/avrdude-doc-6.4.pdf).
|
||||
For more information, refer to the [AVRDUDE documentation](https://avrdudes.github.io/avrdude/).
|
||||
|
|
8
build.sh
8
build.sh
|
@ -50,7 +50,13 @@ case "${ostype}" in
|
|||
then
|
||||
build_flags="${build_flags} -D CMAKE_C_FLAGS=-I/opt/local/include -D CMAKE_EXE_LINKER_FLAGS=-L/opt/local/lib"
|
||||
else
|
||||
build_flags="${build_flags} -D CMAKE_C_FLAGS=-I/usr/local/include -D CMAKE_EXE_LINKER_FLAGS=-L/usr/local/Cellar"
|
||||
# Apple M1 (may be new version of homebrew also)
|
||||
if [ -d /opt/homebrew ]
|
||||
then
|
||||
build_flags="${build_flags} -D CMAKE_C_FLAGS=-I/opt/homebrew/include -D CMAKE_EXE_LINKER_FLAGS=-L/opt/homebrew/Cellar"
|
||||
else
|
||||
build_flags="${build_flags} -D CMAKE_C_FLAGS=-I/usr/local/include -D CMAKE_EXE_LINKER_FLAGS=-L/usr/local/Cellar"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
||||
|
|
|
@ -51,15 +51,10 @@ include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
|
|||
add_compile_definitions(CONFIG_DIR=\"${CONFIG_DIR}\")
|
||||
|
||||
if(WIN32)
|
||||
set(EXTRA_WINDOWS_SOURCES "${PROJECT_BINARY_DIR}/src/windows.rc")
|
||||
set(EXTRA_WINDOWS_RESOURCES "${PROJECT_BINARY_DIR}/src/windows.rc")
|
||||
set(EXTRA_WINDOWS_LIBRARIES setupapi ws2_32)
|
||||
endif()
|
||||
|
||||
if(NOT WIN32)
|
||||
set(LIB_MATH m)
|
||||
add_compile_options(-Wall) # -Wextra
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
add_compile_definitions(_CRT_SECURE_NO_WARNINGS=1)
|
||||
add_compile_definitions(_CRT_NONSTDC_NO_WARNINGS=1)
|
||||
|
@ -79,6 +74,9 @@ if(MSVC)
|
|||
set(EXTRA_WINDOWS_INCLUDES ${EXTRA_WINDOWS_INCLUDES}
|
||||
"msvc"
|
||||
)
|
||||
else()
|
||||
set(LIB_MATH m)
|
||||
add_compile_options(-Wall) # -Wextra
|
||||
endif()
|
||||
|
||||
# =====================================
|
||||
|
@ -173,7 +171,6 @@ add_library(libavrdude
|
|||
ppi.c
|
||||
ppi.h
|
||||
ppiwin.c
|
||||
safemode.c
|
||||
serbb.h
|
||||
serbb_posix.c
|
||||
serbb_win32.c
|
||||
|
@ -217,6 +214,7 @@ add_library(libavrdude
|
|||
xbee.c
|
||||
${FLEX_Parser_OUTPUTS}
|
||||
${BISON_Parser_OUTPUTS}
|
||||
"${EXTRA_WINDOWS_SOURCES}"
|
||||
)
|
||||
|
||||
set_target_properties(libavrdude PROPERTIES
|
||||
|
@ -240,6 +238,7 @@ target_link_libraries(libavrdude
|
|||
${LIB_LIBELF}
|
||||
${LIB_LIBUSB}
|
||||
${LIB_LIBUSB_1_0}
|
||||
${LIB_LIBHID}
|
||||
${LIB_LIBHIDAPI}
|
||||
${LIB_LIBFTDI}
|
||||
${LIB_LIBFTDI1}
|
||||
|
@ -253,7 +252,7 @@ add_executable(avrdude
|
|||
term.h
|
||||
whereami.c
|
||||
whereami.h
|
||||
"${EXTRA_WINDOWS_SOURCES}"
|
||||
"${EXTRA_WINDOWS_RESOURCES}"
|
||||
)
|
||||
|
||||
target_link_libraries(avrdude PUBLIC libavrdude)
|
||||
|
@ -264,9 +263,9 @@ target_link_libraries(avrdude PUBLIC libavrdude)
|
|||
|
||||
install(TARGETS avrdude DESTINATION bin)
|
||||
install(TARGETS libavrdude
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
PUBLIC_HEADER DESTINATION include COMPONENT dev
|
||||
)
|
||||
install(FILES "${PROJECT_BINARY_DIR}/avrdude.conf" TYPE SYSCONF)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/avrdude.conf" TYPE SYSCONF)
|
||||
install(FILES avrdude.1 TYPE MAN)
|
||||
|
|
|
@ -148,7 +148,6 @@ libavrdude_a_SOURCES = \
|
|||
ppi.c \
|
||||
ppi.h \
|
||||
ppiwin.c \
|
||||
safemode.c \
|
||||
serbb.h \
|
||||
serbb_posix.c \
|
||||
serbb_win32.c \
|
||||
|
|
24
src/avr.c
24
src/avr.c
|
@ -791,30 +791,6 @@ int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
||||
unsigned long addr, unsigned char data)
|
||||
{
|
||||
|
||||
unsigned char safemode_lfuse;
|
||||
unsigned char safemode_hfuse;
|
||||
unsigned char safemode_efuse;
|
||||
unsigned char safemode_fuse;
|
||||
|
||||
/* If we write the fuses, then we need to tell safemode that they *should* change */
|
||||
safemode_memfuses(0, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
|
||||
|
||||
if (strcmp(mem->desc, "fuse")==0) {
|
||||
safemode_fuse = data;
|
||||
}
|
||||
if (strcmp(mem->desc, "lfuse")==0) {
|
||||
safemode_lfuse = data;
|
||||
}
|
||||
if (strcmp(mem->desc, "hfuse")==0) {
|
||||
safemode_hfuse = data;
|
||||
}
|
||||
if (strcmp(mem->desc, "efuse")==0) {
|
||||
safemode_efuse = data;
|
||||
}
|
||||
|
||||
safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
|
||||
|
||||
return pgm->write_byte(pgm, p, mem, addr, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
.\"
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd DATE November 22, 2021
|
||||
.Dd November 22, 2021
|
||||
.Os
|
||||
.Dt AVRDUDE 1
|
||||
.Sh NAME
|
||||
|
@ -607,40 +607,11 @@ 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.
|
||||
.It Fl s
|
||||
Disable safemode prompting. When safemode discovers that one or more
|
||||
fuse bits have unintentionally changed, it will prompt for
|
||||
confirmation regarding whether or not it should attempt to recover the
|
||||
fuse bit(s). Specifying this flag disables the prompt and assumes
|
||||
that the fuse bit(s) should be recovered without asking for
|
||||
confirmation first.
|
||||
.It Fl t
|
||||
Tells
|
||||
.Nm
|
||||
to enter the interactive ``terminal'' mode instead of up- or downloading
|
||||
files. See below for a detailed description of the terminal mode.
|
||||
.It Fl u
|
||||
Disable the safemode fuse bit checks. Safemode is enabled by default
|
||||
and is intended to prevent unintentional fuse bit changes. When
|
||||
enabled, safemode will issue a warning if the any fuse bits are found
|
||||
to be different at program exit than they were when
|
||||
.Nm
|
||||
was invoked. Safemode won't alter fuse bits itself, but rather will
|
||||
prompt for instructions, unless the terminal is non-interactive, in
|
||||
which case safemode is disabled. See the
|
||||
.Fl s
|
||||
option to disable safemode prompting.
|
||||
.Pp
|
||||
If one of the configuration files has a line
|
||||
.Dl "default_safemode = no;"
|
||||
safemode is disabled by default.
|
||||
The
|
||||
.Fl u
|
||||
option's effect is negated in that case, i. e. it
|
||||
.Em enables
|
||||
safemode.
|
||||
.Pp
|
||||
Safemode is always disabled for AVR32, Xmega and TPI devices.
|
||||
.It Xo Fl U Ar memtype Ns
|
||||
.Ar \&: Ns Ar op Ns
|
||||
.Ar \&: Ns Ar filename Ns
|
||||
|
|
|
@ -339,10 +339,6 @@ default_parallel = "@DEFAULT_PAR_PORT@";
|
|||
default_serial = "@DEFAULT_SER_PORT@";
|
||||
# default_bitclock = 2.5;
|
||||
|
||||
# Turn off safemode by default
|
||||
#default_safemode = no;
|
||||
|
||||
|
||||
#
|
||||
# PROGRAMMER DEFINITIONS
|
||||
#
|
||||
|
@ -597,6 +593,38 @@ programmer
|
|||
reset = 3; # TMS 7
|
||||
;
|
||||
|
||||
# Kristech KT-LINK FT2232H interface with IO switching and voltage buffers.
|
||||
# Created on 20220410 by CeDeROM Tomasz CEDRO (www.cederom.io).
|
||||
# Interface DataSheet: https://kristech.pl/files/KT-LINK-UM-ENG.pdf
|
||||
# AVRDUDE FT2232H PIN NUMBER DECODE:
|
||||
# | 0 | 1 | .. | 7 | 8 | 9 | .. | 15 |
|
||||
# | ADBUS0 | ADBUS1 | .. | ADBUS7 | ACBUS0 | ACBUS1 | .. | ACBUS7 |
|
||||
# KT-LINK JTAG CONN:
|
||||
# 1=Vsense(->EXT13), 19=5V(EXT1->EXT3), 20=GND, 3=TPIRST, 9=TPICLK, 7=TPIDATA.
|
||||
# INTERNALS CONFIGURATION ("~" MEANS ACTIVE LOW):
|
||||
# ~TRST_EN=10(ACBUS2), ~CLK_EN=14(ACBUS6), ~MOSI_EN=13(ACBUS5),
|
||||
# TMS_SEL=5(ADBUS5), ~TMS_EN=12(ACBUS4), LED=~15(ACBUS7).
|
||||
# CONNECTION NOTES:
|
||||
# * Connect EXT connector pin 1 with 3 to get 5V on JTAG connector pin 19.
|
||||
# * Connect JTAG connector pin 1 to 5V (i.e. EXT pin 13 or JTAG pin 19).
|
||||
# * For TPI connection use resistors: TDO --[470R]-- TPIDATA --[470R]-- TDI.
|
||||
# * Powering target from JTAG pin 19 allows KT-LINK current measurement.
|
||||
programmer
|
||||
id = "ktlink";
|
||||
desc = "KT-LINK FT2232H interface with IO switching and voltage buffers.";
|
||||
type = "avrftdi";
|
||||
connection_type = usb;
|
||||
usbvid= 0x0403;
|
||||
usbpid= 0xBBE2;
|
||||
usbdev= "A";
|
||||
reset = 8;
|
||||
sck = 0;
|
||||
mosi = 1;
|
||||
miso = 2;
|
||||
buff = ~10,~14,~13,5;
|
||||
rdyled = ~15;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "serialupdi";
|
||||
desc = "SerialUPDI";
|
||||
|
@ -890,6 +918,24 @@ programmer
|
|||
usbpid = 0x0c9f;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "arduinoisp";
|
||||
desc = "Arduino ISP Programmer";
|
||||
type = "usbtiny";
|
||||
connection_type = usb;
|
||||
usbvid = 0x2341;
|
||||
usbpid = 0x0049;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "arduinoisporg";
|
||||
desc = "Arduino ISP Programmer";
|
||||
type = "usbtiny";
|
||||
connection_type = usb;
|
||||
usbvid = 0x2A03;
|
||||
usbpid = 0x0049;
|
||||
;
|
||||
|
||||
# commercial version of USBtiny, using a separate VID/PID
|
||||
programmer
|
||||
id = "ehajo-isp";
|
||||
|
@ -900,6 +946,17 @@ programmer
|
|||
usbpid = 0x0BA5;
|
||||
;
|
||||
|
||||
# commercial version of USBtiny, using a separate VID/PID
|
||||
# https://github.com/IowaScaledEngineering/ckt-avrprogrammer
|
||||
programmer
|
||||
id = "iseavrprog";
|
||||
desc = "USBtiny-based programmer, https://iascaled.com";
|
||||
type = "usbtiny";
|
||||
connection_type = usb;
|
||||
usbvid = 0x1209;
|
||||
usbpid = 0x6570;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "micronucleus";
|
||||
desc = "Micronucleus Bootloader";
|
||||
|
@ -918,16 +975,6 @@ programmer
|
|||
usbpid = 0x0478;
|
||||
;
|
||||
|
||||
# commercial version of USBtiny, using a separate VID/PID
|
||||
programmer
|
||||
id = "iseavrprog";
|
||||
desc = "USBtiny-based USB programmer, https://github.com/IowaScaledEngineering/ckt-avrprogrammer";
|
||||
type = "usbtiny";
|
||||
connection_type = usb;
|
||||
usbvid = 0x1209;
|
||||
usbpid = 0x6570;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "butterfly";
|
||||
desc = "Atmel Butterfly Development Board";
|
||||
|
@ -4727,16 +4774,79 @@ part parent "m324p"
|
|||
signature = 0x1e 0x94 0x0a;
|
||||
|
||||
memory "eeprom"
|
||||
paged = no; /* leave this "no" */
|
||||
size = 512;
|
||||
page_size = 4;
|
||||
;
|
||||
min_write_delay = 9000;
|
||||
max_write_delay = 9000;
|
||||
readback_p1 = 0xff;
|
||||
readback_p2 = 0xff;
|
||||
read = " 1 0 1 0 0 0 0 0",
|
||||
" 0 0 x x x a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
write = " 1 1 0 0 0 0 0 0",
|
||||
" 0 0 x x x a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
loadpage_lo = " 1 1 0 0 0 0 0 1",
|
||||
" 0 0 0 0 0 0 0 0",
|
||||
" 0 0 0 0 0 0 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
writepage = " 1 1 0 0 0 0 1 0",
|
||||
" 0 0 x x x a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 0 0",
|
||||
" x x x x x x x x";
|
||||
|
||||
mode = 0x41;
|
||||
delay = 10;
|
||||
blocksize = 128;
|
||||
readsize = 256;
|
||||
;
|
||||
|
||||
memory "flash"
|
||||
paged = yes;
|
||||
size = 16384;
|
||||
page_size = 128;
|
||||
num_pages = 128;
|
||||
min_write_delay = 4500;
|
||||
max_write_delay = 4500;
|
||||
readback_p1 = 0xff;
|
||||
readback_p2 = 0xff;
|
||||
read_lo = " 0 0 1 0 0 0 0 0",
|
||||
" 0 a14 a13 a12 a11 a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
read_hi = " 0 0 1 0 1 0 0 0",
|
||||
" 0 a14 a13 a12 a11 a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
loadpage_lo = " 0 1 0 0 0 0 0 0",
|
||||
" 0 0 x x x x x x",
|
||||
" x x a5 a4 a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
loadpage_hi = " 0 1 0 0 1 0 0 0",
|
||||
" 0 0 x x x x x x",
|
||||
" x x a5 a4 a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
writepage = " 0 1 0 0 1 1 0 0",
|
||||
" 0 a14 a13 a12 a11 a10 a9 a8",
|
||||
" a7 a6 x x x x x x",
|
||||
" x x x x x x x x";
|
||||
|
||||
mode = 0x21;
|
||||
delay = 6;
|
||||
blocksize = 256;
|
||||
readsize = 256;
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
|
@ -5893,7 +6003,7 @@ part
|
|||
" i i i i i i i i";
|
||||
|
||||
writepage = " 0 1 0 0 1 1 0 0",
|
||||
" x x x a12 a11 a10 a9 a8",
|
||||
" x a14 a13 a12 a11 a10 a9 a8",
|
||||
" a7 a6 x x x x x x",
|
||||
" x x x x x x x x";
|
||||
|
||||
|
@ -5966,7 +6076,7 @@ part
|
|||
|
||||
part parent "m329"
|
||||
id = "m329a";
|
||||
desc = "ATmega329a";
|
||||
desc = "ATmega329A";
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
|
@ -6147,7 +6257,7 @@ part
|
|||
" i i i i i i i i";
|
||||
|
||||
writepage = " 0 1 0 0 1 1 0 0",
|
||||
" x x x a12 a11 a10 a9 a8",
|
||||
"a15 a14 a13 a12 a11 a10 a9 a8",
|
||||
" a7 x x x x x x x",
|
||||
" x x x x x x x x";
|
||||
|
||||
|
@ -8832,7 +8942,7 @@ part
|
|||
"a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
|
||||
|
||||
write = "1 1 0 0 0 0 0 0 0 0 x x x x x a8",
|
||||
"a8 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
|
||||
"a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
|
||||
|
||||
loadpage_lo = " 1 1 0 0 0 0 0 1",
|
||||
" 0 0 0 0 0 0 0 0",
|
||||
|
@ -8840,8 +8950,8 @@ part
|
|||
" i i i i i i i i";
|
||||
|
||||
writepage = " 1 1 0 0 0 0 1 0",
|
||||
" 0 0 x x x x x x",
|
||||
" 0 0 a5 a4 a3 a2 0 0",
|
||||
" 0 0 x x x x x a8",
|
||||
" a7 a6 a5 a4 a3 a2 0 0",
|
||||
" x x x x x x x x";
|
||||
|
||||
mode = 0x41;
|
||||
|
@ -9019,7 +9129,7 @@ part
|
|||
"a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
|
||||
|
||||
write = "1 1 0 0 0 0 0 0 0 0 x x x x x a8",
|
||||
"a8 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
|
||||
"a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
|
||||
|
||||
loadpage_lo = " 1 1 0 0 0 0 0 1",
|
||||
" 0 0 0 0 0 0 0 0",
|
||||
|
@ -9027,8 +9137,8 @@ part
|
|||
" i i i i i i i i";
|
||||
|
||||
writepage = " 1 1 0 0 0 0 1 0",
|
||||
" 0 0 x x x x x x",
|
||||
" 0 0 a5 a4 a3 a2 0 0",
|
||||
" 0 0 x x x x x a8",
|
||||
" a7 a6 a5 a4 a3 a2 0 0",
|
||||
" x x x x x x x x";
|
||||
|
||||
mode = 0x41;
|
||||
|
@ -9762,6 +9872,81 @@ part parent "m328"
|
|||
signature = 0x1e 0x96 0x84;
|
||||
bs2 = 0xe2;
|
||||
|
||||
memory "eeprom"
|
||||
paged = no;
|
||||
size = 2048;
|
||||
page_size = 8;
|
||||
min_write_delay = 3600;
|
||||
max_write_delay = 3600;
|
||||
readback_p1 = 0xff;
|
||||
readback_p2 = 0xff;
|
||||
read = " 1 0 1 0 0 0 0 0",
|
||||
" 0 0 0 x x a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
write = " 1 1 0 0 0 0 0 0",
|
||||
" 0 0 0 x x a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
loadpage_lo = " 1 1 0 0 0 0 0 1",
|
||||
" 0 0 0 0 0 0 0 0",
|
||||
" 0 0 0 0 0 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
writepage = " 1 1 0 0 0 0 1 0",
|
||||
" 0 0 x x x a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 0 0 0",
|
||||
" x x x x x x x x";
|
||||
|
||||
mode = 0x41;
|
||||
delay = 20;
|
||||
blocksize = 4;
|
||||
readsize = 256;
|
||||
;
|
||||
|
||||
memory "flash"
|
||||
paged = yes;
|
||||
size = 65536;
|
||||
page_size = 256;
|
||||
num_pages = 256;
|
||||
min_write_delay = 4500;
|
||||
max_write_delay = 4500;
|
||||
readback_p1 = 0xff;
|
||||
readback_p2 = 0xff;
|
||||
read_lo = " 0 0 1 0 0 0 0 0",
|
||||
" a15 a14 a13 a12 a11 a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
read_hi = " 0 0 1 0 1 0 0 0",
|
||||
" a15 a14 a13 a12 a11 a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
loadpage_lo = " 0 1 0 0 0 0 0 0",
|
||||
" 0 0 0 x x x x x",
|
||||
" x a6 a5 a4 a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
loadpage_hi = " 0 1 0 0 1 0 0 0",
|
||||
" 0 0 0 x x x x x",
|
||||
" x a6 a5 a4 a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
writepage = " 0 1 0 0 1 1 0 0",
|
||||
" a15 a14 a13 a12 a11 a10 a9 a8",
|
||||
" a7 x x x x x x x",
|
||||
" x x x x x x x x";
|
||||
|
||||
mode = 0x41;
|
||||
delay = 6;
|
||||
blocksize = 128;
|
||||
readsize = 256;
|
||||
|
||||
;
|
||||
|
||||
memory "efuse"
|
||||
size = 1;
|
||||
min_write_delay = 4500;
|
||||
|
@ -10233,7 +10418,7 @@ part
|
|||
" i i i i i i i i";
|
||||
|
||||
writepage = " 1 1 0 0 0 0 1 0",
|
||||
" 0 0 x x x x x x",
|
||||
" 0 0 x x x x x a8",
|
||||
" a7 a6 a5 a4 a3 a2 0 0",
|
||||
" x x x x x x x x";
|
||||
|
||||
|
@ -12101,7 +12286,7 @@ part
|
|||
|
||||
writepage = " 1 1 0 0 0 0 1 0",
|
||||
" 0 0 x x x x x x",
|
||||
" x a6 a5 a4 a3 a2 0 0",
|
||||
" a7 a6 a5 a4 a3 a2 0 0",
|
||||
" x x x x x x x x";
|
||||
|
||||
mode = 0x41;
|
||||
|
@ -12293,8 +12478,8 @@ part
|
|||
" i i i i i i i i";
|
||||
|
||||
writepage = " 1 1 0 0 0 0 1 0",
|
||||
" 0 0 x x x x x x",
|
||||
" x a6 a5 a4 a3 a2 0 0",
|
||||
" 0 0 x x x x x a8",
|
||||
" a7 a6 a5 a4 a3 a2 0 0",
|
||||
" x x x x x x x x";
|
||||
|
||||
mode = 0x41;
|
||||
|
@ -12535,7 +12720,7 @@ part parent "t84"
|
|||
|
||||
part
|
||||
id = "t43u";
|
||||
desc = "ATtiny43u";
|
||||
desc = "ATtiny43U";
|
||||
has_debugwire = yes;
|
||||
flash_instr = 0xB4, 0x07, 0x17;
|
||||
eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
|
||||
|
@ -12595,7 +12780,7 @@ part
|
|||
readback_p1 = 0xff;
|
||||
readback_p2 = 0xff;
|
||||
read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
|
||||
"0 0 a4 a3 a2 a1 a0 o o o o o o o o";
|
||||
"0 0 a5 a4 a3 a2 a1 a0 o o o o o o o o";
|
||||
|
||||
write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
|
||||
"0 0 a5 a4 a3 a2 a1 a0 i i i i i i i i";
|
||||
|
@ -12664,6 +12849,8 @@ part
|
|||
size = 1;
|
||||
write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
|
||||
"x x x x x x x x 1 1 i i i i i i";
|
||||
read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
|
||||
"x x x x x x x x o o o o o o o o";
|
||||
min_write_delay = 4500;
|
||||
max_write_delay = 4500;
|
||||
;
|
||||
|
@ -12702,12 +12889,203 @@ part
|
|||
;
|
||||
|
||||
memory "calibration"
|
||||
size = 2;
|
||||
size = 1;
|
||||
read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
|
||||
"0 0 0 0 0 0 0 a0 o o o o o o o o";
|
||||
;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATmega16u4
|
||||
#------------------------------------------------------------
|
||||
|
||||
part
|
||||
id = "m16u4";
|
||||
desc = "ATmega16U4";
|
||||
signature = 0x1e 0x94 0x88;
|
||||
usbpid = 0x2ff4;
|
||||
has_jtag = yes;
|
||||
# stk500_devcode = 0xB2;
|
||||
# avr910_devcode = 0x43;
|
||||
chip_erase_delay = 9000;
|
||||
pagel = 0xD7;
|
||||
bs2 = 0xA0;
|
||||
reset = dedicated;
|
||||
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
|
||||
chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
|
||||
"x x x x x x x x x x x x x x x x";
|
||||
|
||||
timeout = 200;
|
||||
stabdelay = 100;
|
||||
cmdexedelay = 25;
|
||||
synchloops = 32;
|
||||
bytedelay = 0;
|
||||
pollindex = 3;
|
||||
pollvalue = 0x53;
|
||||
predelay = 1;
|
||||
postdelay = 1;
|
||||
pollmethod = 1;
|
||||
|
||||
pp_controlstack =
|
||||
0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
|
||||
0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
|
||||
0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
|
||||
0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
|
||||
hventerstabdelay = 100;
|
||||
progmodedelay = 0;
|
||||
latchcycles = 5;
|
||||
togglevtg = 1;
|
||||
poweroffdelay = 15;
|
||||
resetdelayms = 1;
|
||||
resetdelayus = 0;
|
||||
hvleavestabdelay = 15;
|
||||
chiperasepulsewidth = 0;
|
||||
chiperasepolltimeout = 10;
|
||||
programfusepulsewidth = 0;
|
||||
programfusepolltimeout = 5;
|
||||
programlockpulsewidth = 0;
|
||||
programlockpolltimeout = 5;
|
||||
|
||||
idr = 0x31;
|
||||
spmcr = 0x57;
|
||||
rampz = 0x3b;
|
||||
allowfullpagebitstream = no;
|
||||
|
||||
ocdrev = 3;
|
||||
|
||||
memory "eeprom"
|
||||
paged = no; /* leave this "no" */
|
||||
page_size = 4; /* for parallel programming */
|
||||
size = 512;
|
||||
min_write_delay = 9000;
|
||||
max_write_delay = 9000;
|
||||
readback_p1 = 0x00;
|
||||
readback_p2 = 0x00;
|
||||
read = " 1 0 1 0 0 0 0 0",
|
||||
" x x x x x x x a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
write = " 1 1 0 0 0 0 0 0",
|
||||
" x x x x x x x a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
loadpage_lo = " 1 1 0 0 0 0 0 1",
|
||||
" 0 0 0 0 0 0 0 0",
|
||||
" 0 0 0 0 0 0 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
writepage = " 1 1 0 0 0 0 1 0",
|
||||
" 0 0 x x x x x a8",
|
||||
" a7 a6 a5 a4 a3 a2 0 0",
|
||||
" x x x x x x x x";
|
||||
|
||||
mode = 0x41;
|
||||
delay = 20;
|
||||
blocksize = 4;
|
||||
readsize = 256;
|
||||
;
|
||||
|
||||
memory "flash"
|
||||
paged = yes;
|
||||
size = 16384;
|
||||
page_size = 128;
|
||||
num_pages = 128;
|
||||
min_write_delay = 4500;
|
||||
max_write_delay = 4500;
|
||||
readback_p1 = 0x00;
|
||||
readback_p2 = 0x00;
|
||||
read_lo = " 0 0 1 0 0 0 0 0",
|
||||
" 0 a14 a13 a12 a11 a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
read_hi = " 0 0 1 0 1 0 0 0",
|
||||
" 0 a14 a13 a12 a11 a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
loadpage_lo = " 0 1 0 0 0 0 0 0",
|
||||
" x x x x x x x x",
|
||||
" x x a5 a4 a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
loadpage_hi = " 0 1 0 0 1 0 0 0",
|
||||
" x x x x x x x x",
|
||||
" x x a5 a4 a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
writepage = " 0 1 0 0 1 1 0 0",
|
||||
" a15 a14 a13 a12 a11 a10 a9 a8",
|
||||
" a7 a6 x x x x x x",
|
||||
" x x x x x x x x";
|
||||
|
||||
mode = 0x41;
|
||||
delay = 6;
|
||||
blocksize = 128;
|
||||
readsize = 256;
|
||||
;
|
||||
|
||||
memory "lfuse"
|
||||
size = 1;
|
||||
write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
|
||||
"x x x x x x x x i i i i i i i i";
|
||||
|
||||
read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
|
||||
"x x x x x x x x o o o o o o o o";
|
||||
min_write_delay = 9000;
|
||||
max_write_delay = 9000;
|
||||
;
|
||||
|
||||
memory "hfuse"
|
||||
size = 1;
|
||||
write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
|
||||
"x x x x x x x x i i i i i i i i";
|
||||
|
||||
read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
|
||||
"x x x x x x x x o o o o o o o o";
|
||||
min_write_delay = 9000;
|
||||
max_write_delay = 9000;
|
||||
;
|
||||
|
||||
memory "efuse"
|
||||
size = 1;
|
||||
write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
|
||||
"x x x x x x x x 1 1 1 1 i i i i";
|
||||
|
||||
read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
|
||||
"x x x x x x x x o o o o o o o o";
|
||||
min_write_delay = 9000;
|
||||
max_write_delay = 9000;
|
||||
;
|
||||
|
||||
memory "lock"
|
||||
size = 1;
|
||||
read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
|
||||
"x x x x x x x x 0 0 o o o o o o";
|
||||
|
||||
write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
|
||||
"x x x x x x x x 1 1 i i i i i i";
|
||||
min_write_delay = 9000;
|
||||
max_write_delay = 9000;
|
||||
;
|
||||
|
||||
memory "calibration"
|
||||
size = 1;
|
||||
read = "0 0 1 1 1 0 0 0 x x x x x x x x",
|
||||
"0 0 0 0 0 0 0 0 o o o o o o o o";
|
||||
;
|
||||
|
||||
memory "signature"
|
||||
size = 3;
|
||||
read = "0 0 1 1 0 0 0 0 x x x x x x x x",
|
||||
"x x x x x x a1 a0 o o o o o o o o";
|
||||
;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATmega32u4
|
||||
#------------------------------------------------------------
|
||||
|
@ -12788,12 +13166,12 @@ part
|
|||
|
||||
loadpage_lo = " 1 1 0 0 0 0 0 1",
|
||||
" 0 0 0 0 0 0 0 0",
|
||||
" 0 0 0 0 0 a2 a1 a0",
|
||||
" 0 0 0 0 0 0 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
writepage = " 1 1 0 0 0 0 1 0",
|
||||
" 0 0 x x x a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 0 0 0",
|
||||
" a7 a6 a5 a4 a3 a2 0 0",
|
||||
" x x x x x x x x";
|
||||
|
||||
mode = 0x41;
|
||||
|
@ -12867,7 +13245,7 @@ part
|
|||
memory "efuse"
|
||||
size = 1;
|
||||
write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
|
||||
"x x x x x x x x x x x x i i i i";
|
||||
"x x x x x x x x 1 1 1 1 i i i i";
|
||||
|
||||
read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
|
||||
"x x x x x x x x o o o o o o o o";
|
||||
|
@ -13187,7 +13565,7 @@ part
|
|||
" i i i i i i i i";
|
||||
|
||||
writepage = " 1 1 0 0 0 0 1 0",
|
||||
" 0 0 x x x a10 a9 a8",
|
||||
" 0 0 x x a11 a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 0 0 0",
|
||||
" x x x x x x x x";
|
||||
|
||||
|
@ -14249,7 +14627,7 @@ part
|
|||
part
|
||||
id = "m165";
|
||||
desc = "ATmega165";
|
||||
signature = 0x1e 0x94 0x07;
|
||||
signature = 0x1e 0x94 0x10;
|
||||
has_jtag = yes;
|
||||
# stk500_devcode = 0x??;
|
||||
# avr910_devcode = 0x??;
|
||||
|
@ -14423,7 +14801,7 @@ part
|
|||
|
||||
memory "signature"
|
||||
size = 3;
|
||||
read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0",
|
||||
read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0",
|
||||
"x x x x x x a1 a0 o o o o o o o o";
|
||||
;
|
||||
|
||||
|
@ -15431,6 +15809,13 @@ part parent "x128c3"
|
|||
id = "x128d4";
|
||||
desc = "ATxmega128D4";
|
||||
signature = 0x1e 0x97 0x47;
|
||||
|
||||
memory "flash"
|
||||
size = 0x22000;
|
||||
offset = 0x800000;
|
||||
page_size = 0x100;
|
||||
readsize = 0x100;
|
||||
;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
|
@ -16239,28 +16624,28 @@ part
|
|||
readback_p1 = 0xff;
|
||||
readback_p2 = 0xff;
|
||||
read_lo = " 0 0 1 0 0 0 0 0",
|
||||
" 0 0 0 a12 a11 a10 a9 a8",
|
||||
" 0 0 a13 a12 a11 a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
read_hi = " 0 0 1 0 1 0 0 0",
|
||||
" 0 0 0 a12 a11 a10 a9 a8",
|
||||
" 0 0 a13 a12 a11 a10 a9 a8",
|
||||
" a7 a6 a5 a4 a3 a2 a1 a0",
|
||||
" o o o o o o o o";
|
||||
|
||||
loadpage_lo = " 0 1 0 0 0 0 0 0",
|
||||
" 0 0 0 x x x x x",
|
||||
" x x a5 a4 a3 a2 a1 a0",
|
||||
" x x x x a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
loadpage_hi = " 0 1 0 0 1 0 0 0",
|
||||
" 0 0 0 x x x x x",
|
||||
" x x a5 a4 a3 a2 a1 a0",
|
||||
" x x x x a3 a2 a1 a0",
|
||||
" i i i i i i i i";
|
||||
|
||||
writepage = " 0 1 0 0 1 1 0 0",
|
||||
" 0 0 0 a12 a11 a10 a9 a8",
|
||||
" a7 a6 x x x x x x",
|
||||
" 0 0 a13 a12 a11 a10 a9 a8",
|
||||
" a7 a6 a5 a4 x x x x",
|
||||
" x x x x x x x x";
|
||||
|
||||
mode = 0x41;
|
||||
|
@ -16499,7 +16884,7 @@ part parent ".reduced_core_tiny"
|
|||
|
||||
part
|
||||
id = "m406";
|
||||
desc = "ATMEGA406";
|
||||
desc = "ATmega406";
|
||||
has_jtag = yes;
|
||||
signature = 0x1e 0x95 0x07;
|
||||
|
||||
|
@ -16632,9 +17017,7 @@ part
|
|||
;
|
||||
|
||||
memory "wdtcfg"
|
||||
size = 1;
|
||||
offset = 0x1280;
|
||||
readsize = 1;
|
||||
alias "fuse0";
|
||||
;
|
||||
|
||||
memory "fuse1"
|
||||
|
@ -16644,9 +17027,7 @@ part
|
|||
;
|
||||
|
||||
memory "bodcfg"
|
||||
size = 1;
|
||||
offset = 0x1281;
|
||||
readsize = 1;
|
||||
alias "fuse1";
|
||||
;
|
||||
|
||||
memory "fuse2"
|
||||
|
@ -16656,9 +17037,7 @@ part
|
|||
;
|
||||
|
||||
memory "osccfg"
|
||||
size = 1;
|
||||
offset = 0x1282;
|
||||
readsize = 1;
|
||||
alias "fuse2";
|
||||
;
|
||||
|
||||
memory "fuse4"
|
||||
|
@ -16668,9 +17047,7 @@ part
|
|||
;
|
||||
|
||||
memory "tcd0cfg"
|
||||
size = 1;
|
||||
offset = 0x1284;
|
||||
readsize = 1;
|
||||
alias "fuse4";
|
||||
;
|
||||
|
||||
memory "fuse5"
|
||||
|
@ -16680,9 +17057,7 @@ part
|
|||
;
|
||||
|
||||
memory "syscfg0"
|
||||
size = 1;
|
||||
offset = 0x1285;
|
||||
readsize = 1;
|
||||
alias "fuse5";
|
||||
;
|
||||
|
||||
memory "fuse6"
|
||||
|
@ -16692,9 +17067,7 @@ part
|
|||
;
|
||||
|
||||
memory "syscfg1"
|
||||
size = 1;
|
||||
offset = 0x1286;
|
||||
readsize = 1;
|
||||
alias "fuse6";
|
||||
;
|
||||
|
||||
memory "fuse7"
|
||||
|
@ -16704,9 +17077,11 @@ part
|
|||
;
|
||||
|
||||
memory "append"
|
||||
size = 1;
|
||||
offset = 0x1287;
|
||||
readsize = 1;
|
||||
alias "fuse7";
|
||||
;
|
||||
|
||||
memory "codesize"
|
||||
alias "fuse7";
|
||||
;
|
||||
|
||||
memory "fuse8"
|
||||
|
@ -16716,9 +17091,11 @@ part
|
|||
;
|
||||
|
||||
memory "bootend"
|
||||
size = 1;
|
||||
offset = 0x1288;
|
||||
readsize = 1;
|
||||
alias "fuse8";
|
||||
;
|
||||
|
||||
memory "bootsize"
|
||||
alias "fuse8";
|
||||
;
|
||||
|
||||
memory "lock"
|
||||
|
@ -16742,12 +17119,16 @@ part parent ".avr8x"
|
|||
desc = "AVR8X tiny family common values";
|
||||
family_id = "tinyAVR";
|
||||
|
||||
memory "usersig"
|
||||
memory "userrow"
|
||||
size = 0x20;
|
||||
offset = 0x1300;
|
||||
page_size = 0x20;
|
||||
readsize = 0x100;
|
||||
;
|
||||
|
||||
memory "usersig"
|
||||
alias "userrow";
|
||||
;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
|
@ -16759,12 +17140,16 @@ part parent ".avr8x"
|
|||
desc = "AVR8X mega family common values";
|
||||
family_id = "megaAVR";
|
||||
|
||||
memory "usersig"
|
||||
memory "userrow"
|
||||
size = 0x40;
|
||||
offset = 0x1300;
|
||||
page_size = 0x40;
|
||||
readsize = 0x100;
|
||||
;
|
||||
|
||||
memory "usersig"
|
||||
alias "userrow";
|
||||
;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
|
@ -17900,9 +18285,7 @@ part
|
|||
;
|
||||
|
||||
memory "wdtcfg"
|
||||
size = 1;
|
||||
offset = 0x1050;
|
||||
readsize = 1;
|
||||
alias "fuse0";
|
||||
;
|
||||
|
||||
memory "fuse1"
|
||||
|
@ -17912,9 +18295,7 @@ part
|
|||
;
|
||||
|
||||
memory "bodcfg"
|
||||
size = 1;
|
||||
offset = 0x1051;
|
||||
readsize = 1;
|
||||
alias "fuse1";
|
||||
;
|
||||
|
||||
memory "fuse2"
|
||||
|
@ -17924,9 +18305,7 @@ part
|
|||
;
|
||||
|
||||
memory "osccfg"
|
||||
size = 1;
|
||||
offset = 0x1052;
|
||||
readsize = 1;
|
||||
alias "fuse2";
|
||||
;
|
||||
|
||||
memory "fuse4"
|
||||
|
@ -17936,9 +18315,7 @@ part
|
|||
;
|
||||
|
||||
memory "tcd0cfg"
|
||||
size = 1;
|
||||
offset = 0x1054;
|
||||
readsize = 1;
|
||||
alias "fuse4";
|
||||
;
|
||||
|
||||
memory "fuse5"
|
||||
|
@ -17948,9 +18325,7 @@ part
|
|||
;
|
||||
|
||||
memory "syscfg0"
|
||||
size = 1;
|
||||
offset = 0x1055;
|
||||
readsize = 1;
|
||||
alias "fuse5";
|
||||
;
|
||||
|
||||
memory "fuse6"
|
||||
|
@ -17960,9 +18335,7 @@ part
|
|||
;
|
||||
|
||||
memory "syscfg1"
|
||||
size = 1;
|
||||
offset = 0x1056;
|
||||
readsize = 1;
|
||||
alias "fuse6";
|
||||
;
|
||||
|
||||
memory "fuse7"
|
||||
|
@ -17972,15 +18345,11 @@ part
|
|||
;
|
||||
|
||||
memory "codesize"
|
||||
size = 1;
|
||||
offset = 0x1057;
|
||||
readsize = 1;
|
||||
alias "fuse7";
|
||||
;
|
||||
|
||||
memory "append"
|
||||
size = 1;
|
||||
offset = 0x1057;
|
||||
readsize = 1;
|
||||
alias "fuse7";
|
||||
;
|
||||
|
||||
memory "fuse8"
|
||||
|
@ -17990,15 +18359,11 @@ part
|
|||
;
|
||||
|
||||
memory "bootsize"
|
||||
size = 1;
|
||||
offset = 0x1058;
|
||||
readsize = 1;
|
||||
alias "fuse8";
|
||||
;
|
||||
|
||||
memory "bootend"
|
||||
size = 1;
|
||||
offset = 0x1058;
|
||||
readsize = 1;
|
||||
alias "fuse8";
|
||||
;
|
||||
|
||||
memory "lock"
|
||||
|
@ -18015,6 +18380,10 @@ part
|
|||
readsize = 0x20;
|
||||
;
|
||||
|
||||
memory "usersig"
|
||||
alias "userrow";
|
||||
;
|
||||
|
||||
memory "data"
|
||||
# SRAM, only used to supply the offset
|
||||
offset = 0x1000000;
|
||||
|
@ -18851,6 +19220,10 @@ part parent ".avrdx"
|
|||
page_size = 0x40;
|
||||
readsize = 0x40;
|
||||
;
|
||||
|
||||
memory "usersig"
|
||||
alias "userrow";
|
||||
;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
|
|
144
src/avrpart.c
144
src/avrpart.c
|
@ -260,6 +260,21 @@ AVRMEM * avr_new_memtype(void)
|
|||
return m;
|
||||
}
|
||||
|
||||
AVRMEM_ALIAS * avr_new_memalias(void)
|
||||
{
|
||||
AVRMEM_ALIAS * m;
|
||||
|
||||
m = (AVRMEM_ALIAS *)malloc(sizeof(*m));
|
||||
if (m == NULL) {
|
||||
avrdude_message(MSG_INFO, "avr_new_memalias(): out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(m, 0, sizeof(*m));
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Allocate and initialize memory buffers for each of the device's
|
||||
|
@ -326,6 +341,17 @@ AVRMEM * avr_dup_mem(AVRMEM * m)
|
|||
return n;
|
||||
}
|
||||
|
||||
AVRMEM_ALIAS * avr_dup_memalias(AVRMEM_ALIAS * m)
|
||||
{
|
||||
AVRMEM_ALIAS * n;
|
||||
|
||||
n = avr_new_memalias();
|
||||
|
||||
*n = *m;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void avr_free_mem(AVRMEM * m)
|
||||
{
|
||||
int i;
|
||||
|
@ -348,7 +374,36 @@ void avr_free_mem(AVRMEM * m)
|
|||
free(m);
|
||||
}
|
||||
|
||||
AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
|
||||
void avr_free_memalias(AVRMEM_ALIAS * m)
|
||||
{
|
||||
free(m);
|
||||
}
|
||||
|
||||
AVRMEM_ALIAS * avr_locate_memalias(AVRPART * p, char * desc)
|
||||
{
|
||||
AVRMEM_ALIAS * m, * match;
|
||||
LNODEID ln;
|
||||
int matches;
|
||||
int l;
|
||||
|
||||
l = strlen(desc);
|
||||
matches = 0;
|
||||
match = NULL;
|
||||
for (ln=lfirst(p->mem_alias); ln; ln=lnext(ln)) {
|
||||
m = ldata(ln);
|
||||
if (strncmp(desc, m->desc, l) == 0) {
|
||||
match = m;
|
||||
matches++;
|
||||
}
|
||||
}
|
||||
|
||||
if (matches == 1)
|
||||
return match;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AVRMEM * avr_locate_mem_noalias(AVRPART * p, char * desc)
|
||||
{
|
||||
AVRMEM * m, * match;
|
||||
LNODEID ln;
|
||||
|
@ -373,11 +428,54 @@ AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
|
|||
}
|
||||
|
||||
|
||||
AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
|
||||
{
|
||||
AVRMEM * m, * match;
|
||||
AVRMEM_ALIAS * alias;
|
||||
LNODEID ln;
|
||||
int matches;
|
||||
int l;
|
||||
|
||||
l = strlen(desc);
|
||||
matches = 0;
|
||||
match = NULL;
|
||||
for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
|
||||
m = ldata(ln);
|
||||
if (strncmp(desc, m->desc, l) == 0) {
|
||||
match = m;
|
||||
matches++;
|
||||
}
|
||||
}
|
||||
|
||||
if (matches == 1)
|
||||
return match;
|
||||
|
||||
/* not yet found: look for matching alias name */
|
||||
alias = avr_locate_memalias(p, desc);
|
||||
if (alias != NULL)
|
||||
return alias->aliased_mem;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AVRMEM_ALIAS * avr_find_memalias(AVRPART * p, AVRMEM * m_orig)
|
||||
{
|
||||
AVRMEM_ALIAS * m;
|
||||
LNODEID ln;
|
||||
|
||||
for (ln=lfirst(p->mem_alias); ln; ln=lnext(ln)) {
|
||||
m = ldata(ln);
|
||||
if (m->aliased_mem == m_orig)
|
||||
return m;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, AVRPART * p,
|
||||
int type, int verbose)
|
||||
{
|
||||
static LNODEID ln;
|
||||
static AVRMEM * n;
|
||||
static unsigned int prev_mem_offset, prev_mem_size;
|
||||
int i, j;
|
||||
char * optr;
|
||||
|
@ -398,25 +496,14 @@ void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, AVRPART * p,
|
|||
prefix, prefix, prefix);
|
||||
}
|
||||
|
||||
// Get the next memory section, and stop before going out of band
|
||||
if (ln == NULL)
|
||||
ln = lnext(lfirst(p->mem));
|
||||
else
|
||||
ln = lnext(ln);
|
||||
if (ln != NULL)
|
||||
n = ldata(ln);
|
||||
|
||||
// Only print memory section if the previous section printed isn't identical
|
||||
if(prev_mem_offset != m->offset || prev_mem_size != m->size || (strcmp(p->family_id, "") == 0)) {
|
||||
prev_mem_offset = m->offset;
|
||||
prev_mem_size = m->size;
|
||||
AVRMEM_ALIAS *ap = avr_find_memalias(p, m);
|
||||
/* Show alias if the current and the next memory section has the same offset
|
||||
and size, we're not out of band and a family_id is present */
|
||||
char * mem_desc_alias = m->offset == n->offset && \
|
||||
m->size == n->size && \
|
||||
ln != NULL && \
|
||||
strcmp(p->family_id, "") != 0 ?
|
||||
n->desc : "";
|
||||
char * mem_desc_alias = ap? ap->desc: "";
|
||||
fprintf(f,
|
||||
"%s%-11s %-8s %4d %5d %5d %4d %-6s %6d %4d %6d %5d %5d 0x%02x 0x%02x\n",
|
||||
prefix,
|
||||
|
@ -488,6 +575,7 @@ AVRPART * avr_new_part(void)
|
|||
p->ocdrev = -1;
|
||||
|
||||
p->mem = lcreat(NULL, 0);
|
||||
p->mem_alias = lcreat(NULL, 0);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
@ -496,19 +584,35 @@ AVRPART * avr_new_part(void)
|
|||
AVRPART * avr_dup_part(AVRPART * d)
|
||||
{
|
||||
AVRPART * p;
|
||||
LISTID save;
|
||||
LNODEID ln;
|
||||
LISTID save, save2;
|
||||
LNODEID ln, ln2;
|
||||
int i;
|
||||
|
||||
p = avr_new_part();
|
||||
save = p->mem;
|
||||
save2 = p->mem_alias;
|
||||
|
||||
*p = *d;
|
||||
|
||||
p->mem = save;
|
||||
p->mem_alias = save2;
|
||||
|
||||
for (ln=lfirst(d->mem); ln; ln=lnext(ln)) {
|
||||
ladd(p->mem, avr_dup_mem(ldata(ln)));
|
||||
AVRMEM *m = ldata(ln);
|
||||
AVRMEM *m2 = avr_dup_mem(m);
|
||||
ladd(p->mem, m2);
|
||||
// see if there is any alias for it
|
||||
for (ln2=lfirst(d->mem_alias); ln2; ln2=lnext(ln2)) {
|
||||
AVRMEM_ALIAS *a = ldata(ln2);
|
||||
if (a->aliased_mem == m) {
|
||||
// yes, duplicate it
|
||||
AVRMEM_ALIAS *a2 = avr_dup_memalias(a);
|
||||
// ... adjust the pointer ...
|
||||
a2->aliased_mem = m2;
|
||||
// ... and add to new list
|
||||
ladd(p->mem_alias, a2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < AVR_OP_MAX; i++) {
|
||||
|
@ -523,6 +627,8 @@ void avr_free_part(AVRPART * d)
|
|||
int i;
|
||||
ldestroy_cb(d->mem, (void(*)(void *))avr_free_mem);
|
||||
d->mem = NULL;
|
||||
ldestroy_cb(d->mem_alias, (void(*)(void *))avr_free_memalias);
|
||||
d->mem_alias = NULL;
|
||||
for(i=0;i<sizeof(d->op)/sizeof(d->op[0]);i++)
|
||||
{
|
||||
if (d->op[i] != NULL)
|
||||
|
|
|
@ -36,7 +36,6 @@ char default_programmer[MAX_STR_CONST];
|
|||
char default_parallel[PATH_MAX];
|
||||
char default_serial[PATH_MAX];
|
||||
double default_bitclock;
|
||||
int default_safemode;
|
||||
|
||||
char string_buf[MAX_STR_CONST];
|
||||
char *string_buf_ptr;
|
||||
|
@ -48,6 +47,7 @@ AVRPART * current_part;
|
|||
AVRMEM * current_mem;
|
||||
LISTID part_list;
|
||||
LISTID programmers;
|
||||
bool is_alias;
|
||||
|
||||
int lineno;
|
||||
const char * infile;
|
||||
|
@ -73,6 +73,7 @@ int init_config(void)
|
|||
current_mem = NULL;
|
||||
part_list = lcreat(NULL, 0);
|
||||
programmers = lcreat(NULL, 0);
|
||||
is_alias = false;
|
||||
|
||||
lineno = 1;
|
||||
infile = NULL;
|
||||
|
|
|
@ -54,6 +54,7 @@ extern int lineno;
|
|||
extern const char * infile;
|
||||
extern LISTID string_list;
|
||||
extern LISTID number_list;
|
||||
extern bool is_alias; // current entry is alias
|
||||
|
||||
|
||||
#if !defined(HAS_YYSTYPE)
|
||||
|
|
|
@ -68,6 +68,7 @@ static int pin_name;
|
|||
%token K_PAGE_SIZE
|
||||
%token K_PAGED
|
||||
|
||||
%token K_ALIAS
|
||||
%token K_BAUDRATE
|
||||
%token K_BS2
|
||||
%token K_BUFF
|
||||
|
@ -77,7 +78,6 @@ static int pin_name;
|
|||
%token K_DEFAULT_BITCLOCK
|
||||
%token K_DEFAULT_PARALLEL
|
||||
%token K_DEFAULT_PROGRAMMER
|
||||
%token K_DEFAULT_SAFEMODE
|
||||
%token K_DEFAULT_SERIAL
|
||||
%token K_DESC
|
||||
%token K_FAMILY_ID
|
||||
|
@ -257,14 +257,6 @@ def :
|
|||
K_DEFAULT_BITCLOCK TKN_EQUAL number_real TKN_SEMI {
|
||||
default_bitclock = $3->value.number_real;
|
||||
free_token($3);
|
||||
} |
|
||||
|
||||
K_DEFAULT_SAFEMODE TKN_EQUAL yesno TKN_SEMI {
|
||||
if ($3->primary == K_YES)
|
||||
default_safemode = 1;
|
||||
else if ($3->primary == K_NO)
|
||||
default_safemode = 0;
|
||||
free_token($3);
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -1248,12 +1240,17 @@ part_parm :
|
|||
{
|
||||
AVRMEM * existing_mem;
|
||||
|
||||
existing_mem = avr_locate_mem(current_part, current_mem->desc);
|
||||
existing_mem = avr_locate_mem_noalias(current_part, current_mem->desc);
|
||||
if (existing_mem != NULL) {
|
||||
lrmv_d(current_part->mem, existing_mem);
|
||||
avr_free_mem(existing_mem);
|
||||
}
|
||||
ladd(current_part->mem, current_mem);
|
||||
if (is_alias) {
|
||||
avr_free_mem(current_mem); // alias mem has been already entered below
|
||||
is_alias = false;
|
||||
} else {
|
||||
ladd(current_part->mem, current_mem);
|
||||
}
|
||||
current_mem = NULL;
|
||||
} |
|
||||
|
||||
|
@ -1290,6 +1287,7 @@ yesno :
|
|||
|
||||
mem_specs :
|
||||
mem_spec TKN_SEMI |
|
||||
mem_alias TKN_SEMI |
|
||||
mem_specs mem_spec TKN_SEMI
|
||||
;
|
||||
|
||||
|
@ -1419,6 +1417,38 @@ mem_spec :
|
|||
}
|
||||
;
|
||||
|
||||
mem_alias :
|
||||
K_ALIAS TKN_STRING
|
||||
{
|
||||
AVRMEM * existing_mem;
|
||||
|
||||
existing_mem = avr_locate_mem(current_part, $2->value.string);
|
||||
if (existing_mem == NULL) {
|
||||
yyerror("%s alias to non-existent memory %s",
|
||||
current_mem->desc, $2->value.string);
|
||||
free_token($2);
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
// if this alias does already exist, drop the old one
|
||||
AVRMEM_ALIAS * alias = avr_locate_memalias(current_part, current_mem->desc);
|
||||
if (alias) {
|
||||
lrmv_d(current_part->mem_alias, alias);
|
||||
avr_free_memalias(alias);
|
||||
}
|
||||
|
||||
is_alias = true;
|
||||
alias = avr_new_memalias();
|
||||
|
||||
// alias->desc and current_mem->desc have the same length
|
||||
// definition, thus no need to check for length here
|
||||
strcpy(alias->desc, current_mem->desc);
|
||||
alias->aliased_mem = existing_mem;
|
||||
ladd(current_part->mem_alias, alias);
|
||||
|
||||
free_token($2);
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.60)
|
||||
AC_INIT(avrdude, 6.99-20211218, avrdude-dev@nongnu.org)
|
||||
AC_INIT(avrdude, 7.0-20220508, avrdude-dev@nongnu.org)
|
||||
|
||||
AC_CANONICAL_BUILD
|
||||
AC_CANONICAL_HOST
|
||||
|
|
|
@ -40,7 +40,7 @@ all-local: info html ps pdf
|
|||
html: avrdude-html/avrdude.html
|
||||
|
||||
avrdude-html/avrdude.html: $(srcdir)/$(info_TEXINFOS) $(GENERATED_TEXINFOS)
|
||||
texi2html -split_node $(srcdir)/$(info_TEXINFOS)
|
||||
texi2html --split=node --css-include=$(srcdir)/avrdude.css $(srcdir)/$(info_TEXINFOS)
|
||||
if [ -e ./avrdude.html -o -e ./avrdude_1.html ]; then \
|
||||
mkdir -p avrdude-html ; \
|
||||
mv -f *.html avrdude-html ; \
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
body { background-color: #ffd; }
|
||||
h1 { text-shadow: .05em .05em #ccc; }
|
||||
table {
|
||||
border: 3px solid #ccf;
|
||||
background-color: white;
|
||||
}
|
||||
div.smallexample {
|
||||
background-color: #dfd;
|
||||
border: 3px solid #cfc;
|
||||
}
|
||||
div.example {
|
||||
background-color: #dfd;
|
||||
border: 3px solid #cfc;
|
||||
}
|
||||
samp {
|
||||
color: blue;
|
||||
}
|
||||
code {
|
||||
color: green;
|
||||
}
|
|
@ -28,9 +28,7 @@ This file documents the avrdude program.
|
|||
|
||||
For avrdude version @value{VERSION}, @value{UPDATED}.
|
||||
|
||||
Copyright @copyright{} 2003, 2005 Brian Dean
|
||||
|
||||
Copyright @copyright{} 2006 - 2021 J@"org Wunsch
|
||||
Copyright @copyright{} Brian Dean, J@"org Wunsch
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
|
@ -64,13 +62,10 @@ the terms of the GNU Free Documentation License (FDL), version 1.3.
|
|||
@author by Brian S. Dean
|
||||
|
||||
@page
|
||||
Send comments on AVRDUDE to @w{@email{avrdude-dev@@nongnu.org}}.
|
||||
|
||||
Use @uref{http://savannah.nongnu.org/bugs/?group=avrdude} to report bugs.
|
||||
Use @uref{https://github.com/avrdudes/avrdude/issues} to report bugs and ask questions.
|
||||
|
||||
Copyright @copyright{} 2003,2005 Brian S. Dean
|
||||
|
||||
Copyright @copyright{} 2006 - 2013 J@"org Wunsch
|
||||
Copyright @copyright{} Brian S. Dean, J@"org Wunsch
|
||||
@sp 2
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
|
@ -102,13 +97,9 @@ programs to Atmel AVR microcontrollers.
|
|||
|
||||
For avrdude version @value{VERSION}, @value{UPDATED}.
|
||||
|
||||
Send comments on AVRDUDE to @w{@email{avrdude-dev@@nongnu.org}}.
|
||||
Use @uref{https://github.com/avrdudes/avrdude/issues} to report bugs and ask questions.
|
||||
|
||||
Use @uref{http://savannah.nongnu.org/bugs/?group=avrdude} to report bugs.
|
||||
|
||||
Copyright @copyright{} 2003,2005 Brian S. Dean
|
||||
|
||||
Copyright @copyright{} 2006 J@"org Wunsch
|
||||
Copyright @copyright{} Brian S. Dean, J@"org Wunsch
|
||||
@end ifinfo
|
||||
|
||||
@menu
|
||||
|
@ -119,6 +110,7 @@ Copyright @copyright{} 2006 J@"org Wunsch
|
|||
* Programmer Specific Information::
|
||||
* Platform Dependent Information::
|
||||
* Troubleshooting::
|
||||
* Index::
|
||||
@end menu
|
||||
|
||||
@c
|
||||
|
@ -127,7 +119,7 @@ Copyright @copyright{} 2006 J@"org Wunsch
|
|||
@node Introduction, Command Line Options, Top, Top
|
||||
@comment node-name, next, previous, up
|
||||
@chapter Introduction
|
||||
@cindex introduction
|
||||
@cindex Introduction
|
||||
|
||||
AVRDUDE - AVR Downloader Uploader - is a program for downloading and
|
||||
uploading the on-chip memories of Atmel's AVR microcontrollers. It can
|
||||
|
@ -145,6 +137,8 @@ from the contents of a file, while interactive mode is useful for
|
|||
exploring memory contents, modifying individual bytes of eeprom,
|
||||
programming fuse/lock bits, etc.
|
||||
|
||||
@cindex Programmers supported
|
||||
|
||||
AVRDUDE supports the following basic programmer types: Atmel's STK500,
|
||||
Atmel's AVRISP and AVRISP mkII devices,
|
||||
Atmel's STK600,
|
||||
|
@ -345,6 +339,7 @@ below for Teensy specific options.
|
|||
@c Node
|
||||
@c
|
||||
@node History, , Introduction, Introduction
|
||||
@cindex History
|
||||
@section History and Credits
|
||||
|
||||
AVRDUDE was written by Brian S. Dean under the name of AVRPROG to run on
|
||||
|
@ -353,13 +348,15 @@ AVRDUDE when interest grew in a Windows port of the software so that the
|
|||
name did not conflict with AVRPROG.EXE which is the name of Atmel's
|
||||
Windows programming software.
|
||||
|
||||
The AVRDUDE source now resides in the public CVS repository on
|
||||
savannah.gnu.org (@url{http://savannah.gnu.org/projects/avrdude/}),
|
||||
where it continues to be enhanced and ported to other systems. In
|
||||
For many years, the AVRDUDE source resided in public repositories on
|
||||
savannah.nongnu.org,
|
||||
where it continued to be enhanced and ported to other systems. In
|
||||
addition to FreeBSD, AVRDUDE now runs on Linux and Windows. The
|
||||
developers behind the porting effort primarily were Ted Roth, Eric
|
||||
Weddington, and Joerg Wunsch.
|
||||
|
||||
In 2022, the project moved to Github (@url{https://github.com/avrdudes/avrdude/}).
|
||||
|
||||
And in the spirit of many open source projects, this manual also draws
|
||||
on the work of others. The initial revision was composed of parts of
|
||||
the original Unix manual page written by Joerg Wunsch, the original web
|
||||
|
@ -374,7 +371,6 @@ Roth.
|
|||
@c
|
||||
@node Command Line Options, Terminal Mode Operation, Introduction, Top
|
||||
@chapter Command Line Options
|
||||
@cindex options
|
||||
|
||||
@menu
|
||||
* Option Descriptions::
|
||||
|
@ -386,6 +382,7 @@ Roth.
|
|||
@c Node
|
||||
@c
|
||||
@node Option Descriptions, Programmers accepting extended parameters, Command Line Options, Command Line Options
|
||||
@cindex Options (command-line)
|
||||
@section Option Descriptions
|
||||
|
||||
@noindent
|
||||
|
@ -410,6 +407,8 @@ 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:
|
||||
|
||||
@cindex Device support
|
||||
|
||||
@multitable @columnfractions .15 .3
|
||||
@include parts.texi
|
||||
@end multitable
|
||||
|
@ -461,6 +460,8 @@ 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:
|
||||
|
||||
@cindex Programmer support
|
||||
|
||||
@multitable @columnfractions .2 .6
|
||||
@include programmers.texi
|
||||
@end multitable
|
||||
|
@ -681,32 +682,6 @@ 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 -u
|
||||
Disables the default behaviour of reading out the fuses three times before
|
||||
programming, then verifying at the end of programming that the fuses have not
|
||||
changed. If you want to change fuses you will need to specify this option,
|
||||
as avrdude will see the fuses have changed (even though you wanted to) and
|
||||
will change them back for your "safety". This option was designed to
|
||||
prevent cases of fuse bits magically changing (usually called @emph{safemode}).
|
||||
|
||||
If one of the configuration files contains a line
|
||||
|
||||
@code{default_safemode = no;}
|
||||
|
||||
safemode is disabled by default.
|
||||
The @option{-u} option's effect is negated in that case, i. e. it
|
||||
@emph{enables} safemode.
|
||||
|
||||
Safemode is always disabled for AVR32, Xmega and TPI devices.
|
||||
|
||||
@item -s
|
||||
Disable safemode prompting. When safemode discovers that one or more
|
||||
fuse bits have unintentionally changed, it will prompt for
|
||||
confirmation regarding whether or not it should attempt to recover the
|
||||
fuse bit(s). Specifying this flag disables the prompt and assumes
|
||||
that the fuse bit(s) should be recovered without asking for
|
||||
confirmation first.
|
||||
|
||||
@item -t
|
||||
Tells AVRDUDE to enter the interactive ``terminal'' mode instead of up-
|
||||
or downloading files. See below for a detailed description of the
|
||||
|
@ -864,7 +839,7 @@ accepting extended parameters.
|
|||
@c
|
||||
@node Programmers accepting extended parameters, Example Command Line Invocations, Option Descriptions, Command Line Options
|
||||
@section Programmers accepting extended parameters
|
||||
|
||||
@cindex @code{-x} AVR Dragon
|
||||
@table @code
|
||||
|
||||
@item JTAG ICE mkII/3
|
||||
|
@ -881,6 +856,7 @@ Each AVR unit within the chain shifts by 4 bits.
|
|||
Other JTAG units might require a different bit shift count.
|
||||
@end table
|
||||
|
||||
@cindex @code{-x} AVR910
|
||||
@item AVR910
|
||||
|
||||
The AVR910 programmer type accepts the following extended parameter:
|
||||
|
@ -901,13 +877,16 @@ Use
|
|||
programmer creates errors during initial sequence.
|
||||
@end table
|
||||
|
||||
@cindex @code{-x} Arduino
|
||||
@item Arduino
|
||||
|
||||
The Arduino programmer type accepts the following extended parameter:
|
||||
@table @code
|
||||
@item @samp{attemps=VALUE}
|
||||
Overide the default number of connection retry attempt by using @var{VALUE}.
|
||||
@end table
|
||||
|
||||
@cindex @code{-x} Buspirate
|
||||
@item BusPirate
|
||||
|
||||
The BusPirate programmer type accepts the following extended parameters:
|
||||
|
@ -997,6 +976,7 @@ The default value is 100ms. Using 10ms might work in most cases.
|
|||
|
||||
@end table
|
||||
|
||||
@cindex @code{-x} Micronucleus bootloader
|
||||
@item Micronucleus bootloader
|
||||
|
||||
When using the Micronucleus programmer type, the
|
||||
|
@ -1009,6 +989,7 @@ If no time-out is specified, AVRDUDE will wait indefinitely until the
|
|||
device is plugged in.
|
||||
@end table
|
||||
|
||||
@cindex @code{-x} Teensy bootloader
|
||||
@item Teensy bootloader
|
||||
|
||||
When using the Teensy programmer type, the
|
||||
|
@ -1021,6 +1002,7 @@ If no time-out is specified, AVRDUDE will wait indefinitely until the
|
|||
device is plugged in.
|
||||
@end table
|
||||
|
||||
@cindex @code{-x} Wiring
|
||||
@item Wiring
|
||||
|
||||
When using the Wiring programmer type, the
|
||||
|
@ -1032,6 +1014,7 @@ After performing the port open phase, AVRDUDE will wait/snooze for
|
|||
No toggling of DTR/RTS is performed if @var{snooze} > 0.
|
||||
@end table
|
||||
|
||||
@cindex @code{-x} PICkit2
|
||||
@item PICkit2
|
||||
Connection to the PICkit2 programmer:
|
||||
@multitable @columnfractions .05 .3
|
||||
|
@ -1052,6 +1035,7 @@ Sets the SPI clocking rate in Hz (default is 100kHz). Alternately the -B or -i o
|
|||
Sets the timeout for USB reads and writes in milliseconds (default is 1500 ms).
|
||||
@end table
|
||||
|
||||
@cindex @code{-x} USBasp
|
||||
@item USBasp
|
||||
Extended parameters:
|
||||
@table @code
|
||||
|
@ -1062,6 +1046,7 @@ rather than entire chip.
|
|||
Only applicable to TPI devices (ATtiny 4/5/9/10/20/40).
|
||||
@end table
|
||||
|
||||
@cindex @code{-x} xbee
|
||||
@item xbee
|
||||
Extended parameters:
|
||||
@table @code
|
||||
|
@ -1078,6 +1063,7 @@ The remaining two necessary XBee-to-MCU connections are not selectable
|
|||
the MCU's ‘TXD’ line.
|
||||
@end table
|
||||
|
||||
@cindex @code{-x} serialupdi
|
||||
@item serialupdi
|
||||
Extended parameters:
|
||||
@table @code
|
||||
|
@ -1133,8 +1119,6 @@ Reading | ################################################## | 100% 6.83s
|
|||
avrdude: verifying ...
|
||||
avrdude: 19278 bytes of flash verified
|
||||
|
||||
avrdude: safemode: Fuses OK
|
||||
|
||||
avrdude done. Thank you.
|
||||
|
||||
%
|
||||
|
@ -1162,8 +1146,6 @@ Reading | ################################################## | 100% 46.10s
|
|||
|
||||
avrdude: writing output file "c:/diag flash.bin"
|
||||
|
||||
avrdude: safemode: Fuses OK
|
||||
|
||||
avrdude done. Thank you.
|
||||
|
||||
%
|
||||
|
@ -1284,6 +1266,7 @@ commands can be recalled and edited.
|
|||
@end menu
|
||||
|
||||
@node Terminal Mode Commands, Terminal Mode Examples, Terminal Mode Operation, Terminal Mode Operation
|
||||
@cindex Terminal Mode
|
||||
@section Terminal Mode Commands
|
||||
|
||||
@noindent
|
||||
|
@ -1291,20 +1274,83 @@ The following commands are implemented:
|
|||
|
||||
@table @code
|
||||
|
||||
@item dump @var{memtype} @var{addr} @var{nbytes}
|
||||
@item dump @var{memtype} [@var{start_addr} [@var{nbytes}]]
|
||||
Read @var{nbytes} from the specified memory area, and display them in
|
||||
the usual hexadecimal and ASCII form.
|
||||
|
||||
@item dump
|
||||
@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}
|
||||
Continue dumping the memory contents for another @var{nbytes} where the
|
||||
previous dump command left off.
|
||||
|
||||
@item write @var{memtype} @var{addr} @var{byte1} @dots{} @var{byteN}
|
||||
Manually program the respective memory cells, starting at address addr,
|
||||
using the values @var{byte1} through @var{byteN}. This feature is not
|
||||
@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.
|
||||
|
||||
Items @var{dataN} can have the following formats:
|
||||
|
||||
@multitable @columnfractions .3 .4 .3
|
||||
@item @strong{Type}
|
||||
@tab @strong{Example}
|
||||
@tab @strong{Size (bytes)}
|
||||
|
||||
@item Character
|
||||
@tab @code{'A'}
|
||||
@tab 1
|
||||
|
||||
@item Decimal integer
|
||||
@tab 12345
|
||||
@tab 1, 2, 4, or 8 (see below)
|
||||
|
||||
@item Octal integer
|
||||
@tab 012345
|
||||
@tab 1, 2, 4, or 8 (see below)
|
||||
|
||||
@item Hexadecimal integer
|
||||
@tab 0x12345
|
||||
@tab 1, 2, 4, or 8 (see below)
|
||||
|
||||
@item Float
|
||||
@tab 3.1415926
|
||||
@tab 4
|
||||
|
||||
@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:
|
||||
|
||||
@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
|
||||
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.
|
||||
|
||||
@item write @var{memtype} @var{start_addr} @var{length} @var{data1} @var{data2} @var{dataN} @dots{}
|
||||
|
||||
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.
|
||||
|
||||
@item erase
|
||||
Perform a chip erase.
|
||||
|
||||
|
@ -1397,6 +1443,7 @@ Display the current target supply voltage and JTAG bit clock rate/period.
|
|||
@c Node
|
||||
@c
|
||||
@node Terminal Mode Examples, , Terminal Mode Commands, Terminal Mode Operation
|
||||
@cindex Terminal Mode
|
||||
@section Terminal Mode Examples
|
||||
|
||||
@noindent
|
||||
|
@ -1408,7 +1455,6 @@ Display part parameters, modify eeprom cells, perform a chip erase:
|
|||
|
||||
avrdude: AVR device initialized and ready to accept instructions
|
||||
avrdude: Device signature = 0x1e9702
|
||||
avrdude: current erase-rewrite cycle count is 52 (if being tracked)
|
||||
avrdude> part
|
||||
>>> part
|
||||
|
||||
|
@ -1470,7 +1516,6 @@ display the factory defaults, then reprogram:
|
|||
|
||||
avrdude: AVR device initialized and ready to accept instructions
|
||||
avrdude: Device signature = 0x1e9702
|
||||
avrdude: current erase-rewrite cycle count is 52 (if being tracked)
|
||||
avrdude> d efuse
|
||||
>>> d efuse
|
||||
0000 fd |. |
|
||||
|
@ -1496,11 +1541,56 @@ avrdude>
|
|||
@end cartouche
|
||||
@end smallexample
|
||||
|
||||
@smallexample
|
||||
@cartouche
|
||||
% avrdude -c pkobn_updi -p avr128db48 -t
|
||||
|
||||
Vtarget : 4.71 V
|
||||
PDI/UPDI clock Xmega/megaAVR : 100 kHz
|
||||
|
||||
avrdude: AVR device initialized and ready to accept instructions
|
||||
|
||||
Reading | ################################################## | 100% 0.01s
|
||||
|
||||
avrdude: Device signature = 0x1e970c (probably avr128db48)
|
||||
avrdude> write eeprom 0 1234567890 'A' 'V' 'R' 2.718282 "Hello World!"
|
||||
>>> write eeprom 0 1234567890 'A' 'V' 'R' 2.718282 "Hello World!"
|
||||
Warning: no size suffix specified for "1234567890". Writing 4 byte(s)
|
||||
Info: Writing 24 bytes starting from address 0x00
|
||||
|
||||
avrdude> dump eeprom 0 32
|
||||
>>> dump eeprom 0 32
|
||||
|
||||
0000 d2 02 96 49 41 56 52 55 f8 2d 40 48 65 6c 6c 6f |...IAVRU.-@@Hello|
|
||||
0010 20 57 6f 72 6c 64 21 00 ff ff ff ff ff ff ff ff | World!.........|
|
||||
|
||||
avrdude> q
|
||||
@end cartouche
|
||||
@end smallexample
|
||||
|
||||
The following example demonstrates the second form of the @code{write}
|
||||
command where the last data value provided is used to fill up the
|
||||
indicated memory range.
|
||||
|
||||
@smallexample
|
||||
@cartouche
|
||||
avrdude> write eeprom 0x00 0x20 'a' 'b' 'c' 0x11 0xcafe 0x55 ...
|
||||
>>> write eeprom 0x00 0x20 'a' 'b' 'c' 0x11 0xcafe 0x55 ...
|
||||
|
||||
avrdude> dump eeprom 0 0x30
|
||||
>>> dump eeprom 0 0x30
|
||||
0000 61 62 63 11 fe ca 55 55 55 55 55 55 55 55 55 55 |abc...UUUUUUUUUU|
|
||||
0010 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 |UUUUUUUUUUUUUUUU|
|
||||
0020 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
|
||||
@end cartouche
|
||||
@end smallexample
|
||||
|
||||
@c
|
||||
@c Node
|
||||
@c
|
||||
@node Configuration File, Programmer Specific Information, Terminal Mode Operation, Top
|
||||
@cindex Configuration File
|
||||
@cindex @code{avrdude.conf}
|
||||
@chapter Configuration File
|
||||
|
||||
@noindent
|
||||
|
@ -1845,9 +1935,6 @@ flash pages of the application section.
|
|||
|
||||
Reading fuse and lock bits is fully supported.
|
||||
|
||||
Note that due to the inability to write the fuse bits, the safemode
|
||||
functionality does not make sense for these boot loaders.
|
||||
|
||||
@end itemize
|
||||
|
||||
@c
|
||||
|
@ -1866,6 +1953,7 @@ functionality does not make sense for these boot loaders.
|
|||
@c Node
|
||||
@c
|
||||
@node Atmel STK600, Atmel DFU bootloader using FLIP version 1, Programmer Specific Information, Programmer Specific Information
|
||||
@cindex STK600
|
||||
@section Atmel STK600
|
||||
|
||||
@c
|
||||
|
@ -1962,6 +2050,7 @@ least 4.5 V in order to work. This can be done using
|
|||
@c Node
|
||||
@c
|
||||
@node Atmel DFU bootloader using FLIP version 1, SerialUPDI programmer , Atmel STK600, Programmer Specific Information
|
||||
@cindex DFU bootloader
|
||||
@section Atmel DFU bootloader using FLIP version 1
|
||||
|
||||
Bootloaders using the FLIP protocol version 1 experience some very
|
||||
|
@ -1990,6 +2079,7 @@ versions of the bootloader.
|
|||
@c Node
|
||||
@c
|
||||
@node SerialUPDI programmer, , Atmel DFU bootloader using FLIP version 1, Programmer Specific Information
|
||||
@cindex SerialUPDI
|
||||
@section SerialUPDI programmer
|
||||
|
||||
SerialUPDI programmer can be used for programming UPDI-only devices
|
||||
|
@ -2021,9 +2111,6 @@ fuse, extended fuse) have no meaning whatsoever, as they have been
|
|||
simply replaced by array of fuses: fuse0..9. Therefore you can simply
|
||||
ignore this particular line of AVRDUDE output.
|
||||
|
||||
In connection to the above, @emph{safemode} has no meaning in context
|
||||
of UPDI devices and should be ignored.
|
||||
|
||||
Currently available devices support only UPDI NVM programming model 0
|
||||
and 2, but there is also experimental implementation of model 3 - not
|
||||
yet tested.
|
||||
|
@ -2243,6 +2330,8 @@ configuration file will be always be @code{/etc/avrdude.conf}.
|
|||
|
||||
@noindent
|
||||
The parallel and serial port device file names are system specific.
|
||||
MacOS has no default serial or parallel port names, but available
|
||||
ports can be found under @code{/dev/cu.*}.
|
||||
The following table lists the default names for a given system.
|
||||
|
||||
@multitable @columnfractions .30 .30 .30
|
||||
|
@ -2475,13 +2564,13 @@ such as @option{--prefix} and @option{--datadir}.
|
|||
@c
|
||||
@c Node
|
||||
@c
|
||||
@node Troubleshooting, ,Platform Dependent Information ,Top
|
||||
@node Troubleshooting,Index ,Platform Dependent Information ,Top
|
||||
@appendix Troubleshooting
|
||||
|
||||
@noindent
|
||||
In general, please report any bugs encountered via
|
||||
@*
|
||||
@url{http://savannah.nongnu.org/bugs/?group=avrdude}.
|
||||
@url{https://github.com/avrdudes/avrdude/issues}.
|
||||
|
||||
|
||||
@itemize @bullet
|
||||
|
@ -2786,7 +2875,11 @@ erase cycle.
|
|||
|
||||
@end itemize
|
||||
|
||||
@node Index, , Troubleshooting, Top
|
||||
|
||||
@unnumbered Concept Index
|
||||
|
||||
@printindex cp
|
||||
|
||||
@bye
|
||||
|
||||
|
|
150
src/jtag3.c
150
src/jtag3.c
|
@ -493,7 +493,7 @@ static int jtag3_edbg_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
|||
}
|
||||
|
||||
if (serial_send(&pgm->fd, buf, max_xfer) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_send(): failed to send command to serial port\n",
|
||||
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_send(): failed to send command to serial port\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
@ -509,7 +509,7 @@ static int jtag3_edbg_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
|||
(frag == nfragments - 1 && status[1] != 0x01))
|
||||
{
|
||||
/* what to do in this case? */
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_send(): Unexpected response 0x%02x, 0x%02x\n",
|
||||
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_send(): Unexpected response 0x%02x, 0x%02x\n",
|
||||
progname, status[0], status[1]);
|
||||
}
|
||||
data += this_len;
|
||||
|
@ -596,36 +596,36 @@ static int jtag3_edbg_signoff(PROGRAMMER * pgm)
|
|||
buf[1] = CMSISDAP_LED_CONNECT;
|
||||
buf[2] = 0;
|
||||
if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to send command to serial port\n",
|
||||
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_signoff(): failed to send command to serial port\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
rv = serial_recv(&pgm->fd, status, pgm->fd.usb.max_xfer);
|
||||
if (rv != pgm->fd.usb.max_xfer) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
|
||||
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
|
||||
progname, rv);
|
||||
return -1;
|
||||
}
|
||||
if (status[0] != CMSISDAP_CMD_LED ||
|
||||
status[1] != 0)
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): unexpected response 0x%02x, 0x%02x\n",
|
||||
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_signoff(): unexpected response 0x%02x, 0x%02x\n",
|
||||
progname, status[0], status[1]);
|
||||
|
||||
buf[0] = CMSISDAP_CMD_DISCONNECT;
|
||||
if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to send command to serial port\n",
|
||||
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_signoff(): failed to send command to serial port\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
rv = serial_recv(&pgm->fd, status, pgm->fd.usb.max_xfer);
|
||||
if (rv != pgm->fd.usb.max_xfer) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
|
||||
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
|
||||
progname, rv);
|
||||
return -1;
|
||||
}
|
||||
if (status[0] != CMSISDAP_CMD_DISCONNECT ||
|
||||
status[1] != 0)
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): unexpected response 0x%02x, 0x%02x\n",
|
||||
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_signoff(): unexpected response 0x%02x, 0x%02x\n",
|
||||
progname, status[0], status[1]);
|
||||
|
||||
return 0;
|
||||
|
@ -686,12 +686,12 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
|
|||
avrdude_message(MSG_TRACE, "%s: jtag3_edbg_recv():\n", progname);
|
||||
|
||||
if ((buf = malloc(USBDEV_MAX_XFER_3)) == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): out of memory\n",
|
||||
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_recv(): out of memory\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
if ((request = malloc(pgm->fd.usb.max_xfer)) == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): out of memory\n",
|
||||
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_recv(): out of memory\n",
|
||||
progname);
|
||||
free(buf);
|
||||
return -1;
|
||||
|
@ -706,7 +706,7 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
|
|||
request[0] = EDBG_VENDOR_AVR_RSP;
|
||||
|
||||
if (serial_send(&pgm->fd, request, pgm->fd.usb.max_xfer) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): error sending CMSIS-DAP vendor command\n",
|
||||
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_recv(): error sending CMSIS-DAP vendor command\n",
|
||||
progname);
|
||||
free(request);
|
||||
free(*msg);
|
||||
|
@ -725,7 +725,7 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
|
|||
}
|
||||
|
||||
if (buf[0] != EDBG_VENDOR_AVR_RSP) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Unexpected response 0x%02x\n",
|
||||
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_recv(): Unexpected response 0x%02x\n",
|
||||
progname, buf[0]);
|
||||
free(*msg);
|
||||
free(request);
|
||||
|
@ -736,7 +736,7 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
|
|||
// Documentation says:
|
||||
// "FragmentInfo 0x00 indicates that no response data is
|
||||
// available, and the rest of the packet is ignored."
|
||||
avrdude_message(MSG_INFO,
|
||||
avrdude_message(MSG_NOTICE,
|
||||
"%s: jtag3_edbg_recv(): "
|
||||
"No response available\n",
|
||||
progname);
|
||||
|
@ -752,7 +752,7 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
|
|||
thisfrag = 1;
|
||||
} else {
|
||||
if (nfrags != (buf[1] & 0x0F)) {
|
||||
avrdude_message(MSG_INFO,
|
||||
avrdude_message(MSG_NOTICE,
|
||||
"%s: jtag3_edbg_recv(): "
|
||||
"Inconsistent # of fragments; had %d, now %d\n",
|
||||
progname, nfrags, (buf[1] & 0x0F));
|
||||
|
@ -762,7 +762,7 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
|
|||
}
|
||||
}
|
||||
if (thisfrag != ((buf[1] >> 4) & 0x0F)) {
|
||||
avrdude_message(MSG_INFO,
|
||||
avrdude_message(MSG_NOTICE,
|
||||
"%s: jtag3_edbg_recv(): "
|
||||
"Inconsistent fragment number; expect %d, got %d\n",
|
||||
progname, thisfrag, ((buf[1] >> 4) & 0x0F));
|
||||
|
@ -773,12 +773,12 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
|
|||
|
||||
int thislen = (buf[2] << 8) | buf[3];
|
||||
if (thislen > rv + 4) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Unexpected length value (%d > %d)\n",
|
||||
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_recv(): Unexpected length value (%d > %d)\n",
|
||||
progname, thislen, rv + 4);
|
||||
thislen = rv + 4;
|
||||
}
|
||||
if (len + thislen > USBDEV_MAX_XFER_3) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Length exceeds max size (%d > %d)\n",
|
||||
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_recv(): Length exceeds max size (%d > %d)\n",
|
||||
progname, len + thislen, USBDEV_MAX_XFER_3);
|
||||
thislen = USBDEV_MAX_XFER_3 - len;
|
||||
}
|
||||
|
@ -865,7 +865,7 @@ int jtag3_recv(PROGRAMMER * pgm, unsigned char **msg) {
|
|||
"%s: Device is locked! Chip erase required to unlock.\n",
|
||||
progname);
|
||||
} else {
|
||||
avrdude_message(MSG_INFO, "%s: bad response to %s command: 0x%02x\n",
|
||||
avrdude_message(MSG_NOTICE, "%s: bad response to %s command: 0x%02x\n",
|
||||
progname, descr, c);
|
||||
}
|
||||
status = (*resp)[3];
|
||||
|
@ -1129,7 +1129,7 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
|
|||
if (PDATA(pgm)->set_sck(pgm, parm) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
jtag3_print_parms1(pgm, progbuf);
|
||||
if (conn == PARM3_CONN_JTAG)
|
||||
{
|
||||
avrdude_message(MSG_NOTICE2, "%s: jtag3_initialize(): "
|
||||
|
@ -1174,7 +1174,8 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
|
|||
u32_to_b4(xd.nvm_fuse_offset, m->offset & ~7);
|
||||
} else if (matches(m->desc, "lock")) {
|
||||
u32_to_b4(xd.nvm_lock_offset, m->offset);
|
||||
} else if (strcmp(m->desc, "usersig") == 0) {
|
||||
} else if (strcmp(m->desc, "usersig") == 0 ||
|
||||
strcmp(m->desc, "userrow") == 0) {
|
||||
u32_to_b4(xd.nvm_user_sig_offset, m->offset);
|
||||
} else if (strcmp(m->desc, "prodsig") == 0) {
|
||||
u32_to_b4(xd.nvm_prod_sig_offset, m->offset);
|
||||
|
@ -1225,7 +1226,8 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
|
|||
u16_to_b2(xd.eeprom_bytes, m->size);
|
||||
u16_to_b2(xd.eeprom_base, m->offset);
|
||||
}
|
||||
else if (strcmp(m->desc, "usersig") == 0)
|
||||
else if (strcmp(m->desc, "usersig") == 0 ||
|
||||
strcmp(m->desc, "userrow") == 0)
|
||||
{
|
||||
u16_to_b2(xd.user_sig_bytes, m->size);
|
||||
u16_to_b2(xd.user_sig_base, m->offset);
|
||||
|
@ -1269,7 +1271,7 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
|
|||
"xd->flash_page_size=%x\n\t"
|
||||
"xd->eeprom_page_size=%x\n\t"
|
||||
"xd->nvmctrl=%x %x\n\t"
|
||||
"xd->ocd=%x %x\n\t",
|
||||
"xd->ocd=%x %x\n\t"
|
||||
"xd->address_mode=%x\n",
|
||||
xd.prog_base_msb,
|
||||
xd.prog_base[0], xd.prog_base[1],
|
||||
|
@ -1355,13 +1357,14 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
|
|||
if ((status = jtag3_command(pgm, cmd, 4, &resp, "AVR sign-on")) >= 0)
|
||||
break;
|
||||
|
||||
avrdude_message(MSG_INFO, "%s: retrying with external reset applied\n",
|
||||
avrdude_message(MSG_NOTICE, "%s: retrying with external reset applied\n",
|
||||
progname);
|
||||
}
|
||||
|
||||
if (use_ext_reset > 1) {
|
||||
avrdude_message(MSG_INFO, "%s: JTAGEN fuse disabled?\n", progname);
|
||||
return -1;
|
||||
if(strcmp(pgm->type, "JTAGICE3") == 0 && p->flags & AVRPART_HAS_JTAG)
|
||||
avrdude_message(MSG_INFO, "%s: JTAGEN fuse disabled?\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1689,9 +1692,10 @@ static int jtag3_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
cmd[3] = XMEGA_ERASE_BOOT_PAGE;
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
cmd[3] = XMEGA_ERASE_EEPROM_PAGE;
|
||||
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
|
||||
} else if (strcmp(m->desc, "usersig") == 0 ||
|
||||
strcmp(m->desc, "userrow") == 0) {
|
||||
cmd[3] = XMEGA_ERASE_USERSIG;
|
||||
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
|
||||
} else if (strcmp(m->desc, "boot") == 0) {
|
||||
cmd[3] = XMEGA_ERASE_BOOT_PAGE;
|
||||
} else {
|
||||
cmd[3] = XMEGA_ERASE_APP_PAGE;
|
||||
|
@ -1763,9 +1767,10 @@ static int jtag3_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
}
|
||||
cmd[3] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM_XMEGA : MTYPE_EEPROM_PAGE;
|
||||
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
|
||||
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
|
||||
} else if (strcmp(m->desc, "usersig") == 0 ||
|
||||
strcmp(m->desc, "userrow") == 0) {
|
||||
cmd[3] = MTYPE_USERSIG;
|
||||
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
|
||||
} else if (strcmp(m->desc, "boot") == 0) {
|
||||
cmd[3] = MTYPE_BOOT_FLASH;
|
||||
} else if ( p->flags & AVRPART_HAS_PDI || p->flags & AVRPART_HAS_UPDI ) {
|
||||
cmd[3] = MTYPE_FLASH;
|
||||
|
@ -1852,11 +1857,12 @@ static int jtag3_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
cmd[3] = ( p->flags & AVRPART_HAS_PDI || p->flags & AVRPART_HAS_UPDI ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
|
||||
if (pgm->flag & PGM_FL_IS_DW)
|
||||
return -1;
|
||||
} else if ( ( strcmp(m->desc, "prodsig") == 0 ) ) {
|
||||
} else if (strcmp(m->desc, "prodsig") == 0) {
|
||||
cmd[3] = MTYPE_PRODSIG;
|
||||
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
|
||||
} else if (strcmp(m->desc, "usersig") == 0 ||
|
||||
strcmp(m->desc, "userrow") == 0) {
|
||||
cmd[3] = MTYPE_USERSIG;
|
||||
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
|
||||
} else if (strcmp(m->desc, "boot") == 0) {
|
||||
cmd[3] = MTYPE_BOOT_FLASH;
|
||||
} else if ( p->flags & AVRPART_HAS_PDI ) {
|
||||
cmd[3] = MTYPE_FLASH;
|
||||
|
@ -1968,10 +1974,23 @@ static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
cmd[3] = MTYPE_FUSE_BITS;
|
||||
if (!(p->flags & AVRPART_HAS_UPDI))
|
||||
addr = mem->offset & 7;
|
||||
} else if (strcmp(mem->desc, "usersig") == 0) {
|
||||
} else if (strcmp(mem->desc, "usersig") == 0 ||
|
||||
strcmp(mem->desc, "userrow") == 0) {
|
||||
cmd[3] = MTYPE_USERSIG;
|
||||
} else if (strcmp(mem->desc, "prodsig") == 0) {
|
||||
cmd[3] = MTYPE_PRODSIG;
|
||||
} else if (strcmp(mem->desc, "sernum") == 0) {
|
||||
cmd[3] = MTYPE_SIGN_JTAG;
|
||||
} else if (strcmp(mem->desc, "osccal16") == 0) {
|
||||
cmd[3] = MTYPE_SIGN_JTAG;
|
||||
} else if (strcmp(mem->desc, "osccal20") == 0) {
|
||||
cmd[3] = MTYPE_SIGN_JTAG;
|
||||
} else if (strcmp(mem->desc, "tempsense") == 0) {
|
||||
cmd[3] = MTYPE_SIGN_JTAG;
|
||||
} else if (strcmp(mem->desc, "osc16err") == 0) {
|
||||
cmd[3] = MTYPE_SIGN_JTAG;
|
||||
} else if (strcmp(mem->desc, "osc20err") == 0) {
|
||||
cmd[3] = MTYPE_SIGN_JTAG;
|
||||
} else if (strcmp(mem->desc, "calibration") == 0) {
|
||||
cmd[3] = MTYPE_OSCCAL_BYTE;
|
||||
if (pgm->flag & PGM_FL_IS_DW)
|
||||
|
@ -2117,7 +2136,8 @@ static int jtag3_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
cmd[3] = MTYPE_FUSE_BITS;
|
||||
if (!(p->flags & AVRPART_HAS_UPDI))
|
||||
addr = mem->offset & 7;
|
||||
} else if (strcmp(mem->desc, "usersig") == 0) {
|
||||
} else if (strcmp(mem->desc, "usersig") == 0 ||
|
||||
strcmp(mem->desc, "userrow") == 0) {
|
||||
cmd[3] = MTYPE_USERSIG;
|
||||
} else if (strcmp(mem->desc, "prodsig") == 0) {
|
||||
cmd[3] = MTYPE_PRODSIG;
|
||||
|
@ -2232,7 +2252,7 @@ int jtag3_getparm(PROGRAMMER * pgm, unsigned char scope,
|
|||
|
||||
c = resp[1];
|
||||
if (c != RSP3_DATA || status < 3) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_getparm(): "
|
||||
avrdude_message(MSG_NOTICE, "%s: jtag3_getparm(): "
|
||||
"bad response to %s\n",
|
||||
progname, descr);
|
||||
free(resp);
|
||||
|
@ -2317,9 +2337,8 @@ static int jtag3_set_vtarget(PROGRAMMER * pgm, double v)
|
|||
utarg = (unsigned)(v * 1000);
|
||||
|
||||
if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_set_vtarget(): cannot obtain V[aref]\n",
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_set_vtarget(): cannot obtain V[target]\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uaref = b2_to_u16(buf);
|
||||
|
@ -2328,8 +2347,11 @@ static int jtag3_set_vtarget(PROGRAMMER * pgm, double v)
|
|||
avrdude_message(MSG_INFO, "%s: jtag3_set_vtarget(): changing V[target] from %.1f to %.1f\n",
|
||||
progname, uaref / 1000.0, v);
|
||||
|
||||
if (jtag3_setparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, sizeof(buf)) < 0)
|
||||
if (jtag3_setparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, sizeof(buf)) < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_set_vtarget(): cannot confirm new V[target] value\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2368,14 +2390,12 @@ static void jtag3_display(PROGRAMMER * pgm, const char * p)
|
|||
memmove(resp, resp + 3, status - 3);
|
||||
resp[status - 3] = 0;
|
||||
|
||||
avrdude_message(MSG_INFO, "%sICE hardware version: %d\n", p, parms[0]);
|
||||
avrdude_message(MSG_INFO, "%sICE firmware version: %d.%02d (rel. %d)\n", p,
|
||||
avrdude_message(MSG_INFO, "%sICE HW version : %d\n", p, parms[0]);
|
||||
avrdude_message(MSG_INFO, "%sICE FW version : %d.%02d (rel. %d)\n", p,
|
||||
parms[1], parms[2],
|
||||
(parms[3] | (parms[4] << 8)));
|
||||
avrdude_message(MSG_INFO, "%sSerial number : %s\n", p, resp);
|
||||
avrdude_message(MSG_INFO, "%sSerial number : %s", p, resp);
|
||||
free(resp);
|
||||
|
||||
jtag3_print_parms1(pgm, p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2386,28 +2406,40 @@ static void jtag3_print_parms1(PROGRAMMER * pgm, const char * p)
|
|||
if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0)
|
||||
return;
|
||||
|
||||
avrdude_message(MSG_INFO, "%sVtarget : %.2f V\n", p,
|
||||
b2_to_u16(buf) / 1000.0);
|
||||
avrdude_message(MSG_INFO, "%sVtarget %s: %.2f V\n", p,
|
||||
verbose ? "" : " ", b2_to_u16(buf) / 1000.0);
|
||||
|
||||
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_PROG, buf, 2) < 0)
|
||||
return;
|
||||
avrdude_message(MSG_INFO, "%sJTAG clock megaAVR/program: %u kHz\n", p,
|
||||
b2_to_u16(buf));
|
||||
|
||||
if (b2_to_u16(buf) > 0) {
|
||||
avrdude_message(MSG_INFO, "%sJTAG clock megaAVR/program : %u kHz\n", p,
|
||||
b2_to_u16(buf));
|
||||
}
|
||||
|
||||
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_DEBUG, buf, 2) < 0)
|
||||
return;
|
||||
avrdude_message(MSG_INFO, "%sJTAG clock megaAVR/debug: %u kHz\n", p,
|
||||
b2_to_u16(buf));
|
||||
|
||||
if (b2_to_u16(buf) > 0) {
|
||||
avrdude_message(MSG_INFO, "%sJTAG clock megaAVR/debug : %u kHz\n", p,
|
||||
b2_to_u16(buf));
|
||||
}
|
||||
|
||||
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_JTAG, buf, 2) < 0)
|
||||
return;
|
||||
avrdude_message(MSG_INFO, "%sJTAG clock Xmega: %u kHz\n", p,
|
||||
b2_to_u16(buf));
|
||||
|
||||
if (b2_to_u16(buf) > 0) {
|
||||
avrdude_message(MSG_INFO, "%sJTAG clock Xmega : %u kHz\n", p,
|
||||
b2_to_u16(buf));
|
||||
}
|
||||
|
||||
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_PDI, buf, 2) < 0)
|
||||
return;
|
||||
avrdude_message(MSG_INFO, "%sPDI clock Xmega : %u kHz\n", p,
|
||||
b2_to_u16(buf));
|
||||
|
||||
if (b2_to_u16(buf) > 0) {
|
||||
avrdude_message(MSG_INFO, "%sPDI/UPDI clock Xmega/megaAVR : %u kHz\n\n", p,
|
||||
b2_to_u16(buf));
|
||||
}
|
||||
}
|
||||
|
||||
static void jtag3_print_parms(PROGRAMMER * pgm)
|
||||
|
@ -2444,14 +2476,14 @@ static unsigned int jtag3_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, uns
|
|||
* Non-Xmega device.
|
||||
*/
|
||||
if (p->flags & AVRPART_HAS_UPDI) {
|
||||
if (strcmp(m->desc, "fuses") == 0) {
|
||||
addr += m->offset;
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
return addr;
|
||||
}
|
||||
else if (matches(m->desc, "fuse")) {
|
||||
addr = m->offset;
|
||||
else if (m->size == 1) {
|
||||
addr = m->offset;
|
||||
}
|
||||
else if (strcmp(m->desc, "flash") != 0) {
|
||||
addr += m->offset;
|
||||
else if (m->size > 1) {
|
||||
addr += m->offset;
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
|
|
|
@ -1275,8 +1275,8 @@ static void jtagmkI_display(PROGRAMMER * pgm, const char * p)
|
|||
jtagmkI_getparm(pgm, PARM_SW_VERSION, &fw) < 0)
|
||||
return;
|
||||
|
||||
avrdude_message(MSG_INFO, "%sICE hardware version: 0x%02x\n", p, hw);
|
||||
avrdude_message(MSG_INFO, "%sICE firmware version: 0x%02x\n", p, fw);
|
||||
avrdude_message(MSG_INFO, "%sICE HW version: 0x%02x\n", p, hw);
|
||||
avrdude_message(MSG_INFO, "%sICE FW version: 0x%02x\n", p, fw);
|
||||
|
||||
jtagmkI_print_parms1(pgm, p);
|
||||
|
||||
|
@ -1320,9 +1320,9 @@ static void jtagmkI_print_parms1(PROGRAMMER * pgm, const char * p)
|
|||
clk = 1e6;
|
||||
}
|
||||
|
||||
avrdude_message(MSG_INFO, "%sVtarget : %.1f V\n", p,
|
||||
avrdude_message(MSG_INFO, "%sVtarget : %.1f V\n", p,
|
||||
6.25 * (unsigned)vtarget / 255.0);
|
||||
avrdude_message(MSG_INFO, "%sJTAG clock : %s (%.1f us)\n", p, clkstr,
|
||||
avrdude_message(MSG_INFO, "%sJTAG clock : %s (%.1f us)\n", p, clkstr,
|
||||
1.0e6 / clk);
|
||||
|
||||
return;
|
||||
|
|
|
@ -1056,7 +1056,8 @@ static void jtagmkII_set_xmega_params(PROGRAMMER * pgm, AVRPART * p)
|
|||
u32_to_b4(sendbuf.dd.nvm_fuse_offset, m->offset & ~7);
|
||||
} else if (strncmp(m->desc, "lock", 4) == 0) {
|
||||
u32_to_b4(sendbuf.dd.nvm_lock_offset, m->offset);
|
||||
} else if (strcmp(m->desc, "usersig") == 0) {
|
||||
} else if (strcmp(m->desc, "usersig") == 0 ||
|
||||
strcmp(m->desc, "userrow") == 0) {
|
||||
u32_to_b4(sendbuf.dd.nvm_user_sig_offset, m->offset);
|
||||
} else if (strcmp(m->desc, "prodsig") == 0) {
|
||||
u32_to_b4(sendbuf.dd.nvm_prod_sig_offset, m->offset);
|
||||
|
@ -1933,9 +1934,10 @@ static int jtagmkII_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
cmd[1] = XMEGA_ERASE_BOOT_PAGE;
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
cmd[1] = XMEGA_ERASE_EEPROM_PAGE;
|
||||
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
|
||||
} else if (strcmp(m->desc, "usersig") == 0 ||
|
||||
strcmp(m->desc, "userrow") == 0) {
|
||||
cmd[1] = XMEGA_ERASE_USERSIG;
|
||||
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
|
||||
} else if (strcmp(m->desc, "boot") == 0) {
|
||||
cmd[1] = XMEGA_ERASE_BOOT_PAGE;
|
||||
} else {
|
||||
cmd[1] = XMEGA_ERASE_APP_PAGE;
|
||||
|
@ -2044,13 +2046,14 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
free(cmd);
|
||||
return n_bytes;
|
||||
}
|
||||
cmd[1] = ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
|
||||
cmd[1] = (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
|
||||
PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
|
||||
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
|
||||
} else if (strcmp(m->desc, "usersig") == 0 ||
|
||||
strcmp(m->desc, "userrow") == 0) {
|
||||
cmd[1] = MTYPE_USERSIG;
|
||||
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
|
||||
} else if (strcmp(m->desc, "boot") == 0) {
|
||||
cmd[1] = MTYPE_BOOT_FLASH;
|
||||
} else if ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) {
|
||||
} else if (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) {
|
||||
cmd[1] = MTYPE_FLASH;
|
||||
} else {
|
||||
cmd[1] = MTYPE_SPM;
|
||||
|
@ -2156,16 +2159,17 @@ static int jtagmkII_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
/* dynamically decide between flash/boot memtype */
|
||||
dynamic_memtype = 1;
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
cmd[1] = ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
|
||||
cmd[1] = (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
|
||||
if (pgm->flag & PGM_FL_IS_DW)
|
||||
return -1;
|
||||
} else if ( ( strcmp(m->desc, "prodsig") == 0 ) ) {
|
||||
} else if (strcmp(m->desc, "prodsig") == 0) {
|
||||
cmd[1] = MTYPE_PRODSIG;
|
||||
} else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
|
||||
} else if (strcmp(m->desc, "usersig") == 0 ||
|
||||
strcmp(m->desc, "userrow") == 0) {
|
||||
cmd[1] = MTYPE_USERSIG;
|
||||
} else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
|
||||
} else if (strcmp(m->desc, "boot") == 0) {
|
||||
cmd[1] = MTYPE_BOOT_FLASH;
|
||||
} else if ( p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI) ) {
|
||||
} else if (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_UPDI)) {
|
||||
cmd[1] = MTYPE_FLASH;
|
||||
} else {
|
||||
cmd[1] = MTYPE_SPM;
|
||||
|
@ -2291,7 +2295,8 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
unsupp = 1;
|
||||
} else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
|
||||
cmd[1] = MTYPE_FUSE_BITS;
|
||||
} else if (strcmp(mem->desc, "usersig") == 0) {
|
||||
} else if (strcmp(mem->desc, "usersig") == 0 ||
|
||||
strcmp(mem->desc, "userrow") == 0) {
|
||||
cmd[1] = MTYPE_USERSIG;
|
||||
} else if (strcmp(mem->desc, "prodsig") == 0) {
|
||||
cmd[1] = MTYPE_PRODSIG;
|
||||
|
@ -2460,7 +2465,8 @@ static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
unsupp = 1;
|
||||
} else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
|
||||
cmd[1] = MTYPE_FUSE_BITS;
|
||||
} else if (strcmp(mem->desc, "usersig") == 0) {
|
||||
} else if (strcmp(mem->desc, "usersig") == 0 ||
|
||||
strcmp(mem->desc, "userrow") == 0) {
|
||||
cmd[1] = MTYPE_USERSIG;
|
||||
} else if (strcmp(mem->desc, "prodsig") == 0) {
|
||||
cmd[1] = MTYPE_PRODSIG;
|
||||
|
@ -2688,11 +2694,11 @@ static void jtagmkII_display(PROGRAMMER * pgm, const char * p)
|
|||
jtagmkII_getparm(pgm, PAR_FW_VERSION, fw) < 0)
|
||||
return;
|
||||
|
||||
avrdude_message(MSG_INFO, "%sM_MCU hardware version: %d\n", p, hw[0]);
|
||||
avrdude_message(MSG_INFO, "%sM_MCU firmware version: %d.%02d\n", p, fw[1], fw[0]);
|
||||
avrdude_message(MSG_INFO, "%sS_MCU hardware version: %d\n", p, hw[1]);
|
||||
avrdude_message(MSG_INFO, "%sS_MCU firmware version: %d.%02d\n", p, fw[3], fw[2]);
|
||||
avrdude_message(MSG_INFO, "%sSerial number: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
avrdude_message(MSG_INFO, "%sM_MCU HW version: %d\n", p, hw[0]);
|
||||
avrdude_message(MSG_INFO, "%sM_MCU FW version: %d.%02d\n", p, fw[1], fw[0]);
|
||||
avrdude_message(MSG_INFO, "%sS_MCU HW version: %d\n", p, hw[1]);
|
||||
avrdude_message(MSG_INFO, "%sS_MCU FW version: %d.%02d\n", p, fw[3], fw[2]);
|
||||
avrdude_message(MSG_INFO, "%sSerial number : %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
p, PDATA(pgm)->serno[0], PDATA(pgm)->serno[1], PDATA(pgm)->serno[2], PDATA(pgm)->serno[3], PDATA(pgm)->serno[4], PDATA(pgm)->serno[5]);
|
||||
|
||||
jtagmkII_print_parms1(pgm, p);
|
||||
|
|
|
@ -117,6 +117,7 @@ SIGN [+-]
|
|||
<strng>\n { yyerror("unterminated character constant");
|
||||
return YYERRCODE; }
|
||||
|
||||
alias { yylval=NULL; return K_ALIAS; }
|
||||
allowfullpagebitstream { yylval=NULL; return K_ALLOWFULLPAGEBITSTREAM; }
|
||||
avr910_devcode { yylval=NULL; return K_AVR910_DEVCODE; }
|
||||
bank_size { yylval=NULL; return K_PAGE_SIZE; }
|
||||
|
@ -137,7 +138,6 @@ 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_safemode { yylval=NULL; return K_DEFAULT_SAFEMODE; }
|
||||
default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
|
||||
delay { yylval=NULL; return K_DELAY; }
|
||||
desc { yylval=NULL; return K_DESC; }
|
||||
|
|
|
@ -261,6 +261,7 @@ typedef struct avrpart {
|
|||
OPCODE * op[AVR_OP_MAX]; /* opcodes */
|
||||
|
||||
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 */
|
||||
} AVRPART;
|
||||
|
@ -292,6 +293,11 @@ typedef struct avrmem {
|
|||
OPCODE * op[AVR_OP_MAX]; /* opcodes */
|
||||
} AVRMEM;
|
||||
|
||||
typedef struct avrmem_alias {
|
||||
char desc[AVR_MEMDESCLEN]; /* alias name ("syscfg0" etc.) */
|
||||
AVRMEM *aliased_mem;
|
||||
} AVRMEM_ALIAS;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -307,10 +313,15 @@ int avr_get_output_index(OPCODE * op);
|
|||
|
||||
/* 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);
|
||||
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);
|
||||
|
||||
|
@ -831,30 +842,6 @@ int fileio(int op, char * filename, FILEFMT format,
|
|||
#endif
|
||||
|
||||
|
||||
/* formerly safemode.h */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Writes the specified fuse in fusename (can be "lfuse", "hfuse", or "efuse") and verifies it. Will try up to tries
|
||||
amount of times before giving up */
|
||||
int safemode_writefuse (unsigned char fuse, char * fusename, PROGRAMMER * pgm, AVRPART * p, int tries);
|
||||
|
||||
/* Reads the fuses three times, checking that all readings are the same. This will ensure that the before values aren't in error! */
|
||||
int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse, unsigned char * efuse, unsigned char * fuse, PROGRAMMER * pgm, AVRPART * p);
|
||||
|
||||
/* This routine will store the current values pointed to by lfuse, hfuse, and efuse into an internal buffer in this routine
|
||||
when save is set to 1. When save is 0 (or not 1 really) it will copy the values from the internal buffer into the locations
|
||||
pointed to be lfuse, hfuse, and efuse. This allows you to change the fuse bits if needed from another routine (ie: have it so
|
||||
if user requests fuse bits are changed, the requested value is now verified */
|
||||
int safemode_memfuses (int save, unsigned char * lfuse, unsigned char * hfuse, unsigned char * efuse, unsigned char * fuse);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* formerly update.h */
|
||||
|
||||
enum {
|
||||
|
@ -926,7 +913,6 @@ extern char default_programmer[];
|
|||
extern char default_parallel[];
|
||||
extern char default_serial[];
|
||||
extern double default_bitclock;
|
||||
extern int default_safemode;
|
||||
|
||||
/* This name is fixed, it's only here for symmetry with
|
||||
* default_parallel and default_serial. */
|
||||
|
|
|
@ -223,7 +223,7 @@ static int linuxspi_open(PROGRAMMER *pgm, char *port)
|
|||
avrdude_message(MSG_INFO,
|
||||
"%s: obsolete use of -b <clock> option for bit clock; use -B <clock>\n",
|
||||
progname);
|
||||
pgm->bitclock = 1E6 / pgm->baudrate;
|
||||
pgm->bitclock = 1.0 / pgm->baudrate;
|
||||
}
|
||||
if (pgm->bitclock == 0) {
|
||||
avrdude_message(MSG_NOTICE,
|
||||
|
|
240
src/main.c
240
src/main.c
|
@ -122,9 +122,6 @@ static void usage(void)
|
|||
" is performed in the order specified.\n"
|
||||
" -n Do not write anything to the device.\n"
|
||||
" -V Do not verify.\n"
|
||||
" -u Disable safemode, default when running from a script.\n"
|
||||
" -s Silent safemode operation, will not ask you if\n"
|
||||
" fuses should be changed back.\n"
|
||||
" -t Enter terminal mode.\n"
|
||||
" -E <exitspec>[,<exitspec>] List programmer exit specifications.\n"
|
||||
" -x <extended_param> Pass <extended_param> to programmer.\n"
|
||||
|
@ -349,19 +346,11 @@ int main(int argc, char * argv [])
|
|||
int baudrate; /* override default programmer baud rate */
|
||||
double bitclock; /* Specify programmer bit clock (JTAG ICE) */
|
||||
int ispdelay; /* Specify the delay for ISP clock */
|
||||
int safemode; /* Enable safemode, 1=safemode on, 0=normal */
|
||||
int silentsafe; /* Don't ask about fuses, 1=silent, 0=normal */
|
||||
int init_ok; /* Device initialization worked well */
|
||||
int is_open; /* Device open succeeded */
|
||||
char * logfile; /* Use logfile rather than stderr for diagnostics */
|
||||
enum updateflags uflags = UF_AUTO_ERASE; /* Flags for do_op() */
|
||||
unsigned char safemode_lfuse = 0xff;
|
||||
unsigned char safemode_hfuse = 0xff;
|
||||
unsigned char safemode_efuse = 0xff;
|
||||
unsigned char safemode_fuse = 0xff;
|
||||
|
||||
char * safemode_response;
|
||||
int fuses_updated = 0;
|
||||
#if !defined(WIN32)
|
||||
char * homedir;
|
||||
#endif
|
||||
|
@ -394,7 +383,6 @@ int main(int argc, char * argv [])
|
|||
default_parallel[0] = 0;
|
||||
default_serial[0] = 0;
|
||||
default_bitclock = 0.0;
|
||||
default_safemode = -1;
|
||||
|
||||
init_config();
|
||||
|
||||
|
@ -434,8 +422,6 @@ int main(int argc, char * argv [])
|
|||
baudrate = 0;
|
||||
bitclock = 0.0;
|
||||
ispdelay = 0;
|
||||
safemode = 1; /* Safemode on by default */
|
||||
silentsafe = 0; /* Ask by default */
|
||||
is_open = 0;
|
||||
logfile = NULL;
|
||||
|
||||
|
@ -581,17 +567,13 @@ int main(int argc, char * argv [])
|
|||
quell_progress++ ;
|
||||
break;
|
||||
|
||||
case 's' : /* Silent safemode */
|
||||
silentsafe = 1;
|
||||
safemode = 1;
|
||||
break;
|
||||
|
||||
case 't': /* enter terminal mode */
|
||||
terminal = 1;
|
||||
break;
|
||||
|
||||
case 'u' : /* Disable safemode */
|
||||
safemode = 0;
|
||||
case 'u':
|
||||
avrdude_message(MSG_INFO, "%s: \"safemode\" feature no longer supported\n",
|
||||
progname);
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
|
@ -975,29 +957,6 @@ int main(int argc, char * argv [])
|
|||
}
|
||||
}
|
||||
|
||||
if (default_safemode == 0) {
|
||||
/* configuration disables safemode: revert meaning of -u */
|
||||
if (safemode == 0)
|
||||
/* -u was given: enable safemode */
|
||||
safemode = 1;
|
||||
else
|
||||
/* -u not given: turn off */
|
||||
safemode = 0;
|
||||
}
|
||||
|
||||
if (isatty(STDIN_FILENO) == 0 && silentsafe == 0)
|
||||
safemode = 0; /* Turn off safemode if this isn't a terminal */
|
||||
|
||||
|
||||
if(p->flags & AVRPART_AVR32) {
|
||||
safemode = 0;
|
||||
}
|
||||
|
||||
if(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_TPI)) {
|
||||
safemode = 0;
|
||||
}
|
||||
|
||||
|
||||
if (avr_initmem(p) != 0)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "\n%s: failed to initialize memories\n",
|
||||
|
@ -1281,36 +1240,6 @@ int main(int argc, char * argv [])
|
|||
}
|
||||
}
|
||||
|
||||
if (init_ok && safemode == 1) {
|
||||
/* If safemode is enabled, go ahead and read the current low, high,
|
||||
and extended fuse bytes as needed */
|
||||
|
||||
rc = safemode_readfuses(&safemode_lfuse, &safemode_hfuse,
|
||||
&safemode_efuse, &safemode_fuse, pgm, p);
|
||||
|
||||
if (rc != 0) {
|
||||
|
||||
//Check if the programmer just doesn't support reading
|
||||
if (rc == -5)
|
||||
{
|
||||
avrdude_message(MSG_NOTICE, "%s: safemode: Fuse reading not supported by programmer.\n"
|
||||
" Safemode disabled.\n", progname);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
avrdude_message(MSG_INFO, "%s: safemode: To protect your AVR the programming "
|
||||
"will be aborted\n",
|
||||
progname);
|
||||
exitrc = 1;
|
||||
goto main_exit;
|
||||
}
|
||||
} else {
|
||||
//Save the fuses as default
|
||||
safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
|
||||
}
|
||||
}
|
||||
|
||||
if (uflags & UF_AUTO_ERASE) {
|
||||
if ((p->flags & AVRPART_HAS_PDI) && pgm->page_erase != NULL &&
|
||||
lsize(updates) > 0) {
|
||||
|
@ -1386,169 +1315,6 @@ int main(int argc, char * argv [])
|
|||
}
|
||||
}
|
||||
|
||||
/* Right before we exit programming mode, which will make the fuse
|
||||
bits active, check to make sure they are still correct */
|
||||
if (safemode == 1) {
|
||||
/* If safemode is enabled, go ahead and read the current low,
|
||||
* high, and extended fuse bytes as needed */
|
||||
unsigned char safemodeafter_lfuse = 0xff;
|
||||
unsigned char safemodeafter_hfuse = 0xff;
|
||||
unsigned char safemodeafter_efuse = 0xff;
|
||||
unsigned char safemodeafter_fuse = 0xff;
|
||||
unsigned char failures = 0;
|
||||
char yes[1] = {'y'};
|
||||
|
||||
if (quell_progress < 2) {
|
||||
avrdude_message(MSG_INFO, "\n");
|
||||
}
|
||||
|
||||
//Restore the default fuse values
|
||||
safemode_memfuses(0, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
|
||||
|
||||
/* Try reading back fuses, make sure they are reliable to read back */
|
||||
if (safemode_readfuses(&safemodeafter_lfuse, &safemodeafter_hfuse,
|
||||
&safemodeafter_efuse, &safemodeafter_fuse, pgm, p) != 0) {
|
||||
/* Uh-oh.. try once more to read back fuses */
|
||||
if (safemode_readfuses(&safemodeafter_lfuse, &safemodeafter_hfuse,
|
||||
&safemodeafter_efuse, &safemodeafter_fuse, pgm, p) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: safemode: Sorry, reading back fuses was unreliable. "
|
||||
"I have given up and exited programming mode\n",
|
||||
progname);
|
||||
exitrc = 1;
|
||||
goto main_exit;
|
||||
}
|
||||
}
|
||||
|
||||
AVRMEM * m;
|
||||
|
||||
/* Now check what fuses are against what they should be */
|
||||
m = avr_locate_mem(p, "fuse");
|
||||
if (compare_memory_masked(m, safemodeafter_fuse, safemode_fuse)) {
|
||||
fuses_updated = 1;
|
||||
avrdude_message(MSG_INFO, "%s: safemode: fuse changed! Was %x, and is now %x\n",
|
||||
progname, safemode_fuse, safemodeafter_fuse);
|
||||
|
||||
|
||||
/* Ask user - should we change them */
|
||||
|
||||
if (silentsafe == 0)
|
||||
safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
|
||||
else
|
||||
safemode_response = yes;
|
||||
|
||||
if (tolower((int)(safemode_response[0])) == 'y') {
|
||||
|
||||
/* Enough chit-chat, time to program some fuses and check them */
|
||||
if (safemode_writefuse (safemode_fuse, "fuse", pgm, p,
|
||||
10) == 0) {
|
||||
avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
|
||||
}
|
||||
else {
|
||||
avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now check what fuses are against what they should be */
|
||||
m = avr_locate_mem(p, "lfuse");
|
||||
if (compare_memory_masked(m, safemodeafter_lfuse, safemode_lfuse)) {
|
||||
fuses_updated = 1;
|
||||
avrdude_message(MSG_INFO, "%s: safemode: lfuse changed! Was %x, and is now %x\n",
|
||||
progname, safemode_lfuse, safemodeafter_lfuse);
|
||||
|
||||
|
||||
/* Ask user - should we change them */
|
||||
|
||||
if (silentsafe == 0)
|
||||
safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
|
||||
else
|
||||
safemode_response = yes;
|
||||
|
||||
if (tolower((int)(safemode_response[0])) == 'y') {
|
||||
|
||||
/* Enough chit-chat, time to program some fuses and check them */
|
||||
if (safemode_writefuse (safemode_lfuse, "lfuse", pgm, p,
|
||||
10) == 0) {
|
||||
avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
|
||||
}
|
||||
else {
|
||||
avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now check what fuses are against what they should be */
|
||||
m = avr_locate_mem(p, "hfuse");
|
||||
if (compare_memory_masked(m, safemodeafter_hfuse, safemode_hfuse)) {
|
||||
fuses_updated = 1;
|
||||
avrdude_message(MSG_INFO, "%s: safemode: hfuse changed! Was %x, and is now %x\n",
|
||||
progname, safemode_hfuse, safemodeafter_hfuse);
|
||||
|
||||
/* Ask user - should we change them */
|
||||
if (silentsafe == 0)
|
||||
safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
|
||||
else
|
||||
safemode_response = yes;
|
||||
if (tolower((int)(safemode_response[0])) == 'y') {
|
||||
|
||||
/* Enough chit-chat, time to program some fuses and check them */
|
||||
if (safemode_writefuse(safemode_hfuse, "hfuse", pgm, p,
|
||||
10) == 0) {
|
||||
avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
|
||||
}
|
||||
else {
|
||||
avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now check what fuses are against what they should be */
|
||||
m = avr_locate_mem(p, "efuse");
|
||||
if (compare_memory_masked(m, safemodeafter_efuse, safemode_efuse)) {
|
||||
fuses_updated = 1;
|
||||
avrdude_message(MSG_INFO, "%s: safemode: efuse changed! Was %x, and is now %x\n",
|
||||
progname, safemode_efuse, safemodeafter_efuse);
|
||||
|
||||
/* Ask user - should we change them */
|
||||
if (silentsafe == 0)
|
||||
safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
|
||||
else
|
||||
safemode_response = yes;
|
||||
if (tolower((int)(safemode_response[0])) == 'y') {
|
||||
|
||||
/* Enough chit-chat, time to program some fuses and check them */
|
||||
if (safemode_writefuse (safemode_efuse, "efuse", pgm, p,
|
||||
10) == 0) {
|
||||
avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
|
||||
}
|
||||
else {
|
||||
avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (quell_progress < 2) {
|
||||
avrdude_message(MSG_INFO, "%s: safemode: ", progname);
|
||||
if (failures == 0) {
|
||||
avrdude_message(MSG_INFO, "Fuses OK (E:%02X, H:%02X, L:%02X)\n",
|
||||
safemodeafter_efuse, safemodeafter_hfuse, safemodeafter_lfuse);
|
||||
}
|
||||
else {
|
||||
avrdude_message(MSG_INFO, "Fuses not recovered, sorry\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (fuses_updated) {
|
||||
exitrc = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
main_exit:
|
||||
|
||||
/*
|
||||
|
|
|
@ -139,6 +139,22 @@ static int micronucleus_check_connection(pdata_t* pdata)
|
|||
}
|
||||
}
|
||||
|
||||
static bool micronucleus_is_device_responsive(pdata_t* pdata, struct usb_device* device)
|
||||
{
|
||||
pdata->usb_handle = usb_open(device);
|
||||
if (pdata->usb_handle == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int result = micronucleus_check_connection(pdata);
|
||||
|
||||
usb_close(pdata->usb_handle);
|
||||
pdata->usb_handle = NULL;
|
||||
|
||||
return result >= 0;
|
||||
}
|
||||
|
||||
static int micronucleus_reconnect(pdata_t* pdata)
|
||||
{
|
||||
struct usb_device* device = usb_device(pdata->usb_handle);
|
||||
|
@ -696,6 +712,7 @@ static int micronucleus_open(PROGRAMMER* pgm, char* port)
|
|||
usb_init();
|
||||
|
||||
bool show_retry_message = true;
|
||||
bool show_unresponsive_device_message = true;
|
||||
|
||||
time_t start_time = time(NULL);
|
||||
for (;;)
|
||||
|
@ -717,6 +734,19 @@ static int micronucleus_open(PROGRAMMER* pgm, char* port)
|
|||
pdata->major_version = (uint8_t)(device->descriptor.bcdDevice >> 8);
|
||||
pdata->minor_version = (uint8_t)(device->descriptor.bcdDevice >> 0);
|
||||
|
||||
if (!micronucleus_is_device_responsive(pdata, device))
|
||||
{
|
||||
if (show_unresponsive_device_message)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: WARNING: Unresponsive Micronucleus device detected, please reconnect...\n",
|
||||
progname);
|
||||
|
||||
show_unresponsive_device_message = false;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
avrdude_message(MSG_NOTICE, "%s: Found device with Micronucleus V%d.%d, bus:device: %s:%s\n",
|
||||
progname,
|
||||
pdata->major_version, pdata->minor_version,
|
||||
|
|
318
src/safemode.c
318
src/safemode.c
|
@ -1,318 +0,0 @@
|
|||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* avrdude is Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
|
||||
*
|
||||
* This file: Copyright (C) 2005-2007 Colin O'Flynn <coflynn@newae.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/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "libavrdude.h"
|
||||
|
||||
/* This value from ac_cfg.h */
|
||||
/*
|
||||
* Writes the specified fuse in fusename (can be "lfuse", "hfuse", or
|
||||
* "efuse") and verifies it. Will try up to tries amount of times
|
||||
* before giving up
|
||||
*/
|
||||
int safemode_writefuse (unsigned char fuse, char * fusename, PROGRAMMER * pgm,
|
||||
AVRPART * p, int tries)
|
||||
{
|
||||
AVRMEM * m;
|
||||
unsigned char fuseread;
|
||||
int returnvalue = -1;
|
||||
|
||||
m = avr_locate_mem(p, fusename);
|
||||
if (m == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Keep trying to write then read back the fuse values */
|
||||
while (tries > 0) {
|
||||
if (avr_write_byte(pgm, p, m, 0, fuse) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (pgm->read_byte(pgm, p, m, 0, &fuseread) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Report information to user if needed */
|
||||
avrdude_message(MSG_NOTICE, "%s: safemode: Wrote %s to %x, read as %x. %d attempts left\n",
|
||||
progname, fusename, fuse, fuseread, tries-1);
|
||||
|
||||
/* If fuse wrote OK, no need to keep going */
|
||||
if (fuse == fuseread) {
|
||||
tries = 0;
|
||||
returnvalue = 0;
|
||||
}
|
||||
tries--;
|
||||
}
|
||||
|
||||
return returnvalue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads the fuses three times, checking that all readings are the
|
||||
* same. This will ensure that the before values aren't in error!
|
||||
*/
|
||||
int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
|
||||
unsigned char * efuse, unsigned char * fuse,
|
||||
PROGRAMMER * pgm, AVRPART * p)
|
||||
{
|
||||
|
||||
unsigned char value;
|
||||
unsigned char fusegood = 0;
|
||||
unsigned char allowfuseread = 1;
|
||||
unsigned char safemode_lfuse;
|
||||
unsigned char safemode_hfuse;
|
||||
unsigned char safemode_efuse;
|
||||
unsigned char safemode_fuse;
|
||||
AVRMEM * m;
|
||||
|
||||
safemode_lfuse = *lfuse;
|
||||
safemode_hfuse = *hfuse;
|
||||
safemode_efuse = *efuse;
|
||||
safemode_fuse = *fuse;
|
||||
|
||||
|
||||
/* Read fuse three times */
|
||||
fusegood = 2; /* If AVR device doesn't support this fuse, don't want
|
||||
to generate a verify error */
|
||||
m = avr_locate_mem(p, "fuse");
|
||||
if (m != NULL) {
|
||||
fusegood = 0; /* By default fuse is a failure */
|
||||
if(pgm->read_byte(pgm, p, m, 0, &safemode_fuse) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
avrdude_message(MSG_DEBUG, "%s: safemode read 1, fuse value: %x\n",progname, safemode_fuse);
|
||||
if(pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
avrdude_message(MSG_DEBUG, "%s: safemode read 2, fuse value: %x\n",progname, value);
|
||||
if (value == safemode_fuse) {
|
||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
avrdude_message(MSG_DEBUG, "%s: safemode read 3, fuse value: %x\n",progname, value);
|
||||
if (value == safemode_fuse)
|
||||
{
|
||||
fusegood = 1; /* Fuse read OK three times */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Programmer does not allow fuse reading.... no point trying anymore
|
||||
if (allowfuseread == 0)
|
||||
{
|
||||
return -5;
|
||||
}
|
||||
|
||||
if (fusegood == 0) {
|
||||
avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read fuse properly. "
|
||||
"Programmer may not be reliable.\n", progname);
|
||||
return -1;
|
||||
}
|
||||
else if (fusegood == 1) {
|
||||
avrdude_message(MSG_NOTICE, "%s: safemode: fuse reads as %X\n", progname, safemode_fuse);
|
||||
}
|
||||
|
||||
|
||||
/* Read lfuse three times */
|
||||
fusegood = 2; /* If AVR device doesn't support this fuse, don't want
|
||||
to generate a verify error */
|
||||
m = avr_locate_mem(p, "lfuse");
|
||||
if (m != NULL) {
|
||||
fusegood = 0; /* By default fuse is a failure */
|
||||
if (pgm->read_byte(pgm, p, m, 0, &safemode_lfuse) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
avrdude_message(MSG_DEBUG, "%s: safemode read 1, lfuse value: %x\n",progname, safemode_lfuse);
|
||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
avrdude_message(MSG_DEBUG, "%s: safemode read 2, lfuse value: %x\n",progname, value);
|
||||
if (value == safemode_lfuse) {
|
||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
avrdude_message(MSG_DEBUG, "%s: safemode read 3, lfuse value: %x\n",progname, value);
|
||||
if (value == safemode_lfuse){
|
||||
fusegood = 1; /* Fuse read OK three times */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Programmer does not allow fuse reading.... no point trying anymore
|
||||
if (allowfuseread == 0)
|
||||
{
|
||||
return -5;
|
||||
}
|
||||
|
||||
|
||||
if (fusegood == 0) {
|
||||
avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read lfuse properly. "
|
||||
"Programmer may not be reliable.\n", progname);
|
||||
return -1;
|
||||
}
|
||||
else if (fusegood == 1) {
|
||||
avrdude_message(MSG_NOTICE, "%s: safemode: lfuse reads as %X\n", progname, safemode_lfuse);
|
||||
}
|
||||
|
||||
/* Read hfuse three times */
|
||||
fusegood = 2; /* If AVR device doesn't support this fuse, don't want
|
||||
to generate a verify error */
|
||||
m = avr_locate_mem(p, "hfuse");
|
||||
if (m != NULL) {
|
||||
fusegood = 0; /* By default fuse is a failure */
|
||||
if (pgm->read_byte(pgm, p, m, 0, &safemode_hfuse) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
avrdude_message(MSG_DEBUG, "%s: safemode read 1, hfuse value: %x\n",progname, safemode_hfuse);
|
||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
avrdude_message(MSG_DEBUG, "%s: safemode read 2, hfuse value: %x\n",progname, value);
|
||||
if (value == safemode_hfuse) {
|
||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
avrdude_message(MSG_DEBUG, "%s: safemode read 3, hfuse value: %x\n",progname, value);
|
||||
if (value == safemode_hfuse){
|
||||
fusegood = 1; /* Fuse read OK three times */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Programmer does not allow fuse reading.... no point trying anymore
|
||||
if (allowfuseread == 0)
|
||||
{
|
||||
return -5;
|
||||
}
|
||||
|
||||
if (fusegood == 0) {
|
||||
avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read hfuse properly. "
|
||||
"Programmer may not be reliable.\n", progname);
|
||||
return -2;
|
||||
}
|
||||
else if (fusegood == 1){
|
||||
avrdude_message(MSG_NOTICE, "%s: safemode: hfuse reads as %X\n", progname, safemode_hfuse);
|
||||
}
|
||||
|
||||
/* Read efuse three times */
|
||||
fusegood = 2; /* If AVR device doesn't support this fuse, don't want
|
||||
to generate a verify error */
|
||||
m = avr_locate_mem(p, "efuse");
|
||||
if (m != NULL) {
|
||||
fusegood = 0; /* By default fuse is a failure */
|
||||
if (pgm->read_byte(pgm, p, m, 0, &safemode_efuse) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
avrdude_message(MSG_DEBUG, "%s: safemode read 1, efuse value: %x\n",progname, safemode_efuse);
|
||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
avrdude_message(MSG_DEBUG, "%s: safemode read 2, efuse value: %x\n",progname, value);
|
||||
if (value == safemode_efuse) {
|
||||
if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
|
||||
{
|
||||
allowfuseread = 0;
|
||||
}
|
||||
avrdude_message(MSG_DEBUG, "%s: safemode read 3, efuse value: %x\n",progname, value);
|
||||
if (value == safemode_efuse){
|
||||
fusegood = 1; /* Fuse read OK three times */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Programmer does not allow fuse reading.... no point trying anymore
|
||||
if (allowfuseread == 0)
|
||||
{
|
||||
return -5;
|
||||
}
|
||||
|
||||
if (fusegood == 0) {
|
||||
avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read efuse properly. "
|
||||
"Programmer may not be reliable.\n", progname);
|
||||
return -3;
|
||||
}
|
||||
else if (fusegood == 1) {
|
||||
avrdude_message(MSG_NOTICE, "%s: safemode: efuse reads as %X\n", progname, safemode_efuse);
|
||||
}
|
||||
|
||||
*lfuse = safemode_lfuse;
|
||||
*hfuse = safemode_hfuse;
|
||||
*efuse = safemode_efuse;
|
||||
*fuse = safemode_fuse;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This routine will store the current values pointed to by lfuse,
|
||||
* hfuse, and efuse into an internal buffer in this routine when save
|
||||
* is set to 1. When save is 0 (or not 1 really) it will copy the
|
||||
* values from the internal buffer into the locations pointed to be
|
||||
* lfuse, hfuse, and efuse. This allows you to change the fuse bits if
|
||||
* needed from another routine (ie: have it so if user requests fuse
|
||||
* bits are changed, the requested value is now verified
|
||||
*/
|
||||
int safemode_memfuses (int save, unsigned char * lfuse, unsigned char * hfuse,
|
||||
unsigned char * efuse, unsigned char * fuse)
|
||||
{
|
||||
static unsigned char safemode_lfuse = 0xff;
|
||||
static unsigned char safemode_hfuse = 0xff;
|
||||
static unsigned char safemode_efuse = 0xff;
|
||||
static unsigned char safemode_fuse = 0xff;
|
||||
|
||||
switch (save) {
|
||||
|
||||
/* Save the fuses as safemode setting */
|
||||
case 1:
|
||||
safemode_lfuse = *lfuse;
|
||||
safemode_hfuse = *hfuse;
|
||||
safemode_efuse = *efuse;
|
||||
safemode_fuse = *fuse;
|
||||
|
||||
break;
|
||||
/* Read back the fuses */
|
||||
default:
|
||||
*lfuse = safemode_lfuse;
|
||||
*hfuse = safemode_hfuse;
|
||||
*efuse = safemode_efuse;
|
||||
*fuse = safemode_fuse;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -26,11 +26,12 @@
|
|||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#if defined(HAVE_LIBHIDAPI) || (defined(WIN32) && defined(HAVE_LIBHID))
|
||||
#if defined(HAVE_LIBHIDAPI)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "libavrdude.h"
|
||||
|
@ -64,12 +65,6 @@ static int avrdoperRxPosition = 0; /* amount of bytes already consu
|
|||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#if defined(HAVE_LIBHIDAPI)
|
||||
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
|
||||
int product, char *productName, int doReportIDs)
|
||||
{
|
||||
|
@ -154,181 +149,6 @@ static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNum
|
|||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#else /* !defined(HAVE_LIBHIDAPI) */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
#include <hidsdi.h>
|
||||
#include <hidpi.h>
|
||||
|
||||
#ifdef USB_DEBUG
|
||||
#define DEBUG_PRINT(arg) printf arg
|
||||
#else
|
||||
#define DEBUG_PRINT(arg)
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static void convertUniToAscii(char *buffer)
|
||||
{
|
||||
unsigned short *uni = (void *)buffer;
|
||||
char *ascii = buffer;
|
||||
|
||||
while(*uni != 0){
|
||||
if(*uni >= 256){
|
||||
*ascii++ = '?';
|
||||
uni++;
|
||||
}else{
|
||||
*ascii++ = *uni++;
|
||||
}
|
||||
}
|
||||
*ascii++ = 0;
|
||||
}
|
||||
|
||||
static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
|
||||
int product, char *productName, int usesReportIDs)
|
||||
{
|
||||
GUID hidGuid; /* GUID for HID driver */
|
||||
HDEVINFO deviceInfoList;
|
||||
SP_DEVICE_INTERFACE_DATA deviceInfo;
|
||||
SP_DEVICE_INTERFACE_DETAIL_DATA *deviceDetails = NULL;
|
||||
DWORD size;
|
||||
int i, openFlag = 0; /* may be FILE_FLAG_OVERLAPPED */
|
||||
int errorCode = USB_ERROR_NOTFOUND;
|
||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||
HIDD_ATTRIBUTES deviceAttributes;
|
||||
|
||||
HidD_GetHidGuid(&hidGuid);
|
||||
deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL,
|
||||
DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
|
||||
deviceInfo.cbSize = sizeof(deviceInfo);
|
||||
for(i=0;;i++){
|
||||
if(handle != INVALID_HANDLE_VALUE){
|
||||
CloseHandle(handle);
|
||||
handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
if(!SetupDiEnumDeviceInterfaces(deviceInfoList, 0, &hidGuid, i, &deviceInfo))
|
||||
break; /* no more entries */
|
||||
/* first do a dummy call just to determine the actual size required */
|
||||
SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL);
|
||||
if(deviceDetails != NULL)
|
||||
free(deviceDetails);
|
||||
deviceDetails = malloc(size);
|
||||
deviceDetails->cbSize = sizeof(*deviceDetails);
|
||||
/* this call is for real: */
|
||||
SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails,
|
||||
size, &size, NULL);
|
||||
DEBUG_PRINT(("checking HID path \"%s\"\n", deviceDetails->DevicePath));
|
||||
/* attempt opening for R/W -- we don't care about devices which can't be accessed */
|
||||
handle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
|
||||
openFlag, NULL);
|
||||
if(handle == INVALID_HANDLE_VALUE){
|
||||
DEBUG_PRINT(("opening failed: %d\n", (int)GetLastError()));
|
||||
/* errorCode = USB_ERROR_ACCESS; opening will always fail for mouse -- ignore */
|
||||
continue;
|
||||
}
|
||||
deviceAttributes.Size = sizeof(deviceAttributes);
|
||||
HidD_GetAttributes(handle, &deviceAttributes);
|
||||
DEBUG_PRINT(("device attributes: vid=%d pid=%d\n",
|
||||
deviceAttributes.VendorID, deviceAttributes.ProductID));
|
||||
if(deviceAttributes.VendorID != vendor || deviceAttributes.ProductID != product)
|
||||
continue; /* ignore this device */
|
||||
errorCode = USB_ERROR_NOTFOUND;
|
||||
if(vendorName != NULL && productName != NULL){
|
||||
char buffer[512];
|
||||
if(!HidD_GetManufacturerString(handle, buffer, sizeof(buffer))){
|
||||
DEBUG_PRINT(("error obtaining vendor name\n"));
|
||||
errorCode = USB_ERROR_IO;
|
||||
continue;
|
||||
}
|
||||
convertUniToAscii(buffer);
|
||||
DEBUG_PRINT(("vendorName = \"%s\"\n", buffer));
|
||||
if(strcmp(vendorName, buffer) != 0)
|
||||
continue;
|
||||
if(!HidD_GetProductString(handle, buffer, sizeof(buffer))){
|
||||
DEBUG_PRINT(("error obtaining product name\n"));
|
||||
errorCode = USB_ERROR_IO;
|
||||
continue;
|
||||
}
|
||||
convertUniToAscii(buffer);
|
||||
DEBUG_PRINT(("productName = \"%s\"\n", buffer));
|
||||
if(strcmp(productName, buffer) != 0)
|
||||
continue;
|
||||
}
|
||||
break; /* we have found the device we are looking for! */
|
||||
}
|
||||
SetupDiDestroyDeviceInfoList(deviceInfoList);
|
||||
if(deviceDetails != NULL)
|
||||
free(deviceDetails);
|
||||
if(handle != INVALID_HANDLE_VALUE){
|
||||
fdp->pfd = (void *)handle;
|
||||
errorCode = 0;
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static void usbCloseDevice(union filedescriptor *fdp)
|
||||
{
|
||||
CloseHandle((HANDLE)fdp->pfd);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static int usbSetReport(union filedescriptor *fdp, int reportType, char *buffer, int len)
|
||||
{
|
||||
HANDLE handle = (HANDLE)fdp->pfd;
|
||||
BOOLEAN rval = 0;
|
||||
DWORD bytesWritten;
|
||||
|
||||
switch(reportType){
|
||||
case USB_HID_REPORT_TYPE_INPUT:
|
||||
break;
|
||||
case USB_HID_REPORT_TYPE_OUTPUT:
|
||||
rval = WriteFile(handle, buffer, len, &bytesWritten, NULL);
|
||||
break;
|
||||
case USB_HID_REPORT_TYPE_FEATURE:
|
||||
rval = HidD_SetFeature(handle, buffer, len);
|
||||
break;
|
||||
}
|
||||
return rval == 0 ? USB_ERROR_IO : 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNumber,
|
||||
char *buffer, int *len)
|
||||
{
|
||||
HANDLE handle = (HANDLE)fdp->pfd;
|
||||
BOOLEAN rval = 0;
|
||||
DWORD bytesRead;
|
||||
|
||||
switch(reportType){
|
||||
case USB_HID_REPORT_TYPE_INPUT:
|
||||
buffer[0] = reportNumber;
|
||||
rval = ReadFile(handle, buffer, *len, &bytesRead, NULL);
|
||||
if(rval)
|
||||
*len = bytesRead;
|
||||
break;
|
||||
case USB_HID_REPORT_TYPE_OUTPUT:
|
||||
break;
|
||||
case USB_HID_REPORT_TYPE_FEATURE:
|
||||
buffer[0] = reportNumber;
|
||||
rval = HidD_GetFeature(handle, buffer, *len);
|
||||
break;
|
||||
}
|
||||
return rval == 0 ? USB_ERROR_IO : 0;
|
||||
}
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
@ -551,4 +371,4 @@ struct serial_device avrdoper_serdev =
|
|||
.flags = SERDEV_FL_NONE,
|
||||
};
|
||||
|
||||
#endif /* defined(HAVE_LIBHIDAPI) || (defined(WIN32) && defined(HAVE_LIBHID)) */
|
||||
#endif /* defined(HAVE_LIBHIDAPI) */
|
||||
|
|
136
src/ser_posix.c
136
src/ser_posix.c
|
@ -28,6 +28,7 @@
|
|||
#include "ac_cfg.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -42,6 +43,10 @@
|
|||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <IOKit/serial/ioss.h>
|
||||
#endif
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "libavrdude.h"
|
||||
|
||||
|
@ -78,10 +83,12 @@ 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)
|
||||
static speed_t serial_baud_lookup(long baud, bool *nonstandard)
|
||||
{
|
||||
struct baud_mapping *map = baud_lookup_table;
|
||||
|
||||
*nonstandard = false;
|
||||
|
||||
while (map->baud) {
|
||||
if (map->baud == baud)
|
||||
return map->speed;
|
||||
|
@ -92,30 +99,20 @@ static speed_t 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",
|
||||
avrdude_message(MSG_NOTICE, "%s: serial_baud_lookup(): Using non-standard baud rate: %ld\n",
|
||||
progname, baud);
|
||||
|
||||
return baud;
|
||||
}
|
||||
*nonstandard = true;
|
||||
|
||||
static tcflag_t translate_flags(unsigned long cflags)
|
||||
{
|
||||
return ((cflags & SERIAL_CS5) ? CS5 : 0) |
|
||||
((cflags & SERIAL_CS6) ? CS6 : 0) |
|
||||
((cflags & SERIAL_CS7) ? CS7 : 0) |
|
||||
((cflags & SERIAL_CS8) ? CS8 : 0) |
|
||||
((cflags & SERIAL_CSTOPB) ? CSTOPB : 0) |
|
||||
((cflags & SERIAL_CREAD) ? CREAD : 0) |
|
||||
((cflags & (SERIAL_PARENB | SERIAL_PARODD)) ? PARENB : 0) |
|
||||
((cflags & SERIAL_PARODD) ? PARODD : 0) |
|
||||
((cflags & SERIAL_CLOCAL) ? CLOCAL : 0) ;
|
||||
return baud;
|
||||
}
|
||||
|
||||
static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cflags)
|
||||
{
|
||||
int rc;
|
||||
struct termios termios;
|
||||
speed_t speed = serial_baud_lookup (baud);
|
||||
bool nonstandard;
|
||||
speed_t speed = serial_baud_lookup (baud, &nonstandard);
|
||||
|
||||
if (!isatty(fd->ifd))
|
||||
return -ENOTTY;
|
||||
|
@ -137,15 +134,86 @@ static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cfla
|
|||
original_termios = termios;
|
||||
}
|
||||
|
||||
termios.c_iflag = IGNBRK;
|
||||
termios.c_oflag = 0;
|
||||
termios.c_lflag = 0;
|
||||
termios.c_cflag = translate_flags(cflags);
|
||||
termios.c_cc[VMIN] = 1;
|
||||
termios.c_cc[VTIME] = 0;
|
||||
if (cflags & SERIAL_CREAD) {
|
||||
termios.c_cflag |= CREAD;
|
||||
}
|
||||
if (cflags & SERIAL_CLOCAL) {
|
||||
termios.c_cflag |= CLOCAL;
|
||||
}
|
||||
termios.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ISIG | IEXTEN);
|
||||
#ifdef ECHOCTL
|
||||
termios.c_lflag &= ~ECHOCTL;
|
||||
#endif /* ECHOCTL */
|
||||
#ifdef ECHOKE
|
||||
termios.c_lflag &= ~ECHOKE;
|
||||
#endif /* ECHOKE */
|
||||
termios.c_oflag &= ~(OPOST | ONLCR | OCRNL);
|
||||
termios.c_iflag &= ~(INLCR | IGNCR | ICRNL | IGNBRK);
|
||||
#ifdef IUCLC
|
||||
termios.c_iflag &= ~IUCLC;
|
||||
#endif /* IUCLC */
|
||||
#ifdef PARMRK
|
||||
termios.c_iflag &= ~PARMRK;
|
||||
#endif /* PARMRK */
|
||||
|
||||
// MacOS doesn't handle nonstandard baudrate values in
|
||||
// normal tcsetattr(), sigh.
|
||||
#ifdef __APPLE__
|
||||
if (!nonstandard) {
|
||||
#endif
|
||||
cfsetospeed(&termios, speed);
|
||||
cfsetispeed(&termios, speed);
|
||||
#ifdef __APPLE__
|
||||
}
|
||||
#endif
|
||||
|
||||
termios.c_cflag &= ~CSIZE;
|
||||
if (cflags & SERIAL_CS8) {
|
||||
termios.c_cflag |= CS8;
|
||||
}
|
||||
if (cflags & SERIAL_CS7) {
|
||||
termios.c_cflag |= CS7;
|
||||
}
|
||||
if (cflags & SERIAL_CS6) {
|
||||
termios.c_cflag |= CS6;
|
||||
}
|
||||
if (cflags & SERIAL_CS5) {
|
||||
termios.c_cflag |= CS5;
|
||||
}
|
||||
|
||||
if (cflags & SERIAL_CSTOPB) {
|
||||
termios.c_cflag |= CSTOPB;
|
||||
} else {
|
||||
termios.c_cflag &= ~CSTOPB;
|
||||
}
|
||||
|
||||
termios.c_iflag &= ~(INPCK | ISTRIP);
|
||||
|
||||
if (cflags & (SERIAL_PARENB | SERIAL_PARODD)) {
|
||||
termios.c_cflag |= PARENB;
|
||||
} else {
|
||||
termios.c_cflag &= ~PARENB;
|
||||
}
|
||||
|
||||
if (cflags & SERIAL_PARODD) {
|
||||
termios.c_cflag |= PARODD;
|
||||
} else {
|
||||
termios.c_cflag &= ~PARODD;
|
||||
}
|
||||
|
||||
#ifdef IXANY
|
||||
termios.c_iflag &= ~IXANY;
|
||||
#endif /* IXANY */
|
||||
termios.c_iflag &= ~(IXON | IXOFF);
|
||||
|
||||
#ifdef CRTSCTS
|
||||
termios.c_iflag &= ~CRTSCTS;
|
||||
#endif /* CRTSCTS */
|
||||
|
||||
#ifdef CNEW_RTSCTS
|
||||
termios.c_iflag &= ~CNEW_RTSCTS;
|
||||
#endif /* CRTSCTS */
|
||||
|
||||
cfsetospeed(&termios, speed);
|
||||
cfsetispeed(&termios, speed);
|
||||
|
||||
rc = tcsetattr(fd->ifd, TCSANOW, &termios);
|
||||
if (rc < 0) {
|
||||
|
@ -154,13 +222,18 @@ static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cfla
|
|||
return -errno;
|
||||
}
|
||||
|
||||
/*
|
||||
* Everything is now set up for a local line without modem control
|
||||
* or flow control, so clear O_NONBLOCK again.
|
||||
*/
|
||||
rc = fcntl(fd->ifd, F_GETFL, 0);
|
||||
if (rc != -1)
|
||||
fcntl(fd->ifd, F_SETFL, rc & ~O_NONBLOCK);
|
||||
#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;
|
||||
}
|
||||
}
|
||||
#endif // __APPLE__
|
||||
|
||||
tcflush(fd->ifd, TCIFLUSH);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -520,3 +593,4 @@ struct serial_device serial_serdev =
|
|||
struct serial_device *serdev = &serial_serdev;
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
|
|
|
@ -1613,11 +1613,11 @@ static int stk500v2_open(PROGRAMMER * pgm, char * port)
|
|||
PDATA(pgm)->pgmtype = PGMTYPE_UNKNOWN;
|
||||
|
||||
if(strcasecmp(port, "avrdoper") == 0){
|
||||
#if defined(HAVE_LIBHIDAPI) || (defined(WIN32) && defined(HAVE_LIBHID))
|
||||
#if defined(HAVE_LIBHIDAPI)
|
||||
serdev = &avrdoper_serdev;
|
||||
PDATA(pgm)->pgmtype = PGMTYPE_STK500;
|
||||
#else
|
||||
avrdude_message(MSG_INFO, "avrdoper requires avrdude with hid support.\n");
|
||||
avrdude_message(MSG_INFO, "avrdoper requires avrdude with libhidapi support.\n");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
@ -3869,7 +3869,8 @@ static int stk600_xprog_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
* fuses.
|
||||
*/
|
||||
need_erase = 1;
|
||||
} else if (strcmp(mem->desc, "usersig") == 0) {
|
||||
} else if (strcmp(mem->desc, "usersig") == 0 ||
|
||||
strcmp(mem->desc, "userrow") == 0) {
|
||||
memcode = XPRG_MEM_TYPE_USERSIG;
|
||||
} else {
|
||||
avrdude_message(MSG_INFO, "%s: stk600_xprog_write_byte(): unknown memory \"%s\"\n",
|
||||
|
@ -3944,7 +3945,8 @@ static int stk600_xprog_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
} else if (strcmp(mem->desc, "calibration") == 0 ||
|
||||
strcmp(mem->desc, "prodsig") == 0) {
|
||||
b[1] = XPRG_MEM_TYPE_FACTORY_CALIBRATION;
|
||||
} else if (strcmp(mem->desc, "usersig") == 0) {
|
||||
} else if (strcmp(mem->desc, "usersig") == 0 ||
|
||||
strcmp(mem->desc, "userrow") == 0) {
|
||||
b[1] = XPRG_MEM_TYPE_USERSIG;
|
||||
} else {
|
||||
avrdude_message(MSG_INFO, "%s: stk600_xprog_read_byte(): unknown memory \"%s\"\n",
|
||||
|
@ -4019,7 +4021,8 @@ static int stk600_xprog_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
} else if (strcmp(mem->desc, "calibration") == 0 ||
|
||||
strcmp(mem->desc, "prodsig") == 0) {
|
||||
memtype = XPRG_MEM_TYPE_FACTORY_CALIBRATION;
|
||||
} else if (strcmp(mem->desc, "usersig") == 0) {
|
||||
} else if (strcmp(mem->desc, "usersig") == 0 ||
|
||||
strcmp(mem->desc, "userrow") == 0) {
|
||||
memtype = XPRG_MEM_TYPE_USERSIG;
|
||||
} else {
|
||||
avrdude_message(MSG_INFO, "%s: stk600_xprog_paged_load(): unknown paged memory \"%s\"\n",
|
||||
|
@ -4132,7 +4135,8 @@ static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
|
|||
} else if (strcmp(mem->desc, "calibration") == 0) {
|
||||
memtype = XPRG_MEM_TYPE_FACTORY_CALIBRATION;
|
||||
writemode = (1 << XPRG_MEM_WRITE_WRITE);
|
||||
} else if (strcmp(mem->desc, "usersig") == 0) {
|
||||
} else if (strcmp(mem->desc, "usersig") == 0 ||
|
||||
strcmp(mem->desc, "userrow") == 0) {
|
||||
memtype = XPRG_MEM_TYPE_USERSIG;
|
||||
writemode = (1 << XPRG_MEM_WRITE_WRITE);
|
||||
} else {
|
||||
|
@ -4290,7 +4294,8 @@ static int stk600_xprog_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
|||
b[1] = XPRG_ERASE_BOOT_PAGE;
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
b[1] = XPRG_ERASE_EEPROM_PAGE;
|
||||
} else if (strcmp(m->desc, "usersig") == 0) {
|
||||
} else if (strcmp(m->desc, "usersig") == 0 ||
|
||||
strcmp(m->desc, "userrow") == 0) {
|
||||
b[1] = XPRG_ERASE_USERSIG;
|
||||
} else {
|
||||
avrdude_message(MSG_INFO, "%s: stk600_xprog_page_erase(): unknown paged memory \"%s\"\n",
|
||||
|
|
390
src/term.c
390
src/term.c
|
@ -23,6 +23,7 @@
|
|||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
@ -97,8 +98,8 @@ struct command cmd[] = {
|
|||
{ "sig", cmd_sig, "display device signature bytes" },
|
||||
{ "part", cmd_part, "display the current part information" },
|
||||
{ "send", cmd_send, "send a raw command : %s <b1> <b2> <b3> <b4>" },
|
||||
{ "parms", cmd_parms, "display adjustable parameters (STK500 only)" },
|
||||
{ "vtarg", cmd_vtarg, "set <V[target]> (STK500 only)" },
|
||||
{ "parms", cmd_parms, "display adjustable parameters (STK500 and Curiosity Nano only)" },
|
||||
{ "vtarg", cmd_vtarg, "set <V[target]> (STK500 and Curiosity Nano only)" },
|
||||
{ "varef", cmd_varef, "set <V[aref]> (STK500 only)" },
|
||||
{ "fosc", cmd_fosc, "set <oscillator frequency> (STK500 only)" },
|
||||
{ "sck", cmd_sck, "set <SCK period> (STK500 only)" },
|
||||
|
@ -125,9 +126,15 @@ static int nexttok(char * buf, char ** tok, char ** next)
|
|||
q++;
|
||||
|
||||
/* isolate first token */
|
||||
n = q+1;
|
||||
while (*n && !isspace((int)*n))
|
||||
n = q;
|
||||
uint8_t quotes = 0;
|
||||
while (*n && (!isspace((int)*n) || quotes)) {
|
||||
if (*n == '\"')
|
||||
quotes++;
|
||||
else if (isspace((int)*n) && *(n-1) == '\"')
|
||||
break;
|
||||
n++;
|
||||
}
|
||||
|
||||
if (*n) {
|
||||
*n = 0;
|
||||
|
@ -148,12 +155,10 @@ static int nexttok(char * buf, char ** tok, char ** next)
|
|||
static int hexdump_line(char * buffer, unsigned char * p, int n, int pad)
|
||||
{
|
||||
char * hexdata = "0123456789abcdef";
|
||||
char * b;
|
||||
int i, j;
|
||||
char * b = buffer;
|
||||
int32_t i = 0;
|
||||
int32_t j = 0;
|
||||
|
||||
b = buffer;
|
||||
|
||||
j = 0;
|
||||
for (i=0; i<n; i++) {
|
||||
if (i && ((i % 8) == 0))
|
||||
b[j++] = ' ';
|
||||
|
@ -182,7 +187,7 @@ static int chardump_line(char * buffer, unsigned char * p, int n, int pad)
|
|||
int i;
|
||||
char b [ 128 ];
|
||||
|
||||
for (i=0; i<n; i++) {
|
||||
for (int32_t i = 0; i < n; i++) {
|
||||
memcpy(b, p, n);
|
||||
buffer[i] = '.';
|
||||
if (isalpha((int)(b[i])) || isdigit((int)(b[i])) || ispunct((int)(b[i])))
|
||||
|
@ -191,7 +196,7 @@ static int chardump_line(char * buffer, unsigned char * p, int n, int pad)
|
|||
buffer[i] = ' ';
|
||||
}
|
||||
|
||||
for (i=n; i<pad; i++)
|
||||
for (i = n; i < pad; i++)
|
||||
buffer[i] = ' ';
|
||||
|
||||
buffer[i] = 0;
|
||||
|
@ -202,16 +207,13 @@ static int chardump_line(char * buffer, unsigned char * p, int n, int pad)
|
|||
|
||||
static int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len)
|
||||
{
|
||||
int addr;
|
||||
int n;
|
||||
unsigned char * p;
|
||||
char dst1[80];
|
||||
char dst2[80];
|
||||
|
||||
addr = startaddr;
|
||||
p = (unsigned char *)buf;
|
||||
int32_t addr = startaddr;
|
||||
unsigned char * p = (unsigned char *)buf;
|
||||
while (len) {
|
||||
n = 16;
|
||||
int32_t n = 16;
|
||||
if (n > len)
|
||||
n = len;
|
||||
hexdump_line(dst1, p, n, 48);
|
||||
|
@ -229,92 +231,99 @@ static int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len)
|
|||
static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
static char prevmem[128] = {0};
|
||||
char * e;
|
||||
unsigned char * buf;
|
||||
int maxsize;
|
||||
unsigned long i;
|
||||
static unsigned long addr=0;
|
||||
static int len=64;
|
||||
AVRMEM * mem;
|
||||
char * memtype = NULL;
|
||||
int rc;
|
||||
|
||||
if (!((argc == 2) || (argc == 4))) {
|
||||
avrdude_message(MSG_INFO, "Usage: dump <memtype> [<addr> <len>]\n");
|
||||
return -1;
|
||||
if (argc < 2) {
|
||||
avrdude_message(MSG_INFO, "Usage: %s <memtype> [<start addr> <len>]\n"
|
||||
" %s <memtype> [<start addr> <...>]\n"
|
||||
" %s <memtype> <...>\n"
|
||||
" %s <memtype>\n",
|
||||
argv[0], argv[0], argv[0], argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memtype = argv[1];
|
||||
|
||||
if (strncmp(prevmem, memtype, strlen(memtype)) != 0) {
|
||||
addr = 0;
|
||||
len = 64;
|
||||
strncpy(prevmem, memtype, sizeof(prevmem)-1);
|
||||
prevmem[sizeof(prevmem)-1] = 0;
|
||||
}
|
||||
|
||||
mem = avr_locate_mem(p, memtype);
|
||||
enum { read_size = 256 };
|
||||
static char prevmem[128] = {0x00};
|
||||
char * memtype = argv[1];
|
||||
AVRMEM * mem = avr_locate_mem(p, memtype);
|
||||
if (mem == NULL) {
|
||||
avrdude_message(MSG_INFO, "\"%s\" memory type not defined for part \"%s\"\n",
|
||||
memtype, p->desc);
|
||||
return -1;
|
||||
}
|
||||
uint32_t maxsize = mem->size;
|
||||
|
||||
// Get start address if present
|
||||
char * end_ptr;
|
||||
static uint32_t addr = 0;
|
||||
if (argc == 4) {
|
||||
addr = strtoul(argv[2], &e, 0);
|
||||
if (*e || (e == argv[2])) {
|
||||
avrdude_message(MSG_INFO, "%s (dump): can't parse address \"%s\"\n",
|
||||
progname, argv[2]);
|
||||
addr = strtoul(argv[2], &end_ptr, 0);
|
||||
if (*end_ptr || (end_ptr == argv[2])) {
|
||||
avrdude_message(MSG_INFO, "%s (%s): can't parse address \"%s\"\n",
|
||||
progname, argv[0], argv[2]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = strtol(argv[3], &e, 0);
|
||||
if (*e || (e == argv[3])) {
|
||||
avrdude_message(MSG_INFO, "%s (dump): can't parse length \"%s\"\n",
|
||||
progname, argv[3]);
|
||||
} else if (addr >= maxsize) {
|
||||
avrdude_message(MSG_INFO, "%s (%s): address 0x%05lx is out of range for %s memory\n",
|
||||
progname, argv[0], addr, mem->desc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
maxsize = mem->size;
|
||||
|
||||
if (addr >= maxsize) {
|
||||
if (argc == 2) {
|
||||
/* wrap around */
|
||||
// Get no. bytes to read if present
|
||||
static int32_t len = read_size;
|
||||
if (argc >= 3) {
|
||||
memset(prevmem, 0x00, sizeof(prevmem));
|
||||
if (strcmp(argv[argc - 1], "...") == 0) {
|
||||
if (argc == 3)
|
||||
addr = 0;
|
||||
len = maxsize - addr;
|
||||
} else if (argc == 4) {
|
||||
len = strtol(argv[3], &end_ptr, 0);
|
||||
if (*end_ptr || (end_ptr == argv[3])) {
|
||||
avrdude_message(MSG_INFO, "%s (%s): can't parse length \"%s\"\n",
|
||||
progname, argv[0], argv[3]);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
len = read_size;
|
||||
}
|
||||
}
|
||||
// No address or length specified
|
||||
else if (argc == 2) {
|
||||
if (strncmp(prevmem, memtype, strlen(memtype)) != 0) {
|
||||
addr = 0;
|
||||
len = read_size;
|
||||
strncpy(prevmem, memtype, sizeof(prevmem) - 1);
|
||||
prevmem[sizeof(prevmem) - 1] = 0;
|
||||
}
|
||||
else {
|
||||
avrdude_message(MSG_INFO, "%s (dump): address 0x%05lx is out of range for %s memory\n",
|
||||
progname, addr, mem->desc);
|
||||
return -1;
|
||||
}
|
||||
if (addr >= maxsize)
|
||||
addr = 0; // Wrap around
|
||||
}
|
||||
|
||||
/* trim len if nessary to not read past the end of memory */
|
||||
// Trim len if nessary to not read past the end of memory
|
||||
if ((addr + len) > maxsize)
|
||||
len = maxsize - addr;
|
||||
|
||||
buf = malloc(len);
|
||||
uint8_t * buf = malloc(len);
|
||||
if (buf == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s (dump): out of memory\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
rc = pgm->read_byte(pgm, p, mem, addr+i, &buf[i]);
|
||||
report_progress(0, 1, "Reading");
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
int32_t rc = pgm->read_byte(pgm, p, mem, addr + i, &buf[i]);
|
||||
if (rc != 0) {
|
||||
avrdude_message(MSG_INFO, "error reading %s address 0x%05lx of part %s\n",
|
||||
mem->desc, addr+i, p->desc);
|
||||
mem->desc, addr + i, p->desc);
|
||||
if (rc == -1)
|
||||
avrdude_message(MSG_INFO, "read operation not supported on memory type \"%s\"\n",
|
||||
mem->desc);
|
||||
return -1;
|
||||
}
|
||||
report_progress(i, len, NULL);
|
||||
}
|
||||
report_progress(1, 1, NULL);
|
||||
|
||||
hexdump_buf(stdout, addr, buf, len);
|
||||
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
free(buf);
|
||||
|
@ -328,35 +337,31 @@ static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
|
|||
static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
|
||||
int argc, char * argv[])
|
||||
{
|
||||
char * e;
|
||||
int len, maxsize;
|
||||
char * memtype;
|
||||
unsigned long addr, i;
|
||||
unsigned char * buf;
|
||||
unsigned char b;
|
||||
int rc;
|
||||
int werror;
|
||||
AVRMEM * mem;
|
||||
|
||||
if (argc < 4) {
|
||||
avrdude_message(MSG_INFO, "Usage: write <memtype> <addr> <byte1> "
|
||||
"<byte2> ... <byteN>\n");
|
||||
avrdude_message(MSG_INFO,
|
||||
"Usage: write <memtype> <start addr> <data1> <data2> <dataN>\n"
|
||||
" write <memtype> <start addr> <no. bytes> <data1> <dataN> <...>\n\n"
|
||||
" Add a suffix to manually specify the size for each field:\n"
|
||||
" HH/hh: 8-bit, H/h/S/s: 16-bit, L/l: 32-bit, LL/ll: 64-bit, F/f: 32-bit float\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memtype = argv[1];
|
||||
|
||||
mem = avr_locate_mem(p, memtype);
|
||||
int32_t i;
|
||||
uint8_t write_mode; // Operation mode, "standard" or "fill"
|
||||
uint8_t start_offset; // Which argc argument
|
||||
int32_t len; // Number of bytes to write to memory
|
||||
char * memtype = argv[1]; // Memory name string
|
||||
AVRMEM * mem = avr_locate_mem(p, memtype);
|
||||
if (mem == NULL) {
|
||||
avrdude_message(MSG_INFO, "\"%s\" memory type not defined for part \"%s\"\n",
|
||||
memtype, p->desc);
|
||||
return -1;
|
||||
}
|
||||
uint32_t maxsize = mem->size;
|
||||
|
||||
maxsize = mem->size;
|
||||
|
||||
addr = strtoul(argv[2], &e, 0);
|
||||
if (*e || (e == argv[2])) {
|
||||
char * end_ptr;
|
||||
int32_t addr = strtoul(argv[2], &end_ptr, 0);
|
||||
if (*end_ptr || (end_ptr == argv[2])) {
|
||||
avrdude_message(MSG_INFO, "%s (write): can't parse address \"%s\"\n",
|
||||
progname, argv[2]);
|
||||
return -1;
|
||||
|
@ -368,61 +373,228 @@ static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* number of bytes to write at the specified address */
|
||||
len = argc - 3;
|
||||
|
||||
if ((addr + len) > maxsize) {
|
||||
avrdude_message(MSG_INFO, "%s (write): selected address and # bytes exceed "
|
||||
"range for %s memory\n",
|
||||
progname, memtype);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf = malloc(len);
|
||||
// Allocate a buffer guaranteed to be large enough
|
||||
uint8_t * buf = calloc(mem->size + 0x10 + strlen(argv[argc - 2]), sizeof(uint8_t));
|
||||
if (buf == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s (write): out of memory\n", progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=3; i<argc; i++) {
|
||||
buf[i-3] = strtoul(argv[i], &e, 0);
|
||||
if (*e || (e == argv[i])) {
|
||||
avrdude_message(MSG_INFO, "%s (write): can't parse byte \"%s\"\n",
|
||||
progname, argv[i]);
|
||||
// Find the first argument to write to flash and how many arguments to parse and write
|
||||
if (strcmp(argv[argc - 1], "...") == 0) {
|
||||
write_mode = WRITE_MODE_FILL;
|
||||
start_offset = 4;
|
||||
len = strtoul(argv[3], &end_ptr, 0);
|
||||
if (*end_ptr || (end_ptr == argv[3])) {
|
||||
avrdude_message(MSG_INFO, "%s (write ...): can't parse address \"%s\"\n",
|
||||
progname, argv[3]);
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
write_mode = WRITE_MODE_STANDARD;
|
||||
start_offset = 3;
|
||||
len = argc - start_offset;
|
||||
}
|
||||
|
||||
pgm->err_led(pgm, OFF);
|
||||
for (werror=0, i=0; i<len; i++) {
|
||||
// Structure related to data that is being written to memory
|
||||
struct Data {
|
||||
// Data info
|
||||
int32_t bytes_grown;
|
||||
uint8_t size;
|
||||
bool is_float;
|
||||
bool is_signed;
|
||||
char * str_ptr;
|
||||
// Data union
|
||||
union {
|
||||
float f;
|
||||
int64_t ll;
|
||||
uint8_t a[8];
|
||||
};
|
||||
} data = {
|
||||
.bytes_grown = 0,
|
||||
.size = 0,
|
||||
.is_float = false,
|
||||
.is_signed = false,
|
||||
.str_ptr = NULL,
|
||||
.ll = 0
|
||||
};
|
||||
|
||||
rc = avr_write_byte(pgm, p, mem, addr+i, buf[i]);
|
||||
for (i = start_offset; i < len + start_offset; i++) {
|
||||
data.is_float = false;
|
||||
data.size = 0;
|
||||
|
||||
// Handle the next argument
|
||||
if (i < argc - start_offset + 3) {
|
||||
// Free string pointer if already allocated
|
||||
if(data.str_ptr) {
|
||||
free(data.str_ptr);
|
||||
data.str_ptr = NULL;
|
||||
}
|
||||
|
||||
// Get suffix if present
|
||||
char suffix = argv[i][strlen(argv[i]) - 1];
|
||||
char lsuffix = argv[i][strlen(argv[i]) - 2];
|
||||
if ((suffix == 'L' && lsuffix == 'L') || (suffix == 'l' && lsuffix == 'l')) {
|
||||
argv[i][strlen(argv[i]) - 2] = '\0';
|
||||
data.size = 8;
|
||||
} else if (suffix == 'L' || suffix == 'l') {
|
||||
argv[i][strlen(argv[i]) - 1] = '\0';
|
||||
data.size = 4;
|
||||
} else if ((suffix == 'F' || suffix == 'f') &&
|
||||
strncmp(argv[i], "0x", 2) != 0 && strncmp(argv[i], "-0x", 3) != 0) {
|
||||
argv[i][strlen(argv[i]) - 1] = '\0';
|
||||
data.size = 4;
|
||||
} else if ((suffix == 'H' && lsuffix == 'H') || (suffix == 'h' && lsuffix == 'h')) {
|
||||
argv[i][strlen(argv[i]) - 2] = '\0';
|
||||
data.size = 1;
|
||||
} else if (suffix == 'H' || suffix == 'h' || suffix == 'S' || suffix == 's') {
|
||||
argv[i][strlen(argv[i]) - 1] = '\0';
|
||||
data.size = 2;
|
||||
} else if (suffix == '\'') {
|
||||
data.size = 1;
|
||||
}
|
||||
|
||||
// Try integers
|
||||
data.ll = strtoll(argv[i], &end_ptr, 0);
|
||||
if (*end_ptr || (end_ptr == argv[i])) {
|
||||
// Try float
|
||||
data.f = strtof(argv[i], &end_ptr);
|
||||
data.is_float = true;
|
||||
if (*end_ptr || (end_ptr == argv[i])) {
|
||||
data.is_float = false;
|
||||
// Try single character
|
||||
if (argv[i][0] == '\'' && argv[i][2] == '\'') {
|
||||
data.ll = argv[i][1];
|
||||
} else {
|
||||
// Try string that starts and ends with quotes
|
||||
if (argv[i][0] == '\"' && argv[i][strlen(argv[i]) - 1] == '\"') {
|
||||
data.str_ptr = calloc(strlen(argv[i]), sizeof(char));
|
||||
if (data.str_ptr == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s (write str): out of memory\n", progname);
|
||||
return -1;
|
||||
}
|
||||
// Strip start and end quotes
|
||||
strncpy(data.str_ptr, argv[i] + 1, strlen(argv[i]) - 2);
|
||||
} else {
|
||||
avrdude_message(MSG_INFO, "\n%s (write): can't parse data '%s'\n",
|
||||
progname, argv[i]);
|
||||
free(buf);
|
||||
if(data.str_ptr != NULL)
|
||||
free(data.str_ptr);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Print warning if data size might be ambiguous
|
||||
bool is_hex = (strncmp(argv[i], "0x", 2) == 0);
|
||||
bool is_neg_hex = (strncmp(argv[i], "-0x", 3) == 0);
|
||||
bool leading_zero = (strncmp(argv[i], "0x0", 3) == 0);
|
||||
int8_t hex_digits = (strlen(argv[i]) - 2);
|
||||
if(!data.size // No pre-defined size
|
||||
&& (is_neg_hex // Hex with - sign in front
|
||||
|| (is_hex && leading_zero && (hex_digits & (hex_digits - 1))) // Hex with 3, 5, 6 or 7 digits
|
||||
|| (!is_hex && !data.is_float && llabs(data.ll) > 0xFF && strlen(argv[i]) > 2))) // Base10 int greater than 255
|
||||
{
|
||||
avrdude_message(MSG_INFO, "Warning: no size suffix specified for \"%s\". "
|
||||
"Writing %d byte(s)\n",
|
||||
argv[i],
|
||||
llabs(data.ll) > UINT32_MAX ? 8 :
|
||||
llabs(data.ll) > UINT16_MAX || data.is_float ? 4 : \
|
||||
llabs(data.ll) > UINT8_MAX ? 2 : 1);
|
||||
}
|
||||
// Flag if signed integer and adjust size
|
||||
if (data.ll < 0 && !data.is_float) {
|
||||
data.is_signed = true;
|
||||
if (data.ll < INT32_MIN)
|
||||
data.size = 8;
|
||||
else if (data.ll < INT16_MIN)
|
||||
data.size = 4;
|
||||
else if (data.ll < INT8_MIN)
|
||||
data.size = 2;
|
||||
else
|
||||
data.size = 1;
|
||||
}
|
||||
}
|
||||
if(data.str_ptr) {
|
||||
for(int16_t j = 0; j < strlen(data.str_ptr); j++)
|
||||
buf[i - start_offset + data.bytes_grown++] = (uint8_t)data.str_ptr[j];
|
||||
} else {
|
||||
buf[i - start_offset + data.bytes_grown] = data.a[0];
|
||||
if (llabs(data.ll) > 0x000000FF || data.size >= 2 || data.is_float)
|
||||
buf[i - start_offset + ++data.bytes_grown] = data.a[1];
|
||||
if (llabs(data.ll) > 0x0000FFFF || data.size >= 4 || data.is_float) {
|
||||
buf[i - start_offset + ++data.bytes_grown] = data.a[2];
|
||||
buf[i - start_offset + ++data.bytes_grown] = data.a[3];
|
||||
}
|
||||
if (llabs(data.ll) > 0xFFFFFFFF || data.size == 8) {
|
||||
buf[i - start_offset + ++data.bytes_grown] = data.a[4];
|
||||
buf[i - start_offset + ++data.bytes_grown] = data.a[5];
|
||||
buf[i - start_offset + ++data.bytes_grown] = data.a[6];
|
||||
buf[i - start_offset + ++data.bytes_grown] = data.a[7];
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure buf does not overflow
|
||||
if (i - start_offset + data.bytes_grown > maxsize)
|
||||
break;
|
||||
}
|
||||
|
||||
// When in "fill" mode, the maximum size is already predefined
|
||||
if (write_mode == WRITE_MODE_FILL)
|
||||
data.bytes_grown = 0;
|
||||
|
||||
if ((addr + len + data.bytes_grown) > maxsize) {
|
||||
avrdude_message(MSG_INFO, "%s (write): selected address and # bytes exceed "
|
||||
"range for %s memory\n",
|
||||
progname, memtype);
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(data.str_ptr)
|
||||
free(data.str_ptr);
|
||||
|
||||
avrdude_message(MSG_NOTICE, "\nInfo: Writing %d bytes starting from address 0x%02x",
|
||||
len + data.bytes_grown, addr);
|
||||
if (write_mode == WRITE_MODE_FILL)
|
||||
avrdude_message(MSG_NOTICE, ". Remaining space filled with %s", argv[argc - 2]);
|
||||
avrdude_message(MSG_NOTICE, "\n");
|
||||
|
||||
pgm->err_led(pgm, OFF);
|
||||
bool werror = false;
|
||||
report_progress(0, 1, "Writing");
|
||||
for (i = 0; i < (len + data.bytes_grown); i++) {
|
||||
int32_t rc = avr_write_byte(pgm, p, mem, addr+i, buf[i]);
|
||||
if (rc) {
|
||||
avrdude_message(MSG_INFO, "%s (write): error writing 0x%02x at 0x%05lx, rc=%d\n",
|
||||
progname, buf[i], addr+i, rc);
|
||||
if (rc == -1)
|
||||
avrdude_message(MSG_INFO, "write operation not supported on memory type \"%s\"\n",
|
||||
mem->desc);
|
||||
werror = 1;
|
||||
werror = true;
|
||||
}
|
||||
|
||||
uint8_t b;
|
||||
rc = pgm->read_byte(pgm, p, mem, addr+i, &b);
|
||||
if (b != buf[i]) {
|
||||
avrdude_message(MSG_INFO, "%s (write): error writing 0x%02x at 0x%05lx cell=0x%02x\n",
|
||||
progname, buf[i], addr+i, b);
|
||||
werror = 1;
|
||||
werror = true;
|
||||
}
|
||||
|
||||
if (werror) {
|
||||
pgm->err_led(pgm, ON);
|
||||
}
|
||||
|
||||
report_progress(i, (len + data.bytes_grown), NULL);
|
||||
}
|
||||
report_progress(1, 1, NULL);
|
||||
|
||||
free(buf);
|
||||
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,11 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
WRITE_MODE_STANDARD = 0,
|
||||
WRITE_MODE_FILL = 1,
|
||||
} mode;
|
||||
|
||||
int terminal_mode(PROGRAMMER * pgm, struct avrpart * p);
|
||||
char * terminal_get_input(const char *prompt);
|
||||
|
||||
|
|
47
src/update.c
47
src/update.c
|
@ -227,6 +227,13 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
|
|||
return -1;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (upd->op == DEVICE_READ) {
|
||||
/*
|
||||
* read out the specified device memory and write it to a file
|
||||
|
@ -238,14 +245,14 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
|
|||
return -1;
|
||||
}
|
||||
if (quell_progress < 2) {
|
||||
avrdude_message(MSG_INFO, "%s: reading %s memory:\n",
|
||||
progname, mem->desc);
|
||||
avrdude_message(MSG_INFO, "%s: reading %s%s memory:\n",
|
||||
progname, mem->desc, alias_mem_desc);
|
||||
}
|
||||
report_progress(0,1,"Reading");
|
||||
rc = avr_read(pgm, p, upd->memtype, 0);
|
||||
if (rc < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: failed to read all of %s memory, rc=%d\n",
|
||||
progname, mem->desc, rc);
|
||||
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;
|
||||
}
|
||||
report_progress(1,1,NULL);
|
||||
|
@ -288,8 +295,8 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
|
|||
* write the buffer contents to the selected memory type
|
||||
*/
|
||||
if (quell_progress < 2) {
|
||||
avrdude_message(MSG_INFO, "%s: writing %s (%d bytes):\n",
|
||||
progname, mem->desc, size);
|
||||
avrdude_message(MSG_INFO, "%s: writing %s%s (%d bytes):\n",
|
||||
progname, mem->desc, alias_mem_desc, size);
|
||||
}
|
||||
|
||||
if (!(flags & UF_NOWRITE)) {
|
||||
|
@ -306,16 +313,16 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
|
|||
}
|
||||
|
||||
if (rc < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: failed to write %s memory, rc=%d\n",
|
||||
progname, mem->desc, rc);
|
||||
avrdude_message(MSG_INFO, "%s: failed to write %s%s memory, rc=%d\n",
|
||||
progname, mem->desc, alias_mem_desc, rc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
vsize = rc;
|
||||
|
||||
if (quell_progress < 2) {
|
||||
avrdude_message(MSG_INFO, "%s: %d bytes of %s written\n", progname,
|
||||
vsize, mem->desc);
|
||||
avrdude_message(MSG_INFO, "%s: %d bytes of %s%s written\n", progname,
|
||||
vsize, mem->desc, alias_mem_desc);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -327,11 +334,11 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
|
|||
pgm->vfy_led(pgm, ON);
|
||||
|
||||
if (quell_progress < 2) {
|
||||
avrdude_message(MSG_INFO, "%s: verifying %s memory against %s:\n",
|
||||
progname, mem->desc, upd->filename);
|
||||
avrdude_message(MSG_INFO, "%s: verifying %s%s memory against %s:\n",
|
||||
progname, mem->desc, alias_mem_desc, upd->filename);
|
||||
|
||||
avrdude_message(MSG_NOTICE2, "%s: load data %s data from input file %s:\n",
|
||||
progname, mem->desc, upd->filename);
|
||||
avrdude_message(MSG_NOTICE2, "%s: load data %s%s data from input file %s:\n",
|
||||
progname, mem->desc, alias_mem_desc, upd->filename);
|
||||
}
|
||||
|
||||
rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
|
||||
|
@ -345,15 +352,15 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
|
|||
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 data:\n",
|
||||
progname, mem->desc);
|
||||
avrdude_message(MSG_NOTICE2, "%s: reading on-chip %s%s data:\n",
|
||||
progname, mem->desc, alias_mem_desc);
|
||||
}
|
||||
|
||||
report_progress (0,1,"Reading");
|
||||
rc = avr_read(pgm, p, upd->memtype, v);
|
||||
if (rc < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: failed to read all of %s memory, rc=%d\n",
|
||||
progname, mem->desc, rc);
|
||||
avrdude_message(MSG_INFO, "%s: failed to read all of %s%s memory, rc=%d\n",
|
||||
progname, mem->desc, alias_mem_desc, rc);
|
||||
pgm->err_led(pgm, ON);
|
||||
avr_free_part(v);
|
||||
return -1;
|
||||
|
@ -375,8 +382,8 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
|
|||
}
|
||||
|
||||
if (quell_progress < 2) {
|
||||
avrdude_message(MSG_INFO, "%s: %d bytes of %s verified\n",
|
||||
progname, rc, mem->desc);
|
||||
avrdude_message(MSG_INFO, "%s: %d bytes of %s%s verified\n",
|
||||
progname, rc, mem->desc, alias_mem_desc);
|
||||
}
|
||||
|
||||
pgm->vfy_led(pgm, OFF);
|
||||
|
|
|
@ -53,7 +53,7 @@ static void updi_set_rtsdtr_mode(PROGRAMMER* pgm)
|
|||
|
||||
static int updi_physical_open(PROGRAMMER* pgm, int baudrate, unsigned long cflags)
|
||||
{
|
||||
serial_recv_timeout = 100;
|
||||
serial_recv_timeout = 1000;
|
||||
union pinfo pinfo;
|
||||
|
||||
pinfo.serialinfo.baud = baudrate;
|
||||
|
@ -155,12 +155,19 @@ static int updi_physical_send_double_break(PROGRAMMER * pgm)
|
|||
serial_send(&pgm->fd, buffer, 1);
|
||||
serial_recv(&pgm->fd, buffer, 1);
|
||||
|
||||
serial_drain(&pgm->fd, 0);
|
||||
|
||||
if (serial_setparams(&pgm->fd, pgm->baudrate? pgm->baudrate: 115200, SERIAL_8E2) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
updi_set_rtsdtr_mode(pgm);
|
||||
|
||||
/*
|
||||
* drain any extraneous input
|
||||
*/
|
||||
serial_drain(&pgm->fd, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -191,10 +198,14 @@ int updi_physical_sib(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size)
|
|||
|
||||
int updi_link_open(PROGRAMMER * pgm)
|
||||
{
|
||||
unsigned char init_buffer[1];
|
||||
|
||||
if (updi_physical_open(pgm, pgm->baudrate? pgm->baudrate: 115200, SERIAL_8E2) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return updi_physical_send_double_break(pgm);
|
||||
|
||||
init_buffer[0]=UPDI_BREAK;
|
||||
return updi_physical_send(pgm, init_buffer, 1);
|
||||
}
|
||||
|
||||
void updi_link_close(PROGRAMMER * pgm)
|
||||
|
|
|
@ -291,7 +291,7 @@ static int usbhid_recv(union filedescriptor *fd, unsigned char *buf, size_t nbyt
|
|||
if (udev == NULL)
|
||||
return -1;
|
||||
|
||||
rv = i = hid_read_timeout(udev, buf, nbytes, 300);
|
||||
rv = i = hid_read_timeout(udev, buf, nbytes, 10000);
|
||||
if (i != nbytes)
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: Short read, read only %d out of %u bytes\n",
|
||||
|
|
Loading…
Reference in New Issue