Merge branch 'avrdudes:main' into main

This commit is contained in:
Jörg Wunsch 2022-01-08 21:46:12 +01:00 committed by GitHub
commit a447673b07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 3148 additions and 750 deletions

View File

@ -1,5 +1,5 @@
#
# build_cmake.yml - GitHub build action for AVRDUDE
# build.yml - GitHub build action for AVRDUDE
# Copyright (C) 2021 Marius Greuel
#
# This program is free software; you can redistribute it and/or modify
@ -43,23 +43,83 @@ jobs:
bison
libelf-dev
libusb-dev
libftdi1-dev
libusb-1.0-0-dev
libhidapi-dev
libftdi1-dev
libreadline-dev
- name: Configure
run: >-
cmake
-D DEBUG_CMAKE=1
-D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
-B ${{github.workspace}}/build
-B ../build
- name: Build
run: cmake --build ${{github.workspace}}/build
run: cmake --build ../build
- name: Archive build artifacts
if: always()
uses: actions/upload-artifact@v2
with:
name: linux-x86_64
path: |
${{github.workspace}}/build/*
build/
!**/*.d
!**/*.o
linux:
runs-on: ubuntu-latest
container: debian:11
defaults:
run:
working-directory: ./src
strategy:
matrix:
include:
- { arch: i386, processor: i686, prefix: i686-linux-gnu, inc-lib: i386-linux-gnu }
- { arch: armhf, processor: armhf, prefix: arm-linux-gnueabihf, inc-lib: arm-linux-gnueabihf }
- { arch: arm64, processor: aarch64, prefix: aarch64-linux-gnu, inc-lib: aarch64-linux-gnu }
steps:
- uses: actions/checkout@v2
- name: Add architecture
run: |
dpkg --add-architecture ${{matrix.arch}}
apt-get update
- name: Install prerequisites
run: >-
apt-get install -y
git
cmake
flex
bison
crossbuild-essential-${{matrix.arch}}
libelf-dev:${{matrix.arch}}
libusb-dev:${{matrix.arch}}
libusb-1.0-0-dev:${{matrix.arch}}
libhidapi-dev:${{matrix.arch}}
libftdi1-dev:${{matrix.arch}}
libreadline-dev:${{matrix.arch}}
- name: Configure
run: >-
cmake
-D DEBUG_CMAKE=1
-D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
-D CMAKE_SYSTEM_NAME=Linux
-D CMAKE_SYSTEM_PROCESSOR=${{matrix.processor}}
-D CMAKE_C_COMPILER=${{matrix.prefix}}-gcc
-D CMAKE_FIND_ROOT_PATH=/usr/${{matrix.prefix}}
-D CMAKE_INCLUDE_PATH=/usr/include/${{matrix.inc-lib}}
-D CMAKE_LIBRARY_PATH=/usr/lib/${{matrix.inc-lib}}
-B ../build
- name: Build
run: cmake --build ../build
- name: Archive build artifacts
if: always()
uses: actions/upload-artifact@v2
with:
name: linux-${{matrix.processor}}
path: |
build/
!**/*.d
!**/*.o
macos-x86_64:
runs-on: macos-latest
@ -76,8 +136,8 @@ jobs:
bison
libelf
libusb
libftdi
hidapi
libftdi
- name: Configure
run: >-
cmake
@ -85,16 +145,58 @@ jobs:
-D CMAKE_EXE_LINKER_FLAGS=-L/usr/local/Cellar
-D DEBUG_CMAKE=1
-D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
-B ${{github.workspace}}/build
-B ../build
- name: Build
run: cmake --build ${{github.workspace}}/build
run: cmake --build ../build
- name: Archive build artifacts
if: always()
uses: actions/upload-artifact@v2
with:
name: macos-x86_64
path: |
${{github.workspace}}/build/*
build/
!**/*.d
!**/*.o
msvc:
runs-on: windows-latest
defaults:
run:
working-directory: ./src
strategy:
matrix:
include:
- { arch: x86, platform: Win32 }
- { arch: x64, platform: x64 }
- { arch: arm64, platform: ARM64 }
steps:
- uses: actions/checkout@v2
- name: Install prerequisites
run: choco install winflexbison3
- name: Configure
run: >-
cmake
-A ${{matrix.platform}}
-D DEBUG_CMAKE=1
-D CMAKE_SYSTEM_VERSION=11
-D CMAKE_C_FLAGS_RELWITHDEBINFO="/MT /GL /Zi /O2 /Ob1 /DNDEBUG"
-D CMAKE_CXX_FLAGS_RELWITHDEBINFO="/MT /GL /Zi /O2 /Ob1 /DNDEBUG"
-D CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO="/DEBUG /INCREMENTAL:NO /LTCG /OPT:REF /OPT:ICF"
-D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
-D USE_EXTERNAL=1
-B ../build
- name: Build
run: cmake --build ../build --config ${{env.BUILD_TYPE}}
- name: Archive build artifacts
if: always()
uses: actions/upload-artifact@v2
with:
name: msvc-${{matrix.arch}}
path: |
build/
!**/_deps/
!**/*.obj
mingw:
runs-on: windows-latest
defaults:

85
.github/workflows/deploy.yml vendored Normal file
View File

@ -0,0 +1,85 @@
#
# deploy.yml - GitHub deploy action for AVRDUDE
# Copyright (C) 2021 Marius Greuel
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
name: Deploy
on:
push:
tags:
- 'v*'
jobs:
build:
uses: avrdudes/avrdude/.github/workflows/build.yml@main
release:
needs: build
runs-on: ubuntu-latest
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
steps:
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
with:
tag_name: ${{github.ref}}
release_name: AVRDUDE ${{github.ref}}
body: "**[Release Notes:](https://github.com/avrdudes/avrdude/blob/main/NEWS)**"
draft: false
prerelease: false
asset-msvc:
needs: release
runs-on: ubuntu-latest
strategy:
matrix:
include:
- { arch: x86 }
- { arch: x64 }
- { arch: arm64 }
steps:
- name: Download artifact
uses: actions/download-artifact@v2
with:
name: msvc-${{matrix.arch}}
- name: Create release asset
run: >-
zip -j asset.zip
RelWithDebInfo/avrdude.exe
RelWithDebInfo/avrdude.pdb
avrdude.conf
- name: Upload release asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
with:
upload_url: ${{needs.release.outputs.upload_url}}
asset_path: ./asset.zip
asset_name: avrdude-${{github.ref_name}}-windows-${{matrix.arch}}.zip
asset_content_type: application/zip
#deploy:
# needs: [asset-msvc]
# runs-on: ubuntu-latest
# steps:
# - name: Create package (Chocolatey)
# run: echo TODO

1
.gitignore vendored
View File

@ -14,6 +14,7 @@ INSTALL
Makefile.in
Makefile
ac_cfg.h.in
ac_cfg.h.in~
aclocal.m4
autom4te.cache
configure

15
NEWS
View File

@ -9,15 +9,19 @@ Changes since version 6.4:
* Major changes compared to the previous version:
- Completely revamped Windows support, including MSVC
- Started to add CMake (by now, parallel with autoconf/automake)
* New devices supported:
- ATtiny828, ATtiny87, ATtiny167, ATtiny48, ATtiny102, ATtiny104
* New programmers supported:
- SerialUPDI (UPDI devices connected to serial port with few
passive parts)
- PicKit4 / SNAP (now also in ISP and PDI mode)
- Teensy bootloader (PR #802)
* Issues fixed:
@ -29,6 +33,9 @@ Changes since version 6.4:
- CMake doesn't correctly handle conditionals in avrdude.conf.in
#776
- CMake: Recognize more than just bison #785
- [bug #26007] ATTiny167 not supported #150
- [bug #47375] ATtiny102/104 descriptions missing in configuration
file #409
* Pull requests:
@ -50,6 +57,14 @@ Changes since version 6.4:
- buspirate: fix -Wtautological-constant-out-of-range-compare #796
- avrftdi: don't use the deprecated ftdi_usb_purge_buffers routine #792
- Ignore ctags index file #804
- term: fix memleakOnRealloc #806
- Add missing ATtiny targets to avrdude.conf #803
- Add support for Teensy bootloader #802
- Conffile clean up #801
- Fix typos all over the code #807
- Add MSVC builds and better WinUSB/FTDI support #798
- buspirate: fix invalidScanfArgType_int warning #808
- Ignore ac_cfg.h.in~ #810
* Internals:

138
README.md
View File

@ -1,5 +1,7 @@
# AVRDUDE
[![Build Status](https://github.com/avrdudes/avrdude/actions/workflows/build.yml/badge.svg)](https://github.com/avrdudes/avrdude/actions/workflows/build.yml)
AVRDUDE - AVR Downloader Uploader - is a program for downloading and uploading
the on-chip memories of Microchips [AVR microcontrollers](https://en.wikipedia.org/wiki/AVR_microcontrollers).
It can program the Flash and EEPROM, and where supported by the programming
@ -18,7 +20,7 @@ The latest version of AVRDUDE is always available here:\
To get AVRDUDE for Windows, install the latest version from the [Releases](http://download.savannah.gnu.org/releases/avrdude/) page.
Alternatively, you may [build AVRDUDE](#building-avrdude-for-windows) yourself from source.
Alternatively, you may [build AVRDUDE](https://github.com/avrdudes/avrdude/wiki) yourself from source.
## Getting AVRDUDE for Linux
@ -28,13 +30,13 @@ To install AVRDUDE for Linux, install the package `avrdude` by running the follo
sudo apt-get install avrdude
```
Alternatively, you may [build AVRDUDE](#building-avrdude-for-linux) yourself from source.
Alternatively, you may [build AVRDUDE](https://github.com/avrdudes/avrdude/wiki) yourself from source.
## Getting AVRDUDE for MacOS
On MacOS, AVRDUDE can be installed through Mac Ports.
Alternatively, you may [build AVRDUDE](#building-avrdude-for-macos) yourself from source.
Alternatively, you may [build AVRDUDE](https://github.com/avrdudes/avrdude/wiki) yourself from source.
## Using AVRDUDE
@ -54,133 +56,5 @@ 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](#todo).
## General build instructions
### Prerequisites
Depending on your requirements, the following prerequisites are
needed:
* libelf including header files (for directly reading ELF files)
* libusb 0.1 or 1.0 (or compatible), including header files
* libftdi or libftdi1 (for direct access to FTDI devices)
* libhidapi or libhid (for access to recent Atmel/Microchip dongles)
### Building
All source code is located in the `src/` subdirectory. Thus all
instructions are relative to that directory.
Source-code releases contain an up-to-date configure script that
can be run to generate the required Makefiles:
```console
cd src && ./configure && make && sudo make install
```
At the end of the configure script, a configuration summary is issued,
like this:
```console
Configuration summary:
----------------------
DO HAVE libelf
DO HAVE libusb
DO HAVE libusb_1_0
DO HAVE libftdi1
DON'T HAVE libftdi
DON'T HAVE libhid
DO HAVE libhidapi
DO HAVE pthread
DISABLED doc
DISABLED parport
DISABLED linuxgpio
DISABLED linuxspi
```
Make sure all the features you are interested in have been found.
Building the development source tree might possibly require to
re-generate the configure script using the autoconf/automake
tools. This can be done using the `bootstrap` script:
```console
cd src && ./bootstrap
```
## Building AVRDUDE for Windows
### Windows Prerequisites
TODO.
### Windows Build Instructions
TODO.
## Building AVRDUDE for Linux
### Linux Prerequisites
To build AVRDUDE for Linux, you need to install the following packages:
```console
sudo apt-get install build-essential git automake libtool flex bison libelf-dev libusb-dev libftdi1-dev libhidapi-dev
```
To build the documentation, you need to install the following packages:
```console
sudo apt-get install texlive texi2html
```
### Linux Build Instructions
To build AVRDUDE for Linux, run the following commands:
```console
git clone https://github.com/avrdudes/avrdude
cd avrdude
./bootstrap
./configure
make
```
To build the documentation for AVRDUDE, run the following commands:
```console
cd doc
make all
```
## Building AVRDUDE for MacOS
### Prerequisites
The following things are needed to build AVRDUDE on MacOS:
* a C compiler; either full XCode, or the XCode Command Line tools
* autoconf, automake, libtool, hidapi, libftdi1, libusb, libelf;
they can be installed e.g. from Mac Ports using
```console
port install autoconf automake \
libtool hidapi libftdi1 libusb libelf
```
### Compilation
Depending on the location of the prerequisites, the `CPPFLAGS` and
`LDFLAGS` variables need to be set accordingly. Mac Ports installs
everything under `/opt/local`, so use
```console
./configure CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib
```
MacOS Brew requires
```console
./configure CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/Cellar
```
For more information, refer to the [AVRDUDE documentation](http://download.savannah.gnu.org/releases/avrdude/avrdude-doc-6.4.pdf).

View File

@ -30,19 +30,18 @@ option(BUILD_DOC "Enable building documents" OFF)
option(HAVE_LINUXGPIO "Enable Linux sysfs GPIO support" OFF)
option(HAVE_LINUXSPI "Enable Linux SPI support" OFF)
option(HAVE_PARPORT "Enable parallel port support" OFF)
option(USE_EXTERNAL "Use local code from the 'external' folder" OFF)
option(USE_EXTERNAL "Use external libraries from AVRDUDE GitHub repositories" OFF)
option(USE_LIBUSBWIN32 "Prefer libusb-win32 over libusb" OFF)
option(DEBUG_CMAKE "Enable debugging output for this CMake project" OFF)
include(CheckIncludeFile)
include(CheckFunctionExists)
include(CheckSymbolExists)
include(GNUInstallDirs)
include(FetchContent)
include(FindPackageMessage)
include(GNUInstallDirs)
set(CONFIG_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}")
set(AVRDUDE_FULL_VERSION ${CMAKE_PROJECT_VERSION})
set(AVRDUDE_EXTERNAL_PATH "${PROJECT_SOURCE_DIR}/external")
# =====================================
# Get Git commit info
@ -125,24 +124,6 @@ else()
endif()
endif()
# =====================================
# Detect headers
# =====================================
check_include_file(stdint.h HAVE_STDINT_H)
check_include_file(stdlib.h HAVE_STDLIB_H)
check_include_file(inttypes.h HAVE_INTTYPES_H)
check_include_file(netinet/in.h HAVE_NETINET_IN_H)
# =====================================
# Detect functions
# =====================================
check_function_exists(usleep HAVE_USLEEP)
check_function_exists(getaddrinfo HAVE_GETADDRINFO)
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
check_function_exists(strcasecmp HAVE_STRCASECMP)
# =====================================
# Detect installed libraries
# =====================================
@ -218,14 +199,14 @@ endif()
# -------------------------------------
# Find libhidapi
find_library(HAVE_LIBHID NAMES hid)
find_library(HAVE_LIBHIDAPI NAMES ${PREFERRED_LIBHIDAPI})
if(HAVE_LIBHIDAPI)
set(LIB_LIBHIDAPI ${HAVE_LIBHIDAPI})
check_include_file(hidapi/hidapi.h HAVE_HIDAPI_HIDAPI_H)
endif()
find_library(HAVE_LIBHID NAMES hid)
# -------------------------------------
# Find libftdi
@ -251,6 +232,60 @@ if(HAVE_LIBREADLINE)
set(LIB_LIBREADLINE ${HAVE_LIBREADLINE})
endif()
# =====================================
# Use external libraries if requested
# =====================================
if(USE_EXTERNAL)
FetchContent_Declare(libelf
GIT_REPOSITORY https://github.com/avrdudes/libelf.git
GIT_TAG e5a39bf19bd6598c42e09172be5a78ceec2a065c
)
FetchContent_Declare(libusb
GIT_REPOSITORY https://github.com/avrdudes/libusb.git
GIT_TAG 632bc25d04eff563cc00de29435b9a7ed6f4654c
)
FetchContent_Declare(libhidapi
GIT_REPOSITORY https://github.com/avrdudes/libhidapi.git
GIT_TAG e3700e951f762ef92871ff4fc94586e4d1c042a6
)
FetchContent_Declare(libftdi
GIT_REPOSITORY https://github.com/avrdudes/libftdi.git
GIT_TAG f3a54da710002a7d25a32a69e667a69ef84cc120
)
message(STATUS "Fetching external libraries, please wait...")
FetchContent_MakeAvailable(
libelf
libusb
libhidapi
libftdi
)
message(STATUS "Using external library 'libelf'")
set(LIB_LIBELF libelf)
set(HAVE_LIBELF 1)
set(HAVE_LIBELF_H 1)
message(STATUS "Using external library 'libusb'")
set(LIB_LIBUSB libusb)
set(HAVE_LIBUSB 1)
set(HAVE_LUSB0_USB_H 1)
message(STATUS "Using external library 'libhidapi'")
set(LIB_LIBHIDAPI libhidapi)
set(HAVE_LIBHIDAPI 1)
set(HAVE_HIDAPI_HIDAPI_H 1)
message(STATUS "Using external library 'libftdi'")
set(LIB_LIBFTDI libftdi)
set(HAVE_LIBFTDI 1)
set(HAVE_LIBFTDI_TYPE_232H 1)
endif()
# =====================================
# Setup target specific options
# =====================================
@ -258,15 +293,35 @@ endif()
add_compile_definitions(CONFIG_DIR=\"${CONFIG_DIR}\")
if(WIN32)
set(HAVE_LIBWS2_32 1)
set(EXTRA_WINDOWS_SOURCES "${PROJECT_BINARY_DIR}/windows.rc")
set(EXTRA_WINDOWS_LIBRARIES setupapi ws2_32)
add_compile_definitions(WIN32NATIVE=1)
endif()
if(NOT WIN32)
set(LIB_MATH m)
#add_compile_options(-Wall -Wextra -pedantic)
add_compile_options(-Wall) # -Wextra
endif()
if(MSVC)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS=1)
add_compile_definitions(_CRT_NONSTDC_NO_WARNINGS=1)
add_compile_definitions(_WINSOCK_DEPRECATED_NO_WARNINGS=1)
add_compile_options(/W3)
add_compile_options(/wd4018) # warning C4018: signed/unsigned mismatch
add_compile_options(/wd4244) # warning C4244: conversion from '...' to '...', possible loss of data
add_compile_options(/wd4267) # warning C4267: conversion from '...' to '...', possible loss of data
add_compile_options(/wd5105) # warning C5105: macro expansion producing 'xxx' has undefined behavior
add_compile_options(/wd6255) # warning C6255: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead
set(EXTRA_WINDOWS_SOURCES ${EXTRA_WINDOWS_SOURCES}
"${PROJECT_SOURCE_DIR}/msvc/getopt.c"
"${PROJECT_SOURCE_DIR}/msvc/gettimeofday.c"
"${PROJECT_SOURCE_DIR}/msvc/usleep.cpp"
)
set(EXTRA_WINDOWS_INCLUDES ${EXTRA_WINDOWS_INCLUDES}
"${PROJECT_SOURCE_DIR}/msvc"
"${PROJECT_SOURCE_DIR}/msvc/generated"
)
endif()
# =====================================
@ -300,6 +355,8 @@ message(STATUS "----------------------")
if (DEBUG_CMAKE)
message(STATUS "CMAKE_HOST_SYSTEM: ${CMAKE_HOST_SYSTEM}")
message(STATUS "CMAKE_SYSTEM: ${CMAKE_SYSTEM}")
message(STATUS "CMAKE_FIND_ROOT_PATH: ${CMAKE_FIND_ROOT_PATH}")
message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}")
message(STATUS "CONFIG_DIR: ${CONFIG_DIR}")
message(STATUS "AVRDUDE_FULL_VERSION: ${AVRDUDE_FULL_VERSION}")
message(STATUS "USE_EXTERNAL: ${USE_EXTERNAL}")
@ -308,11 +365,11 @@ if (DEBUG_CMAKE)
message(STATUS "HAVE_LIBUSB: ${HAVE_LIBUSB}")
message(STATUS "HAVE_LIBUSB_1_0: ${HAVE_LIBUSB_1_0}")
message(STATUS "HAVE_LIBUSB_WIN32: ${HAVE_LIBUSB_WIN32}")
message(STATUS "HAVE_LIBHID: ${HAVE_LIBHID}")
message(STATUS "HAVE_LIBHIDAPI: ${HAVE_LIBHIDAPI}")
message(STATUS "HAVE_LIBFTDI: ${HAVE_LIBFTDI}")
message(STATUS "HAVE_LIBFTDI1: ${HAVE_LIBFTDI1}")
message(STATUS "HAVE_LIBREADLINE: ${HAVE_LIBREADLINE}")
message(STATUS "HAVE_LIBWS2_32: ${HAVE_LIBWS2_32}")
message(STATUS "HAVE_LIBELF_H: ${HAVE_LIBELF_H}")
message(STATUS "HAVE_LIBELF_LIBELF_H: ${HAVE_LIBELF_LIBELF_H}")
message(STATUS "HAVE_USB_H: ${HAVE_USB_H}")
@ -472,7 +529,6 @@ add_library(libavrdude STATIC
lists.c
micronucleus.c
micronucleus.h
my_ddk_hidsdi.h
par.c
par.h
pgm.c
@ -501,6 +557,8 @@ add_library(libavrdude STATIC
stk500v2_private.h
stk500generic.c
stk500generic.h
teensy.c
teensy.h
tpi.h
updi_constants.h
updi_link.c

View File

@ -138,7 +138,6 @@ libavrdude_a_SOURCES = \
lists.c \
micronucleus.c \
micronucleus.h \
my_ddk_hidsdi.h \
par.c \
par.h \
pgm.c \
@ -165,6 +164,8 @@ libavrdude_a_SOURCES = \
stk500v2_private.h \
stk500generic.c \
stk500generic.h \
teensy.c \
teensy.h \
tpi.h \
usbasp.c \
usbasp.h \

View File

@ -115,7 +115,7 @@ programmer type can be used to directly connect to and program a chip
using the built in interfaces on the computer. The requirements to use
this type are that an SPI interface is exposed along with one GPIO
pin. The GPIO serves as the reset output since the Linux SPI drivers
do not hold slave select down when a transfer is not occuring and thus
do not hold slave select down when a transfer is not occurring and thus
it cannot be used as the reset pin. A readily available level
translator should be used between the SPI bus/reset GPIO and the chip
to avoid potentially damaging the computer's SPI controller in the
@ -244,11 +244,20 @@ The Micronucleus bootloader is supported for both protocol version V1
and V2. As the bootloader does not support reading from flash memory,
use the
.Fl V
option to prevent AVRDUDE from verifing the flash memory.
option to prevent AVRDUDE from verifying the flash memory.
See the section on
.Em extended parameters
for Micronucleus specific options.
.Pp
The Teensy bootloader is supported for all AVR boards.
As the bootloader does not support reading from flash memory,
use the
.Fl V
option to prevent AVRDUDE from verifing the flash memory.
See the section on
.Em extended parameters
for Teensy specific options.
.Pp
Input files can be provided, and output files can be written in
different file formats, such as raw binary files containing the data
to download to the chip, Intel hex format, or Motorola S-record
@ -549,9 +558,9 @@ be specified as
Libhidapi support is required on Unix and Mac OS but not on Windows. For more
information about AVR-Doper see http://www.obdev.at/avrusb/avrdoper.html.
.Pp
For the USBtinyISP, which is a simplicistic device not implementing
For the USBtinyISP, which is a simplistic device not implementing
serial numbers, multiple devices can be distinguished by their
location in the USB hierarchy. See the the respective
location in the USB hierarchy. See the respective
.Em Troubleshooting
entry in the detailed documentation for examples.
.Pp
@ -599,10 +608,10 @@ Posix systems (by now).
Disable (or quell) output of the progress bar while reading or writing
to the device. Specify it a second time for even quieter operation.
.It Fl s
Disable safemode prompting. When safemode discovers that one or more
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
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
@ -1110,6 +1119,16 @@ specifies the connection time-out in seconds.
If no time-out is specified, AVRDUDE will wait indefinitely until the
device is plugged in.
.El
.It Ar Teensy bootloader
.Bl -tag -offset indent -width indent
.It Ar wait[=<timeout>]
If the device is not connected, wait for the device to be plugged in.
The optional
.Ar timeout
specifies the connection time-out in seconds.
If no time-out is specified, AVRDUDE will wait indefinitely until the
device is plugged in.
.El
.It Ar Wiring
When using the Wiring programmer type, the
following optional extended parameter is accepted:

View File

@ -925,6 +925,15 @@ programmer
usbpid = 0x0753;
;
programmer
id = "teensy";
desc = "Teensy Bootloader";
type = "teensy";
connection_type = usb;
usbvid = 0x16C0;
usbpid = 0x0478;
;
# commercial version of USBtiny, using a separate VID/PID
programmer
id = "iseavrprog";
@ -8554,6 +8563,756 @@ part parent "m168"
ocdrev = 1;
;
#------------------------------------------------------------
# ATtiny828
#------------------------------------------------------------
part
id = "t828";
desc = "ATtiny828";
has_debugwire = yes;
flash_instr = 0xB6, 0x01, 0x11;
eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
0x99, 0xF9, 0xBB, 0xAF;
stk500_devcode = 0x86;
# avr910_devcode = 0x;
signature = 0x1e 0x93 0x14;
pagel = 0xd7;
bs2 = 0xc2;
chip_erase_delay = 15000;
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 x x x x x",
"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;
resetdelay = 15;
chiperasepulsewidth = 0;
chiperasepolltimeout = 10;
programfusepulsewidth = 0;
programfusepolltimeout = 5;
programlockpulsewidth = 0;
programlockpolltimeout = 5;
memory "eeprom"
paged = no;
page_size = 4;
size = 256;
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 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",
" 0 0 0 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 = 5;
blocksize = 4;
readsize = 256;
;
memory "flash"
paged = yes;
size = 8192;
page_size = 64;
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 0 0 0 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 0 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 x 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 x x a4 a3 a2 a1 a0",
" i i i i i i i i";
writepage = " 0 1 0 0 1 1 0 0",
" 0 0 0 0 a11 a10 a9 a8",
" a7 a6 a5 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;
min_write_delay = 4500;
max_write_delay = 4500;
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";
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";
;
memory "hfuse"
size = 1;
min_write_delay = 4500;
max_write_delay = 4500;
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";
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";
;
memory "efuse"
size = 1;
min_write_delay = 4500;
max_write_delay = 4500;
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";
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 i i i i i";
;
memory "lock"
size = 1;
min_write_delay = 4500;
max_write_delay = 4500;
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";
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";
;
memory "calibration"
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 0 o o o o o o o o";
;
memory "signature"
size = 3;
read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
"x x x x x x a1 a0 o o o o o o o o";
;
;
#------------------------------------------------------------
# ATtiny87
#------------------------------------------------------------
part
id = "t87";
desc = "ATtiny87";
has_debugwire = yes;
flash_instr = 0xB6, 0x01, 0x11;
eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4,
0x00, 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB,
0xBF, 0x99, 0xF9, 0xBB, 0xAF;
## no STK500 devcode in XML file, use the ATtiny45 one
stk500_devcode = 0x14;
## Try the AT90S2313 devcode:
avr910_devcode = 0x20;
signature = 0x1e 0x93 0x87;
reset = io;
chip_erase_delay = 15000;
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 x x x x x",
"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 = 0;
pp_controlstack =
0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E,
0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E,
0x06, 0x16, 0x46, 0x56, 0x0A, 0x1A, 0x4A, 0x5A,
0x1E, 0x7C, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
hventerstabdelay = 100;
progmodedelay = 0;
latchcycles = 5;
togglevtg = 1;
poweroffdelay = 20;
resetdelayms = 1;
resetdelayus = 0;
hvleavestabdelay = 15;
chiperasepulsewidth = 0;
chiperasepolltimeout = 10;
programfusepulsewidth = 0;
programfusepolltimeout = 5;
programlockpulsewidth = 0;
programlockpolltimeout = 5;
idr = 0x00;
spmcr = 0x57;
allowfullpagebitstream = no;
memory "eeprom"
size = 512;
paged = no;
page_size = 4;
min_write_delay = 4000;
max_write_delay = 4500;
readback_p1 = 0xff;
readback_p2 = 0xff;
read = "1 0 1 0 0 0 0 0 0 0 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 0 0 x x x x x a8",
"a8 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 x",
" 0 0 a5 a4 a3 a2 0 0",
" x x x x x x x x";
mode = 0x41;
delay = 10;
blocksize = 4;
readsize = 256;
;
memory "flash"
paged = yes;
size = 8192;
page_size = 128;
num_pages = 64;
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 0 0 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",
" 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",
" 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",
" i i i i i i i i";
writepage = " 0 1 0 0 1 1 0 0",
" 0 0 0 0 a11 a10 a9 a8",
" a7 a6 a5 x x x x x",
" x x x x x x x x";
mode = 0x41;
delay = 10;
blocksize = 64;
readsize = 256;
;
# ATtiny87 has Signature Bytes: 0x1E 0x93 0x87.
memory "signature"
size = 3;
read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
"x x x x x x a1 a0 o o o o o o o o";
;
memory "lock"
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 x x x x x x i i";
read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
"0 0 0 0 0 0 0 0 o o o o o o o o";
min_write_delay = 9000;
max_write_delay = 9000;
;
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 x x x x x x x 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 "calibration"
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";
;
;
#------------------------------------------------------------
# ATtiny167
#------------------------------------------------------------
part
id = "t167";
desc = "ATtiny167";
has_debugwire = yes;
flash_instr = 0xB6, 0x01, 0x11;
eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4,
0x00, 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB,
0xBF, 0x99, 0xF9, 0xBB, 0xAF;
## no STK500 devcode in XML file, use the ATtiny45 one
stk500_devcode = 0x14;
## avr910_devcode = ?;
## Try the AT90S2313 devcode:
avr910_devcode = 0x20;
signature = 0x1e 0x94 0x87;
reset = io;
chip_erase_delay = 15000;
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 x x x x x",
"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 = 0;
pp_controlstack =
0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E,
0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E,
0x06, 0x16, 0x46, 0x56, 0x0A, 0x1A, 0x4A, 0x5A,
0x1E, 0x7C, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
hventerstabdelay = 100;
progmodedelay = 0;
latchcycles = 5;
togglevtg = 1;
poweroffdelay = 20;
resetdelayms = 1;
resetdelayus = 0;
hvleavestabdelay = 15;
chiperasepulsewidth = 0;
chiperasepolltimeout = 10;
programfusepulsewidth = 0;
programfusepolltimeout = 5;
programlockpulsewidth = 0;
programlockpolltimeout = 5;
idr = 0x00;
spmcr = 0x57;
allowfullpagebitstream = no;
memory "eeprom"
size = 512;
paged = no;
page_size = 4;
min_write_delay = 4000;
max_write_delay = 4500;
readback_p1 = 0xff;
readback_p2 = 0xff;
read = "1 0 1 0 0 0 0 0 0 0 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 0 0 x x x x x a8",
"a8 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 x",
" 0 0 a5 a4 a3 a2 0 0",
" x x x x x x x x";
mode = 0x41;
delay = 10;
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 = 0xff;
readback_p2 = 0xff;
read_lo = " 0 0 1 0 0 0 0 0",
" 0 0 0 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",
" 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",
" 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",
" 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",
" x x x x x x x x";
mode = 0x41;
delay = 10;
blocksize = 64;
readsize = 256;
;
# ATtiny167 has Signature Bytes: 0x1E 0x94 0x87.
memory "signature"
size = 3;
read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
"x x x x x x a1 a0 o o o o o o o o";
;
memory "lock"
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 x x x x x x i i";
read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
"0 0 0 0 0 0 0 0 o o o o o o o o";
min_write_delay = 9000;
max_write_delay = 9000;
;
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 x x x x x x x 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 "calibration"
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";
;
;
#------------------------------------------------------------
# ATtiny48
#------------------------------------------------------------
part
id = "t48";
desc = "ATtiny48";
has_debugwire = yes;
flash_instr = 0xB6, 0x01, 0x11;
eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
0x99, 0xF9, 0xBB, 0xAF;
stk500_devcode = 0x73;
# avr910_devcode = 0x;
signature = 0x1e 0x92 0x09;
pagel = 0xd7;
bs2 = 0xc2;
chip_erase_delay = 15000;
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 x x x x x",
"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;
resetdelay = 15;
chiperasepulsewidth = 0;
chiperasepolltimeout = 10;
programfusepulsewidth = 0;
programfusepolltimeout = 5;
programlockpulsewidth = 0;
programlockpolltimeout = 5;
ocdrev = 1;
memory "eeprom"
paged = no;
page_size = 4;
size = 64;
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 x x x",
" x 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 x x x",
" x 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 x",
" x a6 a5 a4 a3 a2 0 0",
" x x x x x x x x";
mode = 0x41;
delay = 20;
blocksize = 4;
readsize = 64;
;
memory "flash"
paged = yes;
size = 4096;
page_size = 64;
num_pages = 64;
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 0 0 0 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 0 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 x 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 x x a4 a3 a2 a1 a0",
" i i i i i i i i";
writepage = " 0 1 0 0 1 1 0 0",
" 0 0 0 0 a11 a10 a9 a8",
" a7 a6 a5 x x x x x",
" x x x x x x x x";
mode = 0x41;
delay = 6;
blocksize = 64;
readsize = 256;
;
memory "lfuse"
size = 1;
min_write_delay = 4500;
max_write_delay = 4500;
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";
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";
;
memory "hfuse"
size = 1;
min_write_delay = 4500;
max_write_delay = 4500;
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";
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";
;
memory "efuse"
size = 1;
min_write_delay = 4500;
max_write_delay = 4500;
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";
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 1 1 1 i";
;
memory "lock"
size = 1;
min_write_delay = 4500;
max_write_delay = 4500;
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";
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";
;
memory "calibration"
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 0 o o o o o o o o";
;
memory "signature"
size = 3;
read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
"x x x x x x a1 a0 o o o o o o o o";
;
;
#------------------------------------------------------------
# ATtiny88
#------------------------------------------------------------
@ -15327,6 +16086,40 @@ part parent ".reduced_core_tiny"
;
;
#------------------------------------------------------------
# ATtiny102
#------------------------------------------------------------
part parent ".reduced_core_tiny"
id = "t102";
desc = "ATtiny102";
signature = 0x1e 0x90 0x0C;
memory "flash"
size = 1024;
offset = 0x4000;
page_size = 16;
blocksize = 128;
;
;
#------------------------------------------------------------
# ATtiny104
#------------------------------------------------------------
part parent ".reduced_core_tiny"
id = "t104";
desc = "ATtiny104";
signature = 0x1e 0x90 0x0B;
memory "flash"
size = 1024;
offset = 0x4000;
page_size = 16;
blocksize = 128;
;
;
#------------------------------------------------------------
# ATmega406
#------------------------------------------------------------

View File

@ -16,48 +16,32 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* $Id$ */
/* $Id$ */
#ifndef avrdude_h
#define avrdude_h
#define SYSTEM_CONF_FILE "avrdude.conf"
#if defined(WIN32)
#define USER_CONF_FILE "avrdude.rc"
#else
#define USER_CONF_FILE ".avrduderc"
#endif
extern char * progname; /* name of program, for messages */
extern char progbuf[]; /* spaces same length as progname */
extern int ovsigck; /* override signature check (-F) */
extern int verbose; /* verbosity level (-v, -vv, ...) */
extern int quell_progress; /* quiteness level (-q, -qq) */
extern int quell_progress; /* quietness level (-q, -qq) */
int avrdude_message(const int msglvl, const char *format, ...);
#define MSG_INFO (0) /* no -v option, can be supressed with -qq */
#define MSG_INFO (0) /* no -v option, can be suppressed with -qq */
#define MSG_NOTICE (1) /* displayed with -v */
#define MSG_NOTICE2 (2) /* displayed with -vv, used rarely */
#define MSG_DEBUG (3) /* displayed with -vvv */
#define MSG_TRACE (4) /* displayed with -vvvv, show trace commuication */
#define MSG_TRACE (4) /* displayed with -vvvv, show trace communication */
#define MSG_TRACE2 (5) /* displayed with -vvvvv */
#if defined(WIN32NATIVE)
#include "ac_cfg.h"
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(HAVE_USLEEP)
int usleep(unsigned int us);
#endif
#if !defined(HAVE_GETTIMEOFDAY)
struct timezone;
int gettimeofday(struct timeval *tv, struct timezone *tz);
#endif /* HAVE_GETTIMEOFDAY */
#ifdef __cplusplus
}
#endif
#endif /* defined(WIN32NATIVE) */
#endif

