mirror of
https://github.com/mariusgreuel/avrdude.git
synced 2025-12-16 18:44:17 +00:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a8f35fad0 | ||
|
|
04c1887b12 | ||
|
|
60849ce3c9 | ||
|
|
7aa558e562 | ||
|
|
c686946563 | ||
|
|
1e05c4339f | ||
|
|
6326b19cfe | ||
|
|
4305a99484 | ||
|
|
a7238c44af | ||
|
|
b41fbccf3d | ||
|
|
5e874c8a04 | ||
|
|
141bdc7171 | ||
|
|
172f34f872 | ||
|
|
7d2a1c916b | ||
|
|
f428a6db07 |
52
ChangeLog
52
ChangeLog
@@ -1,35 +1,41 @@
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
2016-02-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Martino Facchin:
|
||||
bug #45727: Wrong atmega8u2 flash parameters
|
||||
* avrdude.conf.in (ATmega8U2): correct page and block size
|
||||
* configure.ac: Released version 6.3.
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Pasquale Cocchini:
|
||||
bug #46020: Add TIAO TUMPA to the conf file.
|
||||
* avrdude.conf.in (tumpa): New entry.
|
||||
patch #8894: Spelling in 6.2 doc
|
||||
* doc/avrdude.texi: Various spelling fixes.
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Pasquale Cocchini:
|
||||
bug #46021: Please add read in the memory lock section of ATtiny85
|
||||
* avrdude.conf.in (ATtiny25/45/85): add read pattern for lock bits
|
||||
patch #8895: Spelling in 6.2 code
|
||||
* avrftdi.c (avrftdi_open): Spell fix.
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am (libavrdude_a_SOURCES): reflect recent changes
|
||||
(pgm.h is gone, config.h is new).
|
||||
patch #8896: Silence cppcheck warnings in 6.2 code
|
||||
* linuxgpio.c: Use %ud to print GPIO values.
|
||||
|
||||
2015-04-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #44717: avrdude creates empty flash dump
|
||||
* update.c (do_op): When about to write an empty flash dump file,
|
||||
warn about this to avoid surprises.
|
||||
* avrdude.1: Document the truncation of trailing 0xFF bytes for
|
||||
flash memory areas.
|
||||
patch #8735: ATtiny28 support in avrdude.conf
|
||||
* avrdude.conf.in (ATtiny28): New device.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.conf.in (ATmega48PB, ATmega88PB, ATmega168PB): New
|
||||
devices.
|
||||
|
||||
2016-02-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
patch #8435: Implementing mEDBG CMSIS-DAP protocol
|
||||
* usb_libusb.c: Add endpoint IDs for Xplained Mini, correctly
|
||||
transfer trailing ZLP when needed
|
||||
* avrdude.conf.in (xplainedmini, xplainedmini_dw): New entries.
|
||||
* jtag3.c (jtag3_edbg_send, jtag3_edbg_recv_frame): Implement
|
||||
fragmentation needed for the 64-byte EP size of the Xplained Mini
|
||||
* avrdude.1: Document the change
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2015-04-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Annual ChangeLog rotation.
|
||||
|
||||
54
ChangeLog-2015
Normal file
54
ChangeLog-2015
Normal file
@@ -0,0 +1,54 @@
|
||||
2015-12-15 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* avrdude.1 (-C): Do not suggest users might change the
|
||||
default config file. It will be overwritten by updates.
|
||||
|
||||
2015-12-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #46610: Floating point exception (core dumped) arch linux rpi2
|
||||
bug #46483: version 6.2. ser_open(): can't set attributes for device
|
||||
* ser_posix.c: Back out change from patch #8380
|
||||
|
||||
2015-11-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Bump for post-release 6.2.
|
||||
|
||||
2015-11-16 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* configure.ac: Released version 6.2.
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Martino Facchin:
|
||||
bug #45727: Wrong atmega8u2 flash parameters
|
||||
* avrdude.conf.in (ATmega8U2): correct page and block size
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Pasquale Cocchini:
|
||||
bug #46020: Add TIAO TUMPA to the conf file.
|
||||
* avrdude.conf.in (tumpa): New entry.
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Submitted by Pasquale Cocchini:
|
||||
bug #46021: Please add read in the memory lock section of ATtiny85
|
||||
* avrdude.conf.in (ATtiny25/45/85): add read pattern for lock bits
|
||||
|
||||
2015-10-31 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* Makefile.am (libavrdude_a_SOURCES): reflect recent changes
|
||||
(pgm.h is gone, config.h is new).
|
||||
|
||||
2015-04-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
bug #44717: avrdude creates empty flash dump
|
||||
* update.c (do_op): When about to write an empty flash dump file,
|
||||
warn about this to avoid surprises.
|
||||
* avrdude.1: Document the truncation of trailing 0xFF bytes for
|
||||
flash memory areas.
|
||||
* doc/avrdude.texi: (Dito.)
|
||||
|
||||
2015-04-09 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
Annual ChangeLog rotation.
|
||||
31
NEWS
31
NEWS
@@ -5,7 +5,35 @@ Approximate change log for AVRDUDE by version.
|
||||
(For more detailed changes, see the ChangeLog file.)
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Current:
|
||||
Version 6.3:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
|
||||
- Backout of
|
||||
patch #8380: adds 500k 1M 2M baud to ser_posix.c
|
||||
It broke the functionality in too many situations
|
||||
(bug #46610/46483)
|
||||
|
||||
* New devices supported:
|
||||
|
||||
- ATmega48PB, ATmega88PB, ATmega168PB
|
||||
- ATtiny28 (HVPP-only device)
|
||||
|
||||
* New programmers supported:
|
||||
|
||||
- Atmel mEDBG: xplainedmini, xplainedmini_dw
|
||||
|
||||
* Bugfixes
|
||||
|
||||
- bug #46610: Floating point exception (core dumped) arch linux rpi2
|
||||
- bug #46483: version 6.2. ser_open(): can't set attributes for device
|
||||
- patch #8435: Implementing mEDBG CMSIS-DAP protocol
|
||||
- patch #8735: ATtiny28 support in avrdude.conf
|
||||
- patch #8896: Silence cppcheck warnings in 6.2 code
|
||||
- patch #8895: Spelling in 6.2 code
|
||||
|
||||
|
||||
Version 6.2:
|
||||
|
||||
* Major changes compared to the previous version:
|
||||
|
||||
@@ -63,7 +91,6 @@ Current:
|
||||
- bug #40870: config nitpick: ATtiny25/45/85 have 1 calibration byte not 2
|
||||
- bug #42908: no external reset at JTAGICE3
|
||||
- patch #8437: [PATCH] Serial-over-ethernet for Win32
|
||||
- patch #8380: adds 500k 1M 2M baud to ser_posix.c
|
||||
- bug #44717: avrdude creates empty flash dump
|
||||
|
||||
* Internals:
|
||||
|
||||
14
avrdude.1
14
avrdude.1
@@ -1,6 +1,6 @@
|
||||
.\"
|
||||
.\" avrdude - A Downloader/Uploader for AVR device programmers
|
||||
.\" Copyright (C) 2001, 2002, 2003, 2005 - 2014 Joerg Wunsch
|
||||
.\" Copyright (C) 2001, 2002, 2003, 2005 - 2016 Joerg Wunsch
|
||||
.\"
|
||||
.\" 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
|
||||
@@ -18,7 +18,7 @@
|
||||
.\"
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd DATE November 23, 2014
|
||||
.Dd DATE February 15, 2016
|
||||
.Os
|
||||
.Dt AVRDUDE 1
|
||||
.Sh NAME
|
||||
@@ -156,6 +156,9 @@ ISP).
|
||||
Atmel's XplainedPro boards, using the EDBG protocol (CMSIS-DAP compatible),
|
||||
are supported using the "jtag3" programmer type.
|
||||
.Pp
|
||||
Atmel's XplainedMini boards, using the mEDBG protocol,
|
||||
are also supported using the "jtag3" programmer type.
|
||||
.Pp
|
||||
The AVR Dragon is supported in all modes (ISP, JTAG, HVSP, PP, debugWire).
|
||||
When used in JTAG and debugWire mode, the AVR Dragon behaves similar to a
|
||||
JTAG ICE mkII, so all device-specific comments for that device
|
||||
@@ -289,11 +292,8 @@ by using ? as programmer-id.
|
||||
Use the specified config file to load configuration data. This file
|
||||
contains all programmer and part definitions that
|
||||
.Nm avrdude
|
||||
knows about. If you have a programmer or part that
|
||||
.Nm avrdude
|
||||
does not know about, you can add it to the config file (be sure and
|
||||
submit a patch back to the author so that it can be incorporated for
|
||||
the next version). See the config file, located at
|
||||
knows about.
|
||||
See the config file, located at
|
||||
.Pa ${PREFIX}/etc/avrdude.conf ,
|
||||
which contains a description of the format.
|
||||
.Pp
|
||||
|
||||
112
avrdude.conf.in
112
avrdude.conf.in
@@ -1094,6 +1094,22 @@ programmer
|
||||
usbpid = 0x2111;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "xplainedmini";
|
||||
desc = "Atmel AVR XplainedMini in ISP mode";
|
||||
type = "jtagice3_isp";
|
||||
connection_type = usb;
|
||||
usbpid = 0x2145;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "xplainedmini_dw";
|
||||
desc = "Atmel AVR XplainedMini in debugWIRE mode";
|
||||
type = "jtagice3_dw";
|
||||
connection_type = usb;
|
||||
usbpid = 0x2145;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "atmelice";
|
||||
desc = "Atmel-ICE (ARM/AVR) in JTAG mode";
|
||||
@@ -7585,6 +7601,66 @@ part
|
||||
;
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATtiny28
|
||||
#------------------------------------------------------------
|
||||
|
||||
# This is an HVPP-only device.
|
||||
|
||||
part
|
||||
id = "t28";
|
||||
desc = "ATtiny28";
|
||||
stk500_devcode = 0x22;
|
||||
avr910_devcode = 0x5c;
|
||||
signature = 0x1e 0x91 0x07;
|
||||
|
||||
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 = 0;
|
||||
togglevtg = 0;
|
||||
poweroffdelay = 0;
|
||||
resetdelayms = 0;
|
||||
resetdelayus = 0;
|
||||
hvleavestabdelay = 15;
|
||||
resetdelay = 15;
|
||||
chiperasepulsewidth = 0;
|
||||
chiperasepolltimeout = 10;
|
||||
programfusepulsewidth = 0;
|
||||
programfusepolltimeout = 5;
|
||||
programlockpulsewidth = 0;
|
||||
programlockpolltimeout = 5;
|
||||
|
||||
memory "flash"
|
||||
size = 2048;
|
||||
page_size = 2;
|
||||
readsize = 256;
|
||||
delay = 5;
|
||||
;
|
||||
|
||||
memory "signature"
|
||||
size = 3;
|
||||
;
|
||||
|
||||
memory "lock"
|
||||
size = 1;
|
||||
;
|
||||
|
||||
memory "calibration"
|
||||
size = 1;
|
||||
;
|
||||
|
||||
memory "fuse"
|
||||
size = 1;
|
||||
;
|
||||
;
|
||||
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATmega48
|
||||
#------------------------------------------------------------
|
||||
@@ -7785,6 +7861,18 @@ part parent "m48"
|
||||
ocdrev = 1;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATmega48PB
|
||||
#------------------------------------------------------------
|
||||
|
||||
part parent "m48"
|
||||
id = "m48pb";
|
||||
desc = "ATmega48PB";
|
||||
signature = 0x1e 0x92 0x10;
|
||||
|
||||
ocdrev = 1;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATmega88
|
||||
#------------------------------------------------------------
|
||||
@@ -7985,6 +8073,18 @@ part parent "m88"
|
||||
ocdrev = 1;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATmega88PB
|
||||
#------------------------------------------------------------
|
||||
|
||||
part parent "m88"
|
||||
id = "m88pb";
|
||||
desc = "ATmega88PB";
|
||||
signature = 0x1e 0x93 0x16;
|
||||
|
||||
ocdrev = 1;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATmega168
|
||||
#------------------------------------------------------------
|
||||
@@ -8187,6 +8287,18 @@ part parent "m168"
|
||||
ocdrev = 1;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATmega168PB
|
||||
#------------------------------------------------------------
|
||||
|
||||
part parent "m168"
|
||||
id = "m168pb";
|
||||
desc = "ATmega168PB";
|
||||
signature = 0x1e 0x94 0x15;
|
||||
|
||||
ocdrev = 1;
|
||||
;
|
||||
|
||||
#------------------------------------------------------------
|
||||
# ATtiny88
|
||||
#------------------------------------------------------------
|
||||
|
||||
@@ -703,7 +703,7 @@ static int avrftdi_open(PROGRAMMER * pgm, char *port)
|
||||
|
||||
err = ftdi_usb_open_desc_index(pdata->ftdic, vid, pid, desc, serial, index);
|
||||
if(err) {
|
||||
log_err("Error %d occured: %s\n", err, ftdi_get_error_string(pdata->ftdic));
|
||||
log_err("Error %d occurred: %s\n", err, ftdi_get_error_string(pdata->ftdic));
|
||||
//stupid hack, because avrdude calls pgm->close() even when pgm->open() fails
|
||||
//and usb_dev is intialized to the last usb device from probing
|
||||
pdata->ftdic->usb_dev = NULL;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.60)
|
||||
AC_INIT(avrdude, 6.1-20140519, avrdude-dev@nongnu.org)
|
||||
AC_INIT(avrdude, 6.3, avrdude-dev@nongnu.org)
|
||||
|
||||
AC_CANONICAL_BUILD
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
@@ -154,7 +154,7 @@ serial bit-bang adapters,
|
||||
and the PPI (parallel port interface). PPI represents a class
|
||||
of simple programmers where the programming lines are directly
|
||||
connected to the PC parallel port. Several pin configurations exist
|
||||
for several variations of the PPI programmers, and AVRDUDE can be be
|
||||
for several variations of the PPI programmers, and AVRDUDE can be
|
||||
configured to work with them by either specifying the appropriate
|
||||
programmer on the command line or by creating a new entry in its
|
||||
configuration file. All that's usually required for a new entry is to
|
||||
@@ -173,7 +173,7 @@ available (like almost all embedded Linux boards) you can do without
|
||||
any additional hardware - just connect them to the MOSI, MISO, RESET
|
||||
and SCK pins on the AVR and use the linuxgpio programmer type. It bitbangs
|
||||
the lines using the Linux sysfs GPIO interface. Of course, care should
|
||||
be taken about voltage level compatibility. Also, although not strictrly
|
||||
be taken about voltage level compatibility. Also, although not strictly
|
||||
required, it is strongly advisable to protect the GPIO pins from
|
||||
overcurrent situations in some way. The simplest would be to just put
|
||||
some resistors in series or better yet use a 3-state buffer driver like
|
||||
@@ -181,7 +181,7 @@ the 74HC244. Have a look at http://kolev.info/avrdude-linuxgpio for a more
|
||||
detailed tutorial about using this programmer type.
|
||||
|
||||
The STK500, JTAG ICE, avr910, and avr109/butterfly use the serial port to communicate with the PC.
|
||||
The STK600, JTAG ICE mkII/3, AVRISP mkII, USBasp, avrftdi (and derivitives), and USBtinyISP
|
||||
The STK600, JTAG ICE mkII/3, AVRISP mkII, USBasp, avrftdi (and derivatives), and USBtinyISP
|
||||
programmers communicate through the USB, using @code{libusb} as a
|
||||
platform abstraction layer.
|
||||
The avrftdi adds support for the FT2232C/D, FT2232H, and FT4232H devices. These all use
|
||||
@@ -216,7 +216,10 @@ has a revision 1 hardware and firmware version of at least 5.37 (decimal).
|
||||
The Atmel-ICE (ARM/AVR) is supported (JTAG, PDI for Xmega, debugWIRE, ISP modes).
|
||||
|
||||
Atmel's XplainedPro boards, using EDBG protocol (CMSIS-DAP compliant), are
|
||||
supported by teh ``jtag3'' programmer type.
|
||||
supported by the ``jtag3'' programmer type.
|
||||
|
||||
Atmel's XplainedMini boards, using mEDBG protocol, are also
|
||||
supported by the ``jtag3'' programmer type.
|
||||
|
||||
The AVR Dragon is supported in all modes (ISP, JTAG, PDI, HVSP, PP, debugWire).
|
||||
When used in JTAG and debugWire mode, the AVR Dragon behaves similar to a
|
||||
@@ -543,7 +546,7 @@ be specified as @var{avrdoper}. Libusb support is required on Unix
|
||||
but not on Windows. For more information about AVR-Doper see
|
||||
@url{http://www.obdev.at/avrusb/avrdoper.html}.
|
||||
|
||||
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.
|
||||
@xref{Troubleshooting}, for examples.
|
||||
@@ -898,7 +901,7 @@ Connection to the PICkit2 programmer:
|
||||
@item @code{OSI} @tab @code{AUX (6) }
|
||||
@end multitable
|
||||
|
||||
Extended commandline parameters:
|
||||
Extended command line parameters:
|
||||
@table @code
|
||||
@item @samp{clockrate=@var{rate}}
|
||||
Sets the SPI clocking rate in Hz (default is 100kHz). Alternately the -B or -i options can be used to set the period.
|
||||
@@ -1150,7 +1153,7 @@ Return to programming mode (from direct SPI mode).
|
||||
Change (when @var{level} is provided), or display the verbosity
|
||||
level.
|
||||
The initial verbosity level is controlled by the number of @code{-v} options
|
||||
given on the commandline.
|
||||
given on the command line.
|
||||
|
||||
@item ?
|
||||
@itemx help
|
||||
@@ -1329,7 +1332,7 @@ programmer work with AVRDUDE.
|
||||
|
||||
AVRDUDE first looks for a system wide configuration file in a platform
|
||||
dependent location. On Unix, this is usually
|
||||
@code{/usr/local/etc/avrdude.conf}, while on Windows it is usally in the
|
||||
@code{/usr/local/etc/avrdude.conf}, while on Windows it is usually in the
|
||||
same location as the executable file. The name of this file can be
|
||||
changed using the @option{-C} command line option. After the system wide
|
||||
configuration file is parsed, AVRDUDE looks for a per-user configuration
|
||||
@@ -1657,7 +1660,7 @@ flash pages of the application section.
|
||||
|
||||
Reading fuse and lock bits is fully supported.
|
||||
|
||||
Note that due to the unability to write the fuse bits, the safemode
|
||||
Note that due to the inability to write the fuse bits, the safemode
|
||||
functionality does not make sense for these boot loaders.
|
||||
|
||||
@end itemize
|
||||
@@ -1842,7 +1845,7 @@ The default location of the install is into @code{/usr/local} so you
|
||||
will need to be sure that @code{/usr/local/bin} is in your @code{PATH}
|
||||
environment variable.
|
||||
|
||||
If you do not have root access to your system, you can do the the
|
||||
If you do not have root access to your system, you can do the
|
||||
following instead:
|
||||
|
||||
@example
|
||||
@@ -1892,7 +1895,7 @@ obtained.
|
||||
@subsubsection Linux Installation
|
||||
|
||||
@noindent
|
||||
On rpm based Linux systems (such as RedHat, SUSE, Mandrake, etc), you
|
||||
On rpm based Linux systems (such as RedHat, SUSE, Mandrake, etc.), you
|
||||
can build and install the rpm binaries directly from the tarball:
|
||||
|
||||
@example
|
||||
@@ -2386,7 +2389,7 @@ be added to the @var{-P usb} option, similar to adding a serial number
|
||||
on other USB-based programmers.
|
||||
|
||||
The actual naming convention for the bus and device names is
|
||||
operating-system dependant; AVRDUDE will print out what it found
|
||||
operating-system dependent; AVRDUDE will print out what it found
|
||||
on the bus when running it with (at least) one @var{-v} option.
|
||||
By specifying a string that cannot match any existing device
|
||||
(for example, @var{-P usb:xxx}), the scan will list all possible
|
||||
|
||||
224
jtag3.c
224
jtag3.c
@@ -446,39 +446,66 @@ static int jtag3_edbg_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
|
||||
avrdude_message(MSG_DEBUG, "\n%s: jtag3_edbg_send(): sending %lu bytes\n",
|
||||
progname, (unsigned long)len);
|
||||
|
||||
if (len + 8 > USBDEV_MAX_XFER_3)
|
||||
/* 4 bytes overhead for CMD, fragment #, and length info */
|
||||
int max_xfer = pgm->fd.usb.max_xfer;
|
||||
int nfragments = (len + max_xfer - 1) / max_xfer;
|
||||
if (nfragments > 1)
|
||||
{
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_send(): Fragmentation not (yet) implemented!\n",
|
||||
progname);
|
||||
return -1;
|
||||
avrdude_message(MSG_DEBUG, "%s: jtag3_edbg_send(): fragmenting into %d packets\n",
|
||||
progname, nfragments);
|
||||
}
|
||||
buf[0] = EDBG_VENDOR_AVR_CMD;
|
||||
buf[1] = (1 << 4) | 1; /* first out of a total of 1 fragments */
|
||||
buf[2] = (len + 4) >> 8;
|
||||
buf[3] = (len + 4) & 0xff;
|
||||
buf[4] = TOKEN;
|
||||
buf[5] = 0; /* dummy */
|
||||
u16_to_b2(buf + 6, PDATA(pgm)->command_sequence);
|
||||
memcpy(buf + 8, data, len);
|
||||
|
||||
if (serial_send(&pgm->fd, buf, USBDEV_MAX_XFER_3) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_send(): failed to send command to serial port\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
rv = serial_recv(&pgm->fd, status, USBDEV_MAX_XFER_3);
|
||||
|
||||
if (rv < 0) {
|
||||
/* timeout in receive */
|
||||
avrdude_message(MSG_NOTICE2, "%s: jtag3_edbg_send(): Timeout receiving packet\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
if (status[0] != EDBG_VENDOR_AVR_CMD || status[1] != 0x01)
|
||||
int frag;
|
||||
for (frag = 0; frag < nfragments; frag++)
|
||||
{
|
||||
/* what to do in this case? */
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_send(): Unexpected response 0x%02x, 0x%02x\n",
|
||||
progname, status[0], status[1]);
|
||||
int this_len;
|
||||
|
||||
/* All fragments have the (CMSIS-DAP layer) CMD, the fragment
|
||||
* identifier, and the length field. */
|
||||
buf[0] = EDBG_VENDOR_AVR_CMD;
|
||||
buf[1] = ((frag + 1) << 4) | nfragments;
|
||||
|
||||
if (frag == 0)
|
||||
{
|
||||
/* Only first fragment has TOKEN and seq#, thus four bytes
|
||||
* less payload than subsequent fragments. */
|
||||
this_len = len < max_xfer - 8? len: max_xfer - 8;
|
||||
buf[2] = (this_len + 4) >> 8;
|
||||
buf[3] = (this_len + 4) & 0xff;
|
||||
buf[4] = TOKEN;
|
||||
buf[5] = 0; /* dummy */
|
||||
u16_to_b2(buf + 6, PDATA(pgm)->command_sequence);
|
||||
memcpy(buf + 8, data, this_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
this_len = len < max_xfer - 4? len: max_xfer - 4;
|
||||
buf[2] = (this_len) >> 8;
|
||||
buf[3] = (this_len) & 0xff;
|
||||
memcpy(buf + 4, data, this_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",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
rv = serial_recv(&pgm->fd, status, max_xfer);
|
||||
|
||||
if (rv < 0) {
|
||||
/* timeout in receive */
|
||||
avrdude_message(MSG_NOTICE2, "%s: jtag3_edbg_send(): Timeout receiving packet\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
if (status[0] != EDBG_VENDOR_AVR_CMD ||
|
||||
(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",
|
||||
progname, status[0], status[1]);
|
||||
}
|
||||
data += this_len;
|
||||
len -= this_len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -501,13 +528,13 @@ static int jtag3_edbg_prepare(PROGRAMMER * pgm)
|
||||
|
||||
buf[0] = CMSISDAP_CMD_CONNECT;
|
||||
buf[1] = CMSISDAP_CONN_SWD;
|
||||
if (serial_send(&pgm->fd, buf, USBDEV_MAX_XFER_3) != 0) {
|
||||
if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_prepare(): failed to send command to serial port\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
rv = serial_recv(&pgm->fd, status, USBDEV_MAX_XFER_3);
|
||||
if (rv != USBDEV_MAX_XFER_3) {
|
||||
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_prepare(): failed to read from serial port (%d)\n",
|
||||
progname, rv);
|
||||
return -1;
|
||||
@@ -522,13 +549,13 @@ static int jtag3_edbg_prepare(PROGRAMMER * pgm)
|
||||
buf[0] = CMSISDAP_CMD_LED;
|
||||
buf[1] = CMSISDAP_LED_CONNECT;
|
||||
buf[2] = 1;
|
||||
if (serial_send(&pgm->fd, buf, USBDEV_MAX_XFER_3) != 0) {
|
||||
if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_prepare(): failed to send command to serial port\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
rv = serial_recv(&pgm->fd, status, USBDEV_MAX_XFER_3);
|
||||
if (rv != USBDEV_MAX_XFER_3) {
|
||||
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_prepare(): failed to read from serial port (%d)\n",
|
||||
progname, rv);
|
||||
return -1;
|
||||
@@ -560,13 +587,13 @@ static int jtag3_edbg_signoff(PROGRAMMER * pgm)
|
||||
buf[0] = CMSISDAP_CMD_LED;
|
||||
buf[1] = CMSISDAP_LED_CONNECT;
|
||||
buf[2] = 0;
|
||||
if (serial_send(&pgm->fd, buf, USBDEV_MAX_XFER_3) != 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",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
rv = serial_recv(&pgm->fd, status, USBDEV_MAX_XFER_3);
|
||||
if (rv != USBDEV_MAX_XFER_3) {
|
||||
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",
|
||||
progname, rv);
|
||||
return -1;
|
||||
@@ -577,13 +604,13 @@ static int jtag3_edbg_signoff(PROGRAMMER * pgm)
|
||||
progname, status[0], status[1]);
|
||||
|
||||
buf[0] = CMSISDAP_CMD_DISCONNECT;
|
||||
if (serial_send(&pgm->fd, buf, USBDEV_MAX_XFER_3) != 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",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
rv = serial_recv(&pgm->fd, status, USBDEV_MAX_XFER_3);
|
||||
if (rv != USBDEV_MAX_XFER_3) {
|
||||
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",
|
||||
progname, rv);
|
||||
return -1;
|
||||
@@ -644,8 +671,9 @@ static int jtag3_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
|
||||
}
|
||||
|
||||
static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
|
||||
int rv, len;
|
||||
int rv, len = 0;
|
||||
unsigned char *buf = NULL;
|
||||
unsigned char *request;
|
||||
|
||||
avrdude_message(MSG_TRACE, "%s: jtag3_edbg_recv():\n", progname);
|
||||
|
||||
@@ -654,42 +682,92 @@ static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf[0] = EDBG_VENDOR_AVR_RSP;
|
||||
|
||||
if (serial_send(&pgm->fd, buf, USBDEV_MAX_XFER_3) != 0) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): error sending CMSIS-DAP vendor command\n",
|
||||
progname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = serial_recv(&pgm->fd, buf, USBDEV_MAX_XFER_3);
|
||||
|
||||
if (rv < 0) {
|
||||
/* timeout in receive */
|
||||
avrdude_message(MSG_NOTICE2, "%s: jtag3_edbg_recv(): Timeout receiving packet\n",
|
||||
progname);
|
||||
if ((request = malloc(pgm->fd.usb.max_xfer)) == NULL) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): out of memory\n",
|
||||
progname);
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buf[0] != EDBG_VENDOR_AVR_RSP ||
|
||||
buf[1] != ((1 << 4) | 1)) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Unexpected response 0x%02x, 0x%02x\n",
|
||||
progname, buf[0], buf[1]);
|
||||
return -1;
|
||||
}
|
||||
/* calculate length from response; CMSIS-DAP response might be larger */
|
||||
len = (buf[2] << 8) | buf[3];
|
||||
if (len > rv + 4) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Unexpected length value (%d > %d)\n",
|
||||
progname, len, rv + 4);
|
||||
len = rv + 4;
|
||||
}
|
||||
memmove(buf, buf + 4, len);
|
||||
|
||||
*msg = buf;
|
||||
|
||||
int nfrags = 0;
|
||||
int thisfrag = 0;
|
||||
|
||||
do {
|
||||
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",
|
||||
progname);
|
||||
free(request);
|
||||
free(*msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = serial_recv(&pgm->fd, buf, pgm->fd.usb.max_xfer);
|
||||
|
||||
if (rv < 0) {
|
||||
/* timeout in receive */
|
||||
avrdude_message(MSG_NOTICE2, "%s: jtag3_edbg_recv(): Timeout receiving packet\n",
|
||||
progname);
|
||||
free(*msg);
|
||||
free(request);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buf[0] != EDBG_VENDOR_AVR_RSP) {
|
||||
avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Unexpected response 0x%02x\n",
|
||||
progname, buf[0]);
|
||||
free(*msg);
|
||||
free(request);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* calculate fragment information */
|
||||
if (thisfrag == 0) {
|
||||
/* first fragment */
|
||||
nfrags = buf[1] & 0x0F;
|
||||
thisfrag = 1;
|
||||
} else {
|
||||
if (nfrags != (buf[1] & 0x0F)) {
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: jtag3_edbg_recv(): "
|
||||
"Inconsistent # of fragments; had %d, now %d\n",
|
||||
progname, nfrags, (buf[1] & 0x0F));
|
||||
free(*msg);
|
||||
free(request);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (thisfrag != ((buf[1] >> 4) & 0x0F)) {
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: jtag3_edbg_recv(): "
|
||||
"Inconsistent fragment number; expect %d, got %d\n",
|
||||
progname, thisfrag, ((buf[1] >> 4) & 0x0F));
|
||||
free(*msg);
|
||||
free(request);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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",
|
||||
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",
|
||||
progname, len + thislen, USBDEV_MAX_XFER_3);
|
||||
thislen = USBDEV_MAX_XFER_3 - len;
|
||||
}
|
||||
memmove(buf, buf + 4, thislen);
|
||||
thisfrag++;
|
||||
len += thislen;
|
||||
buf += thislen;
|
||||
} while (thisfrag <= nfrags);
|
||||
|
||||
free(request);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ static int linuxgpio_export(unsigned int gpio)
|
||||
return fd;
|
||||
}
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%d", gpio);
|
||||
len = snprintf(buf, sizeof(buf), "%ud", gpio);
|
||||
r = write(fd, buf, len);
|
||||
close(fd);
|
||||
|
||||
@@ -84,7 +84,7 @@ static int linuxgpio_unexport(unsigned int gpio)
|
||||
return fd;
|
||||
}
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%d", gpio);
|
||||
len = snprintf(buf, sizeof(buf), "%ud", gpio);
|
||||
r = write(fd, buf, len);
|
||||
close(fd);
|
||||
|
||||
@@ -95,7 +95,7 @@ static int linuxgpio_openfd(unsigned int gpio)
|
||||
{
|
||||
char filepath[60];
|
||||
|
||||
snprintf(filepath, sizeof(filepath), "/sys/class/gpio/gpio%d/value", gpio);
|
||||
snprintf(filepath, sizeof(filepath), "/sys/class/gpio/gpio%ud/value", gpio);
|
||||
return (open(filepath, O_RDWR));
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ static int linuxgpio_dir(unsigned int gpio, unsigned int dir)
|
||||
int fd, r;
|
||||
char buf[60];
|
||||
|
||||
snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio);
|
||||
snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%ud/direction", gpio);
|
||||
|
||||
fd = open(buf, O_WRONLY);
|
||||
if (fd < 0) {
|
||||
|
||||
88
ser_posix.c
88
ser_posix.c
@@ -37,9 +37,6 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#ifdef __linux__
|
||||
#include <linux/serial.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
@@ -55,13 +52,8 @@ struct baud_mapping {
|
||||
speed_t speed;
|
||||
};
|
||||
|
||||
static struct termios original_termios;
|
||||
static int saved_original_termios;
|
||||
/* There are a lot more baud rates we could handle, but what's the point? */
|
||||
|
||||
#if !defined __linux__
|
||||
/* For linux this mapping is no longer needed.
|
||||
* (OSX and *BSD do not need this mapping either because for them,
|
||||
* Bxxx is the same as xxx.) */
|
||||
static struct baud_mapping baud_lookup_table [] = {
|
||||
{ 1200, B1200 },
|
||||
{ 2400, B2400 },
|
||||
@@ -81,6 +73,8 @@ static struct baud_mapping baud_lookup_table [] = {
|
||||
{ 0, 0 } /* Terminator. */
|
||||
};
|
||||
|
||||
static struct termios original_termios;
|
||||
static int saved_original_termios;
|
||||
|
||||
static speed_t serial_baud_lookup(long baud)
|
||||
{
|
||||
@@ -101,19 +95,12 @@ static speed_t serial_baud_lookup(long baud)
|
||||
|
||||
return baud;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ser_setspeed(union filedescriptor *fd, long baud)
|
||||
{
|
||||
int rc;
|
||||
struct termios termios;
|
||||
#if defined __linux__
|
||||
/* for linux no conversion is needed*/
|
||||
speed_t speed = baud;
|
||||
#else
|
||||
/* converting the baud rate to the bit set needed by posix way*/
|
||||
speed_t speed = serial_baud_lookup (baud);
|
||||
#endif
|
||||
|
||||
if (!isatty(fd->ifd))
|
||||
return -ENOTTY;
|
||||
@@ -141,79 +128,16 @@ static int ser_setspeed(union filedescriptor *fd, long baud)
|
||||
termios.c_cflag = (CS8 | CREAD | CLOCAL);
|
||||
termios.c_cc[VMIN] = 1;
|
||||
termios.c_cc[VTIME] = 0;
|
||||
#ifdef __linux__
|
||||
/* Support for custom baud rate for linux is implemented by setting
|
||||
* a dummy baud rate of 38400 and manupulating the custom divider of
|
||||
* the serial interface*/
|
||||
struct serial_struct ss;
|
||||
int ioret = ioctl(fd->ifd, TIOCGSERIAL, &ss);
|
||||
if (ioret < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: Cannot get serial port settings. ioctl returned %d\n",
|
||||
progname, ioret);
|
||||
return -errno;
|
||||
}
|
||||
ss.flags = (ss.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST;
|
||||
ss.custom_divisor = (ss.baud_base + (speed / 2)) / speed;
|
||||
unsigned int closestSpeed = ss.baud_base / ss.custom_divisor;
|
||||
|
||||
if (closestSpeed < speed * 98 / 100 || closestSpeed > speed * 102 / 100) {
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: Cannot set serial port speed to %d. Closest possible is %d\n",
|
||||
progname, speed, closestSpeed);
|
||||
return -errno;
|
||||
}
|
||||
ioret= ioctl(fd->ifd, TIOCSSERIAL, &ss);
|
||||
if (ioret < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: Cannot set serial port speed to %d. ioctl returned %d\n",
|
||||
progname, speed, ioret);
|
||||
return -errno;
|
||||
}
|
||||
if (cfsetispeed(&termios, B38400) < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: cfsetispeed: failed to set dummy baud\n",
|
||||
progname);
|
||||
return -errno;
|
||||
}
|
||||
if (cfsetospeed(&termios, B38400) < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: cfsetospeed: failed to set dummy baud\n",
|
||||
progname);
|
||||
return -errno;
|
||||
}
|
||||
#else /* !linux */
|
||||
if (cfsetospeed(&termios, speed) < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: cfsetospeed: failed to set speed: %d\n",
|
||||
progname, speed);
|
||||
return -errno;
|
||||
}
|
||||
if (cfsetispeed(&termios, speed) < 0){
|
||||
avrdude_message(MSG_INFO,
|
||||
"%s: cfsetispeed: failed to set speed: %d\n",
|
||||
progname, speed);
|
||||
return -errno;
|
||||
}
|
||||
#endif /* linux */
|
||||
cfsetospeed(&termios, speed);
|
||||
cfsetispeed(&termios, speed);
|
||||
|
||||
rc = tcsetattr(fd->ifd, TCSANOW, &termios);
|
||||
if (rc < 0) {
|
||||
avrdude_message(MSG_INFO, "%s: ser_setspeed(): tcsetattr() failed\n",
|
||||
progname);
|
||||
return -errno;
|
||||
}
|
||||
#ifdef __linux__
|
||||
/* a bit more linux specific stuff to set custom baud rates*/
|
||||
if (ioctl(fd->ifd, TIOCGSERIAL, &ss) < 0){
|
||||
avrdude_message(MSG_INFO, "%s: ioctl: failed to get port settins\n", progname);
|
||||
return -errno;
|
||||
}
|
||||
ss.flags &= ~ASYNC_SPD_MASK;
|
||||
if (ioctl(fd->ifd, TIOCSSERIAL, &ss) < 0){
|
||||
avrdude_message(MSG_INFO, "%s: ioctl: failed to set port settins\n", progname);
|
||||
return -errno;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Everything is now set up for a local line without modem control
|
||||
|
||||
@@ -166,6 +166,13 @@ static int usbdev_open(char * port, union pinfo pinfo, union filedescriptor *fd)
|
||||
fd->usb.eep = 0;
|
||||
}
|
||||
|
||||
if(strstr(product, "mEDBG") != NULL)
|
||||
{
|
||||
/* The AVR Xplained Mini uses different endpoints. */
|
||||
fd->usb.rep = 0x81;
|
||||
fd->usb.wep = 0x02;
|
||||
}
|
||||
|
||||
avrdude_message(MSG_NOTICE, "%s: usbdev_open(): Found %s, serno: %s\n",
|
||||
progname, product, string);
|
||||
if (serno != NULL)
|
||||
@@ -353,7 +360,7 @@ static int usbdev_send(union filedescriptor *fd, const unsigned char *bp, size_t
|
||||
}
|
||||
bp += tx_size;
|
||||
mlen -= tx_size;
|
||||
} while (tx_size == fd->usb.max_xfer);
|
||||
} while (mlen > 0);
|
||||
|
||||
if (verbose > 3)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user