Compare commits

...

25 Commits

Author SHA1 Message Date
Marius Greuel 91be527265 Add CMakeSettings.json for Visual Studio 2022 2022-02-20 18:17:10 +01:00
Marius Greuel 33bba04124 Update GitHub deploy action 2022-02-20 17:46:09 +01:00
Marius Greuel 231e42ca13 Update README.md 2022-02-20 17:41:49 +01:00
Marius Greuel 8692169f6d Add support for COM port discovery via USB VID/PID Add support for Leonardo USB bootloader auto-reset 2022-02-20 14:44:28 +01:00
Marius Greuel 0a452105f4 Correct endpoint direction for control messages of USBtinyISP devices 2022-02-20 14:44:28 +01:00
Marius Greuel b76c9522e7 Change Intel HEX line length from 32 to 16 to match line length of avr-objcopy 2022-02-20 14:44:28 +01:00
Marius Greuel 6d24d95594 Change program URL to github.com 2022-02-20 14:44:27 +01:00
Joerg Wunsch c7d1ebcf1f Issue #881 also fixed 2022-02-20 14:37:04 +01:00
Joerg Wunsch b891b7c64b Issue #874 is closed 2022-02-20 14:35:50 +01:00
Joerg Wunsch 428cd89e8d PRs #878, #873, #885 done 2022-02-19 21:54:23 +01:00
Jörg Wunsch 3efd3b2052
Merge pull request #873 from MCUdude/add-arduino-programmers
Add missing USBtiny derived programmers
2022-02-19 21:51:31 +01:00
Jörg Wunsch 7c65adba26
Merge pull request #885 from dbuchwald/simple_updi_fix
Smallest possible fix for PL2303HX
2022-02-19 21:50:41 +01:00
Dawid Buchwald 75ab3c418e Fixed warning with unsigned char 2022-02-19 21:18:03 +01:00
Dawid Buchwald de19f203e0 Smallest possible fix for PL2303HX 2022-02-19 15:07:32 +01:00
Jörg Wunsch d054c68b19
Merge pull request #878 from MCUdude/fix-pkob-target-voltage
Fix Curiosity Nano target voltage
2022-02-18 23:01:49 +01:00
Joerg Wunsch 5c90fbbaae PR #877 done 2022-02-18 22:53:45 +01:00
Jörg Wunsch c2fe68ef7d
Merge pull request #877 from MCUdude/jtag3-verbosity
Reduce jtag3 output verbosity
2022-02-18 22:38:40 +01:00
Joerg Wunsch c1ec836fbd PR #882 done 2022-02-18 21:37:27 +01:00
Jörg Wunsch ba01fd7e30
Merge pull request #882 from mariusgreuel/pr-libhid-cleanup-part1
Remove libhid support in ser_avrdoper.c in favor of libhidapi
2022-02-18 21:36:12 +01:00
Marius Greuel 59ecd4cc65 Remove libhid support in ser_avrdoper.c in favor of libhidapi 2022-02-18 20:05:52 +01:00
Marius Greuel e31be88ce0 Add LIB_LIBHID to CMake project to fix MinGW build issue 2022-02-18 19:58:13 +01:00
MCUdude 19e2cae053 Add Curiosity Nano to terminal list 2022-02-14 10:30:21 +01:00
MCUdude 932f68f24c Set target voltage even thoug not target is detected 2022-02-14 10:28:54 +01:00
MCUdude b1d34a510c Reduce jtag3 output verbosity 2022-02-13 19:23:48 +01:00
MCUdude f2bdcbe977 Add missing USBtiny derived programmers
ArduinoISP and the Arduino.org ISP are commercial versions of the USBtiny programmer with different USB VIDs/PIDs
2022-02-11 22:46:11 +01:00
20 changed files with 1675 additions and 263 deletions

View File

@ -25,7 +25,7 @@ on:
jobs:
build:
uses: avrdudes/avrdude/.github/workflows/build.yml@main
uses: mariusgreuel/avrdude/.github/workflows/build.yml@windows
release:
needs: build

View File

@ -182,6 +182,9 @@ endif()
# Find libhidapi
find_library(HAVE_LIBHID NAMES hid)
if(HAVE_LIBHID)
set(LIB_LIBHID ${HAVE_LIBHID})
endif()
find_library(HAVE_LIBHIDAPI NAMES ${PREFERRED_LIBHIDAPI})
if(HAVE_LIBHIDAPI)

126
CMakeSettings.json Normal file
View File

@ -0,0 +1,126 @@
{
"configurations": [
{
"name": "x86-Debug",
"generator": "Visual Studio 17 2022",
"configurationType": "Debug",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x86" ],
"variables": [
{
"name": "DEBUG_CMAKE",
"value": "True",
"type": "BOOL"
},
{
"name": "USE_EXTERNAL",
"value": "True",
"type": "BOOL"
}
]
},
{
"name": "x86-Release",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x86" ],
"variables": [
{
"name": "DEBUG_CMAKE",
"value": "True",
"type": "BOOL"
},
{
"name": "USE_EXTERNAL",
"value": "True",
"type": "BOOL"
},
{
"name": "CMAKE_C_FLAGS_RELWITHDEBINFO",
"value": "/MT /GL /Zi /O2 /Ob1 /DNDEBUG",
"type": "STRING"
},
{
"name": "CMAKE_CXX_FLAGS_RELWITHDEBINFO",
"value": "/MT /GL /Zi /O2 /Ob1 /DNDEBUG",
"type": "STRING"
},
{
"name": "CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO",
"value": "/debug /INCREMENTAL:NO /LTCG /OPT:REF /OPT:ICF",
"type": "STRING"
}
]
},
{
"name": "x64-Debug",
"generator": "Visual Studio 17 2022 Win64",
"configurationType": "Debug",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x64_x64" ],
"variables": [
{
"name": "DEBUG_CMAKE",
"value": "True",
"type": "BOOL"
},
{
"name": "USE_EXTERNAL",
"value": "True",
"type": "BOOL"
}
]
},
{
"name": "x64-Release",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x64_x64" ],
"variables": [
{
"name": "DEBUG_CMAKE",
"value": "True",
"type": "BOOL"
},
{
"name": "USE_EXTERNAL",
"value": "True",
"type": "BOOL"
},
{
"name": "CMAKE_C_FLAGS_RELWITHDEBINFO",
"value": "/MT /GL /Zi /O2 /Ob1 /DNDEBUG",
"type": "STRING"
},
{
"name": "CMAKE_CXX_FLAGS_RELWITHDEBINFO",
"value": "/MT /GL /Zi /O2 /Ob1 /DNDEBUG",
"type": "STRING"
},
{
"name": "CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO",
"value": "/debug /INCREMENTAL:NO /LTCG /OPT:REF /OPT:ICF",
"type": "STRING"
}
]
}
]
}

