diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build.yml similarity index 50% rename from .github/workflows/build_cmake.yml rename to .github/workflows/build.yml index bcbf72ef..3f50c3b6 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build.yml @@ -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: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000..f486cec8 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -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 . +# + +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 diff --git a/.gitignore b/.gitignore index 60305807..70fcb545 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ INSTALL Makefile.in Makefile ac_cfg.h.in +ac_cfg.h.in~ aclocal.m4 autom4te.cache configure diff --git a/NEWS b/NEWS index 6098f34c..d3687459 100644 --- a/NEWS +++ b/NEWS @@ -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: diff --git a/README.md b/README.md index 3296487f..5c0c05ff 100644 --- a/README.md +++ b/README.md @@ -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 Microchip’s [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). diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4e6a16b5..8fbb21d7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 diff --git a/src/Makefile.am b/src/Makefile.am index 834f32fc..dd7adb57 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/avrdude.1 b/src/avrdude.1 index d83f398f..0cadf9ab 100644 --- a/src/avrdude.1 +++ b/src/avrdude.1 @@ -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[=] +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: diff --git a/src/avrdude.conf.in b/src/avrdude.conf.in index 29010407..29107feb 100644 --- a/src/avrdude.conf.in +++ b/src/avrdude.conf.in @@ -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 #------------------------------------------------------------ diff --git a/src/avrdude.h b/src/avrdude.h index 738578f1..9574c78a 100644 --- a/src/avrdude.h +++ b/src/avrdude.h @@ -16,48 +16,32 @@ * along with this program. If not, see . */ -/* $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 - -#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 diff --git a/src/avrftdi.c b/src/avrftdi.c index e7437ddc..e41d775e 100644 --- a/src/avrftdi.c +++ b/src/avrftdi.c @@ -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) { diff --git a/src/avrftdi_private.h b/src/avrftdi_private.h index e89d250e..3c965ed8 100644 --- a/src/avrftdi_private.h +++ b/src/avrftdi_private.h @@ -12,11 +12,14 @@ # include # 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 #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 diff --git a/src/avrftdi_tpi.c b/src/avrftdi_tpi.c index d82444e8..efb56266 100644 --- a/src/avrftdi_tpi.c +++ b/src/avrftdi_tpi.c @@ -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; diff --git a/src/bitbang.c b/src/bitbang.c index fe06c425..592ca124 100644 --- a/src/bitbang.c +++ b/src/bitbang.c @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -/* $Id$ */ + /* $Id$ */ #include "ac_cfg.h" @@ -28,9 +28,12 @@ #include #include -#if !defined(WIN32NATIVE) -# include -# include +#if defined(WIN32) +#define WIN32_LEAN_AND_MEAN +#include +#else +#include +#include #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 */ } /* diff --git a/src/buspirate.c b/src/buspirate.c index 84b2f042..36848179 100644 --- a/src/buspirate.c +++ b/src/buspirate.c @@ -41,9 +41,6 @@ #include #include #include -#if defined(WIN32NATIVE) -# include /* 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]); diff --git a/src/cmake_config.h.in b/src/cmake_config.h.in index d4ca65a6..4b051b04 100644 --- a/src/cmake_config.h.in +++ b/src/cmake_config.h.in @@ -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 header file. */ -#cmakedefine HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDLIB_H 1 - -/* Define to 1 if you have the 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 header file. */ -#cmakedefine HAVE_NETINET_IN_H 1 diff --git a/src/config_gram.y b/src/config_gram.y index 468706e5..d82fae9e 100644 --- a/src/config_gram.y +++ b/src/config_gram.y @@ -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, diff --git a/src/configure.ac b/src/configure.ac index 21442bb9..5527ad6c 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -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 " - else - HIDINCLUDE="#include \"my_ddk_hidsdi.h\"" - fi + HIDINCLUDE="#include " ;; *) 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. diff --git a/src/confwin.c b/src/confwin.c index 95446156..9624947f 100644 --- a/src/confwin.c +++ b/src/confwin.c @@ -20,35 +20,29 @@ #include "avrdude.h" #include "libavrdude.h" -#if defined(WIN32NATIVE) +#if defined(WIN32) -#include +#define WIN32_LEAN_AND_MEAN #include - 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 - - diff --git a/src/dfu.h b/src/dfu.h index 020a75f2..fa5da416 100644 --- a/src/dfu.h +++ b/src/dfu.h @@ -61,7 +61,7 @@ struct dfu_dev #else struct dfu_dev { - // empty + int dummy; }; #endif diff --git a/src/doc/TODO b/src/doc/TODO deleted file mode 100644 index 6c57c5ad..00000000 --- a/src/doc/TODO +++ /dev/null @@ -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 diff --git a/src/doc/avrdude.texi b/src/doc/avrdude.texi index e7fea1b7..06a40219 100644 --- a/src/doc/avrdude.texi +++ b/src/doc/avrdude.texi @@ -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 diff --git a/src/fileio.c b/src/fileio.c index e03aa7fa..7c021ce4 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -35,7 +35,7 @@ #include #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) { diff --git a/src/flip1.c b/src/flip1.c index 220a9426..0c8a3ab2 100644 --- a/src/flip1.c +++ b/src/flip1.c @@ -23,6 +23,7 @@ #include "ac_cfg.h" +#include #include #include #include @@ -30,13 +31,6 @@ #include #include -#if HAVE_STDINT_H -#include -#elif HAVE_INTTYPES_H -#include -#endif - - #include "avrdude.h" #include "libavrdude.h" diff --git a/src/flip2.c b/src/flip2.c index ba90086a..750be244 100644 --- a/src/flip2.c +++ b/src/flip2.c @@ -20,6 +20,7 @@ #include "ac_cfg.h" +#include #include #include #include @@ -27,12 +28,6 @@ #include #include -#if HAVE_STDINT_H -#include -#elif HAVE_INTTYPES_H -#include -#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; } diff --git a/src/ft245r.c b/src/ft245r.c index 3964bd6a..d009d9ed 100644 --- a/src/ft245r.c +++ b/src/ft245r.c @@ -73,10 +73,6 @@ #define TPIPCR_GT_0b 0x07 #define TPI_STOP_BITS 0x03 -#if defined(_WIN32) -#include -#endif - #if defined(HAVE_LIBFTDI1) && defined(HAVE_LIBUSB_1_0) # if defined(HAVE_LIBUSB_1_0_LIBUSB_H) # include @@ -84,11 +80,14 @@ # include # endif # include -#elif defined(HAVE_LIBFTDI) && defined(HAVE_USB_H) -/* ftdi.h includes usb.h */ +#elif defined(HAVE_LIBFTDI) #include #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 diff --git a/src/libavrdude.h b/src/libavrdude.h index 0d1bf3a3..40b49b53 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -27,15 +27,9 @@ #include #include #include - -/* lets try to select at least 32 bits */ -#ifdef HAVE_STDINT_H #include -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 */ diff --git a/src/linuxspi.c b/src/linuxspi.c index 1ad6bcda..d0912e1a 100644 --- a/src/linuxspi.c +++ b/src/linuxspi.c @@ -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) { diff --git a/src/main.c b/src/main.c index c56c933a..6fd432ec 100644 --- a/src/main.c +++ b/src/main.c @@ -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. /../etc/avrdude.conf - * 2. /avrdude.conf - * 3. CONFIG_DIR/avrdude.conf - * - * When found, write the result into the 'sys_config' variable. - */ - if (executable_abspath_found) { - // 1. Check /../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 /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/../etc/avrdude.conf + * 2. /avrdude.conf + * 3. CONFIG_DIR/avrdude.conf + * + * When found, write the result into the 'sys_config' variable. + */ + if (executable_abspath_found) { + // 1. Check /../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 /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) { diff --git a/src/micronucleus.c b/src/micronucleus.c index ef758078..b3c25341 100644 --- a/src/micronucleus.c +++ b/src/micronucleus.c @@ -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()); diff --git a/src/msvc/getopt.c b/src/msvc/getopt.c new file mode 100644 index 00000000..9a0347d4 --- /dev/null +++ b/src/msvc/getopt.c @@ -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 + * + * 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 +#include +#include +#include +#include +#include +#include + +#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)); +} diff --git a/src/msvc/getopt.h b/src/msvc/getopt.h new file mode 100644 index 00000000..1922a0ef --- /dev/null +++ b/src/msvc/getopt.h @@ -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 + +#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__) */ diff --git a/src/msvc/gettimeofday.c b/src/msvc/gettimeofday.c new file mode 100644 index 00000000..eb62d0c7 --- /dev/null +++ b/src/msvc/gettimeofday.c @@ -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 +#include +#include +#include +#include + +#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; +} diff --git a/src/msvc/msvc_compat.h b/src/msvc/msvc_compat.h new file mode 100644 index 00000000..eb3e026a --- /dev/null +++ b/src/msvc/msvc_compat.h @@ -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 . + */ + +#pragma once +#include +#include +#include +#include +#include + +#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); +} diff --git a/src/msvc/sys/time.h b/src/msvc/sys/time.h new file mode 100644 index 00000000..d5c3a8c4 --- /dev/null +++ b/src/msvc/sys/time.h @@ -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 . + */ + +#ifndef _TIME_H_ +#define _TIME_H_ + +// If you need both and , +// make sure you include 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 diff --git a/src/msvc/unistd.h b/src/msvc/unistd.h new file mode 100644 index 00000000..49d5114e --- /dev/null +++ b/src/msvc/unistd.h @@ -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 . + */ + +#ifndef _UNISTD_H +#define _UNISTD_H + +#define STDIN_FILENO _fileno(stdin) +#define STDERR_FILENO _fileno(stderr) + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned int useconds_t; +int usleep(unsigned int us); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/msvc/usleep.cpp b/src/msvc/usleep.cpp new file mode 100644 index 00000000..6759b721 --- /dev/null +++ b/src/msvc/usleep.cpp @@ -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 . + */ + +#include "unistd.h" + +#define WIN32_LEAN_AND_MEAN +#include +#include +#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(¤t); + 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); +} diff --git a/src/my_ddk_hidsdi.h b/src/my_ddk_hidsdi.h deleted file mode 100644 index 46c17d67..00000000 --- a/src/my_ddk_hidsdi.h +++ /dev/null @@ -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 . - */ - -/* $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 -#include -#include -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 -#endif /* MY_DDK_HIDSDI_H */ diff --git a/src/pgm_type.c b/src/pgm_type.c index 195b6ffb..8afb50bd 100644 --- a/src/pgm_type.c +++ b/src/pgm_type.c @@ -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}, diff --git a/src/pickit2.c b/src/pickit2.c index 5a0a5f6c..9e4be94c 100644 --- a/src/pickit2.c +++ b/src/pickit2.c @@ -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 -#if defined(HAVE_DDK_HIDSDI_H) -# include -#else -# include "my_ddk_hidsdi.h" -#endif +#include #include #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"; diff --git a/src/pindefs.c b/src/pindefs.c index 5753fc67..5acb33fd 100644 --- a/src/pindefs.c +++ b/src/pindefs.c @@ -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. diff --git a/src/ppi.c b/src/ppi.c index 2706b850..4478115f 100644 --- a/src/ppi.c +++ b/src/ppi.c @@ -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 */ diff --git a/src/ppiwin.c b/src/ppiwin.c index bedbaf92..71ec0a9f 100644 --- a/src/ppiwin.c +++ b/src/ppiwin.c @@ -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 #include #include @@ -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 - - diff --git a/src/ser_avrdoper.c b/src/ser_avrdoper.c index 8eae2c3f..2e90f0eb 100644 --- a/src/ser_avrdoper.c +++ b/src/ser_avrdoper.c @@ -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 #include @@ -161,15 +161,11 @@ static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNum /* ------------------------------------------------------------------------ */ +#define WIN32_LEAN_AND_MEAN #include #include - -#if defined(HAVE_DDK_HIDSDI_H) -# include -#else -# include "my_ddk_hidsdi.h" -#endif -#include +#include +#include #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)) */ diff --git a/src/ser_posix.c b/src/ser_posix.c index 3d8e15a1..96d665f0 100644 --- a/src/ser_posix.c +++ b/src/ser_posix.c @@ -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 */ diff --git a/src/ser_win32.c b/src/ser_win32.c index 25412cf0..fa4d7aba 100644 --- a/src/ser_win32.c +++ b/src/ser_win32.c @@ -17,22 +17,18 @@ * along with this program. If not, see . */ -/* $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 -#endif +#if defined(WIN32) +#define WIN32_LEAN_AND_MEAN #include +#include +#include #include #include /* for isprint */ #include /* 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 */ diff --git a/src/serbb_posix.c b/src/serbb_posix.c index a7dd0997..9f10dccf 100644 --- a/src/serbb_posix.c +++ b/src/serbb_posix.c @@ -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 */ diff --git a/src/serbb_win32.c b/src/serbb_win32.c index 0e889745..9a58be10 100644 --- a/src/serbb_win32.c +++ b/src/serbb_win32.c @@ -25,11 +25,12 @@ #include "avrdude.h" -#if defined(WIN32NATIVE) +#if defined(WIN32) #include "ac_cfg.h" +#define WIN32_LEAN_AND_MEAN #include #include @@ -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 */ diff --git a/src/stk500.c b/src/stk500.c index 88944afc..ea87b899 100644 --- a/src/stk500.c +++ b/src/stk500.c @@ -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; diff --git a/src/stk500v2.c b/src/stk500v2.c index f6c5b1ca..11aa9a94 100644 --- a/src/stk500v2.c +++ b/src/stk500v2.c @@ -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 diff --git a/src/teensy.c b/src/teensy.c new file mode 100644 index 00000000..b6bfc772 --- /dev/null +++ b/src/teensy.c @@ -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 . + */ + +// 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 +#include +#include +#include +#include +#include +#include +#include +#include "avrdude.h" +#include "teensy.h" +#include "usbdevs.h" + +#if defined(HAVE_LIBHIDAPI) + +#include + +//----------------------------------------------------------------------------- + +#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"; diff --git a/src/teensy.h b/src/teensy.h new file mode 100644 index 00000000..8cec458a --- /dev/null +++ b/src/teensy.h @@ -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 . + */ + +#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 */ diff --git a/src/term.c b/src/term.c index 28aa6253..96bf2bce 100644 --- a/src/term.c +++ b/src/term.c @@ -27,11 +27,9 @@ #include #if defined(HAVE_LIBREADLINE) -#if !defined(WIN32NATIVE) # include # include #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 - -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) diff --git a/src/updi_readwrite.c b/src/updi_readwrite.c index 3ee19cb0..dcc3a849 100644 --- a/src/updi_readwrite.c +++ b/src/updi_readwrite.c @@ -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) diff --git a/src/usb_hidapi.c b/src/usb_hidapi.c index 81e9c4ab..d23c628e 100644 --- a/src/usb_hidapi.c +++ b/src/usb_hidapi.c @@ -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. diff --git a/src/usb_libusb.c b/src/usb_libusb.c index 235e330a..0d9ad440 100644 --- a/src/usb_libusb.c +++ b/src/usb_libusb.c @@ -48,7 +48,7 @@ #include "usbdevs.h" -#if defined(WIN32NATIVE) +#if defined(WIN32) /* someone has defined "interface" to "struct" in Cygwin */ # undef interface #endif diff --git a/src/usbtiny.c b/src/usbtiny.c index 0360d68f..4c6fefcf 100644 --- a/src/usbtiny.c +++ b/src/usbtiny.c @@ -52,13 +52,7 @@ #define TPIPCR_GT_0b 0x07 #define TPI_STOP_BITS 0x03 -#ifdef HAVE_NETINET_IN_H -# include -# 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;