View File

@ -356,6 +356,9 @@ static int avrftdi_transmit_bb(PROGRAMMER * pgm, unsigned char mode, const unsig
blocksize = MAX(1,(max_size-7)/((8*2*6)+(8*1*2)));
//avrdude_message(MSG_INFO, "blocksize %d \n",blocksize);
unsigned char* send_buffer = alloca((8 * 2 * 6) * blocksize + (8 * 1 * 2) * blocksize + 7);
unsigned char* recv_buffer = alloca(2 * 16 * blocksize);
while(remaining)
{
@ -364,7 +367,6 @@ static int avrftdi_transmit_bb(PROGRAMMER * pgm, unsigned char mode, const unsig
// (8*2) outputs per data byte, 6 transmit bytes per output (SET_BITS_LOW/HIGH),
// (8*1) inputs per data byte, 2 transmit bytes per input (GET_BITS_LOW/HIGH),
// 1x SEND_IMMEDIATE
unsigned char send_buffer[(8*2*6)*transfer_size+(8*1*2)*transfer_size+7];
int len = 0;
int i;
@ -384,7 +386,6 @@ static int avrftdi_transmit_bb(PROGRAMMER * pgm, unsigned char mode, const unsig
E(ftdi_write_data(pdata->ftdic, send_buffer, len) != len, pdata->ftdic);
if (mode & MPSSE_DO_READ) {
unsigned char recv_buffer[2*16*transfer_size];
int n;
int k = 0;
do {
@ -761,7 +762,11 @@ static int avrftdi_open(PROGRAMMER * pgm, char *port)
pdata->tx_buffer_size = 1024;
break;
#else
#ifdef _MSC_VER
#pragma message("No support for 232H, use a newer libftdi, version >= 0.20")
#else
#warning No support for 232H, use a newer libftdi, version >= 0.20
#endif
#endif
case TYPE_4232H:
pdata->pin_limit = 8;
@ -953,10 +958,12 @@ static int avrftdi_eeprom_read(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
unsigned int page_size, unsigned int addr, unsigned int len)
{
unsigned char cmd[4];
unsigned char buffer[len], *bufptr = buffer;
unsigned int add;
unsigned char* buffer = alloca(len);
unsigned char* bufptr = buffer;
memset(buffer, 0, len);
memset(buffer, 0, sizeof(buffer));
for (add = addr; add < addr + len; add++)
{
memset(cmd, 0, sizeof(cmd));
@ -980,13 +987,14 @@ static int avrftdi_flash_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int word;
unsigned int poll_index;
unsigned int buf_size;
unsigned char poll_byte;
unsigned char *buffer = &m->buf[addr];
unsigned char buf[4*len+4], *bufptr = buf;
unsigned int buf_size = 4 * len + 4;
unsigned char* buf = alloca(buf_size);
unsigned char* bufptr = buf;
memset(buf, 0, sizeof(buf));
memset(buf, 0, buf_size);
/* pre-check opcodes */
if (m->op[AVR_OP_LOADPAGE_LO] == NULL) {
@ -1102,13 +1110,13 @@ static int avrftdi_flash_read(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
int use_lext_address = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
unsigned int address = addr/2;
unsigned char o_buf[4*len+4];
unsigned char i_buf[4*len+4];
unsigned int buf_size = 4 * len + 4;
unsigned char* o_buf = alloca(buf_size);
unsigned char* i_buf = alloca(buf_size);
unsigned int index;
memset(o_buf, 0, sizeof(o_buf));
memset(i_buf, 0, sizeof(i_buf));
memset(o_buf, 0, buf_size);
memset(i_buf, 0, buf_size);
/* pre-check opcodes */
if (m->op[AVR_OP_READ_LO] == NULL) {

View File

@ -12,11 +12,14 @@
# include <libftdi1/ftdi.h>
# undef HAVE_LIBFTDI_TYPE_232H
# define HAVE_LIBFTDI_TYPE_232H 1
#elif defined(HAVE_LIBFTDI) && defined(HAVE_USB_H)
/* ftdi.h includes usb.h */
#elif defined(HAVE_LIBFTDI)
#include <ftdi.h>
#else
#ifdef _MSC_VER
#pragma message("No libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.")
#else
#warning No libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.
#endif
#define DO_NOT_BUILD_AVRFTDI
#endif

View File

@ -103,11 +103,28 @@ avrftdi_tpi_initialize(PROGRAMMER * pgm, AVRPART * p)
#define TPI_PARITY_MASK 0x2000
static inline int count1s(unsigned int x)
{
#if defined(__GNUC__)
return __builtin_popcount(x);
#else
int count = 0;
while (x)
{
count += x & 1;
x >>= 1;
}
return count;
#endif
}
static uint16_t
tpi_byte2frame(uint8_t byte)
{
uint16_t frame = 0xc00f;
int parity = __builtin_popcount(byte) & 1;
int parity = count1s(byte) & 1;
frame |= ((byte << 5) & 0x1fe0);
@ -123,7 +140,7 @@ tpi_frame2byte(uint16_t frame, uint8_t * byte)
/* drop idle and start bit(s) */
*byte = (frame >> 5) & 0xff;
int parity = __builtin_popcount(*byte) & 1;
int parity = count1s(*byte) & 1;
int parity_rcvd = (frame & TPI_PARITY_MASK) ? 1 : 0;
return parity != parity_rcvd;

View File

@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* $Id$ */
/* $Id$ */
#include "ac_cfg.h"
@ -28,9 +28,12 @@
#include <unistd.h>
#include <errno.h>
#if !defined(WIN32NATIVE)
# include <signal.h>
# include <sys/time.h>
#if defined(WIN32)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <signal.h>
#include <sys/time.h>
#endif
#include "avrdude.h"
@ -43,7 +46,7 @@
static int delay_decrement;
#if defined(WIN32NATIVE)
#if defined(WIN32)
static int has_perfcount;
static LARGE_INTEGER freq;
#else
@ -57,14 +60,14 @@ static void alarmhandler(int signo)
done = 1;
signal(SIGALRM, saved_alarmhandler);
}
#endif /* WIN32NATIVE */
#endif /* WIN32 */
/*
* Calibrate the microsecond delay loop below.
*/
static void bitbang_calibrate_delay(void)
{
#if defined(WIN32NATIVE)
#if defined(WIN32)
/*
* If the hardware supports a high-resolution performance counter,
* we ultimately prefer that one, as it gives quite accurate delays
@ -91,7 +94,7 @@ static void bitbang_calibrate_delay(void)
progname);
delay_decrement = 100;
}
#else /* !WIN32NATIVE */
#else /* !WIN32 */
struct itimerval itv;
volatile int i;
@ -124,7 +127,7 @@ static void bitbang_calibrate_delay(void)
delay_decrement = -i / 100000;
avrdude_message(MSG_NOTICE2, " calibrated to %d cycles per us\n",
delay_decrement);
#endif /* WIN32NATIVE */
#endif /* WIN32 */
}
/*
@ -134,7 +137,7 @@ static void bitbang_calibrate_delay(void)
*/
void bitbang_delay(unsigned int us)
{
#if defined(WIN32NATIVE)
#if defined(WIN32)
LARGE_INTEGER countNow, countEnd;
if (has_perfcount)
@ -147,14 +150,14 @@ void bitbang_delay(unsigned int us)
}
else /* no performance counters -- run normal uncalibrated delay */
{
#endif /* WIN32NATIVE */
#endif /* WIN32 */
volatile unsigned int del = us * delay_decrement;
while (del > 0)
del--;
#if defined(WIN32NATIVE)
#if defined(WIN32)
}
#endif /* WIN32NATIVE */
#endif /* WIN32 */
}
/*

View File

@ -41,9 +41,6 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#if defined(WIN32NATIVE)
# include <malloc.h> /* for alloca() */
#endif
#include "avrdude.h"
#include "libavrdude.h"
@ -860,7 +857,8 @@ static int buspirate_cmd_ascii(struct programmer_t *pgm,
{
char buf[25];
char *rcvd;
int spi_write, spi_read, i = 0;
int i = 0;
unsigned int spi_write, spi_read;
snprintf(buf, sizeof(buf), "0x%02x 0x%02x 0x%02x 0x%02x\n",
cmd[0], cmd[1], cmd[2], cmd[3]);

View File

@ -35,18 +35,6 @@
/* ----- Functions ----- */
/* Define to 1 if you have the `usleep' function. */
#cmakedefine HAVE_USLEEP 1
/* Define to 1 if you have the `getaddrinfo' function. */
#cmakedefine HAVE_GETADDRINFO 1
/* Define to 1 if you have the `gettimeofday' function. */
#cmakedefine HAVE_GETTIMEOFDAY 1
/* Define to 1 if you have the `strcasecmp' function. */
#cmakedefine HAVE_STRCASECMP 1
/* Define if lex/flex has yylex_destroy */
#cmakedefine HAVE_YYLEX_DESTROY 1
@ -61,15 +49,6 @@
/* Define to 1 if the system has the type `ulong_t'. */
#cmakedefine HAVE_ULONG_T 1
/* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#cmakedefine HAVE_STDLIB_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#cmakedefine HAVE_INTTYPES_H 1
/* Define if ELF support is enabled via libelf */
#cmakedefine HAVE_LIBELF 1
@ -120,9 +99,3 @@
/* Define to 1 if you have the `readline' library (-lreadline). */
#cmakedefine HAVE_LIBREADLINE 1
/* Define to 1 if you have the `ws2_32' library (-lws2_32). */
#cmakedefine HAVE_LIBWS2_32 1
/* Define to 1 if you have the <netinet/in.h> header file. */
#cmakedefine HAVE_NETINET_IN_H 1

View File

@ -30,7 +30,7 @@
#include "libavrdude.h"
#include "config.h"
#if defined(WIN32NATIVE)
#if defined(WIN32)
#define strtok_r( _s, _sep, _lasts ) \
( *(_lasts) = strtok( (_s), (_sep) ) )
#endif
@ -285,7 +285,7 @@ prog_def :
id = ldata(lfirst(current_prog->id));
existing_prog = locate_programmer(programmers, id);
if (existing_prog) {
{ /* temporarly set lineno to lineno of programmer start */
{ /* temporarily set lineno to lineno of programmer start */
int temp = lineno; lineno = current_prog->lineno;
yywarning("programmer %s overwrites previous definition %s:%d.",
id, existing_prog->config_file, existing_prog->lineno);
@ -377,7 +377,7 @@ part_def :
existing_part = locate_part(part_list, current_part->id);
if (existing_part) {
{ /* temporarly set lineno to lineno of part start */
{ /* temporarily set lineno to lineno of part start */
int temp = lineno; lineno = current_part->lineno;
yywarning("part %s overwrites previous definition %s:%d.",
current_part->id,

View File

@ -228,23 +228,15 @@ AC_HEADER_TIME
AC_CHECK_HEADERS([netinet/in.h])
# WinSock2
AC_CHECK_LIB([ws2_32], [puts])
# Checks for library functions.
AC_CHECK_FUNCS([memset select strcasecmp strdup strerror strncasecmp strtol strtoul gettimeofday usleep getaddrinfo])
AC_MSG_CHECKING([for a Win32 HID libray])
AC_MSG_CHECKING([for a Win32 HID library])
SAVED_LIBS="${LIBS}"
case $target in
*-*-mingw32* | *-*-cygwin* | *-*-windows*)
LIBHID="-lhid -lsetupapi"
if test $ac_cv_header_ddk_hidsdi_h = yes
then
HIDINCLUDE="#include <ddk/hidsdi.h>"
else
HIDINCLUDE="#include \"my_ddk_hidsdi.h\""
fi
HIDINCLUDE="#include <hidsdi.h>"
;;
*)
LIBHID=""
@ -435,7 +427,7 @@ else
fi
# If we are compiling with gcc, enable all warning and make warnings errors.
# If we are compiling with gcc, enable all warnings and make warnings errors.
if test "$GCC" = yes; then
ENABLE_WARNINGS="-Wall"
@ -519,7 +511,7 @@ AC_CONFIG_FILES([
# The procedure to create avrdude.conf involves two steps. First,
# normal autoconf substitution will be applied, resulting in
# avrdude.conf.tmp. Finally, a sed command will be applied to filter
# avrdude.conf.tmp. Finally, a sed command will be applied to filter
# out unwanted parts (currently the parallel port programmer types)
# based on previous configuration results, thereby producing the final
# avrdude.conf file.

View File

@ -20,35 +20,29 @@
#include "avrdude.h"
#include "libavrdude.h"
#if defined(WIN32NATIVE)
#if defined(WIN32)
#include <limits.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
static char *filename;
void win_sys_config_set(char sys_config[PATH_MAX])
{
sys_config[0] = 0;
/* Use Windows API call to search for the Windows default system config file.*/
SearchPath(NULL, "avrdude.conf", NULL, PATH_MAX, sys_config, &filename);
SearchPath(NULL, SYSTEM_CONF_FILE, NULL, PATH_MAX, sys_config, &filename);
return;
}
void win_usr_config_set(char usr_config[PATH_MAX])
{
usr_config[0] = 0;
/* Use Windows API call to search for the Windows default user config file. */
SearchPath(NULL, "avrdude.rc", NULL, PATH_MAX, usr_config, &filename);
SearchPath(NULL, USER_CONF_FILE, NULL, PATH_MAX, usr_config, &filename);
return;
}
#endif

View File

@ -61,7 +61,7 @@ struct dfu_dev
#else
struct dfu_dev {
// empty
int dummy;
};
#endif

View File

@ -1,26 +0,0 @@
- Man page needs updated for avr910 info.
- Website needs to link to docs:
http://savannah.nongnu.org/download/avrdude/doc/avrdude-html/
- Add "skip empty pages" optimization on avr910 paged write. The stk500 has
this optimization already.
- Fix "overfull \hbox" issues in building documentation.
- FIXME: term.c: terminal_get_input(): strip newlines in non-readline input
code.
- FIXME: avr910.c: avr910_cmd(): Insert version check here.
- FIXME: ser_posix.c: serial_close(): Should really restore the terminal to
original state here.
- FIXME: main.c, par.c: exitspecs don't work if RESET-pin is controlled over
PPICTRL.
- transfer ppi-speedtuning to the windows version (CAVEAT: This will make
programming too fast for chips with 500kHz clock)
- make SCK-period configurable for PPI-programmers

View File

@ -327,6 +327,12 @@ use the @code{-V} option to prevent AVRDUDE from verifing the flash memory.
See the section on @emph{extended parameters}
below for Micronucleus specific options.
The Teensy bootloader is supported for all AVR boards.
As the bootloader does not support reading from flash memory,
use the @code{-V} option to prevent AVRDUDE from verifing the flash memory.
See the section on @emph{extended parameters}
below for Teensy specific options.
@menu
* History::
@end menu
@ -992,6 +998,18 @@ If no time-out is specified, AVRDUDE will wait indefinitely until the
device is plugged in.
@end table
@item Teensy bootloader
When using the Teensy programmer type, the
following optional extended parameter is accepted:
@table @code
@item @samp{wait=@var{timeout}}
If the device is not connected, wait for the device to be plugged in.
The optional @var{timeout} specifies the connection time-out in seconds.
If no time-out is specified, AVRDUDE will wait indefinitely until the
device is plugged in.
@end table
@item Wiring
When using the Wiring programmer type, the

View File

@ -35,7 +35,7 @@
#include <libelf/libelf.h>
#endif
#ifndef EM_AVR32
# define EM_AVR32 0x18ad /* inofficial */
# define EM_AVR32 0x18ad /* unofficial */
#endif
#endif
@ -273,9 +273,9 @@ static int ihex_readrec(struct ihexrec * ihex, char * rec)
/*
* Intel Hex to binary buffer
*
* Given an open file 'inf' which contains Intel Hex formated data,
* Given an open file 'inf' which contains Intel Hex formatted data,
* parse the file and lay it out within the memory buffer pointed to
* by outbuf. The size of outbuf, 'bufsize' is honored; if data would
* by outbuf. The size of outbuf, 'bufsize' is honored; if data would
* fall outsize of the memory buffer outbuf, an error is generated.
*
* Return the maximum memory address within 'outbuf' that was written.
@ -1120,7 +1120,7 @@ static int fileio_imm(struct fioparms * fio,
p = strtok(filename, " ,");
while (p != NULL && loc < size) {
b = strtoul(p, &e, 0);
/* check for binary formated (0b10101001) strings */
/* check for binary formatted (0b10101001) strings */
b = (strncmp (p, "0b", 2))?
strtoul (p, &e, 0):
strtoul (p + 2, &e, 2);
@ -1369,7 +1369,7 @@ static int fmt_autodetect(char * fname)
int found;
int first = 1;
#if defined(WIN32NATIVE)
#if defined(WIN32)
f = fopen(fname, "r");
#else
f = fopen(fname, "rb");
@ -1518,7 +1518,7 @@ int fileio(int op, char * filename, FILEFMT format,
}
}
#if defined(WIN32NATIVE)
#if defined(WIN32)
/* Open Raw Binary and ELF format in binary mode on Windows.*/
if(format == FMT_RBIN || format == FMT_ELF)
{

View File

@ -23,6 +23,7 @@
#include "ac_cfg.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -30,13 +31,6 @@
#include <limits.h>
#include <unistd.h>
#if HAVE_STDINT_H
#include <stdint.h>
#elif HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#include "avrdude.h"
#include "libavrdude.h"

View File

@ -20,6 +20,7 @@
#include "ac_cfg.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -27,12 +28,6 @@
#include <limits.h>
#include <unistd.h>
#if HAVE_STDINT_H
#include <stdint.h>
#elif HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#include "avrdude.h"
#include "libavrdude.h"
@ -215,7 +210,7 @@ int flip2_initialize(PROGRAMMER* pgm, AVRPART *part)
/* A note about return values. Negative return values from this function are
* interpreted as failure by main(), from where this function is called.
* However such failures are interpreted as a device signature check failure
* and the user is adviced to use the -F option to override this check. In
* and the user is advised to use the -F option to override this check. In
* our case, this is misleading, so we defer reporting an error until another
* function is called. Thus, we always return 0 (success) from initialize().
* I don't like this, but I don't want to mess with main().
@ -617,7 +612,7 @@ int flip2_read_memory(struct dfu_dev *dfu,
return -1;
}
ptr += read_size;
ptr = (char*)ptr + read_size;
addr += read_size;
size -= read_size;
}
@ -680,7 +675,7 @@ int flip2_write_memory(struct dfu_dev *dfu,
return -1;
}
ptr += write_size;
ptr = (const char*)ptr + write_size;
addr += write_size;
size -= write_size;
}

View File

@ -73,10 +73,6 @@
#define TPIPCR_GT_0b 0x07
#define TPI_STOP_BITS 0x03
#if defined(_WIN32)
#include <windows.h>
#endif
#if defined(HAVE_LIBFTDI1) && defined(HAVE_LIBUSB_1_0)
# if defined(HAVE_LIBUSB_1_0_LIBUSB_H)
# include <libusb-1.0/libusb.h>
@ -84,11 +80,14 @@
# include <libusb.h>
# endif
# include <libftdi1/ftdi.h>
#elif defined(HAVE_LIBFTDI) && defined(HAVE_USB_H)
/* ftdi.h includes usb.h */
#elif defined(HAVE_LIBFTDI)
#include <ftdi.h>
#else
#ifdef _MSC_VER
#pragma message("No libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.")
#else
#warning No libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.
#endif
#define DO_NOT_BUILD_FT245R
#endif

View File

@ -27,15 +27,9 @@
#include <stdio.h>
#include <limits.h>
#include <stdbool.h>
/* lets try to select at least 32 bits */
#ifdef HAVE_STDINT_H
#include <stdint.h>
typedef uint32_t pinmask_t;
#else
#error Need a C99 capable compiler
#endif
typedef uint32_t pinmask_t;
/* formerly lists.h */
@ -958,7 +952,7 @@ int read_config(const char * file);
/* formerly confwin.h */
#if defined(WIN32NATIVE)
#if defined(WIN32)
#ifdef __cplusplus
extern "C" {
@ -971,7 +965,7 @@ void win_usr_config_set(char usr_config[PATH_MAX]);
}
#endif
#endif /* WIN32NATIVE */
#endif /* WIN32 */
#endif /* libavrdude_h */

View File

@ -66,7 +66,7 @@ static int fd_spidev, fd_gpiochip, fd_linehandle;
/**
* @brief Sends/receives a message in full duplex mode
* @return -1 on failure, otherwise number of bytes sent/recieved
* @return -1 on failure, otherwise number of bytes sent/received
*/
static int linuxspi_spi_duplex(PROGRAMMER *pgm, const unsigned char *tx, unsigned char *rx, int len)
{

View File

@ -302,6 +302,17 @@ static void cleanup_main(void)
cleanup_config();
}
static void replace_backslashes(char *s)
{
// Replace all backslashes with forward slashes
for (int i = 0; i < strlen(s); i++) {
if (s[i] == '\\') {
s[i] = '/';
}
}
}
/*
* main routine
*/
@ -351,7 +362,7 @@ int main(int argc, char * argv [])
char * safemode_response;
int fuses_updated = 0;
#if !defined(WIN32NATIVE)
#if !defined(WIN32)
char * homedir;
#endif
@ -362,12 +373,14 @@ int main(int argc, char * argv [])
setvbuf(stdout, (char*)NULL, _IOLBF, 0);
setvbuf(stderr, (char*)NULL, _IOLBF, 0);
sys_config[0] = '\0';
progname = strrchr(argv[0],'/');
#if defined (WIN32NATIVE)
#if defined (WIN32)
/* take care of backslash as dir sep in W32 */
if (!progname) progname = strrchr(argv[0],'\\');
#endif /* WIN32NATIVE */
#endif /* WIN32 */
if (progname)
progname++;
@ -422,131 +435,6 @@ int main(int argc, char * argv [])
is_open = 0;
logfile = NULL;
/*
* EXECUTABLE ABSPATH
* ------------------
* Determine the absolute path to avrdude executable. This will be used to
* locate the 'avrdude.conf' file later.
*/
int executable_dirpath_len;
int executable_abspath_len = wai_getExecutablePath(
executable_abspath,
PATH_MAX,
&executable_dirpath_len
);
if (
(executable_abspath_len != -1) &&
(executable_abspath_len != 0) &&
(executable_dirpath_len != -1) &&
(executable_dirpath_len != 0)
) {
// All requirements satisfied, executable path was found
executable_abspath_found = true;
// Make sure the string is null terminated
executable_abspath[executable_abspath_len] = '\0';
// Replace all backslashes with forward slashes
i = 0;
while (true) {
if (executable_abspath[i] == '\0') {
break;
}
if (executable_abspath[i] == '\\') {
executable_abspath[i] = '/';
}
i++;
}
// Define 'executable_dirpath' to be the path to the parent folder of the
// executable.
strcpy(executable_dirpath, executable_abspath);
executable_dirpath[executable_dirpath_len] = '\0';
// Debug output
// avrdude_message(MSG_INFO, "executable_abspath = %s\n", executable_abspath);
// avrdude_message(MSG_INFO, "executable_abspath_len = %i\n", executable_abspath_len);
// avrdude_message(MSG_INFO, "executable_dirpath = %s\n", executable_dirpath);
// avrdude_message(MSG_INFO, "executable_dirpath_len = %i\n", executable_dirpath_len);
}
/*
* SYSTEM CONFIG
* -------------
* Determine the location of 'avrdude.conf'. Check in this order:
* 1. <dirpath of executable>/../etc/avrdude.conf
* 2. <dirpath of executable>/avrdude.conf
* 3. CONFIG_DIR/avrdude.conf
*
* When found, write the result into the 'sys_config' variable.
*/
if (executable_abspath_found) {
// 1. Check <dirpath of executable>/../etc/avrdude.conf
strcpy(sys_config, executable_dirpath);
sys_config[PATH_MAX - 1] = '\0';
i = strlen(sys_config);
if (i && (sys_config[i - 1] != '/'))
strcat(sys_config, "/");
strcat(sys_config, "../etc/avrdude.conf");
sys_config[PATH_MAX - 1] = '\0';
if (access(sys_config, F_OK) == 0) {
sys_config_found = true;
}
else {
// 2. Check <dirpath of executable>/avrdude.conf
strcpy(sys_config, executable_dirpath);
sys_config[PATH_MAX - 1] = '\0';
i = strlen(sys_config);
if (i && (sys_config[i - 1] != '/'))
strcat(sys_config, "/");
strcat(sys_config, "avrdude.conf");
sys_config[PATH_MAX - 1] = '\0';
if (access(sys_config, F_OK) == 0) {
sys_config_found = true;
}
}
}
if (!sys_config_found) {
// 3. Check CONFIG_DIR/avrdude.conf
#if defined(WIN32NATIVE)
win_sys_config_set(sys_config);
#else
strcpy(sys_config, CONFIG_DIR);
i = strlen(sys_config);
if (i && (sys_config[i - 1] != '/'))
strcat(sys_config, "/");
strcat(sys_config, "avrdude.conf");
#endif
if (access(sys_config, F_OK) == 0) {
sys_config_found = true;
}
}
// Debug output
// avrdude_message(MSG_INFO, "sys_config = %s\n", sys_config);
// avrdude_message(MSG_INFO, "sys_config_found = %s\n", sys_config_found ? "true" : "false");
// avrdude_message(MSG_INFO, "\n");
/*
* USER CONFIG
* -----------
* Determine the location of '.avrduderc'. Nothing changed here.
*/
#if defined(WIN32NATIVE)
win_usr_config_set(usr_config);
#else
usr_config[0] = 0;
homedir = getenv("HOME");
if (homedir != NULL) {
strcpy(usr_config, homedir);
i = strlen(usr_config);
if (i && (usr_config[i - 1] != '/'))
strcat(usr_config, "/");
strcat(usr_config, ".avrduderc");
}
#endif
len = strlen(progname) + 2;
for (i=0; i<len; i++)
progbuf[i] = ' ';
@ -764,6 +652,122 @@ int main(int argc, char * argv [])
}
}
/* search for system configuration file unless -C conffile was given */
if (strlen(sys_config) == 0) {
/*
* EXECUTABLE ABSPATH
* ------------------
* Determine the absolute path to avrdude executable. This will be used to
* locate the 'avrdude.conf' file later.
*/
int executable_dirpath_len;
int executable_abspath_len = wai_getExecutablePath(
executable_abspath,
PATH_MAX,
&executable_dirpath_len
);
if (
(executable_abspath_len != -1) &&
(executable_abspath_len != 0) &&
(executable_dirpath_len != -1) &&
(executable_dirpath_len != 0)
) {
// All requirements satisfied, executable path was found
executable_abspath_found = true;
// Make sure the string is null terminated
executable_abspath[executable_abspath_len] = '\0';
replace_backslashes(executable_abspath);
// Define 'executable_dirpath' to be the path to the parent folder of the
// executable.
strcpy(executable_dirpath, executable_abspath);
executable_dirpath[executable_dirpath_len] = '\0';
// Debug output
avrdude_message(MSG_DEBUG, "executable_abspath = %s\n", executable_abspath);
avrdude_message(MSG_DEBUG, "executable_abspath_len = %i\n", executable_abspath_len);
avrdude_message(MSG_DEBUG, "executable_dirpath = %s\n", executable_dirpath);
avrdude_message(MSG_DEBUG, "executable_dirpath_len = %i\n", executable_dirpath_len);
}
/*
* SYSTEM CONFIG
* -------------
* Determine the location of 'avrdude.conf'. Check in this order:
* 1. <dirpath of executable>/../etc/avrdude.conf
* 2. <dirpath of executable>/avrdude.conf
* 3. CONFIG_DIR/avrdude.conf
*
* When found, write the result into the 'sys_config' variable.
*/
if (executable_abspath_found) {
// 1. Check <dirpath of executable>/../etc/avrdude.conf
strcpy(sys_config, executable_dirpath);
sys_config[PATH_MAX - 1] = '\0';
i = strlen(sys_config);
if (i && (sys_config[i - 1] != '/'))
strcat(sys_config, "/");
strcat(sys_config, "../etc/" SYSTEM_CONF_FILE);
sys_config[PATH_MAX - 1] = '\0';
if (access(sys_config, F_OK) == 0) {
sys_config_found = true;
}
else {
// 2. Check <dirpath of executable>/avrdude.conf
strcpy(sys_config, executable_dirpath);
sys_config[PATH_MAX - 1] = '\0';
i = strlen(sys_config);
if (i && (sys_config[i - 1] != '/'))
strcat(sys_config, "/");
strcat(sys_config, SYSTEM_CONF_FILE);
sys_config[PATH_MAX - 1] = '\0';
if (access(sys_config, F_OK) == 0) {
sys_config_found = true;
}
}
}
if (!sys_config_found) {
// 3. Check CONFIG_DIR/avrdude.conf
#if defined(WIN32)
win_sys_config_set(sys_config);
#else
strcpy(sys_config, CONFIG_DIR);
i = strlen(sys_config);
if (i && (sys_config[i - 1] != '/'))
strcat(sys_config, "/");
strcat(sys_config, SYSTEM_CONF_FILE);
#endif
if (access(sys_config, F_OK) == 0) {
sys_config_found = true;
}
}
}
// Debug output
avrdude_message(MSG_DEBUG, "sys_config = %s\n", sys_config);
avrdude_message(MSG_DEBUG, "sys_config_found = %s\n", sys_config_found ? "true" : "false");
avrdude_message(MSG_DEBUG, "\n");
/*
* USER CONFIG
* -----------
* Determine the location of '.avrduderc'.
*/
#if defined(WIN32)
win_usr_config_set(usr_config);
#else
usr_config[0] = 0;
homedir = getenv("HOME");
if (homedir != NULL) {
strcpy(usr_config, homedir);
i = strlen(usr_config);
if (i && (usr_config[i - 1] != '/'))
strcat(usr_config, "/");
strcat(usr_config, USER_CONF_FILE);
}
#endif
if (quell_progress == 0) {
if (isatty (STDERR_FILENO))
update_progress = update_progress_tty;
@ -1109,7 +1113,7 @@ int main(int argc, char * argv [])
pgm->vfy_led(pgm, OFF);
/*
* initialize the chip in preperation for accepting commands
* initialize the chip in preparation for accepting commands
*/
init_ok = (rc = pgm->initialize(pgm, p)) >= 0;
if (!init_ok) {

View File

@ -119,7 +119,10 @@ static int micronucleus_check_connection(pdata_t* pdata)
int result = usb_control_msg(
pdata->usb_handle,
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
MICRONUCLEUS_CMD_INFO, 0, 0, (char*)buffer, sizeof(buffer), MICRONUCLEUS_DEFAULT_TIMEOUT);
MICRONUCLEUS_CMD_INFO,
0, 0,
(char*)buffer, sizeof(buffer),
MICRONUCLEUS_DEFAULT_TIMEOUT);
return result == sizeof(buffer) ? 0 : -1;
}
else
@ -128,7 +131,10 @@ static int micronucleus_check_connection(pdata_t* pdata)
int result = usb_control_msg(
pdata->usb_handle,
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
MICRONUCLEUS_CMD_INFO, 0, 0, (char*)buffer, sizeof(buffer), MICRONUCLEUS_DEFAULT_TIMEOUT);
MICRONUCLEUS_CMD_INFO,
0, 0,
(char*)buffer, sizeof(buffer),
MICRONUCLEUS_DEFAULT_TIMEOUT);
return result == sizeof(buffer) ? 0 : -1;
}
}
@ -160,7 +166,10 @@ static int micronucleus_get_bootloader_info_v1(pdata_t* pdata)
int result = usb_control_msg(
pdata->usb_handle,
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
MICRONUCLEUS_CMD_INFO, 0, 0, (char*)buffer, sizeof(buffer), MICRONUCLEUS_DEFAULT_TIMEOUT);
MICRONUCLEUS_CMD_INFO,
0, 0,
(char*)buffer, sizeof(buffer),
MICRONUCLEUS_DEFAULT_TIMEOUT);
if (result < 0)
{
avrdude_message(MSG_INFO, "%s: WARNING: Failed to get bootloader info block: %s\n",
@ -226,7 +235,10 @@ static int micronucleus_get_bootloader_info_v2(pdata_t* pdata)
int result = usb_control_msg(
pdata->usb_handle,
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
MICRONUCLEUS_CMD_INFO, 0, 0, (char*)buffer, sizeof(buffer), MICRONUCLEUS_DEFAULT_TIMEOUT);
MICRONUCLEUS_CMD_INFO,
0, 0,
(char*)buffer, sizeof(buffer),
MICRONUCLEUS_DEFAULT_TIMEOUT);
if (result < 0)
{
avrdude_message(MSG_INFO, "%s: WARNING: Failed to get bootloader info block: %s\n",
@ -291,7 +303,10 @@ static int micronucleus_erase_device(pdata_t* pdata)
int result = usb_control_msg(
pdata->usb_handle,
USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
MICRONUCLEUS_CMD_ERASE, 0, 0, NULL, 0, MICRONUCLEUS_DEFAULT_TIMEOUT);
MICRONUCLEUS_CMD_ERASE,
0, 0,
NULL, 0,
MICRONUCLEUS_DEFAULT_TIMEOUT);
if (result < 0)
{
switch (result)
@ -391,11 +406,12 @@ static void micronucleus_patch_user_vector(pdata_t* pdata, uint8_t* buffer)
static int micronucleus_write_page_v1(pdata_t* pdata, uint32_t address, uint8_t* buffer, uint32_t size)
{
int result = usb_control_msg(pdata->usb_handle,
int result = usb_control_msg(
pdata->usb_handle,
USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
MICRONUCLEUS_CMD_TRANSFER,
size, address,
buffer, size,
(char*)buffer, size,
MICRONUCLEUS_DEFAULT_TIMEOUT);
if (result < 0)
{
@ -501,7 +517,10 @@ static int micronucleus_start(pdata_t* pdata)
int result = usb_control_msg(
pdata->usb_handle,
USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
MICRONUCLEUS_CMD_START, 0, 0, NULL, 0, MICRONUCLEUS_DEFAULT_TIMEOUT);
MICRONUCLEUS_CMD_START,
0, 0,
NULL, 0,
MICRONUCLEUS_DEFAULT_TIMEOUT);
if (result < 0)
{
avrdude_message(MSG_INFO, "%s: WARNING: Failed is issue start command: %s\n", progname, usb_strerror());

563
src/msvc/getopt.c Normal file
View File

@ -0,0 +1,563 @@
/* $OpenBSD: getopt_long.c,v 1.23 2007/10/31 12:34:57 chl Exp $ */
/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
/*
* Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Sponsored in part by the Defense Advanced Research Projects
* Agency (DARPA) and Air Force Research Laboratory, Air Force
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
*/
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Dieter Baron and Thomas Klausner.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#define WIN32_LEAN_AND_MEAN
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <stdarg.h>
#include <stdio.h>
#include <windows.h>
#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */
#ifdef REPLACE_GETOPT
int opterr = 1; /* if error message should be printed */
int optind = 1; /* index into parent argv vector */
int optopt = '?'; /* character checked for validity */
#undef optreset /* see getopt.h */
#define optreset __mingw_optreset
int optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#endif
#define PRINT_ERROR ((opterr) && (*options != ':'))
#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
/* return values */
#define BADCH (int)'?'
#define BADARG ((*options == ':') ? (int)':' : (int)'?')
#define INORDER (int)1
#ifndef __CYGWIN__
#define __progname __argv[0]
#else
extern char __declspec(dllimport) *__progname;
#endif
#ifdef __CYGWIN__
static char EMSG[] = "";
#else
#define EMSG ""
#endif
static int getopt_internal(int, char * const *, const char *,
const struct option *, int *, int);
static int parse_long_options(char * const *, const char *,
const struct option *, int *, int);
static int gcd(int, int);
static void permute_args(int, int, int, char * const *);
static char *place = EMSG; /* option letter processing */
/* XXX: set optreset to 1 rather than these two */
static int nonopt_start = -1; /* first non option argument (for permute) */
static int nonopt_end = -1; /* first option after non options (for permute) */
/* Error messages */
static const char recargchar[] = "option requires an argument -- %c";
static const char recargstring[] = "option requires an argument -- %s";
static const char ambig[] = "ambiguous option -- %.*s";
static const char noarg[] = "option doesn't take an argument -- %.*s";
static const char illoptchar[] = "unknown option -- %c";
static const char illoptstring[] = "unknown option -- %s";
static void
_vwarnx(const char *fmt,va_list ap)
{
(void)fprintf(stderr,"%s: ",__progname);
if (fmt != NULL)
(void)vfprintf(stderr,fmt,ap);
(void)fprintf(stderr,"\n");
}
static void
warnx(const char *fmt,...)
{
va_list ap;
va_start(ap,fmt);
_vwarnx(fmt,ap);
va_end(ap);
}
/*
* Compute the greatest common divisor of a and b.
*/
static int
gcd(int a, int b)
{
int c;
c = a % b;
while (c != 0) {
a = b;
b = c;
c = a % b;
}
return (b);
}
/*
* Exchange the block from nonopt_start to nonopt_end with the block
* from nonopt_end to opt_end (keeping the same order of arguments
* in each block).
*/
static void
permute_args(int panonopt_start, int panonopt_end, int opt_end,
char * const *nargv)
{
int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
char *swap;
/*
* compute lengths of blocks and number and size of cycles
*/
nnonopts = panonopt_end - panonopt_start;
nopts = opt_end - panonopt_end;
ncycle = gcd(nnonopts, nopts);
cyclelen = (opt_end - panonopt_start) / ncycle;
for (i = 0; i < ncycle; i++) {
cstart = panonopt_end+i;
pos = cstart;
for (j = 0; j < cyclelen; j++) {
if (pos >= panonopt_end)
pos -= nnonopts;
else
pos += nopts;
swap = nargv[pos];
/* LINTED const cast */
((char **) nargv)[pos] = nargv[cstart];
/* LINTED const cast */
((char **)nargv)[cstart] = swap;
}
}
}
/*
* parse_long_options --
* Parse long options in argc/argv argument vector.
* Returns -1 if short_too is set and the option does not match long_options.
*/
static int
parse_long_options(char * const *nargv, const char *options,
const struct option *long_options, int *idx, int short_too)
{
char *current_argv, *has_equal;
size_t current_argv_len;
int i, ambiguous, match;
#define IDENTICAL_INTERPRETATION(_x, _y) \
(long_options[(_x)].has_arg == long_options[(_y)].has_arg && \
long_options[(_x)].flag == long_options[(_y)].flag && \
long_options[(_x)].val == long_options[(_y)].val)
current_argv = place;
match = -1;
ambiguous = 0;
optind++;
if ((has_equal = strchr(current_argv, '=')) != NULL) {
/* argument found (--option=arg) */
current_argv_len = has_equal - current_argv;
has_equal++;
} else
current_argv_len = strlen(current_argv);
for (i = 0; long_options[i].name; i++) {
/* find matching long option */
if (strncmp(current_argv, long_options[i].name,
current_argv_len))
continue;
if (strlen(long_options[i].name) == current_argv_len) {
/* exact match */
match = i;
ambiguous = 0;
break;
}
/*
* If this is a known short option, don't allow
* a partial match of a single character.
*/
if (short_too && current_argv_len == 1)
continue;
if (match == -1) /* partial match */
match = i;
else if (!IDENTICAL_INTERPRETATION(i, match))
ambiguous = 1;
}
if (ambiguous) {
/* ambiguous abbreviation */
if (PRINT_ERROR)
warnx(ambig, (int)current_argv_len,
current_argv);
optopt = 0;
return (BADCH);
}
if (match != -1) { /* option found */
if (long_options[match].has_arg == no_argument
&& has_equal) {
if (PRINT_ERROR)
warnx(noarg, (int)current_argv_len,
current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
optopt = long_options[match].val;
else
optopt = 0;
return (BADARG);
}
if (long_options[match].has_arg == required_argument ||
long_options[match].has_arg == optional_argument) {
if (has_equal)
optarg = has_equal;
else if (long_options[match].has_arg ==
required_argument) {
/*
* optional argument doesn't use next nargv
*/
optarg = nargv[optind++];
}
}
if ((long_options[match].has_arg == required_argument)
&& (optarg == NULL)) {
/*
* Missing argument; leading ':' indicates no error
* should be generated.
*/
if (PRINT_ERROR)
warnx(recargstring,
current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
optopt = long_options[match].val;
else
optopt = 0;
--optind;
return (BADARG);
}
} else { /* unknown option */
if (short_too) {
--optind;
return (-1);
}
if (PRINT_ERROR)
warnx(illoptstring, current_argv);
optopt = 0;
return (BADCH);
}
if (idx)
*idx = match;
if (long_options[match].flag) {
*long_options[match].flag = long_options[match].val;
return (0);
} else
return (long_options[match].val);
#undef IDENTICAL_INTERPRETATION
}
/*
* getopt_internal --
* Parse argc/argv argument vector. Called by user level routines.
*/
static int
getopt_internal(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx, int flags)
{
char *oli; /* option letter list index */
int optchar, short_too;
static int posixly_correct = -1;
if (options == NULL)
return (-1);
/*
* XXX Some GNU programs (like cvs) set optind to 0 instead of
* XXX using optreset. Work around this braindamage.
*/
if (optind == 0)
optind = optreset = 1;
/*
* Disable GNU extensions if POSIXLY_CORRECT is set or options
* string begins with a '+'.
*
* CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or
* optreset != 0 for GNU compatibility.
*/
if (posixly_correct == -1 || optreset != 0)
posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
if (*options == '-')
flags |= FLAG_ALLARGS;
else if (posixly_correct || *options == '+')
flags &= ~FLAG_PERMUTE;
if (*options == '+' || *options == '-')
options++;
optarg = NULL;
if (optreset)
nonopt_start = nonopt_end = -1;
start:
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc) { /* end of argument vector */
place = EMSG;
if (nonopt_end != -1) {
/* do permutation, if we have to */
permute_args(nonopt_start, nonopt_end,
optind, nargv);
optind -= nonopt_end - nonopt_start;
}
else if (nonopt_start != -1) {
/*
* If we skipped non-options, set optind
* to the first of them.
*/
optind = nonopt_start;
}
nonopt_start = nonopt_end = -1;
return (-1);
}
if (*(place = nargv[optind]) != '-' ||
(place[1] == '\0' && strchr(options, '-') == NULL)) {
place = EMSG; /* found non-option */
if (flags & FLAG_ALLARGS) {
/*
* GNU extension:
* return non-option as argument to option 1
*/
optarg = nargv[optind++];
return (INORDER);
}
if (!(flags & FLAG_PERMUTE)) {
/*
* If no permutation wanted, stop parsing
* at first non-option.
*/
return (-1);
}
/* do permutation */
if (nonopt_start == -1)
nonopt_start = optind;
else if (nonopt_end != -1) {
permute_args(nonopt_start, nonopt_end,
optind, nargv);
nonopt_start = optind -
(nonopt_end - nonopt_start);
nonopt_end = -1;
}
optind++;
/* process next argument */
goto start;
}
if (nonopt_start != -1 && nonopt_end == -1)
nonopt_end = optind;
/*
* If we have "-" do nothing, if "--" we are done.
*/
if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
optind++;
place = EMSG;
/*
* We found an option (--), so if we skipped
* non-options, we have to permute.
*/
if (nonopt_end != -1) {
permute_args(nonopt_start, nonopt_end,
optind, nargv);
optind -= nonopt_end - nonopt_start;
}
nonopt_start = nonopt_end = -1;
return (-1);
}
}
/*
* Check long options if:
* 1) we were passed some
* 2) the arg is not just "-"
* 3) either the arg starts with -- we are getopt_long_only()
*/
if (long_options != NULL && place != nargv[optind] &&
(*place == '-' || (flags & FLAG_LONGONLY))) {
short_too = 0;
if (*place == '-')
place++; /* --foo long option */
else if (*place != ':' && strchr(options, *place) != NULL)
short_too = 1; /* could be short option too */
optchar = parse_long_options(nargv, options, long_options,
idx, short_too);
if (optchar != -1) {
place = EMSG;
return (optchar);
}
}
if ((optchar = (int)*place++) == (int)':' ||
(optchar == (int)'-' && *place != '\0') ||
(oli = strchr(options, optchar)) == NULL) {
/*
* If the user specified "-" and '-' isn't listed in
* options, return -1 (non-option) as per POSIX.
* Otherwise, it is an unknown option character (or ':').
*/
if (optchar == (int)'-' && *place == '\0')
return (-1);
if (!*place)
++optind;
if (PRINT_ERROR)
warnx(illoptchar, optchar);
optopt = optchar;
return (BADCH);
}
if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
/* -W long-option */
if (*place) /* no space */
/* NOTHING */;
else if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else /* white space */
place = nargv[optind];
optchar = parse_long_options(nargv, options, long_options,
idx, 0);
place = EMSG;
return (optchar);
}
if (*++oli != ':') { /* doesn't take argument */
if (!*place)
++optind;
} else { /* takes (optional) argument */
optarg = NULL;
if (*place) /* no white space */
optarg = place;
else if (oli[1] != ':') { /* arg not optional */
if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else
optarg = nargv[optind];
}
place = EMSG;
++optind;
}
/* dump back option letter */
return (optchar);
}
#ifdef REPLACE_GETOPT
/*
* getopt --
* Parse argc/argv argument vector.
*
* [eventually this will replace the BSD getopt]
*/
int
getopt(int nargc, char * const *nargv, const char *options)
{
/*
* We don't pass FLAG_PERMUTE to getopt_internal() since
* the BSD getopt(3) (unlike GNU) has never done this.
*
* Furthermore, since many privileged programs call getopt()
* before dropping privileges it makes sense to keep things
* as simple (and bug-free) as possible.
*/
return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
}
#endif /* REPLACE_GETOPT */
/*
* getopt_long --
* Parse argc/argv argument vector.
*/
int
getopt_long(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx)
{
return (getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE));
}
/*
* getopt_long_only --
* Parse argc/argv argument vector.
*/
int
getopt_long_only(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx)
{
return (getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE|FLAG_LONGONLY));
}

95
src/msvc/getopt.h Normal file
View File

@ -0,0 +1,95 @@
#ifndef __GETOPT_H__
/**
* DISCLAIMER
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
*
* The mingw-w64 runtime package and its code is distributed in the hope that it
* will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR
* IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to
* warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#define __GETOPT_H__
/* All the headers include this file. */
#include <crtdefs.h>
#ifdef __cplusplus
extern "C" {
#endif
extern int optind; /* index of first non-option in argv */
extern int optopt; /* single option character, as parsed */
extern int opterr; /* flag to enable built-in diagnostics... */
/* (user may set to zero, to suppress) */
extern char *optarg; /* pointer to argument of current option */
extern int getopt(int nargc, char * const *nargv, const char *options);
#ifdef _BSD_SOURCE
/*
* BSD adds the non-standard `optreset' feature, for reinitialisation
* of `getopt' parsing. We support this feature, for applications which
* proclaim their BSD heritage, before including this header; however,
* to maintain portability, developers are advised to avoid it.
*/
# define optreset __mingw_optreset
extern int optreset;
#endif
#ifdef __cplusplus
}
#endif
/*
* POSIX requires the `getopt' API to be specified in `unistd.h';
* thus, `unistd.h' includes this header. However, we do not want
* to expose the `getopt_long' or `getopt_long_only' APIs, when
* included in this manner. Thus, close the standard __GETOPT_H__
* declarations block, and open an additional __GETOPT_LONG_H__
* specific block, only when *not* __UNISTD_H_SOURCED__, in which
* to declare the extended API.
*/
#endif /* !defined(__GETOPT_H__) */
#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__)
#define __GETOPT_LONG_H__
#ifdef __cplusplus
extern "C" {
#endif
struct option /* specification for a long form option... */
{
const char *name; /* option name, without leading hyphens */
int has_arg; /* does it take an argument? */
int *flag; /* where to save its status, or NULL */
int val; /* its associated status value */
};
enum /* permitted values for its `has_arg' field... */
{
no_argument = 0, /* option never takes an argument */
required_argument, /* option always requires an argument */
optional_argument /* option may take an argument */
};
extern int getopt_long(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx);
extern int getopt_long_only(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx);
/*
* Previous MinGW implementation had...
*/
#ifndef HAVE_DECL_GETOPT
/*
* ...for the long form API only; keep this for compatibility.
*/
# define HAVE_DECL_GETOPT 1
#endif
#ifdef __cplusplus
}
#endif
#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */

77
src/msvc/gettimeofday.c Normal file
View File

@ -0,0 +1,77 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#define WIN32_LEAN_AND_MEAN
#include <time.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <errno.h>
#include <windows.h>
#define FILETIME_1970 116444736000000000ull /* seconds between 1/1/1601 and 1/1/1970 */
#define HECTONANOSEC_PER_SEC 10000000ull
int getntptimeofday(struct timespec *, struct timezone *);
int getntptimeofday(struct timespec *tp, struct timezone *z)
{
int res = 0;
union
{
unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
FILETIME ft;
} _now;
TIME_ZONE_INFORMATION TimeZoneInformation;
DWORD tzi;
if (z != NULL)
{
if ((tzi = GetTimeZoneInformation(&TimeZoneInformation)) != TIME_ZONE_ID_INVALID)
{
z->tz_minuteswest = TimeZoneInformation.Bias;
if (tzi == TIME_ZONE_ID_DAYLIGHT)
z->tz_dsttime = 1;
else
z->tz_dsttime = 0;
}
else
{
z->tz_minuteswest = 0;
z->tz_dsttime = 0;
}
}
if (tp != NULL)
{
GetSystemTimeAsFileTime(&_now.ft); /* 100-nanoseconds since 1-1-1601 */
/* The actual accuracy on XP seems to be 125,000 nanoseconds = 125 microseconds = 0.125 milliseconds */
_now.ns100 -= FILETIME_1970; /* 100 nano-seconds since 1-1-1970 */
tp->tv_sec = _now.ns100 / HECTONANOSEC_PER_SEC; /* seconds since 1-1-1970 */
tp->tv_nsec = (long)(_now.ns100 % HECTONANOSEC_PER_SEC) * 100; /* nanoseconds */
}
return res;
}
int __cdecl gettimeofday(struct timeval *p, void *z)
{
struct timespec tp;
if (getntptimeofday(&tp, (struct timezone *) z))
return -1;
p->tv_sec = (long)tp.tv_sec;
p->tv_usec = (tp.tv_nsec / 1000);
return 0;
}
int __cdecl mingw_gettimeofday(struct timeval *p, struct timezone *z)
{
struct timespec tp;
if (getntptimeofday(&tp, z))
return -1;
p->tv_sec = (long)tp.tv_sec;
p->tv_usec = (tp.tv_nsec / 1000);
return 0;
}

58
src/msvc/msvc_compat.h Normal file
View File

@ -0,0 +1,58 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2018 Marius Greuel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <io.h>
#include <malloc.h>
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "hid.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "setupapi.lib")
#define F_OK 0
#define PATH_MAX _MAX_PATH
#define setvbuf msvc_setvbuf
static inline int msvc_setvbuf(
FILE* const public_stream,
char* const buffer,
int const type,
size_t const buffer_size_in_bytes
)
{
// Just ignore calls to setvbuf with invalid buffer size.
// Purpose of setvbuf calls unknown, probably in an attempt to fix broken
// programs that capture stdout and stderr using separate stream handles?
return 0;
}
static inline int strcasecmp(const char* s1, const char* s2)
{
return _stricmp(s1, s2);
}
static inline int strncasecmp(const char* s1, const char* s2, size_t n)
{
return _strnicmp(s1, s2, n);
}

43
src/msvc/sys/time.h Normal file
View File

@ -0,0 +1,43 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2018 Marius Greuel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TIME_H_
#define _TIME_H_
// If you need both <windows.h> and <sys/time.h>,
// make sure you include <windows.h> first.
#ifndef _WINSOCKAPI_
#ifndef _TIMEVAL_DEFINED
#define _TIMEVAL_DEFINED
struct timeval
{
long tv_sec;
long tv_usec;
};
#endif /* _TIMEVAL_DEFINED */
#endif /* _WINSOCKAPI_ */
struct timezone
{
int tz_minuteswest;
int tz_dsttime;
};
int __cdecl gettimeofday(struct timeval* p, void* z);
#endif

38
src/msvc/unistd.h Normal file
View File

@ -0,0 +1,38 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2018 Marius Greuel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _UNISTD_H
#define _UNISTD_H
#define STDIN_FILENO _fileno(stdin)
#define STDERR_FILENO _fileno(stderr)
#include <getopt.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned int useconds_t;
int usleep(unsigned int us);
#ifdef __cplusplus
}
#endif
#endif

93
src/msvc/usleep.cpp Normal file
View File

@ -0,0 +1,93 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2018 Marius Greuel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "unistd.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib")
class MicroSleep
{
public:
MicroSleep()
{
if (::timeBeginPeriod(timerPeriod) == TIMERR_NOERROR)
{
m_resetTimerPeriod = true;
}
}
~MicroSleep()
{
if (m_resetTimerPeriod)
{
::timeEndPeriod(timerPeriod);
}
}
int Sleep(DWORD us)
{
if (us == 0)
{
return 0;
}
LARGE_INTEGER frequency{};
if (QueryPerformanceFrequency(&frequency))
{
LARGE_INTEGER start{};
QueryPerformanceCounter(&start);
if (us > 10000)
{
::Sleep((us - 5000) / 1000);
}
LARGE_INTEGER end{};
end.QuadPart = start.QuadPart + (frequency.QuadPart * us / 1000000);
while (true)
{
LARGE_INTEGER current;
QueryPerformanceCounter(&current);
if (current.QuadPart >= end.QuadPart)
{
break;
}
}
}
else
{
::Sleep((us / 1000) + 1);
}
return 0;
}
private:
static const UINT timerPeriod = 1; // 1ms
bool m_resetTimerPeriod = false;
};
int usleep(unsigned int us)
{
static MicroSleep microSleep;
return microSleep.Sleep(us);
}

View File

@ -1,48 +0,0 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2006 Christian Starkjohann
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* $Id$ */
/*
The following is a replacement for hidsdi.h from the Windows DDK. It defines some
of the types and function prototypes of this header for our project. If you
have the Windows DDK version of this file or a version shipped with MinGW, use
that instead.
*/
#ifndef MY_DDK_HIDSDI_H
#define MY_DDK_HIDSDI_H
#include <pshpack4.h>
#include <ddk/hidusage.h>
#include <ddk/hidpi.h>
typedef struct{
ULONG Size;
USHORT VendorID;
USHORT ProductID;
USHORT VersionNumber;
}HIDD_ATTRIBUTES;
void __stdcall HidD_GetHidGuid(OUT LPGUID hidGuid);
BOOLEAN __stdcall HidD_GetAttributes(IN HANDLE device, OUT HIDD_ATTRIBUTES *attributes);
BOOLEAN __stdcall HidD_GetManufacturerString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen);
BOOLEAN __stdcall HidD_GetProductString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen);
BOOLEAN __stdcall HidD_GetSerialNumberString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen);
BOOLEAN __stdcall HidD_GetFeature(IN HANDLE device, OUT void *reportBuffer, IN ULONG bufferLen);
BOOLEAN __stdcall HidD_SetFeature(IN HANDLE device, IN void *reportBuffer, IN ULONG bufferLen);
BOOLEAN __stdcall HidD_GetNumInputBuffers(IN HANDLE device, OUT ULONG *numBuffers);
BOOLEAN __stdcall HidD_SetNumInputBuffers(IN HANDLE device, OUT ULONG numBuffers);
#include <poppack.h>
#endif /* MY_DDK_HIDSDI_H */

View File

@ -50,6 +50,7 @@
#include "stk500.h"
#include "stk500generic.h"
#include "stk500v2.h"
#include "teensy.h"
#include "usbasp.h"
#include "usbtiny.h"
#include "wiring.h"
@ -99,6 +100,7 @@ const PROGRAMMER_TYPE programmers_types[] = {
{"stk600", stk600_initpgm, stk600_desc},
{"stk600hvsp", stk600hvsp_initpgm, stk600hvsp_desc},
{"stk600pp", stk600pp_initpgm, stk600pp_desc},
{"teensy", teensy_initpgm, teensy_desc},
{"usbasp", usbasp_initpgm, usbasp_desc},
{"usbtiny", usbtiny_initpgm, usbtiny_desc},
{"wiring", wiring_initpgm, wiring_desc},

View File

@ -54,15 +54,12 @@
#include "avrdude.h"
#include "libavrdude.h"
#if defined(HAVE_LIBUSB) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
#if defined(HAVE_LIBUSB) || (defined(WIN32) && defined(HAVE_LIBHID))
#if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
#if (defined(WIN32) && defined(HAVE_LIBHID))
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#if defined(HAVE_DDK_HIDSDI_H)
# include <ddk/hidsdi.h>
#else
# include "my_ddk_hidsdi.h"
#endif
#include <hidsdi.h>
#include <setupapi.h>
#else
#if defined(HAVE_USB_H)
@ -91,10 +88,9 @@
#define SPI_MAX_CHUNK (64 - 10) // max packet size less the command overhead
// win32native only:
#if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
#if (defined(WIN32) && defined(HAVE_LIBHID))
static HANDLE open_hid(unsigned short vid, unsigned short pid);
const char *usb_strerror()
static const char *usb_strerror()
{
return "";
}
@ -106,7 +102,7 @@ static int usb_open_device(struct usb_dev_handle **dev, int vid, int pid);
#define USB_ERROR_NOTFOUND 2
#define USB_ERROR_BUSY 16
#define USB_ERROR_IO 5
#endif // WIN32NATIVE
#endif // WIN32
static int pickit2_write_report(PROGRAMMER *pgm, const unsigned char report[65]);
static int pickit2_read_report(PROGRAMMER *pgm, unsigned char report[65]);
@ -120,7 +116,7 @@ static int pickit2_read_report(PROGRAMMER *pgm, unsigned char report[65]);
*/
struct pdata
{
#if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
#if (defined(WIN32) && defined(HAVE_LIBHID))
HANDLE usb_handle, write_event, read_event;
#else
struct usb_dev_handle *usb_handle; // LIBUSB STUFF
@ -185,7 +181,7 @@ static void pickit2_teardown(PROGRAMMER * pgm)
static int pickit2_open(PROGRAMMER * pgm, char * port)
{
#if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
#if (defined(WIN32) && defined(HAVE_LIBHID))
PDATA(pgm)->usb_handle = open_hid(PICKIT2_VID, PICKIT2_PID);
if (PDATA(pgm)->usb_handle == INVALID_HANDLE_VALUE)
@ -233,13 +229,13 @@ static int pickit2_open(PROGRAMMER * pgm, char * port)
static void pickit2_close(PROGRAMMER * pgm)
{
#if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
#if (defined(WIN32) && defined(HAVE_LIBHID))
CloseHandle(PDATA(pgm)->usb_handle);
CloseHandle(PDATA(pgm)->read_event);
CloseHandle(PDATA(pgm)->write_event);
#else
usb_close(PDATA(pgm)->usb_handle);
#endif // WIN32NATIVE
#endif // WIN32
}
@ -814,7 +810,7 @@ static int pickit2_spi(struct programmer_t * pgm, const unsigned char *cmd,
return n_bytes;
}
#if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
#if (defined(WIN32) && defined(HAVE_LIBHID))
/*
Func: open_hid()
Desc: finds & opens device having specified VID & PID.
@ -1124,7 +1120,7 @@ static int pickit2_read_report(PROGRAMMER * pgm, unsigned char report[65])
return usb_read_interrupt(pgm, report, 65, PDATA(pgm)->transaction_timeout);
}
#else // WIN32NATIVE
#else // WIN32
/* taken (modified) from avrdude usbasp.c */
static int usb_open_device(struct usb_dev_handle **device, int vendor, int product)
{
@ -1188,7 +1184,7 @@ static int usb_open_device(struct usb_dev_handle **device, int vendor, int produ
static int pickit2_write_report(PROGRAMMER * pgm, const unsigned char report[65])
{
// endpoint 1 OUT??
return usb_interrupt_write(PDATA(pgm)->usb_handle, USB_ENDPOINT_OUT | 1, (const char*)(report+1), 64, PDATA(pgm)->transaction_timeout);
return usb_interrupt_write(PDATA(pgm)->usb_handle, USB_ENDPOINT_OUT | 1, (char*)(report+1), 64, PDATA(pgm)->transaction_timeout);
}
static int pickit2_read_report(PROGRAMMER * pgm, unsigned char report[65])
@ -1196,7 +1192,7 @@ static int pickit2_read_report(PROGRAMMER * pgm, unsigned char report[65])
// endpoint 1 IN??
return usb_interrupt_read(PDATA(pgm)->usb_handle, USB_ENDPOINT_IN | 1, (char*)(report+1), 64, PDATA(pgm)->transaction_timeout);
}
#endif // WIN323NATIVE
#endif // WIN32
static int pickit2_parseextparams(struct programmer_t * pgm, LISTID extparms)
{
@ -1314,7 +1310,7 @@ void pickit2_initpgm (PROGRAMMER * pgm)
#else
static int pickit2_nousb_open (struct programmer_t *pgm, char * name) {
avrdude_message(MSG_INFO,
#ifdef WIN32NATIVE
#ifdef WIN32
"%s: error: no usb or hid support. Please compile again with libusb or HID support from Win32 DDK installed.\n",
#else
"%s: error: no usb support. Please compile again with libusb installed.\n",
@ -1336,7 +1332,7 @@ void pickit2_initpgm (PROGRAMMER * pgm)
strncpy(pgm->type, "pickit2", sizeof(pgm->type));
}
#endif /* defined(HAVE_LIBUSB) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID)) */
#endif /* defined(HAVE_LIBUSB) || (defined(WIN32) && defined(HAVE_LIBHID)) */
const char pickit2_desc[] = "Microchip's PICkit2 Programmer";

View File

@ -146,7 +146,7 @@ int pgm_fill_old_pins(struct programmer_t * const pgm) {
/**
* This function returns a string representation of pins in the mask eg. 1,3,5-7,9,12
* Another execution of this function will overwrite the previous result in the static buffer.
* Consecutive pin number are representated as start-end.
* Consecutive pin number are represented as start-end.
*
* @param[in] pinmask the pin mask for which we want the string representation
* @returns pointer to a static string.

View File

@ -19,7 +19,7 @@
/* $Id$ */
#if !defined(WIN32NATIVE)
#if !defined(WIN32)
#include "ac_cfg.h"
@ -233,4 +233,4 @@ void ppi_close(union filedescriptor *fdp)
#endif /* HAVE_PARPORT */
#endif /* !WIN32NATIVE */
#endif /* !WIN32 */

View File

@ -32,8 +32,9 @@ reg = register as defined in an enum in ppi.h. This must be converted
#include "ac_cfg.h"
#if defined (WIN32NATIVE)
#if defined(HAVE_PARPORT) && defined(WIN32)
#define WIN32_LEAN_AND_MEAN
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
@ -336,82 +337,4 @@ static void outb(unsigned char value, unsigned short port)
return;
}
#if !defined(HAVE_GETTIMEOFDAY)
struct timezone;
int gettimeofday(struct timeval *tv, struct timezone *unused){
// i've found only ms resolution, avrdude expects us
SYSTEMTIME st;
GetSystemTime(&st);
tv->tv_sec=(long)(st.wSecond+st.wMinute*60+st.wHour*3600);
tv->tv_usec=(long)(st.wMilliseconds*1000);
return 0;
}
#endif /* HAVE_GETTIMEOFDAY */
// #define W32USLEEPDBG
#ifdef W32USLEEPDBG
# define DEBUG_QueryPerformanceCounter(arg) QueryPerformanceCounter(arg)
# define DEBUG_DisplayTimingInfo(start, stop, freq, us, has_highperf) \
do { \
unsigned long dt; \
dt = (unsigned long)((stop.QuadPart - start.QuadPart) * 1000 * 1000 \
/ freq.QuadPart); \
avrdude_message(MSG_INFO, \
"hpt:%i usleep usec:%lu sleep msec:%lu timed usec:%lu\n", \
has_highperf, us, ((us + 999) / 1000), dt); \
} while (0)
#else
# define DEBUG_QueryPerformanceCounter(arg)
# define DEBUG_DisplayTimingInfo(start, stop, freq, us, has_highperf)
#endif
#if !defined(HAVE_USLEEP)
int usleep(unsigned int us)
{
int has_highperf;
LARGE_INTEGER freq,start,stop,loopend;
// workaround: although usleep is very precise if using
// high-performance-timers there are sometimes problems with
// verify - increasing the delay helps sometimes but not
// realiably. There must be some other problem. Maybe just
// with my test-hardware maybe in the code-base.
//// us=(unsigned long) (us*1.5);
has_highperf=QueryPerformanceFrequency(&freq);
//has_highperf=0; // debug
if (has_highperf) {
QueryPerformanceCounter(&start);
loopend.QuadPart=start.QuadPart+freq.QuadPart*us/(1000*1000);
do {
QueryPerformanceCounter(&stop);
} while (stop.QuadPart<=loopend.QuadPart);
}
else {
DEBUG_QueryPerformanceCounter(&start);
Sleep(1);
Sleep( (DWORD)((us+999)/1000) );
DEBUG_QueryPerformanceCounter(&stop);
}
DEBUG_DisplayTimingInfo(start, stop, freq, us, has_highperf);
return 0;
}
#endif /* !HAVE_USLEEP */
#endif

View File

@ -26,7 +26,7 @@
#include "ac_cfg.h"
#if defined(HAVE_LIBHIDAPI) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
#if defined(HAVE_LIBHIDAPI) || (defined(WIN32) && defined(HAVE_LIBHID))
#include <stdio.h>
#include <string.h>
@ -161,15 +161,11 @@ static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNum
/* ------------------------------------------------------------------------ */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <setupapi.h>
#if defined(HAVE_DDK_HIDSDI_H)
# include <ddk/hidsdi.h>
#else
# include "my_ddk_hidsdi.h"
#endif
#include <ddk/hidpi.h>
#include <hidsdi.h>
#include <hidpi.h>
#ifdef USB_DEBUG
#define DEBUG_PRINT(arg) printf arg
@ -332,7 +328,7 @@ static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNum
return rval == 0 ? USB_ERROR_IO : 0;
}
#endif /* WIN32NATIVE */
#endif /* WIN32 */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
@ -555,4 +551,4 @@ struct serial_device avrdoper_serdev =
.flags = SERDEV_FL_NONE,
};
#endif /* defined(HAVE_LIBHIDAPI) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID)) */
#endif /* defined(HAVE_LIBHIDAPI) || (defined(WIN32) && defined(HAVE_LIBHID)) */

View File

@ -23,7 +23,7 @@
* Posix serial interface for avrdude.
*/
#if !defined(WIN32NATIVE)
#if !defined(WIN32)
#include "ac_cfg.h"
@ -174,7 +174,6 @@ static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cfla
static int
net_open(const char *port, union filedescriptor *fdp)
{
#ifdef HAVE_GETADDRINFO
char *hp, *hstr, *pstr;
int s, fd, ret = -1;
struct addrinfo hints;
@ -247,12 +246,6 @@ net_open(const char *port, union filedescriptor *fdp)
error:
free(hp);
return ret;
#else
avrdude_message(MSG_INFO,
"%s: Networking is not supported on your platform.\n"
"If you need it, please open a bug report.\n", progname);
return -1;
#endif /* HAVE_GETADDRINFO */
}
@ -526,4 +519,4 @@ struct serial_device serial_serdev =
struct serial_device *serdev = &serial_serdev;
#endif /* WIN32NATIVE */
#endif /* WIN32 */

View File

@ -17,22 +17,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* $Id$ */
/*
* Native Win32 serial interface for avrdude.
*/
#include "ac_cfg.h"
#if defined(WIN32NATIVE)
#ifdef HAVE_LIBWS2_32
/* winsock2.h must be included before windows.h from avrdude.h... */
# include <winsock2.h>
#endif
#if defined(WIN32)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h> /* for isprint */
#include <errno.h> /* ENOTTY */
@ -154,7 +150,6 @@ static int ser_setparams(union filedescriptor *fd, long baud, unsigned long cfla
}
}
#ifdef HAVE_LIBWS2_32
static int
net_open(const char *port, union filedescriptor *fdp)
{
@ -246,7 +241,6 @@ net_open(const char *port, union filedescriptor *fdp)
serial_over_ethernet = 1;
return 0;
}
#endif
static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
@ -260,14 +254,7 @@ static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
* handle it as a TCP connection to a terminal server.
*/
if (strncmp(port, "net:", strlen("net:")) == 0) {
#ifdef HAVE_LIBWS2_32
return net_open(port + strlen("net:"), fdp);
#else
avrdude_message(MSG_INFO, "%s: ser_open(): "
"not configured for TCP connections\n",
progname);
return -1;
#endif
}
if (strncasecmp(port, "com", strlen("com")) == 0) {
@ -370,7 +357,6 @@ static int ser_set_dtr_rts(union filedescriptor *fd, int is_on)
}
}
#ifdef HAVE_LIBWS2_32
static int net_send(union filedescriptor *fd, const unsigned char * buf, size_t buflen)
{
LPVOID lpMsgBuf;
@ -429,16 +415,13 @@ static int net_send(union filedescriptor *fd, const unsigned char * buf, size_t
return 0;
}
#endif
static int ser_send(union filedescriptor *fd, const unsigned char * buf, size_t buflen)
{
#ifdef HAVE_LIBWS2_32
if (serial_over_ethernet) {
return net_send(fd, buf, buflen);
}
#endif
size_t len = buflen;
unsigned char c='\0';
@ -493,7 +476,6 @@ static int ser_send(union filedescriptor *fd, const unsigned char * buf, size_t
}
#ifdef HAVE_LIBWS2_32
static int net_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
{
LPVOID lpMsgBuf;
@ -587,15 +569,12 @@ reselect:
return 0;
}
#endif
static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
{
#ifdef HAVE_LIBWS2_32
if (serial_over_ethernet) {
return net_recv(fd, buf, buflen);
}
#endif
unsigned char c;
unsigned char * p = buf;
@ -660,7 +639,6 @@ static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen
return 0;
}
#ifdef HAVE_LIBWS2_32
static int net_drain(union filedescriptor *fd, int display)
{
LPVOID lpMsgBuf;
@ -739,15 +717,12 @@ static int net_drain(union filedescriptor *fd, int display)
return 0;
}
#endif
static int ser_drain(union filedescriptor *fd, int display)
{
#ifdef HAVE_LIBWS2_32
if (serial_over_ethernet) {
return net_drain(fd, display);
}
#endif
// int rc;
unsigned char buf[10];
@ -813,4 +788,4 @@ struct serial_device serial_serdev =
struct serial_device *serdev = &serial_serdev;
#endif /* WIN32NATIVE */
#endif /* WIN32 */

View File

@ -23,7 +23,7 @@
* Posix serial bitbanging interface for avrdude.
*/
#if !defined(WIN32NATIVE)
#if !defined(WIN32)
#include "ac_cfg.h"
@ -318,4 +318,4 @@ void serbb_initpgm(PROGRAMMER *pgm)
pgm->write_byte = avr_write_byte_default;
}
#endif /* WIN32NATIVE */
#endif /* WIN32 */

View File

@ -25,11 +25,12 @@
#include "avrdude.h"
#if defined(WIN32NATIVE)
#if defined(WIN32)
#include "ac_cfg.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
@ -308,8 +309,8 @@ static int serbb_open(PROGRAMMER *pgm, char *port)
progname, port);
return -1;
}
avrdude_message(MSG_DEBUG, "%s: ser_open(): opened comm port \"%s\", handle 0x%x\n",
progname, port, (int)hComPort);
avrdude_message(MSG_DEBUG, "%s: ser_open(): opened comm port \"%s\", handle 0x%zx\n",
progname, port, (INT_PTR)hComPort);
pgm->fd.pfd = (void *)hComPort;
@ -326,8 +327,8 @@ static void serbb_close(PROGRAMMER *pgm)
pgm->setpin(pgm, PIN_AVR_RESET, 1);
CloseHandle (hComPort);
}
avrdude_message(MSG_DEBUG, "%s: ser_close(): closed comm port handle 0x%x\n",
progname, (int)hComPort);
avrdude_message(MSG_DEBUG, "%s: ser_close(): closed comm port handle 0x%zx\n",
progname, (INT_PTR)hComPort);
hComPort = INVALID_HANDLE_VALUE;
}
@ -363,4 +364,4 @@ void serbb_initpgm(PROGRAMMER *pgm)
pgm->write_byte = avr_write_byte_default;
}
#endif /* WIN32NATIVE */
#endif /* WIN32 */

View File

@ -760,7 +760,7 @@ static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
unsigned char buf[page_size + 16];
unsigned char* buf = alloca(page_size + 16);
int memtype;
int a_div;
int block_size;

View File

@ -1613,7 +1613,7 @@ static int stk500v2_open(PROGRAMMER * pgm, char * port)
PDATA(pgm)->pgmtype = PGMTYPE_UNKNOWN;
if(strcasecmp(port, "avrdoper") == 0){
#if defined(HAVE_LIBHIDAPI) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
#if defined(HAVE_LIBHIDAPI) || (defined(WIN32) && defined(HAVE_LIBHID))
serdev = &avrdoper_serdev;
PDATA(pgm)->pgmtype = PGMTYPE_STK500;
#else

641
src/teensy.c Normal file
View File

@ -0,0 +1,641 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2020 Marius Greuel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Notes:
// This file adds support for the HalfKay bootloader,
// so you do no longer need the Teensy loader utility.
//
// This HalfKay bootloader is used on various PJRC Teensy boards,
// such as Teensy 2.0 (ATmega32U4), Teensy++ 2.0 (AT90USB1286),
// and the respective clones.
// By default, it bootloader uses the VID/PID 16C0:0478 (VOTI).
//
// As the Teensy bootloader is optimized for size, it implements
// writing to flash memory only. Since it does not support reading,
// use the -V option to prevent avrdude from verifing the flash memory.
// To have avrdude wait for the device to be connected, use the
// extended option '-x wait'.
//
// Example:
// avrdude -c teensy -p m32u4 -x wait -V -U flash:w:main.hex:i
#include "ac_cfg.h"
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include "avrdude.h"
#include "teensy.h"
#include "usbdevs.h"
#if defined(HAVE_LIBHIDAPI)
#include <hidapi/hidapi.h>
//-----------------------------------------------------------------------------
#define TEENSY_VID 0x16C0
#define TEENSY_PID 0x0478
#define TEENSY_CONNECT_WAIT 100
#define PDATA(pgm) ((pdata_t*)(pgm->cookie))
//-----------------------------------------------------------------------------
typedef struct pdata
{
hid_device* hid_handle;
uint16_t hid_usage;
// Extended parameters
bool wait_until_device_present;
int wait_timout; // in seconds
// Bootloader info (from hid_usage)
const char* board;
uint32_t flash_size;
uint16_t page_size;
uint8_t sig_bytes[3];
// State
bool erase_flash;
bool reboot;
} pdata_t;
//-----------------------------------------------------------------------------
static void delay_ms(uint32_t duration)
{
usleep(duration * 1000);
}
static int teensy_get_bootloader_info(pdata_t* pdata, AVRPART* p)
{
switch (pdata->hid_usage)
{
case 0x19:
pdata->board = "Teensy 1.0 (AT90USB162)";
pdata->flash_size = 0x4000 - 0x200;
pdata->page_size = 128;
pdata->sig_bytes[0] = 0x1E;
pdata->sig_bytes[1] = 0x94;
pdata->sig_bytes[2] = 0x82;
break;
case 0x1A:
pdata->board = "Teensy++ 1.0 (AT90USB646)";
pdata->flash_size = 0x10000 - 0x400;
pdata->page_size = 256;
pdata->sig_bytes[0] = 0x1E;
pdata->sig_bytes[1] = 0x96;
pdata->sig_bytes[2] = 0x82;
break;
case 0x1B:
pdata->board = "Teensy 2.0 (ATmega32U4)";
pdata->flash_size = 0x8000 - 0x200;
pdata->page_size = 128;
pdata->sig_bytes[0] = 0x1E;
pdata->sig_bytes[1] = 0x95;
pdata->sig_bytes[2] = 0x87;
break;
case 0x1C:
pdata->board = "Teensy++ 2.0 (AT90USB1286)";
pdata->flash_size = 0x20000 - 0x400;
pdata->page_size = 256;
pdata->sig_bytes[0] = 0x1E;
pdata->sig_bytes[1] = 0x97;
pdata->sig_bytes[2] = 0x82;
break;
default:
if (pdata->hid_usage == 0)
{
// On Linux, libhidapi does not seem to return the HID usage from the report descriptor.
// We try to infer the board from the part information, until somebody fixes libhidapi.
// To use this workaround, the -F option is required.
avrdude_message(MSG_INFO, "%s: WARNING: Cannot detect board type (HID usage is 0)\n", progname);
AVRMEM* mem = avr_locate_mem(p, "flash");
if (mem == NULL)
{
avrdude_message(MSG_INFO, "No flash memory for part %s\n", p->desc);
return -1;
}
pdata->board = "Unknown Board";
pdata->flash_size = mem->size - (mem->size < 0x10000 ? 0x200 : 0x400);
pdata->page_size = mem->page_size;
// Pass an invalid signature to require -F option.
pdata->sig_bytes[0] = 0x1E;
pdata->sig_bytes[1] = 0x00;
pdata->sig_bytes[2] = 0x00;
}
else
{
avrdude_message(MSG_INFO, "%s: ERROR: Teensy board not supported (HID usage 0x%02X)\n",
progname, pdata->hid_usage);
return -1;
}
}
return 0;
}
static void teensy_dump_device_info(pdata_t* pdata)
{
avrdude_message(MSG_NOTICE, "%s: HID usage: 0x%02X\n", progname, pdata->hid_usage);
avrdude_message(MSG_NOTICE, "%s: Board: %s\n", progname, pdata->board);
avrdude_message(MSG_NOTICE, "%s: Available flash size: %u\n", progname, pdata->flash_size);
avrdude_message(MSG_NOTICE, "%s: Page size: %u\n", progname, pdata->page_size);
avrdude_message(MSG_NOTICE, "%s: Signature: 0x%02X%02X%02X\n", progname,
pdata->sig_bytes[0], pdata->sig_bytes[1], pdata->sig_bytes[2]);
}
static int teensy_write_page(pdata_t* pdata, uint32_t address, const uint8_t* buffer, uint32_t size)
{
avrdude_message(MSG_DEBUG, "%s: teensy_write_page(address=0x%06X, size=%d)\n", progname, address, size);
if (size > pdata->page_size)
{
avrdude_message(MSG_INFO, "%s: ERROR: Invalid page size: %u\n", progname, pdata->page_size);
return -1;
}
size_t report_size = 1 + 2 + (size_t)pdata->page_size;
uint8_t* report = (uint8_t*)malloc(report_size);
if (report == NULL)
{
avrdude_message(MSG_INFO, "%s: ERROR: Failed to allocate memory\n", progname);
return -1;
}
report[0] = 0; // report number
if (pdata->page_size <= 256 && pdata->flash_size < 0x10000)
{
report[1] = (uint8_t)(address >> 0);
report[2] = (uint8_t)(address >> 8);
}
else
{
report[1] = (uint8_t)(address >> 8);
report[2] = (uint8_t)(address >> 16);
}
if (size > 0)
{
memcpy(report + 1 + 2, buffer, size);
}
memset(report + 1 + 2 + size, 0xFF, report_size - (1 + 2 + size));
int result = hid_write(pdata->hid_handle, report, report_size);
free(report);
if (result < 0)
{
avrdude_message(MSG_INFO, "%s: WARNING: Failed to write page: %ls\n",
progname, hid_error(pdata->hid_handle));
return result;
}
return 0;
}
static int teensy_erase_flash(pdata_t* pdata)
{
avrdude_message(MSG_DEBUG, "%s: teensy_erase_flash()\n", progname);
// Write a dummy page at address 0 to explicitly erase the flash.
return teensy_write_page(pdata, 0, NULL, 0);
}
static int teensy_reboot(pdata_t* pdata)
{
avrdude_message(MSG_DEBUG, "%s: teensy_reboot()\n", progname);
// Write a dummy page at address -1 to reboot the Teensy.
return teensy_write_page(pdata, 0xFFFFFFFF, NULL, 0);
}
//-----------------------------------------------------------------------------
static void teensy_setup(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: teensy_setup()\n", progname);
if ((pgm->cookie = malloc(sizeof(pdata_t))) == NULL)
{
avrdude_message(MSG_INFO, "%s: ERROR: Failed to allocate memory\n", progname);
exit(1);
}
memset(pgm->cookie, 0, sizeof(pdata_t));
}
static void teensy_teardown(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: teensy_teardown()\n", progname);
free(pgm->cookie);
}
static int teensy_initialize(PROGRAMMER* pgm, AVRPART* p)
{
avrdude_message(MSG_DEBUG, "%s: teensy_initialize()\n", progname);
pdata_t* pdata = PDATA(pgm);
int result = teensy_get_bootloader_info(pdata, p);
if (result < 0)
return result;
teensy_dump_device_info(pdata);
return 0;
}
static void teensy_display(PROGRAMMER* pgm, const char* prefix)
{
avrdude_message(MSG_DEBUG, "%s: teensy_display()\n", progname);
}
static void teensy_powerup(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: teensy_powerup()\n", progname);
}
static void teensy_powerdown(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: teensy_powerdown()\n", progname);
pdata_t* pdata = PDATA(pgm);
if (pdata->erase_flash)
{
teensy_erase_flash(pdata);
pdata->erase_flash = false;
}
if (pdata->reboot)
{
teensy_reboot(pdata);
pdata->reboot = false;
}
}
static void teensy_enable(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: teensy_enable()\n", progname);
}
static void teensy_disable(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: teensy_disable()\n", progname);
}
static int teensy_program_enable(PROGRAMMER* pgm, AVRPART* p)
{
avrdude_message(MSG_DEBUG, "%s: teensy_program_enable()\n", progname);
return 0;
}
static int teensy_read_sig_bytes(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem)
{
avrdude_message(MSG_DEBUG, "%s: teensy_read_sig_bytes()\n", progname);
if (mem->size < 3)
{
avrdude_message(MSG_INFO, "%s: memory size too small for read_sig_bytes\n", progname);
return -1;
}
pdata_t* pdata = PDATA(pgm);
memcpy(mem->buf, pdata->sig_bytes, sizeof(pdata->sig_bytes));
return 0;
}
static int teensy_chip_erase(PROGRAMMER* pgm, AVRPART* p)
{
avrdude_message(MSG_DEBUG, "%s: teensy_chip_erase()\n", progname);
pdata_t* pdata = PDATA(pgm);
// Schedule a chip erase, either at first write or on powerdown.
pdata->erase_flash = true;
return 0;
}
static int teensy_open(PROGRAMMER* pgm, char* port)
{
avrdude_message(MSG_DEBUG, "%s: teensy_open(\"%s\")\n", progname, port);
pdata_t* pdata = PDATA(pgm);
char* bus_name = NULL;
char* dev_name = NULL;
// if no -P was given or '-P usb' was given
if (strcmp(port, "usb") == 0)
{
port = NULL;
}
else
{
// calculate bus and device names from -P option
if (strncmp(port, "usb", 3) == 0 && ':' == port[3])
{
bus_name = port + 4;
dev_name = strchr(bus_name, ':');
if (dev_name != NULL)
{
*dev_name = '\0';
dev_name++;
}
}
}
if (port != NULL && dev_name == NULL)
{
avrdude_message(MSG_INFO, "%s: ERROR: Invalid -P value: '%s'\n", progname, port);
avrdude_message(MSG_INFO, "%sUse -P usb:bus:device\n", progbuf);
return -1;
}
// Determine VID/PID
int vid = pgm->usbvid ? pgm->usbvid : TEENSY_VID;
int pid = TEENSY_PID;
LNODEID usbpid = lfirst(pgm->usbpid);
if (usbpid != NULL)
{
pid = *(int*)(ldata(usbpid));
if (lnext(usbpid))
{
avrdude_message(MSG_INFO, "%s: WARNING: using PID 0x%04x, ignoring remaining PIDs in list\n",
progname, pid);
}
}
bool show_retry_message = true;
time_t start_time = time(NULL);
for (;;)
{
// Search for device
struct hid_device_info* devices = hid_enumerate(vid, pid);
struct hid_device_info* device = devices;
while (device)
{
if (device->vendor_id == vid && device->product_id == pid)
{
pdata->hid_handle = hid_open_path(device->path);
if (pdata->hid_handle == NULL)
{
avrdude_message(MSG_INFO, "%s: ERROR: Found HID device, but hid_open_path() failed.\n", progname);
}
else
{
pdata->hid_usage = device->usage;
break;
}
}
device = device->next;
}
hid_free_enumeration(devices);
if (pdata->hid_handle == NULL && pdata->wait_until_device_present)
{
if (show_retry_message)
{
if (pdata->wait_timout < 0)
{
avrdude_message(MSG_INFO, "%s: No device found, waiting for device to be plugged in...\n", progname);
}
else
{
avrdude_message(MSG_INFO, "%s: No device found, waiting %d seconds for device to be plugged in...\n",
progname,
pdata->wait_timout);
}
avrdude_message(MSG_INFO, "%s: Press CTRL-C to terminate.\n", progname);
show_retry_message = false;
}
if (pdata->wait_timout < 0 || (time(NULL) - start_time) < pdata->wait_timout)
{
delay_ms(TEENSY_CONNECT_WAIT);
continue;
}
}
break;
}
if (!pdata->hid_handle)
{
avrdude_message(MSG_INFO, "%s: ERROR: Could not find device with Teensy bootloader (%04X:%04X)\n",
progname, vid, pid);
return -1;
}
return 0;
}
static void teensy_close(PROGRAMMER* pgm)
{
avrdude_message(MSG_DEBUG, "%s: teensy_close()\n", progname);
pdata_t* pdata = PDATA(pgm);
if (pdata->hid_handle != NULL)
{
hid_close(pdata->hid_handle);
pdata->hid_handle = NULL;
}
}
static int teensy_read_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
unsigned long addr, unsigned char* value)
{
avrdude_message(MSG_DEBUG, "%s: teensy_read_byte(desc=%s, addr=0x%0X)\n",
progname, mem->desc, addr);
if (strcmp(mem->desc, "lfuse") == 0 ||
strcmp(mem->desc, "hfuse") == 0 ||
strcmp(mem->desc, "efuse") == 0 ||
strcmp(mem->desc, "lock") == 0)
{
*value = 0xFF;
return 0;
}
else
{
avrdude_message(MSG_INFO, "%s: Unsupported memory type: %s\n", progname, mem->desc);
return -1;
}
}
static int teensy_write_byte(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
unsigned long addr, unsigned char value)
{
avrdude_message(MSG_DEBUG, "%s: teensy_write_byte(desc=%s, addr=0x%0X)\n",
progname, mem->desc, addr);
return -1;
}
static int teensy_paged_load(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
avrdude_message(MSG_DEBUG, "%s: teensy_paged_load(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n",
progname, page_size, addr, n_bytes);
return -1;
}
static int teensy_paged_write(PROGRAMMER* pgm, AVRPART* p, AVRMEM* mem,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes)
{
avrdude_message(MSG_DEBUG, "%s: teensy_paged_write(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n",
progname, page_size, addr, n_bytes);
if (strcmp(mem->desc, "flash") == 0)
{
pdata_t* pdata = PDATA(pgm);
if (n_bytes > page_size)
{
avrdude_message(MSG_INFO, "%s: Buffer size (%u) exceeds page size (%u)\n", progname, n_bytes, page_size);
return -1;
}
if (addr + n_bytes > pdata->flash_size)
{
avrdude_message(MSG_INFO, "%s: Program size (%u) exceeds flash size (%u)\n", progname, addr + n_bytes, pdata->flash_size);
return -1;
}
if (pdata->erase_flash)
{
// Writing page 0 will automatically erase the flash.
// If mem does not contain a page at address 0, write a dummy page at address 0.
if (addr != 0)
{
int result = teensy_erase_flash(pdata);
if (result < 0)
{
return result;
}
}
pdata->erase_flash = false;
}
int result = teensy_write_page(pdata, addr, mem->buf + addr, n_bytes);
if (result < 0)
{
return result;
}
// Schedule a reboot.
pdata->reboot = true;
return result;
}
else
{
avrdude_message(MSG_INFO, "%s: Unsupported memory type: %s\n", progname, mem->desc);
return -1;
}
}
static int teensy_parseextparams(PROGRAMMER* pgm, LISTID xparams)
{
avrdude_message(MSG_DEBUG, "%s: teensy_parseextparams()\n", progname);
pdata_t* pdata = PDATA(pgm);
for (LNODEID node = lfirst(xparams); node != NULL; node = lnext(node))
{
const char* param = ldata(node);
if (strcmp(param, "wait") == 0)
{
pdata->wait_until_device_present = true;
pdata->wait_timout = -1;
}
else if (strncmp(param, "wait=", 5) == 0)
{
pdata->wait_until_device_present = true;
pdata->wait_timout = atoi(param + 5);
}
else
{
avrdude_message(MSG_INFO, "%s: Invalid extended parameter '%s'\n", progname, param);
return -1;
}
}
return 0;
}
void teensy_initpgm(PROGRAMMER* pgm)
{
strcpy(pgm->type, "teensy");
pgm->setup = teensy_setup;
pgm->teardown = teensy_teardown;
pgm->initialize = teensy_initialize;
pgm->display = teensy_display;
pgm->powerup = teensy_powerup;
pgm->powerdown = teensy_powerdown;
pgm->enable = teensy_enable;
pgm->disable = teensy_disable;
pgm->program_enable = teensy_program_enable;
pgm->read_sig_bytes = teensy_read_sig_bytes;
pgm->chip_erase = teensy_chip_erase;
pgm->cmd = NULL;
pgm->open = teensy_open;
pgm->close = teensy_close;
pgm->read_byte = teensy_read_byte;
pgm->write_byte = teensy_write_byte;
pgm->paged_load = teensy_paged_load;
pgm->paged_write = teensy_paged_write;
pgm->parseextparams = teensy_parseextparams;
}
#else /* !HAVE_LIBHIDAPI */
// Give a proper error if we were not compiled with libhidapi
static int teensy_nousb_open(struct programmer_t* pgm, char* name)
{
avrdude_message(MSG_INFO, "%s: error: No HID support. Please compile again with libhidapi installed.\n", progname);
return -1;
}
void teensy_initpgm(PROGRAMMER* pgm)
{
strcpy(pgm->type, "teensy");
pgm->open = teensy_nousb_open;
}
#endif /* HAVE_LIBHIDAPI */
const char teensy_desc[] = "Teensy Bootloader";

35
src/teensy.h Normal file
View File

@ -0,0 +1,35 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2020 Marius Greuel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef teensy_h
#define teensy_h
#include "libavrdude.h"
#ifdef __cplusplus
extern "C" {
#endif
extern const char teensy_desc[];
void teensy_initpgm(PROGRAMMER* pgm);
#ifdef __cplusplus
}
#endif
#endif /* teensy_h */

View File

@ -27,11 +27,9 @@
#include <limits.h>
#if defined(HAVE_LIBREADLINE)
#if !defined(WIN32NATIVE)
# include <readline/readline.h>
# include <readline/history.h>
#endif
#endif
#include "avrdude.h"
#include "term.h"
@ -827,12 +825,26 @@ static int tokenize(char * s, char *** argv)
nbuf[0] = 0;
n++;
if ((n % 20) == 0) {
char *buf_tmp;
char **bufv_tmp;
/* realloc space for another 20 args */
bufsize += 20;
nargs += 20;
bufp = buf;
buf = realloc(buf, bufsize);
bufv = realloc(bufv, nargs*sizeof(char *));
buf_tmp = realloc(buf, bufsize);
if (buf_tmp == NULL) {
free(buf);
free(bufv);
return -1;
}
buf = buf_tmp;
bufv_tmp = realloc(bufv, nargs*sizeof(char *));
if (bufv_tmp == NULL) {
free(buf);
free(bufv);
return -1;
}
bufv = bufv_tmp;
nbuf = &buf[l];
/* correct bufv pointers */
k = buf - bufp;
@ -905,7 +917,7 @@ static int do_cmd(PROGRAMMER * pgm, struct avrpart * p,
char * terminal_get_input(const char *prompt)
{
#if defined(HAVE_LIBREADLINE) && !defined(WIN32NATIVE)
#if defined(HAVE_LIBREADLINE) && !defined(WIN32)
char *input;
input = readline(prompt);
if ((input != NULL) && (strlen(input) >= 1))
@ -950,6 +962,10 @@ int terminal_mode(PROGRAMMER * pgm, struct avrpart * p)
/* tokenize command line */
argc = tokenize(q, &argv);
if (argc < 0) {
free(cmdbuf);
return argc;
}
fprintf(stdout, ">>> ");
for (i=0; i<argc; i++)

View File

@ -39,14 +39,9 @@
#include "updi_constants.h"
#include "updi_state.h"
#include <sys/time.h>
void msleep(int tms)
static void msleep(int tms)
{
struct timeval tv;
tv.tv_sec = tms / 1000;
tv.tv_usec = (tms % 1000) * 1000;
select (0, NULL, NULL, NULL, &tv);
usleep(tms * 1000);
}
static int updi_physical_open(PROGRAMMER* pgm, int baudrate, unsigned long cflags)

View File

@ -141,7 +141,7 @@ int updi_read_data(PROGRAMMER * pgm, uint32_t address, uint8_t * buffer, uint16_
self.logger.debug("Reading %d bytes from 0x%04X", size, address)
# Range check
if size > constants.UPDI_MAX_REPEAT_SIZE:
raise PymcuprogError("Cant read that many bytes in one go")
raise PymcuprogError("Can't read that many bytes in one go")
# Store the address
self.datalink.st_ptr(address)
@ -242,7 +242,7 @@ int updi_read_data_words(PROGRAMMER * pgm, uint32_t address, uint8_t * buffer, u
# Range check
if words > constants.UPDI_MAX_REPEAT_SIZE >> 1:
raise PymcuprogError("Cant read that many words in one go")
raise PymcuprogError("Can't read that many words in one go")
# Store the address
self.datalink.st_ptr(address)

View File

@ -42,11 +42,6 @@
#include "usbdevs.h"
#if defined(WIN32NATIVE)
/* someone has defined "interface" to "struct" in Cygwin */
# undef interface
#endif
/*
* The "baud" parameter is meaningless for USB devices, so we reuse it
* to pass the desired USB device ID.

View File

@ -48,7 +48,7 @@
#include "usbdevs.h"
#if defined(WIN32NATIVE)
#if defined(WIN32)
/* someone has defined "interface" to "struct" in Cygwin */
# undef interface
#endif

View File

@ -52,13 +52,7 @@
#define TPIPCR_GT_0b 0x07
#define TPI_STOP_BITS 0x03
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
# define LITTLE_TO_BIG_16(x) (htons(x))
#else
// WIN32
# define LITTLE_TO_BIG_16(x) ((((x) << 8) & 0xFF00) | (((x) >> 8) & 0x00FF))
#endif
#define LITTLE_TO_BIG_16(x) ((((x) << 8) & 0xFF00) | (((x) >> 8) & 0x00FF))
#ifndef HAVE_UINT_T
typedef unsigned int uint_t;
@ -109,7 +103,7 @@ static int usb_control (PROGRAMMER * pgm,
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
requestid,
val, index, // 2 bytes each of data
NULL, 0, // no data buffer in control messge
NULL, 0, // no data buffer in control message
USB_TIMEOUT ); // default timeout
if(nbytes < 0){
avrdude_message(MSG_INFO, "\n%s: error: usbtiny_transmit: %s\n", progname, usb_strerror());
@ -128,7 +122,7 @@ static int usb_in (PROGRAMMER * pgm,
int timeout;
int i;
// calculate the amout of time we expect the process to take by
// calculate the amount of time we expect the process to take by
// figuring the bit-clock time and buffer size and adding to the standard USB timeout.
timeout = USB_TIMEOUT + (buflen * bitclk) / 1000;
@ -167,7 +161,7 @@ static int usb_out (PROGRAMMER * pgm,
int nbytes;
int timeout;
// calculate the amout of time we expect the process to take by
// calculate the amount of time we expect the process to take by
// figuring the bit-clock time and buffer size and adding to the standard USB timeout.
timeout = USB_TIMEOUT + (buflen * bitclk) / 1000;
@ -186,7 +180,7 @@ static int usb_out (PROGRAMMER * pgm,
return nbytes;
}
/* Reverse the bits in a byte. Needed since TPI uses little-endian
/* Reverse the bits in a byte. Needed since TPI uses little-endian
bit order (LSB first) whereas SPI uses big-endian (MSB first).*/
static unsigned char reverse(unsigned char b) {
return
@ -200,7 +194,7 @@ static unsigned char reverse(unsigned char b) {
| ((b & 0x80) >> 7);
}
/* Calculate even parity. */
/* Calculate even parity. */
static unsigned char tpi_parity(unsigned char b)
{
unsigned char parity = 0;
@ -215,9 +209,9 @@ static unsigned char tpi_parity(unsigned char b)
}
/* Encode 1 start bit (0), 8 data bits, 1 parity, 2 stop bits (1)
inside 16 bits. The data is padded to 16 bits by 4 leading 1s
(which will be ignored since they're not start bits). This layout
enables a write to be followed by a read. */
inside 16 bits. The data is padded to 16 bits by 4 leading 1s
(which will be ignored since they're not start bits). This layout
enables a write to be followed by a read. */
static unsigned short tpi_frame(unsigned char b) {
return LITTLE_TO_BIG_16(0xf000 |
(reverse(b) << 3) |
@ -225,8 +219,8 @@ static unsigned short tpi_frame(unsigned char b) {
TPI_STOP_BITS);
}
/* Transmit a single byte encapsulated in a 32-bit transfer. Unused
bits are padded with 1s. */
/* Transmit a single byte encapsulated in a 32-bit transfer. Unused
bits are padded with 1s. */
static int usbtiny_tpi_tx(PROGRAMMER *pgm, unsigned char b0)
{
unsigned char res[4];
@ -239,8 +233,8 @@ static int usbtiny_tpi_tx(PROGRAMMER *pgm, unsigned char b0)
return 1;
}
/* Transmit a two bytes encapsulated in a 32-bit transfer. Unused
bits are padded with 1s. */
/* Transmit a two bytes encapsulated in a 32-bit transfer. Unused
bits are padded with 1s. */
static int usbtiny_tpi_txtx(PROGRAMMER *pgm,
unsigned char b0, unsigned char b1)
{
@ -269,11 +263,11 @@ static int usbtiny_tpi_txrx(PROGRAMMER *pgm, unsigned char b0)
return -1;
w = (res[2] << 8) | res[3];
/* Look for start bit (there shoule be no more than two 1 bits): */
/* Look for start bit (there should be no more than two 1 bits): */
while (w < 0)
w <<= 1;
/* Now that we found the start bit, the top 9 bits contain the start
bit and the 8 data bits, but the latter in reverse order. */
bit and the 8 data bits, but the latter in reverse order. */
r = reverse(w >> 7);
if (tpi_parity(r) != ((w >> 6) & 1)) {
fprintf(stderr, "%s: parity bit is wrong\n", __func__);
@ -336,7 +330,7 @@ static int usbtiny_open(PROGRAMMER* pgm, char* name)
}
usb_init(); // initialize the libusb system
usb_find_busses(); // have libusb scan all the usb busses available
usb_find_busses(); // have libusb scan all the usb buses available
usb_find_devices(); // have libusb scan all the usb devices available
PDATA(pgm)->usb_handle = NULL;
@ -357,7 +351,7 @@ static int usbtiny_open(PROGRAMMER* pgm, char* name)
}
// now we iterate through all the busses and devices
// now we iterate through all the buses and devices
for ( bus = usb_busses; bus; bus = bus->next ) {
for ( dev = bus->devices; dev; dev = dev->next ) {
if (dev->descriptor.idVendor == vid
@ -557,9 +551,9 @@ int usbtiny_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd,
int tx, rx, r;
/* Transmits command two bytes at the time until we're down to 0 or
1 command byte. Then we're either done or we transmit the final
byte optionally followed by reading 1 byte. With the current TPI
protocol, we never receive more than one byte. */
1 command byte. Then we're either done or we transmit the final
byte optionally followed by reading 1 byte. With the current TPI
protocol, we never receive more than one byte. */
for (tx = rx = 0; tx < cmd_len; ) {
b0 = cmd[tx++];
if (tx < cmd_len) {
@ -714,7 +708,7 @@ static int usbtiny_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
m->buf + addr, // Pointer to data
chunk, // Number of bytes to write
32 * PDATA(pgm)->sck_period + delay // each byte gets turned into a
// 4-byte SPI cmd usb_out() multiplies
// 4-byte SPI cmd usb_out() multiplies
// this per byte. Then add the cmd-delay
) < 0) {
return -1;