7
NEWS
View File

@ -68,6 +68,8 @@ Changes since version 6.4:
- Segmentation fault when writing ATtiny104 fuse #823
- USBasp returns ERANGE for unknown error #848
- Compiler warnings #856
- Can't get serialupdi to work #874
- Rework HID support for Windows #881
* Pull requests:
@ -131,6 +133,11 @@ Changes since version 6.4:
- Add fuse name aliases to avrdude.conf + tweak update.c #869
- Print JTAG3 clocks after configuration + string formatting #853
- Tweak programmer info formatting strings #872
- Remove libhid support in ser_avrdoper.c in favor of libhidapi #882
- Reduce jtag3 output verbosity #877
- Fix Curiosity Nano target voltage #878
- Smallest possible fix for PL2303HX #885
- Add missing USBtiny derived programmers #873
* Internals:

60
README-old.md Normal file
View File

@ -0,0 +1,60 @@
# AVRDUDE
[![Build Status](https://github.com/avrdudes/avrdude/actions/workflows/build.yml/badge.svg)](https://github.com/avrdudes/avrdude/actions/workflows/build.yml)
AVRDUDE - AVR Downloader Uploader - is a program for downloading and uploading
the on-chip memories of Microchips [AVR microcontrollers](https://en.wikipedia.org/wiki/AVR_microcontrollers).
It can program the Flash and EEPROM, and where supported by the programming
protocol, it can program fuse and lock bits.
AVRDUDE also supplies a direct instruction mode allowing one to issue any
programming instruction to the AVR chip regardless of whether AVRDUDE
implements that specific feature of a particular chip.
AVRDUDE was originally written in 2003 by Brian S. Dean. Since 2006, AVRDUDE has been maintained by Jörg Wunsch,
with the help of [various contributors](./AUTHORS).
The latest version of AVRDUDE is always available here:\
<https://github.com/avrdudes/avrdude>
## Getting AVRDUDE for Windows
To get AVRDUDE for Windows, install the latest version from the [Releases](http://download.savannah.gnu.org/releases/avrdude/) page.
Alternatively, you may [build AVRDUDE](https://github.com/avrdudes/avrdude/wiki) yourself from source.
## Getting AVRDUDE for Linux
To install AVRDUDE for Linux, install the package `avrdude` by running the following commands:
```console
sudo apt-get install avrdude
```
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](https://github.com/avrdudes/avrdude/wiki) yourself from source.
## Using AVRDUDE
AVRDUDE is a command-line application. Run the command `avrdude` without any arguments for a list of options.
A typical command to program your HEX file into your AVR microcontroller looks like this:
```console
avrdude -c <programmer> -p <part> -U flash:w:<file>:i
```
For instance, to program an **Arduino Uno** connected to the serial port **COM1** with a HEX file called `blink.hex`,
you would run the following command:
```console
avrdude -c arduino -P COM1 -b 115200 -p atmega328p -D -U flash:w:objs/blink.hex:i
```
There are many different programmers and options that may be required for the programming to succeed.
For more information, refer to the [AVRDUDE documentation](http://download.savannah.gnu.org/releases/avrdude/avrdude-doc-6.4.pdf).

226
README.md
View File

@ -1,60 +1,220 @@
# AVRDUDE
# AVRDUDE for Windows
[![Build Status](https://github.com/avrdudes/avrdude/actions/workflows/build.yml/badge.svg)](https://github.com/avrdudes/avrdude/actions/workflows/build.yml)
[![Build Status](https://github.com/mariusgreuel/avrdude/actions/workflows/build.yml/badge.svg?branch=windows)](https://github.com/mariusgreuel/avrdude/actions/workflows/build.yml)
AVRDUDE - AVR Downloader Uploader - is a program for downloading and uploading
the on-chip memories of Microchips [AVR microcontrollers](https://en.wikipedia.org/wiki/AVR_microcontrollers).
It can program the Flash and EEPROM, and where supported by the programming
protocol, it can program fuse and lock bits.
AVRDUDE also supplies a direct instruction mode allowing one to issue any
programming instruction to the AVR chip regardless of whether AVRDUDE
implements that specific feature of a particular chip.
This is a fork of AVRDUDE 6.4 from <https://github.com/avrdudes/avrdude>.
AVRDUDE was originally written in 2003 by Brian S. Dean. Since 2006, AVRDUDE has been maintained by Jörg Wunsch,
with the help of [various contributors](./AUTHORS).
The purpose of this fork is to add better support for Windows to bring it on par with the Linux version of AVRDUDE.
The latest version of AVRDUDE is always available here:\
<https://github.com/avrdudes/avrdude>
Noteable changes include:
## Getting AVRDUDE for Windows
- [Support Atmel AVR programmers out of the box](#support-atmel-avr-programmers-out-of-the-box)
- [Support Micronucleus bootloader](#support-micronucleus-bootloader)
- [Support Teensy HalfKay bootloader](#support-teensy-halfkay-bootloader)
- [Support COM port discovery via USB VID/PID](#support-com-port-discovery-via-usb-vidpid)
- [Support Arduino Leonardo bootloader auto-reset](#support-arduino-leonardo-bootloader-auto-reset)
- [Support WinUSB devices via custom libusb](#support-winusb-devices-via-custom-libusb)
- [Support FTDI devices via custom libftdi](#support-ftdi-devices-via-custom-libftdi)
- [Support HID devices via libhidapi](#support-hid-devices-via-libhidapi)
- [Support Visual Studio](#support-visual-studio)
- [Miscellaneous bug-fixes and patches](#miscellaneous-bug-fixes-and-patches)
To get AVRDUDE for Windows, install the latest version from the [Releases](http://download.savannah.gnu.org/releases/avrdude/) page.
The original AVRDUDE project homepage can be found here <https://savannah.nongnu.org/projects/avrdude>.
Alternatively, you may [build AVRDUDE](https://github.com/avrdudes/avrdude/wiki) yourself from source.
## Download
## Getting AVRDUDE for Linux
To get the latest version of **AVRDUDE for Windows**, go to the [releases folder](https://github.com/mariusgreuel/avrdude/releases):
To install AVRDUDE for Linux, install the package `avrdude` by running the following commands:
<https://github.com/mariusgreuel/avrdude/releases>
## Feature Details
### Support Atmel AVR programmers out of the box
This build contains support for Atmel AVR programmers, such as
- [Atmel-ICE](https://www.microchip.com/DevelopmentTools/ProductDetails/ATATMEL-ICE) (Part Number: ATATMEL-ICE)
- [Atmel AVRISP mkII](https://www.microchip.com/DevelopmentTools/ProductDetails/PartNO/ATAVRISP2) (Part Number: ATAVRISP2)
This build does not rely on **libusb** drivers. Instead the default Atmel drivers can be used, allowing you to use AVRDUDE and Atmel Studio 7 side-by-side, without switching drivers.
If you previously changed the driver of your programmer to libusb, you should use **Windows Device Manager** to uninstall the device, and then reinstall using the default Windows drivers.
### Support Micronucleus bootloader
This build adds support for the [Micronucleus bootloader](https://github.com/micronucleus/micronucleus), so you do no longer need a separate command-line utility when working with devices that use the Micronucleus bootloader.
The Micronucleus bootloader is typically used on small ATtiny boards, such as **Digispark** (ATtiny85), **Digispark Pro** (ATtiny167), and the respective clones.
By default, it uses the USB VID/PID **16D0:0753** (MCS Digistump).
Since this bootloader is optimized for size, it implements writing to flash memory only.
As it does not support reading, you need to 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: Flashing a Micronucleus bootloader device
```console
sudo apt-get install avrdude
avrdude -c micronucleus -p t85 -x wait -V -U flash:w:main.hex:i
```
Alternatively, you may [build AVRDUDE](https://github.com/avrdudes/avrdude/wiki) yourself from source.
### Support Teensy HalfKay bootloader
## Getting AVRDUDE for MacOS
This build adds support for the [Teensy HalfKay bootloader](https://www.pjrc.com/teensy/halfkay_protocol.html), so you do no longer need a the Teensy Loader tool when working with Teensy devices.
On MacOS, AVRDUDE can be installed through Mac Ports.
Since this bootloader is optimized for size, it implements writing to flash memory only.
As it does not support reading, you need to 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'.
Alternatively, you may [build AVRDUDE](https://github.com/avrdudes/avrdude/wiki) yourself from source.
Supported devices are:
## Using AVRDUDE
- Teensy 1.0 (AT90USB162)
- Teensy 2.0 (ATmega32U4)
- Teensy++ 1.0 (AT90USB646)
- Teensy++ 2.0 (AT90USB1286)
AVRDUDE is a command-line application. Run the command `avrdude` without any arguments for a list of options.
A typical command to program your HEX file into your AVR microcontroller looks like this:
#### Example: Flashing a Teensy 2.0 device
```console
avrdude -c <programmer> -p <part> -U flash:w:<file>:i
avrdude -c teensy -p m32u4 -x wait -V -U flash:w:main.hex:i
```
For instance, to program an **Arduino Uno** connected to the serial port **COM1** with a HEX file called `blink.hex`,
you would run the following command:
### Support COM port discovery via USB VID/PID
Most Arduino boards use a USB-based virtual COM port, which is connected to some sort of bootloader. Since COM port numbers (COM1, COM2, ...) are determined by Windows, you first need to use Windows device manager to figure out the COM port before you can use AVRDUDE to flash the board. Alternatively, you may use Windows device manager to assign a COM port of your choice to the USB device. Additionally, the COM port of your Arduino board may change over time, for instance if you plug the device in a different USB port.
To simplify the discovery of your Arduino board, I provided the possibility to specify the USB vendor and product ID instead of the COM port.
For instance, to connect to an Arduino Leonardo, use the following command:
```console
avrdude -c arduino -P COM1 -b 115200 -p atmega328p -D -U flash:w:objs/blink.hex:i
avrdude -c avr109 -P usb:2341:0036 -p m32u4
```
There are many different programmers and options that may be required for the programming to succeed.
Since the USB vendor and device ID **2341:0036** is the identical for all Leonardo boards, the command above will work regardless of which COM port was actually assigned to your board.
Note that can cannot use this method if you have more than one device of the same type (i.e. that share the same USB VID/PID) plugged into your computer. Also, some devices ship various versions of firmwares using different VID/PID.
To figure out the USB VID and PID, you may use **Windows devices manager** (see the **Hardware IDs** of the **Details tab** of the USB device), or look it up in the official list of Arduino devices:
<https://github.com/arduino/ArduinoCore-avr/blob/master/boards.txt>
USB VID/PID pairs for some popular boards and the respective commands are:
- Arduino Uno Rev 3: **2A03:0043** -> `avrdude -c arduino -P usb:2A03:0043 -p m328p`
- Arduino Micro: **2341:0037** -> `avrdude -c avr109 -P usb:2341:0037 -p m32u4`
- Arduino Leonardo: **2341:0036** -> `avrdude -c avr109 -P usb:2341:0036 -p m32u4`
- Sparkfun Pro Micro (5V): **1B4F:9205** -> `avrdude -c avr109 -P usb:1B4F:9205 -p m32u4`
- Sparkfun Pro Micro (3.3V): **1B4F:9203** -> `avrdude -c avr109 -P usb:1B4F:9203 -p m32u4`
- Adafruit Circuit Playground: **239A:0011** -> `avrdude -c avr109 -P usb:239A:0011 -p m32u4`
### Support Arduino Leonardo bootloader auto-reset
Before any Arduino board may be flashed via the bootloader, you need to kick it into bootloader mode first. This can done manually by pressing the reset button, or automatically via an special auto-reset mechanism: For boards with a USB to serial converter chip (such as Arduino Uno or Nano), the tool needs to pull the DTR signal to low, which will briefly pull the RESET pin of the microcontroller to low. For boards with a direct USB connection (such as Arduino Leonardo or Micro), the sketch typically implements a serial port via a USB composite device with a virtual COM port. To perform the auto-reset, the sketch implements a hack that resets the device into bootloader mode when the COM port is opened with a baudrate of 1200bps. To make matters even more complicated, the bootloader COM port has a different USB VID:PID pair than the sketch COM port, which causes the COM port to change while performing the reset.
To simplify the process of auto-resetting the board, this version will auto-reset the device when AVRDUDE detects that the device is running in sketch mode. Note that the sketch is required to implement a USB composite device with a virtual COM port with a matching USB VID:PID, which is implemented in the Arduino core software.
### Support WinUSB devices via custom libusb
Since AVRDUDE originated from Unix, the USB support in AVRDUDE is built upon the Unix-based USB library [libusb](https://sourceforge.net/projects/libusb/). In order to support Windows, libusb has been ported to Windows [libusb-win32](https://sourceforge.net/projects/libusb-win32/).
The downside of using libusb-win32 is that it requires the user to manually install a kernel-mode driver (libusb0.sys or libusbk.sys) instead of the manufacturer supplied Windows driver. There are several hacks to accomplish this, such as the [Zadig driver installation utility](https://zadig.akeo.ie/), which installs a self-signed root certificate in the Windows driver store due to the lack of proper driver installation packages.
This build contains a custom library called **libwinusb**, which implements a sub-set of the libusb-win32 API. The libwinusb implementation supports both the **winusb.sys** driver, and the **libusb0.sys** driver as well. This patch has a number of advantages, such as
- Many USB devices that ship with WinUSB drivers, such as Atmel programmer, will run out of the box.
- Works with both WinUSB and libusb: You can use either Windows built-in WinUSB driver to access your USB devices, or keep using the libusb drivers if you have them installed already.
- No static dependency to libusb0.dll: You cannot run the original version AVRDUDE, unless you previously installed libusb. On systems where libusb is not installed, this build eliminates the error "The code execution cannot proceed because libusb0.dll was not found. Reinstalling the program may fix this problem".
#### Microsoft OS descriptors and firmware examples
Windows provides a mechanism to automatically load the built-in WinUSB driver without providing a driver installation package (INF file). The automatic WinUSB driver installation is triggered via a special [Microsoft OS descriptor](https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors) that must be present in the firmware of the USB device.
To demonstrate how this works, I added Microsoft OS descriptors to the following projects:
- **USBasp** - USB programmer for Atmel AVR controllers: <https://github.com/mariusgreuel/USBasp>
- **FabISP** a.k.a **USBtinyISP** - A fab-able in-system programmer: <https://github.com/mariusgreuel/FabISP>
- **Micronucleus** - ATtiny USB bootloader with a strong emphasis on bootloader compactness: <https://github.com/mariusgreuel/micronucleus>
### Support FTDI devices via custom libftdi
In order to support FTDI devices, AVRDUDE uses the Unix-based library [libftdi1](https://www.intra2net.com/en/developer/libftdi/). Similar to libusb, the libftdi1 library does not play nice on Windows: On Windows, FTDI devices load the manufacturer supplied driver via plug-and-play. The FTDI drivers implement an API via the FTDI D2XX DLLs. However, libftdi1 cannot use the D2XX interface, so it will not work with the plug-and-play drivers.
This build contains a patches library of **libftdi**. The patches load the D2XX DLLs to support FTDI devices, so FTDI devices will just work.
### Support HID devices via libhidapi
This build include the WIN32 version of libhidapi, and some patches, to allow HID devices to work out of the box.
### Support Visual Studio
This build adds support for **Microsoft Visual Studio**. Building AVRDUDE with Microsoft Visual C/C++ will give you the best user and debugging experience while working on Windows.
### Miscellaneous bug-fixes and patches
- This build fixes [bug #54159: Buffer overflow in usbtiny.c](http://savannah.nongnu.org/bugs/?54159), which causes AVRDUDE to crash when using the USBtiny programmer.
- Support new microcontroller: ATtiny167
## Releases
You can find the latest releases of **AVRDUDE for Windows** here:
<https://github.com/mariusgreuel/avrdude/releases>
## Users manual
You can find the original users manual (does not contain AVRDUDE for Windows extras) of AVRDUDE here:
<https://www.nongnu.org/avrdude/user-manual/avrdude.html>
## Build
The build instructions have been moved here:\
<https://github.com/avrdudes/avrdude/wiki>
### Building AVRDUDE for Windows using MSVC
#### Windows Prerequisites
In order to build AVRDUDE on Windows, you need:
- Flex and Bison installed, for instance via [Chocolatey](https://chocolatey.org/)
- Microsoft Visual Studio 2019 with **Desktop development with C++** and **CMake** enabled
#### Windows Build Instructions
To build AVRDUDE on Windows, do the following:
- `git clone --branch windows https://github.com/mariusgreuel/avrdude`
- Open the folder **avrdude** using the menu item **File->Open->Folder**
- Build the project using the menu item **Build->Build All**
### Linux udev rules
If you intent to use either the Micronucleus or Teensy bootloader, you should edit the udev rules so that you can run AVRDUDE without root.
For instance, if you are on Ubuntu and you installed the avrdude package, you would edit `/lib/udev/rules.d/60-avrdude.rules` and add the following rules:
```console
# Micronucleus Bootloader
SUBSYSTEM=="usb", ATTR{idVendor}=="16d0", ATTR{idProduct}=="0753", TAG+="uaccess"
# Teensy Bootloader
SUBSYSTEM=="usb", ATTR{idVendor}=="16c0", ATTR{idProduct}=="0478", TAG+="uaccess"
```
## Troubleshooting Tips & Tricks
### Atmel DFU Device driver broken
The current version of the Atmel DFU drivers that are distributed via the Windows Update are goofed up (@Atmel: It might have something to do with the fact that you commented out the CopyFiles sections!).
Symptoms are:
- You cannot use AVRDUDE to connect to an Atmel DFU device, and you get the error message "No matching USB device found".
- When installing the drivers via Windows Update, you get the error message "Windows encountered a problem installing the drivers for your device" and "A service installation section in this INF is invalid."
- In Windows Device Manager, the Atmel DFU device shows up as an unknown device.
You should use an older driver package that does not contain this bug.
### Outdated libusb0 driver
The most current version of libusb0.sys is 1.2.6.0, signed on 12/17/2012 by Travis Lee Robinson. If you are using an older version (check with Windows Device Manager), you may not be able to connect to your USB devices using the libusb0 driver.
For more information, refer to the [AVRDUDE documentation](http://download.savannah.gnu.org/releases/avrdude/avrdude-doc-6.4.pdf).

View File

@ -75,6 +75,7 @@ if(MSVC)
"msvc/getopt.c"
"msvc/gettimeofday.c"
"msvc/usleep.cpp"
"msvc/usb_com_helper.cpp"
)
set(EXTRA_WINDOWS_INCLUDES ${EXTRA_WINDOWS_INCLUDES}
"msvc"
@ -239,6 +240,7 @@ target_link_libraries(libavrdude
${LIB_LIBELF}
${LIB_LIBUSB}
${LIB_LIBUSB_1_0}
${LIB_LIBHID}
${LIB_LIBHIDAPI}
${LIB_LIBFTDI}
${LIB_LIBFTDI1}

View File

@ -886,6 +886,24 @@ programmer
usbpid = 0x0c9f;
;
programmer
id = "arduinoisp";
desc = "Arduino ISP Programmer";
type = "usbtiny";
connection_type = usb;
usbvid = 0x2341;
usbpid = 0x0049;
;
programmer
id = "arduinoisporg";
desc = "Arduino ISP Programmer";
type = "usbtiny";
connection_type = usb;
usbvid = 0x2A03;
usbpid = 0x0049;
;
# commercial version of USBtiny, using a separate VID/PID
programmer
id = "ehajo-isp";
@ -896,6 +914,16 @@ programmer
usbpid = 0x0BA5;
;
# commercial version of USBtiny, using a separate VID/PID
programmer
id = "iseavrprog";
desc = "USBtiny-based USB programmer, https://github.com/IowaScaledEngineering/ckt-avrprogrammer";
type = "usbtiny";
connection_type = usb;
usbvid = 0x1209;
usbpid = 0x6570;
;
programmer
id = "micronucleus";
desc = "Micronucleus Bootloader";
@ -914,16 +942,6 @@ programmer
usbpid = 0x0478;
;
# commercial version of USBtiny, using a separate VID/PID
programmer
id = "iseavrprog";
desc = "USBtiny-based USB programmer, https://github.com/IowaScaledEngineering/ckt-avrprogrammer";
type = "usbtiny";
connection_type = usb;
usbvid = 0x1209;
usbpid = 0x6570;
;
programmer
id = "butterfly";
desc = "Atmel Butterfly Development Board";

View File

@ -1159,7 +1159,7 @@ static int fileio_ihex(struct fioparms * fio,
switch (fio->op) {
case FIO_WRITE:
rc = b2ihex(mem->buf, size, 32, fio->fileoffset, filename, f);
rc = b2ihex(mem->buf, size, 16, fio->fileoffset, filename, f);
if (rc < 0) {
return -1;
}

View File

@ -493,7 +493,7 @@ static int jtag3_edbg_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
}
if (serial_send(&pgm->fd, buf, max_xfer) != 0) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_send(): failed to send command to serial port\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_send(): failed to send command to serial port\n",
progname);
return -1;
}
@ -509,7 +509,7 @@ static int jtag3_edbg_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
(frag == nfragments - 1 && status[1] != 0x01))
{
/* what to do in this case? */
avrdude_message(MSG_INFO, "%s: jtag3_edbg_send(): Unexpected response 0x%02x, 0x%02x\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_send(): Unexpected response 0x%02x, 0x%02x\n",
progname, status[0], status[1]);
}
data += this_len;
@ -596,36 +596,36 @@ static int jtag3_edbg_signoff(PROGRAMMER * pgm)
buf[1] = CMSISDAP_LED_CONNECT;
buf[2] = 0;
if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to send command to serial port\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_signoff(): failed to send command to serial port\n",
progname);
return -1;
}
rv = serial_recv(&pgm->fd, status, pgm->fd.usb.max_xfer);
if (rv != pgm->fd.usb.max_xfer) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
progname, rv);
return -1;
}
if (status[0] != CMSISDAP_CMD_LED ||
status[1] != 0)
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): unexpected response 0x%02x, 0x%02x\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_signoff(): unexpected response 0x%02x, 0x%02x\n",
progname, status[0], status[1]);
buf[0] = CMSISDAP_CMD_DISCONNECT;
if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to send command to serial port\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_signoff(): failed to send command to serial port\n",
progname);
return -1;
}
rv = serial_recv(&pgm->fd, status, pgm->fd.usb.max_xfer);
if (rv != pgm->fd.usb.max_xfer) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
progname, rv);
return -1;
}
if (status[0] != CMSISDAP_CMD_DISCONNECT ||
status[1] != 0)
avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): unexpected response 0x%02x, 0x%02x\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_signoff(): unexpected response 0x%02x, 0x%02x\n",
progname, status[0], status[1]);
return 0;
@ -686,12 +686,12 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
avrdude_message(MSG_TRACE, "%s: jtag3_edbg_recv():\n", progname);
if ((buf = malloc(USBDEV_MAX_XFER_3)) == NULL) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): out of memory\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_recv(): out of memory\n",
progname);
return -1;
}
if ((request = malloc(pgm->fd.usb.max_xfer)) == NULL) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): out of memory\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_recv(): out of memory\n",
progname);
free(buf);
return -1;
@ -706,7 +706,7 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
request[0] = EDBG_VENDOR_AVR_RSP;
if (serial_send(&pgm->fd, request, pgm->fd.usb.max_xfer) != 0) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): error sending CMSIS-DAP vendor command\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_recv(): error sending CMSIS-DAP vendor command\n",
progname);
free(request);
free(*msg);
@ -725,7 +725,7 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
}
if (buf[0] != EDBG_VENDOR_AVR_RSP) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Unexpected response 0x%02x\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_recv(): Unexpected response 0x%02x\n",
progname, buf[0]);
free(*msg);
free(request);
@ -736,7 +736,7 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
// Documentation says:
// "FragmentInfo 0x00 indicates that no response data is
// available, and the rest of the packet is ignored."
avrdude_message(MSG_INFO,
avrdude_message(MSG_NOTICE,
"%s: jtag3_edbg_recv(): "
"No response available\n",
progname);
@ -752,7 +752,7 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
thisfrag = 1;
} else {
if (nfrags != (buf[1] & 0x0F)) {
avrdude_message(MSG_INFO,
avrdude_message(MSG_NOTICE,
"%s: jtag3_edbg_recv(): "
"Inconsistent # of fragments; had %d, now %d\n",
progname, nfrags, (buf[1] & 0x0F));
@ -762,7 +762,7 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
}
}
if (thisfrag != ((buf[1] >> 4) & 0x0F)) {
avrdude_message(MSG_INFO,
avrdude_message(MSG_NOTICE,
"%s: jtag3_edbg_recv(): "
"Inconsistent fragment number; expect %d, got %d\n",
progname, thisfrag, ((buf[1] >> 4) & 0x0F));
@ -773,12 +773,12 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
int thislen = (buf[2] << 8) | buf[3];
if (thislen > rv + 4) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Unexpected length value (%d > %d)\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_recv(): Unexpected length value (%d > %d)\n",
progname, thislen, rv + 4);
thislen = rv + 4;
}
if (len + thislen > USBDEV_MAX_XFER_3) {
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Length exceeds max size (%d > %d)\n",
avrdude_message(MSG_NOTICE, "%s: jtag3_edbg_recv(): Length exceeds max size (%d > %d)\n",
progname, len + thislen, USBDEV_MAX_XFER_3);
thislen = USBDEV_MAX_XFER_3 - len;
}
@ -865,7 +865,7 @@ int jtag3_recv(PROGRAMMER * pgm, unsigned char **msg) {
"%s: Device is locked! Chip erase required to unlock.\n",
progname);
} else {
avrdude_message(MSG_INFO, "%s: bad response to %s command: 0x%02x\n",
avrdude_message(MSG_NOTICE, "%s: bad response to %s command: 0x%02x\n",
progname, descr, c);
}
status = (*resp)[3];
@ -1351,13 +1351,14 @@ static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
if ((status = jtag3_command(pgm, cmd, 4, &resp, "AVR sign-on")) >= 0)
break;
avrdude_message(MSG_INFO, "%s: retrying with external reset applied\n",
avrdude_message(MSG_NOTICE, "%s: retrying with external reset applied\n",
progname);
}
if (use_ext_reset > 1) {
avrdude_message(MSG_INFO, "%s: JTAGEN fuse disabled?\n", progname);
return -1;
if(strcmp(pgm->type, "JTAGICE3") == 0 && p->flags & AVRPART_HAS_JTAG)
avrdude_message(MSG_INFO, "%s: JTAGEN fuse disabled?\n", progname);
return -1;
}
/*
@ -2240,7 +2241,7 @@ int jtag3_getparm(PROGRAMMER * pgm, unsigned char scope,
c = resp[1];
if (c != RSP3_DATA || status < 3) {
avrdude_message(MSG_INFO, "%s: jtag3_getparm(): "
avrdude_message(MSG_NOTICE, "%s: jtag3_getparm(): "
"bad response to %s\n",
progname, descr);
free(resp);
@ -2325,9 +2326,8 @@ static int jtag3_set_vtarget(PROGRAMMER * pgm, double v)
utarg = (unsigned)(v * 1000);
if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0) {
avrdude_message(MSG_INFO, "%s: jtag3_set_vtarget(): cannot obtain V[aref]\n",
avrdude_message(MSG_INFO, "%s: jtag3_set_vtarget(): cannot obtain V[target]\n",
progname);
return -1;
}
uaref = b2_to_u16(buf);
@ -2336,8 +2336,11 @@ static int jtag3_set_vtarget(PROGRAMMER * pgm, double v)
avrdude_message(MSG_INFO, "%s: jtag3_set_vtarget(): changing V[target] from %.1f to %.1f\n",
progname, uaref / 1000.0, v);
if (jtag3_setparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, sizeof(buf)) < 0)
if (jtag3_setparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, sizeof(buf)) < 0) {
avrdude_message(MSG_INFO, "%s: jtag3_set_vtarget(): cannot confirm new V[target] value\n",
progname);
return -1;
}
return 0;
}
@ -2392,8 +2395,8 @@ static void jtag3_print_parms1(PROGRAMMER * pgm, const char * p)
if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0)
return;
avrdude_message(MSG_INFO, "%sVtarget : %.2f V\n", p,
b2_to_u16(buf) / 1000.0);
avrdude_message(MSG_INFO, "%sVtarget %s: %.2f V\n", p,
verbose ? "" : " ", b2_to_u16(buf) / 1000.0);
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_PROG, buf, 2) < 0)
return;

View File

@ -129,7 +129,7 @@ static void usage(void)
" -q Quell progress output. -q -q for less.\n"
" -l logfile Use logfile rather than stderr for diagnostics.\n"
" -? Display this usage.\n"
"\navrdude version %s, URL: <https://github.com/avrdudes/avrdude>\n"
"\navrdude version %s, URL: <https://github.com/mariusgreuel/avrdude>\n"
,progname, version);
}

View File

@ -0,0 +1,82 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2019 Marius Greuel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
extern "C"
{
#include "avrdude.h"
}
#include "usb_com_helper.h"
#include "usb_com_locator.h"
class AvrdudeConsole : public UsbComLocator::IConsole
{
public:
void WriteLine(UsbComLocator::MessageLevel level, const std::string& message) override
{
switch (level)
{
case UsbComLocator::MessageLevel::Verbose:
avrdude_message(MSG_NOTICE, "%s: %s\n", progname, message.c_str());
break;
case UsbComLocator::MessageLevel::Debug:
avrdude_message(MSG_DEBUG, "%s: %s\n", progname, message.c_str());
break;
default:
avrdude_message(MSG_INFO, "%s: %s\n", progname, message.c_str());
break;
}
}
};
int win32_find_usb_com_port(const char* deviceId, char** port, bool wait_for_device, bool find_related_devices, bool auto_reset)
{
try
{
UsbComLocator::Locator::Options options;
options.WaitForDevice = wait_for_device;
options.FindRelatedDevices = find_related_devices;
options.AutoReset = auto_reset;
AvrdudeConsole console;
UsbComLocator::Locator locator(&console);
std::string filename = locator.FindPortForDevice(deviceId, &options);
if (filename.empty())
{
*port = nullptr;
return -1;
}
filename = "\\\\.\\" + filename;
size_t bufferSize = filename.size() + 1;
*port = static_cast<char*>(malloc(bufferSize));
if (*port == nullptr)
{
return -1;
}
strncpy(*port, filename.c_str(), bufferSize);
return 0;
}
catch (const std::exception&)
{
*port = nullptr;
return -1;
}
}

35
src/msvc/usb_com_helper.h Normal file
View File

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

1074
src/msvc/usb_com_locator.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -26,11 +26,12 @@
#include "ac_cfg.h"
#if defined(HAVE_LIBHIDAPI) || (defined(WIN32) && defined(HAVE_LIBHID))
#if defined(HAVE_LIBHIDAPI)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <hidapi/hidapi.h>
#include "avrdude.h"
#include "libavrdude.h"
@ -64,12 +65,6 @@ static int avrdoperRxPosition = 0; /* amount of bytes already consu
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
#if defined(HAVE_LIBHIDAPI)
#include <hidapi/hidapi.h>
/* ------------------------------------------------------------------------- */
static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
int product, char *productName, int doReportIDs)
{
@ -154,181 +149,6 @@ static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNum
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
#else /* !defined(HAVE_LIBHIDAPI) */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <setupapi.h>
#include <hidsdi.h>
#include <hidpi.h>
#ifdef USB_DEBUG
#define DEBUG_PRINT(arg) printf arg
#else
#define DEBUG_PRINT(arg)
#endif
/* ------------------------------------------------------------------------ */
static void convertUniToAscii(char *buffer)
{
unsigned short *uni = (void *)buffer;
char *ascii = buffer;
while(*uni != 0){
if(*uni >= 256){
*ascii++ = '?';
uni++;
}else{
*ascii++ = *uni++;
}
}
*ascii++ = 0;
}
static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
int product, char *productName, int usesReportIDs)
{
GUID hidGuid; /* GUID for HID driver */
HDEVINFO deviceInfoList;
SP_DEVICE_INTERFACE_DATA deviceInfo;
SP_DEVICE_INTERFACE_DETAIL_DATA *deviceDetails = NULL;
DWORD size;
int i, openFlag = 0; /* may be FILE_FLAG_OVERLAPPED */
int errorCode = USB_ERROR_NOTFOUND;
HANDLE handle = INVALID_HANDLE_VALUE;
HIDD_ATTRIBUTES deviceAttributes;
HidD_GetHidGuid(&hidGuid);
deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL,
DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
deviceInfo.cbSize = sizeof(deviceInfo);
for(i=0;;i++){
if(handle != INVALID_HANDLE_VALUE){
CloseHandle(handle);
handle = INVALID_HANDLE_VALUE;
}
if(!SetupDiEnumDeviceInterfaces(deviceInfoList, 0, &hidGuid, i, &deviceInfo))
break; /* no more entries */
/* first do a dummy call just to determine the actual size required */
SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL);
if(deviceDetails != NULL)
free(deviceDetails);
deviceDetails = malloc(size);
deviceDetails->cbSize = sizeof(*deviceDetails);
/* this call is for real: */
SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails,
size, &size, NULL);
DEBUG_PRINT(("checking HID path \"%s\"\n", deviceDetails->DevicePath));
/* attempt opening for R/W -- we don't care about devices which can't be accessed */
handle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
openFlag, NULL);
if(handle == INVALID_HANDLE_VALUE){
DEBUG_PRINT(("opening failed: %d\n", (int)GetLastError()));
/* errorCode = USB_ERROR_ACCESS; opening will always fail for mouse -- ignore */
continue;
}
deviceAttributes.Size = sizeof(deviceAttributes);
HidD_GetAttributes(handle, &deviceAttributes);
DEBUG_PRINT(("device attributes: vid=%d pid=%d\n",
deviceAttributes.VendorID, deviceAttributes.ProductID));
if(deviceAttributes.VendorID != vendor || deviceAttributes.ProductID != product)
continue; /* ignore this device */
errorCode = USB_ERROR_NOTFOUND;
if(vendorName != NULL && productName != NULL){
char buffer[512];
if(!HidD_GetManufacturerString(handle, buffer, sizeof(buffer))){
DEBUG_PRINT(("error obtaining vendor name\n"));
errorCode = USB_ERROR_IO;
continue;
}
convertUniToAscii(buffer);
DEBUG_PRINT(("vendorName = \"%s\"\n", buffer));
if(strcmp(vendorName, buffer) != 0)
continue;
if(!HidD_GetProductString(handle, buffer, sizeof(buffer))){
DEBUG_PRINT(("error obtaining product name\n"));
errorCode = USB_ERROR_IO;
continue;
}
convertUniToAscii(buffer);
DEBUG_PRINT(("productName = \"%s\"\n", buffer));
if(strcmp(productName, buffer) != 0)
continue;
}
break; /* we have found the device we are looking for! */
}
SetupDiDestroyDeviceInfoList(deviceInfoList);
if(deviceDetails != NULL)
free(deviceDetails);
if(handle != INVALID_HANDLE_VALUE){
fdp->pfd = (void *)handle;
errorCode = 0;
}
return errorCode;
}
/* ------------------------------------------------------------------------ */
static void usbCloseDevice(union filedescriptor *fdp)
{
CloseHandle((HANDLE)fdp->pfd);
}
/* ------------------------------------------------------------------------ */
static int usbSetReport(union filedescriptor *fdp, int reportType, char *buffer, int len)
{
HANDLE handle = (HANDLE)fdp->pfd;
BOOLEAN rval = 0;
DWORD bytesWritten;
switch(reportType){
case USB_HID_REPORT_TYPE_INPUT:
break;
case USB_HID_REPORT_TYPE_OUTPUT:
rval = WriteFile(handle, buffer, len, &bytesWritten, NULL);
break;
case USB_HID_REPORT_TYPE_FEATURE:
rval = HidD_SetFeature(handle, buffer, len);
break;
}
return rval == 0 ? USB_ERROR_IO : 0;
}
/* ------------------------------------------------------------------------ */
static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNumber,
char *buffer, int *len)
{
HANDLE handle = (HANDLE)fdp->pfd;
BOOLEAN rval = 0;
DWORD bytesRead;
switch(reportType){
case USB_HID_REPORT_TYPE_INPUT:
buffer[0] = reportNumber;
rval = ReadFile(handle, buffer, *len, &bytesRead, NULL);
if(rval)
*len = bytesRead;
break;
case USB_HID_REPORT_TYPE_OUTPUT:
break;
case USB_HID_REPORT_TYPE_FEATURE:
buffer[0] = reportNumber;
rval = HidD_GetFeature(handle, buffer, *len);
break;
}
return rval == 0 ? USB_ERROR_IO : 0;
}
#endif /* WIN32 */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
@ -551,4 +371,4 @@ struct serial_device avrdoper_serdev =
.flags = SERDEV_FL_NONE,
};
#endif /* defined(HAVE_LIBHIDAPI) || (defined(WIN32) && defined(HAVE_LIBHID)) */
#endif /* defined(HAVE_LIBHIDAPI) */

View File

@ -36,6 +36,10 @@
#include "avrdude.h"
#include "libavrdude.h"
#ifdef _MSC_VER
#include "msvc/usb_com_helper.h"
#endif
long serial_recv_timeout = 5000; /* ms */
#define W32SERBUFSIZE 1024
@ -257,6 +261,13 @@ static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
return net_open(port + strlen("net:"), fdp);
}
#ifdef _MSC_VER
if (win32_find_usb_com_port(port, &newname, true, true, true) >= 0)
{
port = newname;
}
#endif
if (strncasecmp(port, "com", strlen("com")) == 0) {
// prepend "\\\\.\\" to name, required for port # >= 10

View File

@ -1613,11 +1613,11 @@ static int stk500v2_open(PROGRAMMER * pgm, char * port)
PDATA(pgm)->pgmtype = PGMTYPE_UNKNOWN;
if(strcasecmp(port, "avrdoper") == 0){
#if defined(HAVE_LIBHIDAPI) || (defined(WIN32) && defined(HAVE_LIBHID))
#if defined(HAVE_LIBHIDAPI)
serdev = &avrdoper_serdev;
PDATA(pgm)->pgmtype = PGMTYPE_STK500;
#else
avrdude_message(MSG_INFO, "avrdoper requires avrdude with hid support.\n");
avrdude_message(MSG_INFO, "avrdoper requires avrdude with libhidapi support.\n");
return -1;
#endif
}

View File

@ -97,8 +97,8 @@ struct command cmd[] = {
{ "sig", cmd_sig, "display device signature bytes" },
{ "part", cmd_part, "display the current part information" },
{ "send", cmd_send, "send a raw command : %s <b1> <b2> <b3> <b4>" },
{ "parms", cmd_parms, "display adjustable parameters (STK500 only)" },
{ "vtarg", cmd_vtarg, "set <V[target]> (STK500 only)" },
{ "parms", cmd_parms, "display adjustable parameters (STK500 and Curiosity Nano only)" },
{ "vtarg", cmd_vtarg, "set <V[target]> (STK500 and Curiosity Nano only)" },
{ "varef", cmd_varef, "set <V[aref]> (STK500 only)" },
{ "fosc", cmd_fosc, "set <oscillator frequency> (STK500 only)" },
{ "sck", cmd_sck, "set <SCK period> (STK500 only)" },

View File

@ -53,7 +53,7 @@ static void updi_set_rtsdtr_mode(PROGRAMMER* pgm)
static int updi_physical_open(PROGRAMMER* pgm, int baudrate, unsigned long cflags)
{
serial_recv_timeout = 100;
serial_recv_timeout = 1000;
union pinfo pinfo;
pinfo.serialinfo.baud = baudrate;
@ -155,12 +155,19 @@ static int updi_physical_send_double_break(PROGRAMMER * pgm)
serial_send(&pgm->fd, buffer, 1);
serial_recv(&pgm->fd, buffer, 1);
serial_drain(&pgm->fd, 0);
if (serial_setparams(&pgm->fd, pgm->baudrate? pgm->baudrate: 115200, SERIAL_8E2) < 0) {
return -1;
}
updi_set_rtsdtr_mode(pgm);
/*
* drain any extraneous input
*/
serial_drain(&pgm->fd, 0);
return 0;
}
@ -191,10 +198,14 @@ int updi_physical_sib(PROGRAMMER * pgm, unsigned char * buffer, uint8_t size)
int updi_link_open(PROGRAMMER * pgm)
{
unsigned char init_buffer[1];
if (updi_physical_open(pgm, pgm->baudrate? pgm->baudrate: 115200, SERIAL_8E2) < 0) {
return -1;
}
return updi_physical_send_double_break(pgm);
init_buffer[0]=UPDI_BREAK;
return updi_physical_send(pgm, init_buffer, 1);
}
void updi_link_close(PROGRAMMER * pgm)

View File

@ -100,7 +100,7 @@ static int usb_control (PROGRAMMER * pgm,
{
int nbytes;
nbytes = usb_control_msg( PDATA(pgm)->usb_handle,
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
requestid,
val, index, // 2 bytes each of data
NULL, 0, // no data buffer in control message