diff --git a/.gitignore b/.gitignore index 00e281cbd..8fd574fde 100644 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,5 @@ __pycache__/ !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json -*.code-workspace \ No newline at end of file +*.code-workspace +*.o diff --git a/dfu-util.sh b/dfu-util.sh new file mode 100755 index 000000000..7b520fbd8 --- /dev/null +++ b/dfu-util.sh @@ -0,0 +1,40 @@ +#!/bin/sh - +# +# Use the correct dfu-util program based on the architecture +# + +# Get the directory where the script is running. +DIR=$(cd "$(dirname "$0")" && pwd) +UNAME_OS="$(uname -s)" +case "${UNAME_OS}" in + Linux*) + # Choose dfu program by arch + if [ "$(uname -m)" = "x86_64" ]; then + DFU_UTIL=${DIR}/linux/dfu-util_x86_64/dfu-util + else + DFU_UTIL=${DIR}/linux/dfu-util/dfu-util + fi + ;; + Darwin*) + DFU_UTIL=${DIR}/macosx/dfu-util/dfu-util + if [ ! -x "${DFU_UTIL}" ]; then + DFU_UTIL=/opt/local/bin/dfu-util + fi + ;; + Windows*) + DFU_UTIL=${DIR}/win/dfu-util.exe + ;; + *) + echo "Unknown host OS: ${UNAME_OS}." + exit 1 + ;; +esac + +# Not found! +if [ ! -x "${DFU_UTIL}" ]; then + echo "$0: error: cannot find ${DFU_UTIL}" >&2 + exit 2 +fi + +# Pass all parameters through +"${DFU_UTIL}" "$@" diff --git a/linux/dfu-util.sh b/linux/dfu-util.sh deleted file mode 100755 index 2f355b4ce..000000000 --- a/linux/dfu-util.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# -# Use the correct dfu-util program based on the architecture -# - -# Get the directory where the script is running. -DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# Choose dfu program by arch -if [ "$(uname -m)" == "x86_64" ]; then - DFU_UTIL=${DIR}/dfu-util_x86_64/dfu-util -else - DFU_UTIL=${DIR}/dfu-util/dfu-util -fi - -# Not found! -if [ ! -x "${DFU_UTIL}" ]; then - echo "$0: error: cannot find ${DFU_UTIL}" >&2 - exit 2 -fi - -# Pass all parameters through -"${DFU_UTIL}" "$@" diff --git a/linux/maple_upload.sh b/linux/maple_upload.sh deleted file mode 100755 index 37d21ce20..000000000 --- a/linux/maple_upload.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash - -set -e - -if [ $# -lt 4 ]; then - echo "Usage: $0 $# " >&2 - exit 1 -fi -altID="$2" -usbID="$3" -binfile="$4" -dummy_port_fullpath="/dev/$1" -if [ $# -eq 5 ]; then - dfuse_addr="--dfuse-address $5" -else - dfuse_addr="" -fi - -# Get the directory where the script is running. -DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# ----------------- IMPORTANT ----------------- -# The 2nd parameter to upload-reset is the delay after resetting before it exits -# This value is in milliseonds -# You may need to tune this to your system -# 750ms to 1500ms seems to work on my Mac -# This is less critical now that we automatically retry dfu-util - -if ! "${DIR}/upload-reset" "${dummy_port_fullpath}" 750; then - echo "****************************************" >&2 - echo "* Could not automatically reset device *" >&2 - echo "* Please manually reset device! *" >&2 - echo "****************************************" >&2 - sleep 2 # Wait for user to see message. -fi - -COUNTER=5 -while - "${DIR}/dfu-util.sh" -d "${usbID}" -a "${altID}" -D "${binfile}" "${dfuse_addr}" -R - ((ret = $?)) -do - if [ $ret -eq 74 ] && [ $((--COUNTER)) -gt 0 ]; then - # I/O error, probably because no DFU device was found - echo "Trying ${COUNTER} more time(s)" >&2 - sleep 1 - else - exit $ret - fi -done - -echo -n "Waiting for ${dummy_port_fullpath} serial..." >&2 - -COUNTER=40 -while [ ! -r "${dummy_port_fullpath}" ] && ((COUNTER--)); do - echo -n "." >&2 - sleep 0.1 -done - -if [ $COUNTER -eq -1 ]; then - echo " Timed out." >&2 - exit 1 -else - echo " Done." >&2 -fi diff --git a/linux/src/build_dfu-util.sh b/linux/src/build_dfu-util.sh deleted file mode 100644 index 3563f576c..000000000 --- a/linux/src/build_dfu-util.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -sudo apt-get build-dep dfu-util -sudo apt-get install build-essentials -sudo apt-get install libusb-1.0-0-dev -sudo apt-get install autoconf automake autotools-dev - -cd dfu-util -./autogen.sh -./configure -make -cp src/dfu-util ../../linux/dfu-util -cp src/dfu-suffix ../../linux/dfu-util -cp src/dfu-prefix ../../linux/dfu-util - diff --git a/linux/src/dfu-util/AUTHORS b/linux/src/dfu-util/AUTHORS deleted file mode 100644 index 1b36c739c..000000000 --- a/linux/src/dfu-util/AUTHORS +++ /dev/null @@ -1,30 +0,0 @@ -Authors ordered by first contribution. - -Harald Welte -Werner Almesberger -Michael Lauer -Jim Huang -Stefan Schmidt -Daniel Willmann -Mike Frysinger -Uwe Hermann -C. Scott Ananian -Bernard Blackham -Holger Freyther -Marc Singer -James Perkins -Tommi Keisala -Pascal Schweizer -Bradley Scott -Uwe Bonnes -Andrey Smirnov -Jussi Timperi -Hans Petter Selasky -Bo Shen -Henrique de Almeida Mendonca -Bernd Krumboeck -Dennis Meier -Veli-Pekka Peltola -Dave Hylands -Michael Grzeschik -Paul Fertser diff --git a/linux/src/dfu-util/COPYING b/linux/src/dfu-util/COPYING deleted file mode 100644 index d60c31a97..000000000 --- a/linux/src/dfu-util/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/linux/src/dfu-util/ChangeLog b/linux/src/dfu-util/ChangeLog deleted file mode 100644 index 37f1addba..000000000 --- a/linux/src/dfu-util/ChangeLog +++ /dev/null @@ -1,93 +0,0 @@ -0.8: - o New, separate dfu-prefix tool (Uwe Bonnes) - o Allow filtering on serial number (Uwe Bonnes) - o Improved VID/PID/serial filtering (Bradley Scott) - o Support reading firmware from stdin (Tormod Volden) - o Warn if missing DFU suffix (Tormod Volden) - o Improved progress bar (Hans Petter Selasky) - o Fix dfuse leave option (Uwe Bonnes) - o Major code rework (Hans Petter Selasky) - o MS Visual Studio build support (Henrique Mendonca) - o dfuse-pack.py tool for .dfu files (Antonio Galeo) - o Many other fixes from many people - -2014-09-13: Tormod Volden - -0.7: - o Support for TI Stellaris devices (Tommi Keisala) - o Fix libusb detection on MacOSX (Marc Singer) - o Fix libusb detection on FreeBSD (Tormod Volden) - o Improved DfuSe support (Tormod Volden) - o Support all special commands (leave, unprotect, mass-erase) - o Arbitrary upload lengths - o "force" option for various possible (dangerous) overrides - -2012-10-07: Tormod Volden - -0.6: - o Add detach mode (Stefan Schmidt) - o Check return value on all libusb calls (Tormod Volden) - o Fix segmentation fault with -s option (Tormod Volden) - o Add DFU suffix manipulation tool (Stefan Schmidt) - o Port to Windows: (Tormod Volden, some parts based on work from Satz - Klauer) - o Port file handling to stdio streams - o Sleep() macros - o C99 types - o Pack structs - o Detect DfuSe device correctly on big-endian architectures (Tormod - Volden) - o Add dfuse progress indication on download (Tormod Volden) - o Cleanup: gcc pedantic, gcc extension, ... (Tormod Volden) - o Rely on page size from functional descriptor. Please report if you get - an error about it. (Tormod Volden) - o Add quirk for Maple since it reports wrong DFU version (Tormod Volden) - -2012-04-22: Stefan Schmidt - -0.5: - o DfuSe extension support for ST devices (Tormod Volden) - o Add initial support for bitWillDetach flag from DFU 1.1 (Tormod - Volden) - o Internal cleanup and some manual page fixes (Tormod Volden) - -2011-11-02: Stefan Schmidt - -0.4: - o Rework to use libusb-1.0 (Stefan Schmidt) - o DFU suffix support (Tormod Volden, Stefan Schmidt) - o Sspeed up DFU downloads directly into memory (Bernard Blackham) - o More flexible -d vid:pid parsing (Tormod Volden) - o Many bug fixes and cleanups - -2011-07-20: Stefan Schmidt - -0.3: - o quirks: Add OpenOCD to the poll timeout quirk table. - -2010-12-22: Stefan Schmidt - -0.2: - o Fix some typos on the website and the README (Antonio Ospite, Uwe - Hermann) - o Remove build rule for a static binary. We can use autotools for this. - (Mike Frysinger) - o Fix infinite loop in download error path (C. Scott Ananian) - o Break out to show the 'finished' in upload (C. Scott Ananian) - o Add GPLv2+ headers (Harald Welte) - o Remove dead code (commands.[ch]) remnescent of dfu-programmer (Harald - Welte) - o Simple quirk system with Openmoko quirk for missing bwPollTimeout (Tormod Volden) - o New default (1024) and clamping of transfer size (Tormod Volden) - o Verify sending of completion packet (Tormod Volden) - o Look for DFU functional descriptor among all descriptors (Tormod - Volden) - o Print out in which direction we are transferring data - o Abort in upload if the file already exists - -2010-11-17 Stefan Schmidt - -0.1: - Initial release - -2010-05-23 Stefan Schmidt diff --git a/linux/src/dfu-util/DEVICES.txt b/linux/src/dfu-util/DEVICES.txt deleted file mode 100644 index bdd9f1f2e..000000000 --- a/linux/src/dfu-util/DEVICES.txt +++ /dev/null @@ -1,20 +0,0 @@ -List of supported software and hardware products: - -Software user (bootloader, etc) -------------------------------- -- Sam7DFU: http://www.openpcd.org/Sam7dfu -- U-boot: DFU patches -- Barebox: http://www.barebox.org/ -- Leaflabs: http://code.google.com/p/leaflabs/ -- Blackmagic DFU - -Products using DFU ------------------- -- OpenPCD (sam7dfu) -- Openmoko Neo 1973 and Freerunner (u-boot with DFU patches) -- Leaflabs Maple -- ATUSB from Qi Hardware -- STM32F105/7, STM32F2/F3/F4 in System Bootloader -- Blackmagic debug probe -- NXP LPC31xx/LPC43XX, e.g. LPC-Link and LPC-Link2, need binaries - with LPC prefix and encoding (LPC-Link) diff --git a/linux/src/dfu-util/Makefile.am b/linux/src/dfu-util/Makefile.am deleted file mode 100644 index 641dda58a..000000000 --- a/linux/src/dfu-util/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src doc - -EXTRA_DIST = autogen.sh TODO DEVICES.txt dfuse-pack.py diff --git a/linux/src/dfu-util/README b/linux/src/dfu-util/README deleted file mode 100644 index 0f8f2621a..000000000 --- a/linux/src/dfu-util/README +++ /dev/null @@ -1,20 +0,0 @@ -Dfu-util - Device Firmware Upgrade Utilities - -Dfu-util is the host side implementation of the DFU 1.0 [1] and DFU 1.1 [2] -specification of the USB forum. - -DFU is intended to download and upload firmware to devices connected over -USB. It ranges from small devices like micro-controller boards up to mobile -phones. With dfu-util you are able to download firmware to your device or -upload firmware from it. - -dfu-util has been tested with Openmoko Neo1973 and Freerunner and many -other devices. - -[1] DFU 1.0 spec: http://www.usb.org/developers/devclass_docs/usbdfu10.pdf -[2] DFU 1.1 spec: http://www.usb.org/developers/devclass_docs/DFU_1.1.pdf - -The official website is: - - http://dfu-util.gnumonks.org/ - diff --git a/linux/src/dfu-util/TODO b/linux/src/dfu-util/TODO deleted file mode 100644 index 900c30c29..000000000 --- a/linux/src/dfu-util/TODO +++ /dev/null @@ -1,14 +0,0 @@ -DfuSe: -- Do erase and write in two separate passes when downloading -- Skip "Set Address" command when downloading contiguous blocks -- Implement "Get Commands" command - -Devices: -- Research iPhone/iPod/iPad support - Heavily modified dfu-util fork here: - https://github.com/planetbeing/xpwn/tree/master/dfu-util -- Test against Niftylights - -Non-Code: -- Logo -- Re-License as LGPL for usage as library? diff --git a/linux/src/dfu-util/autogen.sh b/linux/src/dfu-util/autogen.sh deleted file mode 100644 index e67aed39a..000000000 --- a/linux/src/dfu-util/autogen.sh +++ /dev/null @@ -1,2 +0,0 @@ -#! /bin/sh -autoreconf -v -i diff --git a/linux/src/dfu-util/configure.ac b/linux/src/dfu-util/configure.ac deleted file mode 100644 index 86221143f..000000000 --- a/linux/src/dfu-util/configure.ac +++ /dev/null @@ -1,41 +0,0 @@ -# -*- Autoconf -*- -# Process this file with autoconf to produce a configure script. - -AC_PREREQ(2.59) -AC_INIT([dfu-util],[0.8],[dfu-util@lists.gnumonks.org],,[http://dfu-util.gnumonks.org]) -AC_CONFIG_AUX_DIR(m4) -AM_INIT_AUTOMAKE([foreign]) -AC_CONFIG_HEADERS([config.h]) - -# Test for new silent rules and enable only if they are available -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) - -# Checks for programs. -AC_PROG_CC - -# Checks for libraries. -# On FreeBSD the libusb-1.0 is called libusb and resides in system location -AC_CHECK_LIB([usb], [libusb_init],, [native_libusb=no],) -AS_IF([test x$native_libusb = xno], [ - PKG_CHECK_MODULES([USB], [libusb-1.0 >= 1.0.0],, - AC_MSG_ERROR([*** Required libusb-1.0 >= 1.0.0 not installed ***])) -]) -AC_CHECK_LIB([usbpath],[usb_path2devnum],,,-lusb) - -LIBS="$LIBS $USB_LIBS" -CFLAGS="$CFLAGS $USB_CFLAGS" - -# Checks for header files. -AC_HEADER_STDC -AC_CHECK_HEADERS([usbpath.h windows.h sysexits.h]) - -# Checks for typedefs, structures, and compiler characteristics. -AC_C_CONST -AC_TYPE_SIZE_T - -# Checks for library functions. -AC_FUNC_MEMCMP -AC_CHECK_FUNCS([ftruncate getpagesize nanosleep err]) - -AC_CONFIG_FILES(Makefile src/Makefile doc/Makefile) -AC_OUTPUT diff --git a/linux/src/dfu-util/device-logs/README b/linux/src/dfu-util/device-logs/README deleted file mode 100644 index 00d3d1a96..000000000 --- a/linux/src/dfu-util/device-logs/README +++ /dev/null @@ -1,77 +0,0 @@ -Device: -------- -qi-hardware-atusb: -- Qi Hardware ben-wpan -- DFU implementation: - http://projects.qi-hardware.com/index.php/p/ben-wpan/source/tree/master/atusb/fw/usb -- Tester: Stefan Schmidt - -openpcd: -- OpenPCD RFID reader -- DFU implementation: SAM7DFU - http://www.openpcd.org/Sam7dfu, git://git.gnumonks.org/openpcd.git -- Tester: Stefan Schmidt - -simtrace: -- Sysmocom SimTrace -- DFU implementation: SAM7DFU - http://www.openpcd.org/Sam7dfu, git://git.gnumonks.org/openpcd.git -- Tester: Stefan Schmidt - -openmoko-freerunner: -- Openmoko Freerunner -- DFU implementation: Old U-Boot - http://git.openmoko.org/?p=u-boot.git;a=shortlog;h=refs/heads/mokopatches -- Tester: Stefan Schmidt - -openmoko-neo1973: -- Openmoko Neo1073 -- DFU implementation: Old U-Boot - http://git.openmoko.org/?p=u-boot.git;a=shortlog;h=refs/heads/mokopatches -- Tester: Stefan Schmidt - -tdk-bluetooth: -- TDK Corp. Bluetooth Adapter -- DFU implementation: closed soure -- Only upload has been tested -- Tester: Stefan Schmidt - -stm32f107: -- STM32 microcontrollers with built-in (ROM) DFU loader -- DFU implementation: Closed source but probably similar to the one - in their USB device libraries. Some relevant application notes: - http://www.st.com -> AN3156 and AN2606 -- Tested by Uwe Bonnes - -stm32f4discovery: -- STM32 microcontroller board with built-in (ROM) DFU loader -- DFU implementation: Closed source, probably similar to stm32f107. -- Tested by Joe Rothweiler - -dso-nano: -- DSO Nano pocket oscilloscope -- DFU implementation: Based on ST Microelectronics USB FS Library 1.0 - http://dsonano.googlecode.com/files/DS0201_OpenSource.rar -- Tester: Tormod Volden - -opc-20: -- Custom devices based on STM32F1xx -- DFU implementation: ST Microelectronics USB FS Device Library 3.1.0 - http://www.st.com -> um0424.zip -- Tester: Tormod Volden - -lpc-link, lpclink2: -- NXP LPCXpresso debug adapters -- Proprietary DFU implementation, uses special download files with - LPC prefix and encoding of the target firmware code -- Tested by Uwe Bonnes - -Adding the lsusb output and a download log of your device here helps -us to avoid regressions for hardware we cannot test while working on -the code. To extract the lsusb output use this command: -sudo lsusb -v -d $USBID > $DEVICE.lsusb -Prepare a description snippet as above, and send it to us. A log -(copy-paste of the command window) of a firmware download is also -nice, please use the double verbose option -v -v and include the -command line in the log file. - diff --git a/linux/src/dfu-util/device-logs/dsonano.lsusb b/linux/src/dfu-util/device-logs/dsonano.lsusb deleted file mode 100644 index 140a7bc6c..000000000 --- a/linux/src/dfu-util/device-logs/dsonano.lsusb +++ /dev/null @@ -1,60 +0,0 @@ - -Bus 002 Device 004: ID 0483:df11 SGS Thomson Microelectronics -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x0483 SGS Thomson Microelectronics - idProduct 0xdf11 - bcdDevice 1.1a - iManufacturer 1 STMicroelectronics - iProduct 2 STM32 DFU - iSerial 3 001 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 36 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0x80 - (Bus Powered) - MaxPower 64mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 0 - iInterface 4 @Internal Flash /0x08000000/12*001Ka,116*001Kg - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 1 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 0 - iInterface 5 @SPI Flash : M25P64/0x00000000/64*064Kg,64*064Kg - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 11 - Will Detach - Manifestation Intolerant - Upload Supported - Download Supported - wDetachTimeout 255 milliseconds - wTransferSize 1024 bytes - bcdDFUVersion 1.1a -Device Status: 0x0000 - (Bus Powered) diff --git a/linux/src/dfu-util/device-logs/lpclink.log b/linux/src/dfu-util/device-logs/lpclink.log deleted file mode 100644 index 7de4dd3e6..000000000 --- a/linux/src/dfu-util/device-logs/lpclink.log +++ /dev/null @@ -1,59 +0,0 @@ -(The on-board LPC3154 has some encryption key set and LPCXpressoWIN.enc -is encrypted.) - -$ lsusb | grep NXP -Bus 003 Device 011: ID 0471:df55 Philips (or NXP) LPCXpresso LPC-Link - -$ dfu-util -v -v -v -R -D /opt/lpc/lpcxpresso/bin/LPCXpressoWIN.enc - -dfu-util 0.7 - -Copyright 2005-2008 Weston Schmidt, Harald Welte and OpenMoko Inc. -Copyright 2010-2012 Tormod Volden and Stefan Schmidt -This program is Free Software and has ABSOLUTELY NO WARRANTY -Please report bugs to dfu-util@lists.gnumonks.org - -dfu-util: Invalid DFU suffix signature -dfu-util: A valid DFU suffix will be required in a future dfu-util release!!! -Deducing device DFU version from functional descriptor length -Opening DFU capable USB device... -ID 0471:df55 -Run-time device DFU version 0100 -Claiming USB DFU Runtime Interface... -Determining device status: -state = dfuIDLE, status = 0 -dfu-util: WARNING: Runtime device already in DFU state ?!? -Claiming USB DFU Interface... -Setting Alternate Setting #0 ... -Determining device status: -state = dfuIDLE, status = 0 -dfuIDLE, continuing -DFU mode device DFU version 0100 -Device returned transfer size 2048 -Copying data from PC to DFU device -Download [ ] 0% 0 bytes -Download [= ] 6% 2048 bytes -Download [=== ] 13% 4096 bytes -Download [==== ] 19% 6144 bytes -Download [====== ] 26% 8192 bytes -Download [======== ] 32% 10240 bytes -Download [========= ] 39% 12288 bytes -Download [=========== ] 45% 14336 bytes -Download [============= ] 52% 16384 bytes -Download [============== ] 59% 18432 bytes -Download [================ ] 65% 20480 bytes -Download [================== ] 72% 22528 bytes -Download [=================== ] 78% 24576 bytes -Download [===================== ] 85% 26624 bytes -Download [====================== ] 91% 28672 bytes -Download [======================== ] 98% 29192 bytes -Download [=========================] 100% 29192 bytes -Download done. -Sent a total of 29192 bytes -state(8) = dfuMANIFEST-WAIT-RESET, status(0) = No error condition is present -Done! -dfu-util: can't detach -Resetting USB to switch back to runtime mode - -$ lsusb | grep NXP -Bus 003 Device 012: ID 1fc9:0009 NXP Semiconductors diff --git a/linux/src/dfu-util/device-logs/lpclink.lsusb b/linux/src/dfu-util/device-logs/lpclink.lsusb deleted file mode 100644 index 867b2a2c5..000000000 --- a/linux/src/dfu-util/device-logs/lpclink.lsusb +++ /dev/null @@ -1,58 +0,0 @@ - -Bus 003 Device 008: ID 0471:df55 Philips (or NXP) LPCXpresso LPC-Link -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 2.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x0471 Philips (or NXP) - idProduct 0xdf55 LPCXpresso LPC-Link - bcdDevice 0.01 - iManufacturer 0 - iProduct 0 - iSerial 0 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 25 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0x80 - (Bus Powered) - MaxPower 100mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 0 - iInterface 0 - Device Firmware Upgrade Interface Descriptor: - bLength 7 - bDescriptorType 33 - bmAttributes 1 - Will Not Detach - Manifestation Intolerant - Upload Unsupported - Download Supported - wDetachTimeout 65535 milliseconds - wTransferSize 2048 bytes -Device Qualifier (for other device speed): - bLength 10 - bDescriptorType 6 - bcdUSB 2.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - bNumConfigurations 1 -Device Status: 0x0000 - (Bus Powered) diff --git a/linux/src/dfu-util/device-logs/lpclink2.log b/linux/src/dfu-util/device-logs/lpclink2.log deleted file mode 100644 index 4681eff7d..000000000 --- a/linux/src/dfu-util/device-logs/lpclink2.log +++ /dev/null @@ -1,59 +0,0 @@ -$ lsusb | grep NXP -Bus 003 Device 013: ID 1fc9:000c NXP Semiconductors - -$ dfu-util -D ~/devel/dfu-util/firmware.bin.qthdr - -dfu-util 0.7 - -Copyright 2005-2008 Weston Schmidt, Harald Welte and OpenMoko Inc. -Copyright 2010-2012 Tormod Volden and Stefan Schmidt -This program is Free Software and has ABSOLUTELY NO WARRANTY -Please report bugs to dfu-util@lists.gnumonks.org - -dfu-util: Invalid DFU suffix signature -dfu-util: A valid DFU suffix will be required in a future dfu-util release!!! -Possible unencryptes NXP LPC DFU prefix with the following properties -Payload length: 39 kiByte -Opening DFU capable USB device... -ID 1fc9:000c -Run-time device DFU version 0100 -Claiming USB DFU Runtime Interface... -Determining device status: -state = dfuIDLE, status = 0 -dfu-util: WARNING: Runtime device already in DFU state ?!? -Claiming USB DFU Interface... -Setting Alternate Setting #0 ... -Determining device status: -state = dfuIDLE, status = 0 -dfuIDLE, continuing -DFU mode device DFU version 0100 -Device returned transfer size 2048 -Copying data from PC to DFU device -Download [ ] 0% 0 bytes -Download [= ] 4% 2048 bytes -Download [== ] 9% 4096 bytes -Download [=== ] 14% 6144 bytes -Download [==== ] 19% 8192 bytes -Download [====== ] 24% 10240 bytes -Download [======= ] 28% 12288 bytes -Download [======== ] 33% 14336 bytes -Download [========= ] 38% 16384 bytes -Download [========== ] 43% 18432 bytes -Download [============ ] 48% 20480 bytes -Download [============= ] 53% 22528 bytes -Download [============== ] 57% 24576 bytes -Download [=============== ] 62% 26624 bytes -Download [================ ] 67% 28672 bytes -Download [================== ] 72% 30720 bytes -Download [=================== ] 77% 32768 bytes -Download [==================== ] 82% 34816 bytes -Download [===================== ] 86% 36864 bytes -Download [====================== ] 91% 38912 bytes -Download [======================== ] 96% 40356 bytes -Download [=========================] 100% 40356 bytes -Download done. -Sent a total of 40356 bytes -dfu-util: unable to read DFU status - -$ lsusb | grep NXP -Bus 003 Device 014: ID 1fc9:0018 NXP Semiconductors diff --git a/linux/src/dfu-util/device-logs/lpclink2.lsusb b/linux/src/dfu-util/device-logs/lpclink2.lsusb deleted file mode 100644 index b833fca77..000000000 --- a/linux/src/dfu-util/device-logs/lpclink2.lsusb +++ /dev/null @@ -1,203 +0,0 @@ - -Bus 003 Device 007: ID 0c72:000c PEAK System PCAN-USB -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 16 - idVendor 0x0c72 PEAK System - idProduct 0x000c PCAN-USB - bcdDevice 1c.ff - iManufacturer 0 - iProduct 3 VER1:PEAK -VER2:02.8.01 -DAT :06.05.2004 -TIME:09:35:37 - ... - iSerial 0 - bNumConfigurations 3 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 46 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0x80 - (Bus Powered) - MaxPower 200mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 4 - bInterfaceClass 0 (Defined at Interface level) - bInterfaceSubClass 0 - bInterfaceProtocol 0 - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 20 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x01 EP 1 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 20 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x82 EP 2 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x02 EP 2 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 46 - bNumInterfaces 1 - bConfigurationValue 2 - iConfiguration 0 - bmAttributes 0x80 - (Bus Powered) - MaxPower 394mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 4 - bInterfaceClass 0 (Defined at Interface level) - bInterfaceSubClass 0 - bInterfaceProtocol 0 - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 20 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x01 EP 1 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 20 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x82 EP 2 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x02 EP 2 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 46 - bNumInterfaces 1 - bConfigurationValue 3 - iConfiguration 0 - bmAttributes 0x80 - (Bus Powered) - MaxPower 200mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 4 - bInterfaceClass 0 (Defined at Interface level) - bInterfaceSubClass 0 - bInterfaceProtocol 0 - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 3 - Transfer Type Interrupt - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x01 EP 1 OUT - bmAttributes 3 - Transfer Type Interrupt - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x82 EP 2 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x02 EP 2 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 1 -Device Status: 0x0001 - Self Powered diff --git a/linux/src/dfu-util/device-logs/opc-20.lsusb b/linux/src/dfu-util/device-logs/opc-20.lsusb deleted file mode 100644 index 580df90e5..000000000 --- a/linux/src/dfu-util/device-logs/opc-20.lsusb +++ /dev/null @@ -1,60 +0,0 @@ - -Bus 001 Device 004: ID 0483:df11 SGS Thomson Microelectronics -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x0483 SGS Thomson Microelectronics - idProduct 0xdf11 - bcdDevice 2.00 - iManufacturer 1 STMicroelectronics - iProduct 2 STM32 DFU - iSerial 3 ������������ - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 36 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0xc0 - Self Powered - MaxPower 100mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 4 @Internal Flash /0x08000000/12*001Ka,116*001Kg - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 1 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 5 @SPI Flash : M25P64/0x00000000/128*64Kg - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 11 - Will Detach - Manifestation Intolerant - Upload Supported - Download Supported - wDetachTimeout 255 milliseconds - wTransferSize 1024 bytes - bcdDFUVersion 1a.01 -Device Status: 0x0001 - Self Powered diff --git a/linux/src/dfu-util/device-logs/openmoko-freerunner-dfumode.lsusb b/linux/src/dfu-util/device-logs/openmoko-freerunner-dfumode.lsusb deleted file mode 100644 index 4c0abfb06..000000000 --- a/linux/src/dfu-util/device-logs/openmoko-freerunner-dfumode.lsusb +++ /dev/null @@ -1,109 +0,0 @@ -Bus 003 Device 017: ID 1d50:5119 OpenMoko, Inc. GTA01/GTA02 U-Boot Bootloader -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 16 - idVendor 0x1d50 OpenMoko, Inc. - idProduct 0x5119 GTA01/GTA02 U-Boot Bootloader - bcdDevice 0.00 - iManufacturer 1 OpenMoko, Inc - iProduct 2 Neo1973 Bootloader U-Boot 1.3.2-moko12 - iSerial 3 0000000 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 81 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 7 USB Device Firmware Upgrade - bmAttributes 0x80 - (Bus Powered) - MaxPower 100mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 8 RAM 0x32000000 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 1 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 9 u-boot - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 2 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 10 u-boot_env - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 3 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 11 kernel - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 4 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 12 splash - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 5 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 13 factory - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 6 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 14 rootfs - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 7 - Will Not Detach - Manifestation Tolerant - Upload Supported - Download Supported - wDetachTimeout 65280 milliseconds - wTransferSize 4096 bytes - bcdDFUVersion 1.00 -Device Status: 0x0a00 - (Bus Powered) diff --git a/linux/src/dfu-util/device-logs/openmoko-freerunner.lsusb b/linux/src/dfu-util/device-logs/openmoko-freerunner.lsusb deleted file mode 100644 index 835708dd8..000000000 --- a/linux/src/dfu-util/device-logs/openmoko-freerunner.lsusb +++ /dev/null @@ -1,179 +0,0 @@ -Bus 005 Device 033: ID 1d50:5119 OpenMoko, Inc. GTA01/GTA02 U-Boot Bootloader -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.10 - bDeviceClass 2 Communications - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 16 - idVendor 0x1d50 OpenMoko, Inc. - idProduct 0x5119 GTA01/GTA02 U-Boot Bootloader - bcdDevice 0.00 - iManufacturer 1 OpenMoko, Inc - iProduct 2 Neo1973 Bootloader U-Boot 1.3.2-moko12 - iSerial 3 0000000 - bNumConfigurations 2 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 85 - bNumInterfaces 3 - bConfigurationValue 1 - iConfiguration 4 TTY via USB - bmAttributes 0x80 - (Bus Powered) - MaxPower 500mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 1 - bInterfaceClass 2 Communications - bInterfaceSubClass 2 Abstract (modem) - bInterfaceProtocol 1 AT-commands (v.25ter) - iInterface 6 Control Interface - CDC Header: - bcdCDC 0.6e - CDC Call Management: - bmCapabilities 0x00 - bDataInterface 1 - CDC ACM: - bmCapabilities 0x00 - CDC Union: - bMasterInterface 0 - bSlaveInterface 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 3 - Transfer Type Interrupt - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 0 - bNumEndpoints 2 - bInterfaceClass 10 CDC Data - bInterfaceSubClass 0 Unused - bInterfaceProtocol 0 - iInterface 5 Bulk Data Interface - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x02 EP 2 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 2 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 1 - iInterface 7 USB Device Firmware Upgrade - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 7 - Will Not Detach - Manifestation Tolerant - Upload Supported - Download Supported - wDetachTimeout 65280 milliseconds - wTransferSize 4096 bytes - bcdDFUVersion 1.00 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 67 - bNumInterfaces 2 - bConfigurationValue 2 - iConfiguration 4 TTY via USB - bmAttributes 0x80 - (Bus Powered) - MaxPower 100mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 1 - bInterfaceClass 2 Communications - bInterfaceSubClass 2 Abstract (modem) - bInterfaceProtocol 1 AT-commands (v.25ter) - iInterface 6 Control Interface - CDC Header: - bcdCDC 0.6e - CDC Call Management: - bmCapabilities 0x00 - bDataInterface 1 - CDC ACM: - bmCapabilities 0x00 - CDC Union: - bMasterInterface 0 - bSlaveInterface 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 3 - Transfer Type Interrupt - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 0 - bNumEndpoints 2 - bInterfaceClass 10 CDC Data - bInterfaceSubClass 0 Unused - bInterfaceProtocol 0 - iInterface 5 Bulk Data Interface - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x02 EP 2 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 -Device Status: 0x9a00 - (Bus Powered) diff --git a/linux/src/dfu-util/device-logs/openmoko-neo1973.lsusb b/linux/src/dfu-util/device-logs/openmoko-neo1973.lsusb deleted file mode 100644 index 07789506a..000000000 --- a/linux/src/dfu-util/device-logs/openmoko-neo1973.lsusb +++ /dev/null @@ -1,182 +0,0 @@ - -Bus 006 Device 020: ID 1457:5119 First International Computer, Inc. OpenMoko Neo1973 u-boot cdc_acm serial port -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.10 - bDeviceClass 2 Communications - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 16 - idVendor 0x1457 First International Computer, Inc. - idProduct 0x5119 OpenMoko Neo1973 u-boot cdc_acm serial port - bcdDevice 0.00 - iManufacturer 1 - iProduct 2 - iSerial 3 - bNumConfigurations 2 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 85 - bNumInterfaces 3 - bConfigurationValue 1 - iConfiguration 4 - bmAttributes 0x80 - (Bus Powered) - MaxPower 500mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 1 - bInterfaceClass 2 Communications - bInterfaceSubClass 2 Abstract (modem) - bInterfaceProtocol 1 AT-commands (v.25ter) - iInterface 6 - CDC Header: - bcdCDC 0.6e - CDC Call Management: - bmCapabilities 0x00 - bDataInterface 1 - CDC ACM: - bmCapabilities 0x00 - CDC Union: - bMasterInterface 0 - bSlaveInterface 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 3 - Transfer Type Interrupt - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 0 - bNumEndpoints 2 - bInterfaceClass 10 CDC Data - bInterfaceSubClass 0 Unused - bInterfaceProtocol 0 - iInterface 5 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x02 EP 2 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 2 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 1 - iInterface 7 - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 7 - Will Not Detach - Manifestation Tolerant - Upload Supported - Download Supported - wDetachTimeout 65280 milliseconds - wTransferSize 4096 bytes - bcdDFUVersion 1.00 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 67 - bNumInterfaces 2 - bConfigurationValue 2 - iConfiguration 4 - bmAttributes 0x80 - (Bus Powered) - MaxPower 100mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 1 - bInterfaceClass 2 Communications - bInterfaceSubClass 2 Abstract (modem) - bInterfaceProtocol 1 AT-commands (v.25ter) - iInterface 6 - CDC Header: - bcdCDC 0.6e - CDC Call Management: - bmCapabilities 0x00 - bDataInterface 1 - CDC ACM: - bmCapabilities 0x00 - CDC Union: - bMasterInterface 0 - bSlaveInterface 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 3 - Transfer Type Interrupt - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 0 - bNumEndpoints 2 - bInterfaceClass 10 CDC Data - bInterfaceSubClass 0 Unused - bInterfaceProtocol 0 - iInterface 5 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x02 EP 2 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 -Device Status: 0x0006 - (Bus Powered) - Remote Wakeup Enabled - Test Mode diff --git a/linux/src/dfu-util/device-logs/openpcd.lsusb b/linux/src/dfu-util/device-logs/openpcd.lsusb deleted file mode 100644 index f6255a943..000000000 --- a/linux/src/dfu-util/device-logs/openpcd.lsusb +++ /dev/null @@ -1,60 +0,0 @@ - -Bus 006 Device 016: ID 16c0:076b VOTI OpenPCD 13.56MHz RFID Reader -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 8 - idVendor 0x16c0 VOTI - idProduct 0x076b OpenPCD 13.56MHz RFID Reader - bcdDevice 0.00 - iManufacturer 1 - iProduct 2 OpenPCD RFID Simulator - DFU Mode - iSerial 0 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 36 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0x80 - (Bus Powered) - MaxPower 200mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 0 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 1 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 0 - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 3 - Will Not Detach - Manifestation Intolerant - Upload Supported - Download Supported - wDetachTimeout 65280 milliseconds - wTransferSize 256 bytes - bcdDFUVersion 1.00 -Device Status: 0x0000 - (Bus Powered) diff --git a/linux/src/dfu-util/device-logs/qi-hardware-atusb.lsusb b/linux/src/dfu-util/device-logs/qi-hardware-atusb.lsusb deleted file mode 100644 index bfc1701e1..000000000 --- a/linux/src/dfu-util/device-logs/qi-hardware-atusb.lsusb +++ /dev/null @@ -1,59 +0,0 @@ - -Bus 006 Device 013: ID 20b7:1540 Qi Hardware ben-wpan, AT86RF230-based -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 2.00 - bDeviceClass 255 Vendor Specific Class - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x20b7 Qi Hardware - idProduct 0x1540 ben-wpan, AT86RF230-based - bcdDevice 0.01 - iManufacturer 0 - iProduct 0 - iSerial 1 4630333438371508231a - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 34 - bNumInterfaces 2 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0x80 - (Bus Powered) - MaxPower 40mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 1 - bInterfaceClass 255 Vendor Specific Class - bInterfaceSubClass 0 - bInterfaceProtocol 0 - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 0 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 1 - iInterface 0 -Device Status: 0x0000 - (Bus Powered) diff --git a/linux/src/dfu-util/device-logs/simtrace.lsusb b/linux/src/dfu-util/device-logs/simtrace.lsusb deleted file mode 100644 index 578ddf0e1..000000000 --- a/linux/src/dfu-util/device-logs/simtrace.lsusb +++ /dev/null @@ -1,70 +0,0 @@ - -Bus 006 Device 017: ID 16c0:0762 VOTI -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 8 - idVendor 0x16c0 VOTI - idProduct 0x0762 - bcdDevice 0.00 - iManufacturer 1 sysmocom - systems for mobile communications GmbH - iProduct 2 SimTrace SIM Sniffer - DFU Mode - iSerial 0 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 45 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 3 SimTrace DFU Configuration - bmAttributes 0x80 - (Bus Powered) - MaxPower 200mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 4 SimTrace DFU Interface - Application Partition - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 1 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 5 SimTrace DFU Interface - Bootloader Partition - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 2 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 6 SimTrace DFU Interface - RAM - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 3 - Will Not Detach - Manifestation Intolerant - Upload Supported - Download Supported - wDetachTimeout 65280 milliseconds - wTransferSize 256 bytes - bcdDFUVersion 1.00 -Device Status: 0x0000 - (Bus Powered) diff --git a/linux/src/dfu-util/device-logs/sparkcore.lsusb b/linux/src/dfu-util/device-logs/sparkcore.lsusb deleted file mode 100644 index b6029ffa5..000000000 --- a/linux/src/dfu-util/device-logs/sparkcore.lsusb +++ /dev/null @@ -1,60 +0,0 @@ - -Bus 001 Device 008: ID 1d50:607f OpenMoko, Inc. -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x1d50 OpenMoko, Inc. - idProduct 0x607f - bcdDevice 2.00 - iManufacturer 1 Spark Devices - iProduct 2 CORE DFU - iSerial 3 8D80527B5055 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 36 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0xc0 - Self Powered - MaxPower 100mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 4 @Internal Flash /0x08000000/20*001Ka,108*001Kg - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 1 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 5 @SPI Flash : SST25x/0x00000000/512*04Kg - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 11 - Will Detach - Manifestation Intolerant - Upload Supported - Download Supported - wDetachTimeout 255 milliseconds - wTransferSize 1024 bytes - bcdDFUVersion 1.1a -Device Status: 0x0001 - Self Powered diff --git a/linux/src/dfu-util/device-logs/stm32f107.bin-download b/linux/src/dfu-util/device-logs/stm32f107.bin-download deleted file mode 100644 index 45b714f83..000000000 --- a/linux/src/dfu-util/device-logs/stm32f107.bin-download +++ /dev/null @@ -1,48 +0,0 @@ -> src/dfu-util --intf 0 --alt 0 -v -v -v -s 0x8000000 -D test3 -dfu-util 0.4 - -(C) 2005-2008 by Weston Schmidt, Harald Welte and OpenMoko Inc. -(C) 2010-2011 Tormod Volden (DfuSe support) -This program is Free Software and has ABSOLUTELY NO WARRANTY - -dfu-util does currently only support DFU version 1.0 - -Opening DFU USB device... ID 0483:df11 -Run-time device DFU version 011a -Found DFU: [0483:df11] devnum=0, cfg=1, intf=0, alt=0, name="@Internal Flash /0x08000000/128*002Kg" -Claiming USB DFU Interface... -Setting Alternate Setting #0 ... -Determining device status: state = dfuIDLE, status = 0 -dfuIDLE, continuing -DFU mode device DFU version 011a -Device returned transfer size 2048 -No valid DFU suffix signature -Warning: File has no DFU suffix -DfuSe interface name: "Internal Flash " -Memory segment at 0x08000000 128 x 2048 = 262144 (rew) -Uploading to address = 0x08000000, size = 16384 -Erasing page size 2048 at address 0x08000000, page starting at 0x08000000 - Download from image offset 00000000 to memory 08000000-080007ff, size 2048 - Setting address pointer to 0x08000000 -Erasing page size 2048 at address 0x08000800, page starting at 0x08000800 - Download from image offset 00000800 to memory 08000800-08000fff, size 2048 - Setting address pointer to 0x08000800 -Erasing page size 2048 at address 0x08001000, page starting at 0x08001000 - Download from image offset 00001000 to memory 08001000-080017ff, size 2048 - Setting address pointer to 0x08001000 -Erasing page size 2048 at address 0x08001800, page starting at 0x08001800 - Download from image offset 00001800 to memory 08001800-08001fff, size 2048 - Setting address pointer to 0x08001800 -Erasing page size 2048 at address 0x08002000, page starting at 0x08002000 - Download from image offset 00002000 to memory 08002000-080027ff, size 2048 - Setting address pointer to 0x08002000 -Erasing page size 2048 at address 0x08002800, page starting at 0x08002800 - Download from image offset 00002800 to memory 08002800-08002fff, size 2048 - Setting address pointer to 0x08002800 -Erasing page size 2048 at address 0x08003000, page starting at 0x08003000 - Download from image offset 00003000 to memory 08003000-080037ff, size 2048 - Setting address pointer to 0x08003000 -Erasing page size 2048 at address 0x08003800, page starting at 0x08003800 - Download from image offset 00003800 to memory 08003800-08003fff, size 2048 - Setting address pointer to 0x08003800 - diff --git a/linux/src/dfu-util/device-logs/stm32f107.lsusb b/linux/src/dfu-util/device-logs/stm32f107.lsusb deleted file mode 100644 index 14b45cda0..000000000 --- a/linux/src/dfu-util/device-logs/stm32f107.lsusb +++ /dev/null @@ -1,60 +0,0 @@ - -Bus 001 Device 028: ID 0483:df11 SGS Thomson Microelectronics STM Device in DFU Mode -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x0483 SGS Thomson Microelectronics - idProduct 0xdf11 STM Device in DFU Mode - bcdDevice 20.00 - iManufacturer 1 STMicroelectronics - iProduct 2 STM32 0x418 DFU Bootloader - iSerial 3 STM32 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 36 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0xc0 - Self Powered - MaxPower 100mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 4 @Internal Flash /0x08000000/128*002Kg - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 1 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 5 @Option Bytes /0x1FFFF800/01*016 g - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 11 - Will Detach - Manifestation Intolerant - Upload Supported - Download Supported - wDetachTimeout 255 milliseconds - wTransferSize 2048 bytes - bcdDFUVersion 1.1a -Device Status: 0x0000 - (Bus Powered) diff --git a/linux/src/dfu-util/device-logs/stm32f4discovery.bin-download b/linux/src/dfu-util/device-logs/stm32f4discovery.bin-download deleted file mode 100644 index 96e172216..000000000 --- a/linux/src/dfu-util/device-logs/stm32f4discovery.bin-download +++ /dev/null @@ -1,36 +0,0 @@ -dfu-util --device 0483:df11 --alt 0 \ - --dfuse-address 0x08000000 \ - -v -v -v \ - --download arm/iotoggle.bin -No valid DFU suffix signature -Warning: File has no DFU suffix -dfu-util 0.5 - -(C) 2005-2008 by Weston Schmidt, Harald Welte and OpenMoko Inc. -(C) 2010-2011 Tormod Volden (DfuSe support) -This program is Free Software and has ABSOLUTELY NO WARRANTY - -dfu-util does currently only support DFU version 1.0 - -Filter on vendor = 0x0483 product = 0xdf11 -Opening DFU capable USB device... ID 0483:df11 -Run-time device DFU version 011a -Found DFU: [0483:df11] devnum=0, cfg=1, intf=0, alt=0, name="@Internal Flash /0x08000000/04*016Kg,01*064Kg,07*128Kg" -Claiming USB DFU Interface... -Setting Alternate Setting #0 ... -Determining device status: state = dfuERROR, status = 10 -dfuERROR, clearing status -Determining device status: state = dfuIDLE, status = 0 -dfuIDLE, continuing -DFU mode device DFU version 011a -Device returned transfer size 2048 -DfuSe interface name: "Internal Flash " -Memory segment at 0x08000000 4 x 16384 = 65536 (rew) -Memory segment at 0x08010000 1 x 65536 = 65536 (rew) -Memory segment at 0x08020000 7 x 131072 = 917504 (rew) -Uploading to address = 0x08000000, size = 2308 -Erasing page size 16384 at address 0x08000000, page starting at 0x08000000 - Download from image offset 00000000 to memory 08000000-080007ff, size 2048 - Setting address pointer to 0x08000000 - Download from image offset 00000800 to memory 08000800-08000903, size 260 - Setting address pointer to 0x08000800 diff --git a/linux/src/dfu-util/device-logs/stm32f4discovery.lsusb b/linux/src/dfu-util/device-logs/stm32f4discovery.lsusb deleted file mode 100644 index 0b870de91..000000000 --- a/linux/src/dfu-util/device-logs/stm32f4discovery.lsusb +++ /dev/null @@ -1,80 +0,0 @@ - -Bus 001 Device 010: ID 0483:df11 SGS Thomson Microelectronics STM Device in DFU Mode -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x0483 SGS Thomson Microelectronics - idProduct 0xdf11 STM Device in DFU Mode - bcdDevice 21.00 - iManufacturer 1 STMicroelectronics - iProduct 2 STM32 BOOTLOADER - iSerial 3 315A28A0B956 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 54 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0xc0 - Self Powered - MaxPower 100mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 4 @Internal Flash /0x08000000/04*016Kg,01*064Kg,07*128Kg - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 1 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 5 @Option Bytes /0x1FFFC000/01*016 g - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 2 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 6 @OTP Memory /0x1FFF7800/01*512 g,01*016 g - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 3 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 7 @Device Feature/0xFFFF0000/01*004 g - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 11 - Will Detach - Manifestation Intolerant - Upload Supported - Download Supported - wDetachTimeout 255 milliseconds - wTransferSize 2048 bytes - bcdDFUVersion 1.1a -Device Status: 0x0001 - Self Powered diff --git a/linux/src/dfu-util/device-logs/tdk-bluetooth.lsusb b/linux/src/dfu-util/device-logs/tdk-bluetooth.lsusb deleted file mode 100644 index c0cfaceb6..000000000 --- a/linux/src/dfu-util/device-logs/tdk-bluetooth.lsusb +++ /dev/null @@ -1,269 +0,0 @@ - -Bus 006 Device 014: ID 04bf:0320 TDK Corp. Bluetooth Adapter -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 2.00 - bDeviceClass 224 Wireless - bDeviceSubClass 1 Radio Frequency - bDeviceProtocol 1 Bluetooth - bMaxPacketSize0 64 - idVendor 0x04bf TDK Corp. - idProduct 0x0320 Bluetooth Adapter - bcdDevice 26.52 - iManufacturer 1 Ezurio - iProduct 2 Turbo Bluetooth Adapter - iSerial 3 008098D4FFBD - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 193 - bNumInterfaces 3 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0x80 - (Bus Powered) - MaxPower 64mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 3 - bInterfaceClass 224 Wireless - bInterfaceSubClass 1 Radio Frequency - bInterfaceProtocol 1 Bluetooth - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 3 - Transfer Type Interrupt - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x02 EP 2 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x82 EP 2 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 1 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 0 - bNumEndpoints 2 - bInterfaceClass 224 Wireless - bInterfaceSubClass 1 Radio Frequency - bInterfaceProtocol 1 Bluetooth - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x03 EP 3 OUT - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0000 1x 0 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0000 1x 0 bytes - bInterval 1 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 1 - bNumEndpoints 2 - bInterfaceClass 224 Wireless - bInterfaceSubClass 1 Radio Frequency - bInterfaceProtocol 1 Bluetooth - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x03 EP 3 OUT - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0009 1x 9 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0009 1x 9 bytes - bInterval 1 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 2 - bNumEndpoints 2 - bInterfaceClass 224 Wireless - bInterfaceSubClass 1 Radio Frequency - bInterfaceProtocol 1 Bluetooth - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x03 EP 3 OUT - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0011 1x 17 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0011 1x 17 bytes - bInterval 1 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 3 - bNumEndpoints 2 - bInterfaceClass 224 Wireless - bInterfaceSubClass 1 Radio Frequency - bInterfaceProtocol 1 Bluetooth - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x03 EP 3 OUT - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0019 1x 25 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0019 1x 25 bytes - bInterval 1 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 4 - bNumEndpoints 2 - bInterfaceClass 224 Wireless - bInterfaceSubClass 1 Radio Frequency - bInterfaceProtocol 1 Bluetooth - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x03 EP 3 OUT - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0021 1x 33 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0021 1x 33 bytes - bInterval 1 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 5 - bNumEndpoints 2 - bInterfaceClass 224 Wireless - bInterfaceSubClass 1 Radio Frequency - bInterfaceProtocol 1 Bluetooth - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x03 EP 3 OUT - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0031 1x 49 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0031 1x 49 bytes - bInterval 1 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 2 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 0 - iInterface 0 - Device Firmware Upgrade Interface Descriptor: - bLength 7 - bDescriptorType 33 - bmAttributes 7 - Will Not Detach - Manifestation Tolerant - Upload Supported - Download Supported - wDetachTimeout 5000 milliseconds - wTransferSize 1023 bytes -Device Status: 0x0000 - (Bus Powered) diff --git a/linux/src/dfu-util/dfuse-pack.py b/linux/src/dfu-util/dfuse-pack.py deleted file mode 100644 index 875cc5c6e..000000000 --- a/linux/src/dfu-util/dfuse-pack.py +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/python - -# Written by Antonio Galea - 2010/11/18 -# Distributed under Gnu LGPL 3.0 -# see http://www.gnu.org/licenses/lgpl-3.0.txt - -import sys,struct,zlib,os -from optparse import OptionParser - -DEFAULT_DEVICE="0x0483:0xdf11" - -def named(tuple,names): - return dict(zip(names.split(),tuple)) -def consume(fmt,data,names): - n = struct.calcsize(fmt) - return named(struct.unpack(fmt,data[:n]),names),data[n:] -def cstring(string): - return string.split('\0',1)[0] -def compute_crc(data): - return 0xFFFFFFFF & -zlib.crc32(data) -1 - -def parse(file,dump_images=False): - print 'File: "%s"' % file - data = open(file,'rb').read() - crc = compute_crc(data[:-4]) - prefix, data = consume('<5sBIB',data,'signature version size targets') - print '%(signature)s v%(version)d, image size: %(size)d, targets: %(targets)d' % prefix - for t in range(prefix['targets']): - tprefix, data = consume('<6sBI255s2I',data,'signature altsetting named name size elements') - tprefix['num'] = t - if tprefix['named']: - tprefix['name'] = cstring(tprefix['name']) - else: - tprefix['name'] = '' - print '%(signature)s %(num)d, alt setting: %(altsetting)s, name: "%(name)s", size: %(size)d, elements: %(elements)d' % tprefix - tsize = tprefix['size'] - target, data = data[:tsize], data[tsize:] - for e in range(tprefix['elements']): - eprefix, target = consume('<2I',target,'address size') - eprefix['num'] = e - print ' %(num)d, address: 0x%(address)08x, size: %(size)d' % eprefix - esize = eprefix['size'] - image, target = target[:esize], target[esize:] - if dump_images: - out = '%s.target%d.image%d.bin' % (file,t,e) - open(out,'wb').write(image) - print ' DUMPED IMAGE TO "%s"' % out - if len(target): - print "target %d: PARSE ERROR" % t - suffix = named(struct.unpack('<4H3sBI',data[:16]),'device product vendor dfu ufd len crc') - print 'usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x' % suffix - if crc != suffix['crc']: - print "CRC ERROR: computed crc32 is 0x%08x" % crc - data = data[16:] - if data: - print "PARSE ERROR" - -def build(file,targets,device=DEFAULT_DEVICE): - data = '' - for t,target in enumerate(targets): - tdata = '' - for image in target: - tdata += struct.pack('<2I',image['address'],len(image['data']))+image['data'] - tdata = struct.pack('<6sBI255s2I','Target',0,1,'ST...',len(tdata),len(target)) + tdata - data += tdata - data = struct.pack('<5sBIB','DfuSe',1,len(data)+11,len(targets)) + data - v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1)) - data += struct.pack('<4H3sB',0,d,v,0x011a,'UFD',16) - crc = compute_crc(data) - data += struct.pack(' and -Harald Welte . Over time, nearly complete -support of DFU 1.0, DFU 1.1 and DfuSe ("1.1a") has been added. -.SH LICENCE -.B dfu-util -is covered by the GNU General Public License (GPL), version 2 or later. -.SH COPYRIGHT -This manual page was originally written by Uwe Hermann , -and is now part of the dfu-util project. diff --git a/linux/src/dfu-util/msvc/README_msvc.txt b/linux/src/dfu-util/msvc/README_msvc.txt deleted file mode 100644 index 6e68ec6ff..000000000 --- a/linux/src/dfu-util/msvc/README_msvc.txt +++ /dev/null @@ -1,10 +0,0 @@ -# (C) Roger Meier -# (C) Pascal Schweizer -# msvc folder is GPL-2.0+, LGPL-2.1+, BSD-3-Clause or MIT license(SPDX) - -Building dfu-util native on Windows with Visual Studio - -3rd party dependencies: -- libusbx ( git clone https://github.com/libusbx/libusbx.git ) - - getopt (part of libusbx: libusbx/examples/getopt) - diff --git a/linux/src/dfu-util/msvc/dfu-suffix_2010.vcxproj b/linux/src/dfu-util/msvc/dfu-suffix_2010.vcxproj deleted file mode 100644 index 0c316c2e5..000000000 --- a/linux/src/dfu-util/msvc/dfu-suffix_2010.vcxproj +++ /dev/null @@ -1,100 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {8F7600A2-3B37-4956-B39B-A1D43EF29EDA} - dfusuffix - dfu-suffix - - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - $(SolutionDir)..\..\libusbx\examples\getopt;$(SolutionDir)..\..\libusbx\libusb;$(IncludePath) - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\dll;$(LibraryPath) - $(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib - $(ExecutablePath) - - - $(ExecutablePath) - $(SolutionDir)..\..\libusbx\examples\getopt;$(SolutionDir)..\..\libusbx\libusb;$(IncludePath) - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\dll;$(LibraryPath) - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - - - - Level3 - Disabled - HAVE_WINDOWS_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDebug - - - true - - - - - Level3 - MaxSpeed - true - true - HAVE_WINDOWS_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - - - - - - - - - {a2169bc8-cf99-40bf-83f3-b0e38f7067bd} - - - {349ee8f9-7d25-4909-aaf5-ff3fade72187} - - - - - - \ No newline at end of file diff --git a/linux/src/dfu-util/msvc/dfu-util_2010.sln b/linux/src/dfu-util/msvc/dfu-util_2010.sln deleted file mode 100644 index ef797239b..000000000 --- a/linux/src/dfu-util/msvc/dfu-util_2010.sln +++ /dev/null @@ -1,54 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dfu-util", "dfu-util_2010.vcxproj", "{0E071A60-7EF2-4427-BAA8-9143CACB5BCB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C4F8746D-B27E-4806-95E5-2052174E923B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dfu-suffix", "dfu-suffix_2010.vcxproj", "{8F7600A2-3B37-4956-B39B-A1D43EF29EDA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "getopt_2010", "..\..\libusbx\msvc\getopt_2010.vcxproj", "{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libusb-1.0 (static)", "..\..\libusbx\msvc\libusb_static_2010.vcxproj", "{349EE8F9-7D25-4909-AAF5-FF3FADE72187}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Debug|Win32.ActiveCfg = Debug|Win32 - {0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Debug|Win32.Build.0 = Debug|Win32 - {0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Debug|x64.ActiveCfg = Debug|Win32 - {0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Release|Win32.ActiveCfg = Release|Win32 - {0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Release|Win32.Build.0 = Release|Win32 - {0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Release|x64.ActiveCfg = Release|Win32 - {8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Debug|Win32.ActiveCfg = Debug|Win32 - {8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Debug|Win32.Build.0 = Debug|Win32 - {8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Debug|x64.ActiveCfg = Debug|Win32 - {8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Release|Win32.ActiveCfg = Release|Win32 - {8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Release|Win32.Build.0 = Release|Win32 - {8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Release|x64.ActiveCfg = Release|Win32 - {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|Win32.ActiveCfg = Debug|Win32 - {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|Win32.Build.0 = Debug|Win32 - {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|x64.ActiveCfg = Debug|x64 - {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|x64.Build.0 = Debug|x64 - {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|Win32.ActiveCfg = Release|Win32 - {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|Win32.Build.0 = Release|Win32 - {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|x64.ActiveCfg = Release|x64 - {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|x64.Build.0 = Release|x64 - {349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|Win32.ActiveCfg = Debug|Win32 - {349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|Win32.Build.0 = Debug|Win32 - {349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|x64.ActiveCfg = Debug|x64 - {349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|x64.Build.0 = Debug|x64 - {349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|Win32.ActiveCfg = Release|Win32 - {349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|Win32.Build.0 = Release|Win32 - {349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|x64.ActiveCfg = Release|x64 - {349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/linux/src/dfu-util/msvc/dfu-util_2010.vcxproj b/linux/src/dfu-util/msvc/dfu-util_2010.vcxproj deleted file mode 100644 index 17a8bee1b..000000000 --- a/linux/src/dfu-util/msvc/dfu-util_2010.vcxproj +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {0E071A60-7EF2-4427-BAA8-9143CACB5BCB} - dfuutil - dfu-util - - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - $(SolutionDir)..\..\libusbx\examples\getopt;$(SolutionDir)..\..\libusbx\libusb;$(IncludePath) - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\$(Platform)\getopt\$(Configuration);$(LibraryPath) - $(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib - $(ExecutablePath) - - - $(ExecutablePath) - $(SolutionDir)..\..\libusbx\examples\getopt;$(SolutionDir)..\..\libusbx\libusb;$(IncludePath) - $(SolutionDir)..\$(Platform)\getopt\$(Configuration);$(LibraryPath) - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - - - - Level3 - Disabled - HAVE_WINDOWS_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDebug - - - true - - - - - - - - - Level3 - MaxSpeed - true - true - HAVE_WINDOWS_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - copy $(SolutionDir)..\$(Platform)\$(Configuration)\dll\libusb-1.0.dll $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - - - - - - - - - - - - - - - - - - - - - - - - - - {a2169bc8-cf99-40bf-83f3-b0e38f7067bd} - - - {349ee8f9-7d25-4909-aaf5-ff3fade72187} - - - - - - \ No newline at end of file diff --git a/linux/src/dfu-util/src/Makefile.am b/linux/src/dfu-util/src/Makefile.am deleted file mode 100644 index 70179c411..000000000 --- a/linux/src/dfu-util/src/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -AM_CFLAGS = -Wall -Wextra - -bin_PROGRAMS = dfu-util dfu-suffix dfu-prefix -dfu_util_SOURCES = main.c \ - portable.h \ - dfu_load.c \ - dfu_load.h \ - dfu_util.c \ - dfu_util.h \ - dfuse.c \ - dfuse.h \ - dfuse_mem.c \ - dfuse_mem.h \ - dfu.c \ - dfu.h \ - usb_dfu.h \ - dfu_file.c \ - dfu_file.h \ - quirks.c \ - quirks.h - -dfu_suffix_SOURCES = suffix.c \ - dfu_file.h \ - dfu_file.c - -dfu_prefix_SOURCES = prefix.c \ - dfu_file.h \ - dfu_file.c diff --git a/linux/src/dfu-util/src/dfu.c b/linux/src/dfu-util/src/dfu.c deleted file mode 100644 index 14d7673d1..000000000 --- a/linux/src/dfu-util/src/dfu.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Low-level DFU communication routines, originally taken from - * $Id: dfu.c,v 1.3 2006/06/20 06:28:04 schmidtw Exp $ - * (part of dfu-programmer). - * - * Copyright 2005-2006 Weston Schmidt - * Copyright 2011-2014 Tormod Volden - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include - -#include "portable.h" -#include "dfu.h" -#include "quirks.h" - -static int dfu_timeout = 5000; /* 5 seconds - default */ - -/* - * DFU_DETACH Request (DFU Spec 1.0, Section 5.1) - * - * device - the usb_dev_handle to communicate with - * interface - the interface to communicate with - * timeout - the timeout in ms the USB device should wait for a pending - * USB reset before giving up and terminating the operation - * - * returns 0 or < 0 on error - */ -int dfu_detach( libusb_device_handle *device, - const unsigned short interface, - const unsigned short timeout ) -{ - return libusb_control_transfer( device, - /* bmRequestType */ LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_DETACH, - /* wValue */ timeout, - /* wIndex */ interface, - /* Data */ NULL, - /* wLength */ 0, - dfu_timeout ); -} - - -/* - * DFU_DNLOAD Request (DFU Spec 1.0, Section 6.1.1) - * - * device - the usb_dev_handle to communicate with - * interface - the interface to communicate with - * length - the total number of bytes to transfer to the USB - * device - must be less than wTransferSize - * data - the data to transfer - * - * returns the number of bytes written or < 0 on error - */ -int dfu_download( libusb_device_handle *device, - const unsigned short interface, - const unsigned short length, - const unsigned short transaction, - unsigned char* data ) -{ - int status; - - status = libusb_control_transfer( device, - /* bmRequestType */ LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_DNLOAD, - /* wValue */ transaction, - /* wIndex */ interface, - /* Data */ data, - /* wLength */ length, - dfu_timeout ); - return status; -} - - -/* - * DFU_UPLOAD Request (DFU Spec 1.0, Section 6.2) - * - * device - the usb_dev_handle to communicate with - * interface - the interface to communicate with - * length - the maximum number of bytes to receive from the USB - * device - must be less than wTransferSize - * data - the buffer to put the received data in - * - * returns the number of bytes received or < 0 on error - */ -int dfu_upload( libusb_device_handle *device, - const unsigned short interface, - const unsigned short length, - const unsigned short transaction, - unsigned char* data ) -{ - int status; - - status = libusb_control_transfer( device, - /* bmRequestType */ LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_UPLOAD, - /* wValue */ transaction, - /* wIndex */ interface, - /* Data */ data, - /* wLength */ length, - dfu_timeout ); - return status; -} - - -/* - * DFU_GETSTATUS Request (DFU Spec 1.0, Section 6.1.2) - * - * device - the usb_dev_handle to communicate with - * interface - the interface to communicate with - * status - the data structure to be populated with the results - * - * return the number of bytes read in or < 0 on an error - */ -int dfu_get_status( struct dfu_if *dif, struct dfu_status *status ) -{ - unsigned char buffer[6]; - int result; - - /* Initialize the status data structure */ - status->bStatus = DFU_STATUS_ERROR_UNKNOWN; - status->bwPollTimeout = 0; - status->bState = STATE_DFU_ERROR; - status->iString = 0; - - result = libusb_control_transfer( dif->dev_handle, - /* bmRequestType */ LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_GETSTATUS, - /* wValue */ 0, - /* wIndex */ dif->interface, - /* Data */ buffer, - /* wLength */ 6, - dfu_timeout ); - - if( 6 == result ) { - status->bStatus = buffer[0]; - if (dif->quirks & QUIRK_POLLTIMEOUT) - status->bwPollTimeout = DEFAULT_POLLTIMEOUT; - else - status->bwPollTimeout = ((0xff & buffer[3]) << 16) | - ((0xff & buffer[2]) << 8) | - (0xff & buffer[1]); - status->bState = buffer[4]; - status->iString = buffer[5]; - } - - return result; -} - - -/* - * DFU_CLRSTATUS Request (DFU Spec 1.0, Section 6.1.3) - * - * device - the usb_dev_handle to communicate with - * interface - the interface to communicate with - * - * return 0 or < 0 on an error - */ -int dfu_clear_status( libusb_device_handle *device, - const unsigned short interface ) -{ - return libusb_control_transfer( device, - /* bmRequestType */ LIBUSB_ENDPOINT_OUT| LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_CLRSTATUS, - /* wValue */ 0, - /* wIndex */ interface, - /* Data */ NULL, - /* wLength */ 0, - dfu_timeout ); -} - - -/* - * DFU_GETSTATE Request (DFU Spec 1.0, Section 6.1.5) - * - * device - the usb_dev_handle to communicate with - * interface - the interface to communicate with - * length - the maximum number of bytes to receive from the USB - * device - must be less than wTransferSize - * data - the buffer to put the received data in - * - * returns the state or < 0 on error - */ -int dfu_get_state( libusb_device_handle *device, - const unsigned short interface ) -{ - int result; - unsigned char buffer[1]; - - result = libusb_control_transfer( device, - /* bmRequestType */ LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_GETSTATE, - /* wValue */ 0, - /* wIndex */ interface, - /* Data */ buffer, - /* wLength */ 1, - dfu_timeout ); - - /* Return the error if there is one. */ - if (result < 1) - return -1; - - /* Return the state. */ - return buffer[0]; -} - - -/* - * DFU_ABORT Request (DFU Spec 1.0, Section 6.1.4) - * - * device - the usb_dev_handle to communicate with - * interface - the interface to communicate with - * - * returns 0 or < 0 on an error - */ -int dfu_abort( libusb_device_handle *device, - const unsigned short interface ) -{ - return libusb_control_transfer( device, - /* bmRequestType */ LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_ABORT, - /* wValue */ 0, - /* wIndex */ interface, - /* Data */ NULL, - /* wLength */ 0, - dfu_timeout ); -} - - -const char* dfu_state_to_string( int state ) -{ - const char *message; - - switch (state) { - case STATE_APP_IDLE: - message = "appIDLE"; - break; - case STATE_APP_DETACH: - message = "appDETACH"; - break; - case STATE_DFU_IDLE: - message = "dfuIDLE"; - break; - case STATE_DFU_DOWNLOAD_SYNC: - message = "dfuDNLOAD-SYNC"; - break; - case STATE_DFU_DOWNLOAD_BUSY: - message = "dfuDNBUSY"; - break; - case STATE_DFU_DOWNLOAD_IDLE: - message = "dfuDNLOAD-IDLE"; - break; - case STATE_DFU_MANIFEST_SYNC: - message = "dfuMANIFEST-SYNC"; - break; - case STATE_DFU_MANIFEST: - message = "dfuMANIFEST"; - break; - case STATE_DFU_MANIFEST_WAIT_RESET: - message = "dfuMANIFEST-WAIT-RESET"; - break; - case STATE_DFU_UPLOAD_IDLE: - message = "dfuUPLOAD-IDLE"; - break; - case STATE_DFU_ERROR: - message = "dfuERROR"; - break; - default: - message = NULL; - break; - } - - return message; -} - -/* Chapter 6.1.2 */ -static const char *dfu_status_names[] = { - /* DFU_STATUS_OK */ - "No error condition is present", - /* DFU_STATUS_errTARGET */ - "File is not targeted for use by this device", - /* DFU_STATUS_errFILE */ - "File is for this device but fails some vendor-specific test", - /* DFU_STATUS_errWRITE */ - "Device is unable to write memory", - /* DFU_STATUS_errERASE */ - "Memory erase function failed", - /* DFU_STATUS_errCHECK_ERASED */ - "Memory erase check failed", - /* DFU_STATUS_errPROG */ - "Program memory function failed", - /* DFU_STATUS_errVERIFY */ - "Programmed memory failed verification", - /* DFU_STATUS_errADDRESS */ - "Cannot program memory due to received address that is out of range", - /* DFU_STATUS_errNOTDONE */ - "Received DFU_DNLOAD with wLength = 0, but device does not think that it has all data yet", - /* DFU_STATUS_errFIRMWARE */ - "Device's firmware is corrupt. It cannot return to run-time (non-DFU) operations", - /* DFU_STATUS_errVENDOR */ - "iString indicates a vendor specific error", - /* DFU_STATUS_errUSBR */ - "Device detected unexpected USB reset signalling", - /* DFU_STATUS_errPOR */ - "Device detected unexpected power on reset", - /* DFU_STATUS_errUNKNOWN */ - "Something went wrong, but the device does not know what it was", - /* DFU_STATUS_errSTALLEDPKT */ - "Device stalled an unexpected request" -}; - - -const char *dfu_status_to_string(int status) -{ - if (status > DFU_STATUS_errSTALLEDPKT) - return "INVALID"; - return dfu_status_names[status]; -} - -int dfu_abort_to_idle(struct dfu_if *dif) -{ - int ret; - struct dfu_status dst; - - ret = dfu_abort(dif->dev_handle, dif->interface); - if (ret < 0) { - errx(EX_IOERR, "Error sending dfu abort request"); - exit(1); - } - ret = dfu_get_status(dif, &dst); - if (ret < 0) { - errx(EX_IOERR, "Error during abort get_status"); - exit(1); - } - if (dst.bState != DFU_STATE_dfuIDLE) { - errx(EX_IOERR, "Failed to enter idle state on abort"); - exit(1); - } - milli_sleep(dst.bwPollTimeout); - return ret; -} diff --git a/linux/src/dfu-util/src/dfu.h b/linux/src/dfu-util/src/dfu.h deleted file mode 100644 index 8e3caeb7b..000000000 --- a/linux/src/dfu-util/src/dfu.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * dfu-programmer - * - * $Id: dfu.h,v 1.2 2005/09/25 01:27:42 schmidtw Exp $ - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef DFU_H -#define DFU_H - -#include -#include "usb_dfu.h" - -/* DFU states */ -#define STATE_APP_IDLE 0x00 -#define STATE_APP_DETACH 0x01 -#define STATE_DFU_IDLE 0x02 -#define STATE_DFU_DOWNLOAD_SYNC 0x03 -#define STATE_DFU_DOWNLOAD_BUSY 0x04 -#define STATE_DFU_DOWNLOAD_IDLE 0x05 -#define STATE_DFU_MANIFEST_SYNC 0x06 -#define STATE_DFU_MANIFEST 0x07 -#define STATE_DFU_MANIFEST_WAIT_RESET 0x08 -#define STATE_DFU_UPLOAD_IDLE 0x09 -#define STATE_DFU_ERROR 0x0a - - -/* DFU status */ -#define DFU_STATUS_OK 0x00 -#define DFU_STATUS_ERROR_TARGET 0x01 -#define DFU_STATUS_ERROR_FILE 0x02 -#define DFU_STATUS_ERROR_WRITE 0x03 -#define DFU_STATUS_ERROR_ERASE 0x04 -#define DFU_STATUS_ERROR_CHECK_ERASED 0x05 -#define DFU_STATUS_ERROR_PROG 0x06 -#define DFU_STATUS_ERROR_VERIFY 0x07 -#define DFU_STATUS_ERROR_ADDRESS 0x08 -#define DFU_STATUS_ERROR_NOTDONE 0x09 -#define DFU_STATUS_ERROR_FIRMWARE 0x0a -#define DFU_STATUS_ERROR_VENDOR 0x0b -#define DFU_STATUS_ERROR_USBR 0x0c -#define DFU_STATUS_ERROR_POR 0x0d -#define DFU_STATUS_ERROR_UNKNOWN 0x0e -#define DFU_STATUS_ERROR_STALLEDPKT 0x0f - -/* DFU commands */ -#define DFU_DETACH 0 -#define DFU_DNLOAD 1 -#define DFU_UPLOAD 2 -#define DFU_GETSTATUS 3 -#define DFU_CLRSTATUS 4 -#define DFU_GETSTATE 5 -#define DFU_ABORT 6 - -/* DFU interface */ -#define DFU_IFF_DFU 0x0001 /* DFU Mode, (not Runtime) */ - -/* This is based off of DFU_GETSTATUS - * - * 1 unsigned byte bStatus - * 3 unsigned byte bwPollTimeout - * 1 unsigned byte bState - * 1 unsigned byte iString -*/ - -struct dfu_status { - unsigned char bStatus; - unsigned int bwPollTimeout; - unsigned char bState; - unsigned char iString; -}; - -struct dfu_if { - struct usb_dfu_func_descriptor func_dfu; - uint16_t quirks; - uint16_t busnum; - uint16_t devnum; - uint16_t vendor; - uint16_t product; - uint16_t bcdDevice; - uint8_t configuration; - uint8_t interface; - uint8_t altsetting; - uint8_t flags; - uint8_t bMaxPacketSize0; - char *alt_name; - char *serial_name; - libusb_device *dev; - libusb_device_handle *dev_handle; - struct dfu_if *next; -}; - -int dfu_detach( libusb_device_handle *device, - const unsigned short interface, - const unsigned short timeout ); -int dfu_download( libusb_device_handle *device, - const unsigned short interface, - const unsigned short length, - const unsigned short transaction, - unsigned char* data ); -int dfu_upload( libusb_device_handle *device, - const unsigned short interface, - const unsigned short length, - const unsigned short transaction, - unsigned char* data ); -int dfu_get_status( struct dfu_if *dif, - struct dfu_status *status ); -int dfu_clear_status( libusb_device_handle *device, - const unsigned short interface ); -int dfu_get_state( libusb_device_handle *device, - const unsigned short interface ); -int dfu_abort( libusb_device_handle *device, - const unsigned short interface ); -int dfu_abort_to_idle( struct dfu_if *dif); - -const char *dfu_state_to_string( int state ); - -const char *dfu_status_to_string( int status ); - -#endif /* DFU_H */ diff --git a/linux/src/dfu-util/src/dfu_file.c b/linux/src/dfu-util/src/dfu_file.c deleted file mode 100644 index 7c897d4f6..000000000 --- a/linux/src/dfu-util/src/dfu_file.c +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Load or store DFU files including suffix and prefix - * - * Copyright 2014 Tormod Volden - * Copyright 2012 Stefan Schmidt - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "portable.h" -#include "dfu_file.h" - -#define DFU_SUFFIX_LENGTH 16 -#define LMDFU_PREFIX_LENGTH 8 -#define LPCDFU_PREFIX_LENGTH 16 -#define PROGRESS_BAR_WIDTH 25 -#define STDIN_CHUNK_SIZE 65536 - -static const unsigned long crc32_table[] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, - 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, - 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, - 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, - 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, - 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, - 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, - 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, - 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, - 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, - 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, - 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, - 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, - 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, - 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, - 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, - 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, - 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}; - -static uint32_t crc32_byte(uint32_t accum, uint8_t delta) -{ - return crc32_table[(accum ^ delta) & 0xff] ^ (accum >> 8); -} - -static int probe_prefix(struct dfu_file *file) -{ - uint8_t *prefix = file->firmware; - - if (file->size.total < LMDFU_PREFIX_LENGTH) - return 1; - if ((prefix[0] == 0x01) && (prefix[1] == 0x00)) { - file->prefix_type = LMDFU_PREFIX; - file->size.prefix = LMDFU_PREFIX_LENGTH; - file->lmdfu_address = 1024 * ((prefix[3] << 8) | prefix[2]); - } - else if (((prefix[0] & 0x3f) == 0x1a) && ((prefix[1] & 0x3f)== 0x3f)) { - file->prefix_type = LPCDFU_UNENCRYPTED_PREFIX; - file->size.prefix = LPCDFU_PREFIX_LENGTH; - } - - if (file->size.prefix + file->size.suffix > file->size.total) - return 1; - return 0; -} - -void dfu_progress_bar(const char *desc, unsigned long long curr, - unsigned long long max) -{ - static char buf[PROGRESS_BAR_WIDTH + 1]; - static unsigned long long last_progress = -1; - static time_t last_time; - time_t curr_time = time(NULL); - unsigned long long progress; - unsigned long long x; - - /* check for not known maximum */ - if (max < curr) - max = curr + 1; - /* make none out of none give zero */ - if (max == 0 && curr == 0) - max = 1; - - /* compute completion */ - progress = (PROGRESS_BAR_WIDTH * curr) / max; - if (progress > PROGRESS_BAR_WIDTH) - progress = PROGRESS_BAR_WIDTH; - if (progress == last_progress && - curr_time == last_time) - return; - last_progress = progress; - last_time = curr_time; - - for (x = 0; x != PROGRESS_BAR_WIDTH; x++) { - if (x < progress) - buf[x] = '='; - else - buf[x] = ' '; - } - buf[x] = 0; - - printf("\r%s\t[%s] %3lld%% %12lld bytes", desc, buf, - (100ULL * curr) / max, curr); - - if (progress == PROGRESS_BAR_WIDTH) - printf("\n%s done.\n", desc); -} - -void *dfu_malloc(size_t size) -{ - void *ptr = malloc(size); - if (ptr == NULL) - errx(EX_SOFTWARE, "Cannot allocate memory of size %d bytes", (int)size); - return (ptr); -} - -uint32_t dfu_file_write_crc(int f, uint32_t crc, const void *buf, int size) -{ - int x; - - /* compute CRC */ - for (x = 0; x != size; x++) - crc = crc32_byte(crc, ((uint8_t *)buf)[x]); - - /* write data */ - if (write(f, buf, size) != size) - err(EX_IOERR, "Could not write %d bytes to file %d", size, f); - - return (crc); -} - -void dfu_load_file(struct dfu_file *file, enum suffix_req check_suffix, enum prefix_req check_prefix) -{ - off_t offset; - int f; - int i; - int res; - - file->size.prefix = 0; - file->size.suffix = 0; - - /* default values, if no valid suffix is found */ - file->bcdDFU = 0; - file->idVendor = 0xffff; /* wildcard value */ - file->idProduct = 0xffff; /* wildcard value */ - file->bcdDevice = 0xffff; /* wildcard value */ - - /* default values, if no valid prefix is found */ - file->lmdfu_address = 0; - - free(file->firmware); - - if (!strcmp(file->name, "-")) { - int read_bytes; - -#ifdef WIN32 - _setmode( _fileno( stdin ), _O_BINARY ); -#endif - file->firmware = (uint8_t*) dfu_malloc(STDIN_CHUNK_SIZE); - read_bytes = fread(file->firmware, 1, STDIN_CHUNK_SIZE, stdin); - file->size.total = read_bytes; - while (read_bytes == STDIN_CHUNK_SIZE) { - file->firmware = (uint8_t*) realloc(file->firmware, file->size.total + STDIN_CHUNK_SIZE); - if (!file->firmware) - err(EX_IOERR, "Could not allocate firmware buffer"); - read_bytes = fread(file->firmware + file->size.total, 1, STDIN_CHUNK_SIZE, stdin); - file->size.total += read_bytes; - } - if (verbose) - printf("Read %i bytes from stdin\n", file->size.total); - /* Never require suffix when reading from stdin */ - check_suffix = MAYBE_SUFFIX; - } else { - f = open(file->name, O_RDONLY | O_BINARY); - if (f < 0) - err(EX_IOERR, "Could not open file %s for reading", file->name); - - offset = lseek(f, 0, SEEK_END); - - if ((int)offset < 0 || (int)offset != offset) - err(EX_IOERR, "File size is too big"); - - if (lseek(f, 0, SEEK_SET) != 0) - err(EX_IOERR, "Could not seek to beginning"); - - file->size.total = offset; - file->firmware = dfu_malloc(file->size.total); - - if (read(f, file->firmware, file->size.total) != file->size.total) { - err(EX_IOERR, "Could not read %d bytes from %s", - file->size.total, file->name); - } - close(f); - } - - /* Check for possible DFU file suffix by trying to parse one */ - { - uint32_t crc = 0xffffffff; - const uint8_t *dfusuffix; - int missing_suffix = 0; - const char *reason; - - if (file->size.total < DFU_SUFFIX_LENGTH) { - reason = "File too short for DFU suffix"; - missing_suffix = 1; - goto checked; - } - - dfusuffix = file->firmware + file->size.total - - DFU_SUFFIX_LENGTH; - - for (i = 0; i < file->size.total - 4; i++) - crc = crc32_byte(crc, file->firmware[i]); - - if (dfusuffix[10] != 'D' || - dfusuffix[9] != 'F' || - dfusuffix[8] != 'U') { - reason = "Invalid DFU suffix signature"; - missing_suffix = 1; - goto checked; - } - - file->dwCRC = (dfusuffix[15] << 24) + - (dfusuffix[14] << 16) + - (dfusuffix[13] << 8) + - dfusuffix[12]; - - if (file->dwCRC != crc) { - reason = "DFU suffix CRC does not match"; - missing_suffix = 1; - goto checked; - } - - /* At this point we believe we have a DFU suffix - so we require further checks to succeed */ - - file->bcdDFU = (dfusuffix[7] << 8) + dfusuffix[6]; - - if (verbose) - printf("DFU suffix version %x\n", file->bcdDFU); - - file->size.suffix = dfusuffix[11]; - - if (file->size.suffix < DFU_SUFFIX_LENGTH) { - errx(EX_IOERR, "Unsupported DFU suffix length %d", - file->size.suffix); - } - - if (file->size.suffix > file->size.total) { - errx(EX_IOERR, "Invalid DFU suffix length %d", - file->size.suffix); - } - - file->idVendor = (dfusuffix[5] << 8) + dfusuffix[4]; - file->idProduct = (dfusuffix[3] << 8) + dfusuffix[2]; - file->bcdDevice = (dfusuffix[1] << 8) + dfusuffix[0]; - -checked: - if (missing_suffix) { - if (check_suffix == NEEDS_SUFFIX) { - warnx("%s", reason); - errx(EX_IOERR, "Valid DFU suffix needed"); - } else if (check_suffix == MAYBE_SUFFIX) { - warnx("%s", reason); - warnx("A valid DFU suffix will be required in " - "a future dfu-util release!!!"); - } - } else { - if (check_suffix == NO_SUFFIX) { - errx(EX_SOFTWARE, "Please remove existing DFU suffix before adding a new one.\n"); - } - } - } - res = probe_prefix(file); - if ((res || file->size.prefix == 0) && check_prefix == NEEDS_PREFIX) - errx(EX_IOERR, "Valid DFU prefix needed"); - if (file->size.prefix && check_prefix == NO_PREFIX) - errx(EX_IOERR, "A prefix already exists, please delete it first"); - if (file->size.prefix && verbose) { - uint8_t *data = file->firmware; - if (file->prefix_type == LMDFU_PREFIX) - printf("Possible TI Stellaris DFU prefix with " - "the following properties\n" - "Address: 0x%08x\n" - "Payload length: %d\n", - file->lmdfu_address, - data[4] | (data[5] << 8) | - (data[6] << 16) | (data[7] << 14)); - else if (file->prefix_type == LPCDFU_UNENCRYPTED_PREFIX) - printf("Possible unencrypted NXP LPC DFU prefix with " - "the following properties\n" - "Payload length: %d kiByte\n", - data[2] >>1 | (data[3] << 7) ); - else - errx(EX_IOERR, "Unknown DFU prefix type"); - } -} - -void dfu_store_file(struct dfu_file *file, int write_suffix, int write_prefix) -{ - uint32_t crc = 0xffffffff; - int f; - - f = open(file->name, O_WRONLY | O_BINARY | O_TRUNC | O_CREAT, 0666); - if (f < 0) - err(EX_IOERR, "Could not open file %s for writing", file->name); - - /* write prefix, if any */ - if (write_prefix) { - if (file->prefix_type == LMDFU_PREFIX) { - uint8_t lmdfu_prefix[LMDFU_PREFIX_LENGTH]; - uint32_t addr = file->lmdfu_address / 1024; - - /* lmdfu_dfu_prefix payload length excludes prefix and suffix */ - uint32_t len = file->size.total - - file->size.prefix - file->size.suffix; - - lmdfu_prefix[0] = 0x01; /* STELLARIS_DFU_PROG */ - lmdfu_prefix[1] = 0x00; /* Reserved */ - lmdfu_prefix[2] = (uint8_t)(addr & 0xff); - lmdfu_prefix[3] = (uint8_t)(addr >> 8); - lmdfu_prefix[4] = (uint8_t)(len & 0xff); - lmdfu_prefix[5] = (uint8_t)(len >> 8) & 0xff; - lmdfu_prefix[6] = (uint8_t)(len >> 16) & 0xff; - lmdfu_prefix[7] = (uint8_t)(len >> 24); - - crc = dfu_file_write_crc(f, crc, lmdfu_prefix, LMDFU_PREFIX_LENGTH); - } - if (file->prefix_type == LPCDFU_UNENCRYPTED_PREFIX) { - uint8_t lpcdfu_prefix[LPCDFU_PREFIX_LENGTH] = {0}; - int i; - - /* Payload is firmware and prefix rounded to 512 bytes */ - uint32_t len = (file->size.total - file->size.suffix + 511) /512; - - lpcdfu_prefix[0] = 0x1a; /* Unencypted*/ - lpcdfu_prefix[1] = 0x3f; /* Reserved */ - lpcdfu_prefix[2] = (uint8_t)(len & 0xff); - lpcdfu_prefix[3] = (uint8_t)((len >> 8) & 0xff); - for (i = 12; i < LPCDFU_PREFIX_LENGTH; i++) - lpcdfu_prefix[i] = 0xff; - - crc = dfu_file_write_crc(f, crc, lpcdfu_prefix, LPCDFU_PREFIX_LENGTH); - } - } - /* write firmware binary */ - crc = dfu_file_write_crc(f, crc, file->firmware + file->size.prefix, - file->size.total - file->size.prefix - file->size.suffix); - - /* write suffix, if any */ - if (write_suffix) { - uint8_t dfusuffix[DFU_SUFFIX_LENGTH]; - - dfusuffix[0] = file->bcdDevice & 0xff; - dfusuffix[1] = file->bcdDevice >> 8; - dfusuffix[2] = file->idProduct & 0xff; - dfusuffix[3] = file->idProduct >> 8; - dfusuffix[4] = file->idVendor & 0xff; - dfusuffix[5] = file->idVendor >> 8; - dfusuffix[6] = file->bcdDFU & 0xff; - dfusuffix[7] = file->bcdDFU >> 8; - dfusuffix[8] = 'U'; - dfusuffix[9] = 'F'; - dfusuffix[10] = 'D'; - dfusuffix[11] = DFU_SUFFIX_LENGTH; - - crc = dfu_file_write_crc(f, crc, dfusuffix, - DFU_SUFFIX_LENGTH - 4); - - dfusuffix[12] = crc; - dfusuffix[13] = crc >> 8; - dfusuffix[14] = crc >> 16; - dfusuffix[15] = crc >> 24; - - crc = dfu_file_write_crc(f, crc, dfusuffix + 12, 4); - } - close(f); -} - -void show_suffix_and_prefix(struct dfu_file *file) -{ - if (file->size.prefix == LMDFU_PREFIX_LENGTH) { - printf("The file %s contains a TI Stellaris DFU prefix with the following properties:\n", file->name); - printf("Address:\t0x%08x\n", file->lmdfu_address); - } else if (file->size.prefix == LPCDFU_PREFIX_LENGTH) { - uint8_t * prefix = file->firmware; - printf("The file %s contains a NXP unencrypted LPC DFU prefix with the following properties:\n", file->name); - printf("Size:\t%5d kiB\n", prefix[2]>>1|prefix[3]<<7); - } else if (file->size.prefix != 0) { - printf("The file %s contains an unknown prefix\n", file->name); - } - if (file->size.suffix > 0) { - printf("The file %s contains a DFU suffix with the following properties:\n", file->name); - printf("BCD device:\t0x%04X\n", file->bcdDevice); - printf("Product ID:\t0x%04X\n",file->idProduct); - printf("Vendor ID:\t0x%04X\n", file->idVendor); - printf("BCD DFU:\t0x%04X\n", file->bcdDFU); - printf("Length:\t\t%i\n", file->size.suffix); - printf("CRC:\t\t0x%08X\n", file->dwCRC); - } -} diff --git a/linux/src/dfu-util/src/dfu_file.h b/linux/src/dfu-util/src/dfu_file.h deleted file mode 100644 index abebd44f4..000000000 --- a/linux/src/dfu-util/src/dfu_file.h +++ /dev/null @@ -1,60 +0,0 @@ - -#ifndef DFU_FILE_H -#define DFU_FILE_H - -#include - -struct dfu_file { - /* File name */ - const char *name; - /* Pointer to file loaded into memory */ - uint8_t *firmware; - /* Different sizes */ - struct { - int total; - int prefix; - int suffix; - } size; - /* From prefix fields */ - uint32_t lmdfu_address; - /* From prefix fields */ - uint32_t prefix_type; - - /* From DFU suffix fields */ - uint32_t dwCRC; - uint16_t bcdDFU; - uint16_t idVendor; - uint16_t idProduct; - uint16_t bcdDevice; -}; - -enum suffix_req { - NO_SUFFIX, - NEEDS_SUFFIX, - MAYBE_SUFFIX -}; - -enum prefix_req { - NO_PREFIX, - NEEDS_PREFIX, - MAYBE_PREFIX -}; - -enum prefix_type { - ZERO_PREFIX, - LMDFU_PREFIX, - LPCDFU_UNENCRYPTED_PREFIX -}; - -extern int verbose; - -void dfu_load_file(struct dfu_file *file, enum suffix_req check_suffix, enum prefix_req check_prefix); -void dfu_store_file(struct dfu_file *file, int write_suffix, int write_prefix); - -void dfu_progress_bar(const char *desc, unsigned long long curr, - unsigned long long max); -void *dfu_malloc(size_t size); -uint32_t dfu_file_write_crc(int f, uint32_t crc, const void *buf, int size); -void show_suffix_and_prefix(struct dfu_file *file); - -#endif /* DFU_FILE_H */ diff --git a/linux/src/dfu-util/src/dfu_load.c b/linux/src/dfu-util/src/dfu_load.c deleted file mode 100644 index 64f7009df..000000000 --- a/linux/src/dfu-util/src/dfu_load.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * DFU transfer routines - * - * This is supposed to be a general DFU implementation, as specified in the - * USB DFU 1.0 and 1.1 specification. - * - * The code was originally intended to interface with a USB device running the - * "sam7dfu" firmware (see http://www.openpcd.org/) on an AT91SAM7 processor. - * - * Copyright 2007-2008 Harald Welte - * Copyright 2013 Hans Petter Selasky - * Copyright 2014 Tormod Volden - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#include - -#include "portable.h" -#include "dfu.h" -#include "usb_dfu.h" -#include "dfu_file.h" -#include "dfu_load.h" -#include "quirks.h" - -int dfuload_do_upload(struct dfu_if *dif, int xfer_size, - int expected_size, int fd) -{ - int total_bytes = 0; - unsigned short transaction = 0; - unsigned char *buf; - int ret; - - buf = dfu_malloc(xfer_size); - - printf("Copying data from DFU device to PC\n"); - dfu_progress_bar("Upload", 0, 1); - - while (1) { - int rc; - rc = dfu_upload(dif->dev_handle, dif->interface, - xfer_size, transaction++, buf); - if (rc < 0) { - warnx("Error during upload"); - ret = rc; - goto out_free; - } - - dfu_file_write_crc(fd, 0, buf, rc); - total_bytes += rc; - - if (total_bytes < 0) - errx(EX_SOFTWARE, "Received too many bytes (wraparound)"); - - if (rc < xfer_size) { - /* last block, return */ - ret = total_bytes; - break; - } - dfu_progress_bar("Upload", total_bytes, expected_size); - } - ret = 0; - -out_free: - dfu_progress_bar("Upload", total_bytes, total_bytes); - if (total_bytes == 0) - printf("\nFailed.\n"); - free(buf); - if (verbose) - printf("Received a total of %i bytes\n", total_bytes); - if (expected_size != 0 && total_bytes != expected_size) - errx(EX_SOFTWARE, "Unexpected number of bytes uploaded from device"); - return ret; -} - -int dfuload_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file) -{ - int bytes_sent; - int expected_size; - unsigned char *buf; - unsigned short transaction = 0; - struct dfu_status dst; - int ret; - - printf("Copying data from PC to DFU device\n"); - - buf = file->firmware; - expected_size = file->size.total - file->size.suffix; - bytes_sent = 0; - - dfu_progress_bar("Download", 0, 1); - while (bytes_sent < expected_size) { - int bytes_left; - int chunk_size; - - bytes_left = expected_size - bytes_sent; - if (bytes_left < xfer_size) - chunk_size = bytes_left; - else - chunk_size = xfer_size; - - ret = dfu_download(dif->dev_handle, dif->interface, - chunk_size, transaction++, chunk_size ? buf : NULL); - if (ret < 0) { - warnx("Error during download"); - goto out; - } - bytes_sent += chunk_size; - buf += chunk_size; - - do { - ret = dfu_get_status(dif, &dst); - if (ret < 0) { - errx(EX_IOERR, "Error during download get_status"); - goto out; - } - - if (dst.bState == DFU_STATE_dfuDNLOAD_IDLE || - dst.bState == DFU_STATE_dfuERROR) - break; - - /* Wait while device executes flashing */ - milli_sleep(dst.bwPollTimeout); - - } while (1); - if (dst.bStatus != DFU_STATUS_OK) { - printf(" failed!\n"); - printf("state(%u) = %s, status(%u) = %s\n", dst.bState, - dfu_state_to_string(dst.bState), dst.bStatus, - dfu_status_to_string(dst.bStatus)); - ret = -1; - goto out; - } - dfu_progress_bar("Download", bytes_sent, bytes_sent + bytes_left); - } - - /* send one zero sized download request to signalize end */ - ret = dfu_download(dif->dev_handle, dif->interface, - 0, transaction, NULL); - if (ret < 0) { - errx(EX_IOERR, "Error sending completion packet"); - goto out; - } - - dfu_progress_bar("Download", bytes_sent, bytes_sent); - - if (verbose) - printf("Sent a total of %i bytes\n", bytes_sent); - -get_status: - /* Transition to MANIFEST_SYNC state */ - ret = dfu_get_status(dif, &dst); - if (ret < 0) { - warnx("unable to read DFU status after completion"); - goto out; - } - printf("state(%u) = %s, status(%u) = %s\n", dst.bState, - dfu_state_to_string(dst.bState), dst.bStatus, - dfu_status_to_string(dst.bStatus)); - - milli_sleep(dst.bwPollTimeout); - - /* FIXME: deal correctly with ManifestationTolerant=0 / WillDetach bits */ - switch (dst.bState) { - case DFU_STATE_dfuMANIFEST_SYNC: - case DFU_STATE_dfuMANIFEST: - /* some devices (e.g. TAS1020b) need some time before we - * can obtain the status */ - milli_sleep(1000); - goto get_status; - break; - case DFU_STATE_dfuIDLE: - break; - } - printf("Done!\n"); - -out: - return bytes_sent; -} diff --git a/linux/src/dfu-util/src/dfu_load.h b/linux/src/dfu-util/src/dfu_load.h deleted file mode 100644 index be23e9b4f..000000000 --- a/linux/src/dfu-util/src/dfu_load.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef DFU_LOAD_H -#define DFU_LOAD_H - -int dfuload_do_upload(struct dfu_if *dif, int xfer_size, int expected_size, int fd); -int dfuload_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file); - -#endif /* DFU_LOAD_H */ diff --git a/linux/src/dfu-util/src/dfu_util.c b/linux/src/dfu-util/src/dfu_util.c deleted file mode 100644 index b94c7ccd3..000000000 --- a/linux/src/dfu-util/src/dfu_util.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Functions for detecting DFU USB entities - * - * Written by Harald Welte - * Copyright 2007-2008 by OpenMoko, Inc. - * Copyright 2013 Hans Petter Selasky - * - * Based on existing code of dfu-programmer-0.4 - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#include "portable.h" -#include "dfu.h" -#include "usb_dfu.h" -#include "dfu_file.h" -#include "dfu_load.h" -#include "dfu_util.h" -#include "dfuse.h" -#include "quirks.h" - -#ifdef HAVE_USBPATH_H -#include -#endif - -/* - * Look for a descriptor in a concatenated descriptor list. Will - * return upon the first match of the given descriptor type. Returns length of - * found descriptor, limited to res_size - */ -static int find_descriptor(const uint8_t *desc_list, int list_len, - uint8_t desc_type, void *res_buf, int res_size) -{ - int p = 0; - - if (list_len < 2) - return (-1); - - while (p + 1 < list_len) { - int desclen; - - desclen = (int) desc_list[p]; - if (desclen == 0) { - warnx("Invalid descriptor list"); - return -1; - } - if (desc_list[p + 1] == desc_type) { - if (desclen > res_size) - desclen = res_size; - if (p + desclen > list_len) - desclen = list_len - p; - memcpy(res_buf, &desc_list[p], desclen); - return desclen; - } - p += (int) desc_list[p]; - } - return -1; -} - -static void probe_configuration(libusb_device *dev, struct libusb_device_descriptor *desc) -{ - struct usb_dfu_func_descriptor func_dfu; - libusb_device_handle *devh; - struct dfu_if *pdfu; - struct libusb_config_descriptor *cfg; - const struct libusb_interface_descriptor *intf; - const struct libusb_interface *uif; - char alt_name[MAX_DESC_STR_LEN + 1]; - char serial_name[MAX_DESC_STR_LEN + 1]; - int cfg_idx; - int intf_idx; - int alt_idx; - int ret; - int has_dfu; - - for (cfg_idx = 0; cfg_idx != desc->bNumConfigurations; cfg_idx++) { - memset(&func_dfu, 0, sizeof(func_dfu)); - has_dfu = 0; - - ret = libusb_get_config_descriptor(dev, cfg_idx, &cfg); - if (ret != 0) - return; - if (match_config_index > -1 && match_config_index != cfg->bConfigurationValue) { - libusb_free_config_descriptor(cfg); - continue; - } - - /* - * In some cases, noticably FreeBSD if uid != 0, - * the configuration descriptors are empty - */ - if (!cfg) - return; - - ret = find_descriptor(cfg->extra, cfg->extra_length, - USB_DT_DFU, &func_dfu, sizeof(func_dfu)); - if (ret > -1) - goto found_dfu; - - for (intf_idx = 0; intf_idx < cfg->bNumInterfaces; - intf_idx++) { - uif = &cfg->interface[intf_idx]; - if (!uif) - break; - - for (alt_idx = 0; alt_idx < cfg->interface[intf_idx].num_altsetting; - alt_idx++) { - intf = &uif->altsetting[alt_idx]; - - ret = find_descriptor(intf->extra, intf->extra_length, USB_DT_DFU, - &func_dfu, sizeof(func_dfu)); - if (ret > -1) - goto found_dfu; - - if (intf->bInterfaceClass != 0xfe || - intf->bInterfaceSubClass != 1) - continue; - - has_dfu = 1; - } - } - if (has_dfu) { - /* - * Finally try to retrieve it requesting the - * device directly This is not supported on - * all devices for non-standard types - */ - if (libusb_open(dev, &devh) == 0) { - ret = libusb_get_descriptor(devh, USB_DT_DFU, 0, - (void *)&func_dfu, sizeof(func_dfu)); - libusb_close(devh); - if (ret > -1) - goto found_dfu; - } - warnx("Device has DFU interface, " - "but has no DFU functional descriptor"); - - /* fake version 1.0 */ - func_dfu.bLength = 7; - func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100); - goto found_dfu; - } - libusb_free_config_descriptor(cfg); - continue; - -found_dfu: - if (func_dfu.bLength == 7) { - printf("Deducing device DFU version from functional descriptor " - "length\n"); - func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100); - } else if (func_dfu.bLength < 9) { - printf("Error obtaining DFU functional descriptor\n"); - printf("Please report this as a bug!\n"); - printf("Warning: Assuming DFU version 1.0\n"); - func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100); - printf("Warning: Transfer size can not be detected\n"); - func_dfu.wTransferSize = 0; - } - - for (intf_idx = 0; intf_idx < cfg->bNumInterfaces; - intf_idx++) { - if (match_iface_index > -1 && match_iface_index != intf_idx) - continue; - - uif = &cfg->interface[intf_idx]; - if (!uif) - break; - - for (alt_idx = 0; - alt_idx < uif->num_altsetting; alt_idx++) { - int dfu_mode; - - intf = &uif->altsetting[alt_idx]; - - if (intf->bInterfaceClass != 0xfe || - intf->bInterfaceSubClass != 1) - continue; - - dfu_mode = (intf->bInterfaceProtocol == 2); - /* e.g. DSO Nano has bInterfaceProtocol 0 instead of 2 */ - if (func_dfu.bcdDFUVersion == 0x011a && intf->bInterfaceProtocol == 0) - dfu_mode = 1; - - if (dfu_mode && - match_iface_alt_index > -1 && match_iface_alt_index != alt_idx) - continue; - - if (dfu_mode) { - if ((match_vendor_dfu >= 0 && match_vendor_dfu != desc->idVendor) || - (match_product_dfu >= 0 && match_product_dfu != desc->idProduct)) { - continue; - } - } else { - if ((match_vendor >= 0 && match_vendor != desc->idVendor) || - (match_product >= 0 && match_product != desc->idProduct)) { - continue; - } - } - - if (libusb_open(dev, &devh)) { - warnx("Cannot open DFU device %04x:%04x", desc->idVendor, desc->idProduct); - break; - } - if (intf->iInterface != 0) - ret = libusb_get_string_descriptor_ascii(devh, - intf->iInterface, (void *)alt_name, MAX_DESC_STR_LEN); - else - ret = -1; - if (ret < 1) - strcpy(alt_name, "UNKNOWN"); - if (desc->iSerialNumber != 0) - ret = libusb_get_string_descriptor_ascii(devh, - desc->iSerialNumber, (void *)serial_name, MAX_DESC_STR_LEN); - else - ret = -1; - if (ret < 1) - strcpy(serial_name, "UNKNOWN"); - libusb_close(devh); - - if (dfu_mode && - match_iface_alt_name != NULL && strcmp(alt_name, match_iface_alt_name)) - continue; - - if (dfu_mode) { - if (match_serial_dfu != NULL && strcmp(match_serial_dfu, serial_name)) - continue; - } else { - if (match_serial != NULL && strcmp(match_serial, serial_name)) - continue; - } - - pdfu = dfu_malloc(sizeof(*pdfu)); - - memset(pdfu, 0, sizeof(*pdfu)); - - pdfu->func_dfu = func_dfu; - pdfu->dev = libusb_ref_device(dev); - pdfu->quirks = get_quirks(desc->idVendor, - desc->idProduct, desc->bcdDevice); - pdfu->vendor = desc->idVendor; - pdfu->product = desc->idProduct; - pdfu->bcdDevice = desc->bcdDevice; - pdfu->configuration = cfg->bConfigurationValue; - pdfu->interface = intf->bInterfaceNumber; - pdfu->altsetting = intf->bAlternateSetting; - pdfu->devnum = libusb_get_device_address(dev); - pdfu->busnum = libusb_get_bus_number(dev); - pdfu->alt_name = strdup(alt_name); - if (pdfu->alt_name == NULL) - errx(EX_SOFTWARE, "Out of memory"); - pdfu->serial_name = strdup(serial_name); - if (pdfu->serial_name == NULL) - errx(EX_SOFTWARE, "Out of memory"); - if (dfu_mode) - pdfu->flags |= DFU_IFF_DFU; - if (pdfu->quirks & QUIRK_FORCE_DFU11) { - pdfu->func_dfu.bcdDFUVersion = - libusb_cpu_to_le16(0x0110); - } - pdfu->bMaxPacketSize0 = desc->bMaxPacketSize0; - - /* queue into list */ - pdfu->next = dfu_root; - dfu_root = pdfu; - } - } - libusb_free_config_descriptor(cfg); - } -} - -void probe_devices(libusb_context *ctx) -{ - libusb_device **list; - ssize_t num_devs; - ssize_t i; - - num_devs = libusb_get_device_list(ctx, &list); - for (i = 0; i < num_devs; ++i) { - struct libusb_device_descriptor desc; - struct libusb_device *dev = list[i]; - - if (match_bus > -1 && match_bus != libusb_get_bus_number(dev)) - continue; - if (match_device > -1 && match_device != libusb_get_device_address(dev)) - continue; - if (libusb_get_device_descriptor(dev, &desc)) - continue; - probe_configuration(dev, &desc); - } - libusb_free_device_list(list, 0); -} - -void disconnect_devices(void) -{ - struct dfu_if *pdfu; - struct dfu_if *prev = NULL; - - for (pdfu = dfu_root; pdfu != NULL; pdfu = pdfu->next) { - free(prev); - libusb_unref_device(pdfu->dev); - free(pdfu->alt_name); - free(pdfu->serial_name); - prev = pdfu; - } - free(prev); - dfu_root = NULL; -} - -void print_dfu_if(struct dfu_if *dfu_if) -{ - printf("Found %s: [%04x:%04x] ver=%04x, devnum=%u, cfg=%u, intf=%u, " - "alt=%u, name=\"%s\", serial=\"%s\"\n", - dfu_if->flags & DFU_IFF_DFU ? "DFU" : "Runtime", - dfu_if->vendor, dfu_if->product, - dfu_if->bcdDevice, dfu_if->devnum, - dfu_if->configuration, dfu_if->interface, - dfu_if->altsetting, dfu_if->alt_name, - dfu_if->serial_name); -} - -/* Walk the device tree and print out DFU devices */ -void list_dfu_interfaces(void) -{ - struct dfu_if *pdfu; - - for (pdfu = dfu_root; pdfu != NULL; pdfu = pdfu->next) - print_dfu_if(pdfu); -} diff --git a/linux/src/dfu-util/src/dfu_util.h b/linux/src/dfu-util/src/dfu_util.h deleted file mode 100644 index fc0c19dca..000000000 --- a/linux/src/dfu-util/src/dfu_util.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef DFU_UTIL_H -#define DFU_UTIL_H - -/* USB string descriptor should contain max 126 UTF-16 characters - * but 253 would even accomodate any UTF-8 encoding */ -#define MAX_DESC_STR_LEN 253 - -enum mode { - MODE_NONE, - MODE_VERSION, - MODE_LIST, - MODE_DETACH, - MODE_UPLOAD, - MODE_DOWNLOAD -}; - -extern struct dfu_if *dfu_root; -extern int match_bus; -extern int match_device; -extern int match_vendor; -extern int match_product; -extern int match_vendor_dfu; -extern int match_product_dfu; -extern int match_config_index; -extern int match_iface_index; -extern int match_iface_alt_index; -extern const char *match_iface_alt_name; -extern const char *match_serial; -extern const char *match_serial_dfu; - -void probe_devices(libusb_context *); -void disconnect_devices(void); -void print_dfu_if(struct dfu_if *); -void list_dfu_interfaces(void); - -#endif /* DFU_UTIL_H */ diff --git a/linux/src/dfu-util/src/dfuse.c b/linux/src/dfu-util/src/dfuse.c deleted file mode 100644 index fce29fed6..000000000 --- a/linux/src/dfu-util/src/dfuse.c +++ /dev/null @@ -1,652 +0,0 @@ -/* - * DfuSe specific functions - * - * This implements the ST Microsystems DFU extensions (DfuSe) - * as per the DfuSe 1.1a specification (ST documents AN3156, AN2606) - * The DfuSe file format is described in ST document UM0391. - * - * Copyright 2010-2014 Tormod Volden - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#include "portable.h" -#include "dfu.h" -#include "usb_dfu.h" -#include "dfu_file.h" -#include "dfuse.h" -#include "dfuse_mem.h" - -#define DFU_TIMEOUT 5000 - -extern int verbose; -static unsigned int last_erased_page = 1; /* non-aligned value, won't match */ -static struct memsegment *mem_layout; -static unsigned int dfuse_address = 0; -static unsigned int dfuse_length = 0; -static int dfuse_force = 0; -static int dfuse_leave = 0; -static int dfuse_unprotect = 0; -static int dfuse_mass_erase = 0; - -unsigned int quad2uint(unsigned char *p) -{ - return (*p + (*(p + 1) << 8) + (*(p + 2) << 16) + (*(p + 3) << 24)); -} - -void dfuse_parse_options(const char *options) -{ - char *end; - const char *endword; - unsigned int number; - - /* address, possibly empty, must be first */ - if (*options != ':') { - endword = strchr(options, ':'); - if (!endword) - endword = options + strlen(options); /* GNU strchrnul */ - - number = strtoul(options, &end, 0); - if (end == endword) { - dfuse_address = number; - } else { - errx(EX_IOERR, "Invalid dfuse address: %s", options); - } - options = endword; - } - - while (*options) { - if (*options == ':') { - options++; - continue; - } - endword = strchr(options, ':'); - if (!endword) - endword = options + strlen(options); - - if (!strncmp(options, "force", endword - options)) { - dfuse_force++; - options += 5; - continue; - } - if (!strncmp(options, "leave", endword - options)) { - dfuse_leave = 1; - options += 5; - continue; - } - if (!strncmp(options, "unprotect", endword - options)) { - dfuse_unprotect = 1; - options += 9; - continue; - } - if (!strncmp(options, "mass-erase", endword - options)) { - dfuse_mass_erase = 1; - options += 10; - continue; - } - - /* any valid number is interpreted as upload length */ - number = strtoul(options, &end, 0); - if (end == endword) { - dfuse_length = number; - } else { - errx(EX_IOERR, "Invalid dfuse modifier: %s", options); - } - options = endword; - } -} - -/* DFU_UPLOAD request for DfuSe 1.1a */ -int dfuse_upload(struct dfu_if *dif, const unsigned short length, - unsigned char *data, unsigned short transaction) -{ - int status; - - status = libusb_control_transfer(dif->dev_handle, - /* bmRequestType */ LIBUSB_ENDPOINT_IN | - LIBUSB_REQUEST_TYPE_CLASS | - LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_UPLOAD, - /* wValue */ transaction, - /* wIndex */ dif->interface, - /* Data */ data, - /* wLength */ length, - DFU_TIMEOUT); - if (status < 0) { - errx(EX_IOERR, "%s: libusb_control_msg returned %d", - __FUNCTION__, status); - } - return status; -} - -/* DFU_DNLOAD request for DfuSe 1.1a */ -int dfuse_download(struct dfu_if *dif, const unsigned short length, - unsigned char *data, unsigned short transaction) -{ - int status; - - status = libusb_control_transfer(dif->dev_handle, - /* bmRequestType */ LIBUSB_ENDPOINT_OUT | - LIBUSB_REQUEST_TYPE_CLASS | - LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_DNLOAD, - /* wValue */ transaction, - /* wIndex */ dif->interface, - /* Data */ data, - /* wLength */ length, - DFU_TIMEOUT); - if (status < 0) { - errx(EX_IOERR, "%s: libusb_control_transfer returned %d", - __FUNCTION__, status); - } - return status; -} - -/* DfuSe only commands */ -/* Leaves the device in dfuDNLOAD-IDLE state */ -int dfuse_special_command(struct dfu_if *dif, unsigned int address, - enum dfuse_command command) -{ - const char* dfuse_command_name[] = { "SET_ADDRESS" , "ERASE_PAGE", - "MASS_ERASE", "READ_UNPROTECT"}; - unsigned char buf[5]; - int length; - int ret; - struct dfu_status dst; - int firstpoll = 1; - - if (command == ERASE_PAGE) { - struct memsegment *segment; - int page_size; - - segment = find_segment(mem_layout, address); - if (!segment || !(segment->memtype & DFUSE_ERASABLE)) { - errx(EX_IOERR, "Page at 0x%08x can not be erased", - address); - } - page_size = segment->pagesize; - if (verbose > 1) - printf("Erasing page size %i at address 0x%08x, page " - "starting at 0x%08x\n", page_size, address, - address & ~(page_size - 1)); - buf[0] = 0x41; /* Erase command */ - length = 5; - last_erased_page = address & ~(page_size - 1); - } else if (command == SET_ADDRESS) { - if (verbose > 2) - printf(" Setting address pointer to 0x%08x\n", - address); - buf[0] = 0x21; /* Set Address Pointer command */ - length = 5; - } else if (command == MASS_ERASE) { - buf[0] = 0x41; /* Mass erase command when length = 1 */ - length = 1; - } else if (command == READ_UNPROTECT) { - buf[0] = 0x92; - length = 1; - } else { - errx(EX_IOERR, "Non-supported special command %d", command); - } - buf[1] = address & 0xff; - buf[2] = (address >> 8) & 0xff; - buf[3] = (address >> 16) & 0xff; - buf[4] = (address >> 24) & 0xff; - - ret = dfuse_download(dif, length, buf, 0); - if (ret < 0) { - errx(EX_IOERR, "Error during special command \"%s\" download", - dfuse_command_name[command]); - } - do { - ret = dfu_get_status(dif, &dst); - if (ret < 0) { - errx(EX_IOERR, "Error during special command \"%s\" get_status", - dfuse_command_name[command]); - } - if (firstpoll) { - firstpoll = 0; - if (dst.bState != DFU_STATE_dfuDNBUSY) { - printf("state(%u) = %s, status(%u) = %s\n", dst.bState, - dfu_state_to_string(dst.bState), dst.bStatus, - dfu_status_to_string(dst.bStatus)); - errx(EX_IOERR, "Wrong state after command \"%s\" download", - dfuse_command_name[command]); - } - } - /* wait while command is executed */ - if (verbose) - printf(" Poll timeout %i ms\n", dst.bwPollTimeout); - milli_sleep(dst.bwPollTimeout); - if (command == READ_UNPROTECT) - return ret; - } while (dst.bState == DFU_STATE_dfuDNBUSY); - - if (dst.bStatus != DFU_STATUS_OK) { - errx(EX_IOERR, "%s not correctly executed", - dfuse_command_name[command]); - } - return ret; -} - -int dfuse_dnload_chunk(struct dfu_if *dif, unsigned char *data, int size, - int transaction) -{ - int bytes_sent; - struct dfu_status dst; - int ret; - - ret = dfuse_download(dif, size, size ? data : NULL, transaction); - if (ret < 0) { - errx(EX_IOERR, "Error during download"); - return ret; - } - bytes_sent = ret; - - do { - ret = dfu_get_status(dif, &dst); - if (ret < 0) { - errx(EX_IOERR, "Error during download get_status"); - return ret; - } - milli_sleep(dst.bwPollTimeout); - } while (dst.bState != DFU_STATE_dfuDNLOAD_IDLE && - dst.bState != DFU_STATE_dfuERROR && - dst.bState != DFU_STATE_dfuMANIFEST); - - if (dst.bState == DFU_STATE_dfuMANIFEST) - printf("Transitioning to dfuMANIFEST state\n"); - - if (dst.bStatus != DFU_STATUS_OK) { - printf(" failed!\n"); - printf("state(%u) = %s, status(%u) = %s\n", dst.bState, - dfu_state_to_string(dst.bState), dst.bStatus, - dfu_status_to_string(dst.bStatus)); - return -1; - } - return bytes_sent; -} - -int dfuse_do_upload(struct dfu_if *dif, int xfer_size, int fd, - const char *dfuse_options) -{ - int total_bytes = 0; - int upload_limit = 0; - unsigned char *buf; - int transaction; - int ret; - - buf = dfu_malloc(xfer_size); - - if (dfuse_options) - dfuse_parse_options(dfuse_options); - if (dfuse_length) - upload_limit = dfuse_length; - if (dfuse_address) { - struct memsegment *segment; - - mem_layout = parse_memory_layout((char *)dif->alt_name); - if (!mem_layout) - errx(EX_IOERR, "Failed to parse memory layout"); - - segment = find_segment(mem_layout, dfuse_address); - if (!dfuse_force && - (!segment || !(segment->memtype & DFUSE_READABLE))) - errx(EX_IOERR, "Page at 0x%08x is not readable", - dfuse_address); - - if (!upload_limit) { - upload_limit = segment->end - dfuse_address + 1; - printf("Limiting upload to end of memory segment, " - "%i bytes\n", upload_limit); - } - dfuse_special_command(dif, dfuse_address, SET_ADDRESS); - dfu_abort_to_idle(dif); - } else { - /* Boot loader decides the start address, unknown to us */ - /* Use a short length to lower risk of running out of bounds */ - if (!upload_limit) - upload_limit = 0x4000; - printf("Limiting default upload to %i bytes\n", upload_limit); - } - - dfu_progress_bar("Upload", 0, 1); - - transaction = 2; - while (1) { - int rc; - - /* last chunk can be smaller than original xfer_size */ - if (upload_limit - total_bytes < xfer_size) - xfer_size = upload_limit - total_bytes; - rc = dfuse_upload(dif, xfer_size, buf, transaction++); - if (rc < 0) { - ret = rc; - goto out_free; - } - - dfu_file_write_crc(fd, 0, buf, rc); - total_bytes += rc; - - if (total_bytes < 0) - errx(EX_SOFTWARE, "Received too many bytes"); - - if (rc < xfer_size || total_bytes >= upload_limit) { - /* last block, return successfully */ - ret = total_bytes; - break; - } - dfu_progress_bar("Upload", total_bytes, upload_limit); - } - - dfu_progress_bar("Upload", total_bytes, total_bytes); - - dfu_abort_to_idle(dif); - if (dfuse_leave) { - dfuse_special_command(dif, dfuse_address, SET_ADDRESS); - dfuse_dnload_chunk(dif, NULL, 0, 2); /* Zero-size */ - } - - out_free: - free(buf); - - return ret; -} - -/* Writes an element of any size to the device, taking care of page erases */ -/* returns 0 on success, otherwise -EINVAL */ -int dfuse_dnload_element(struct dfu_if *dif, unsigned int dwElementAddress, - unsigned int dwElementSize, unsigned char *data, - int xfer_size) -{ - int p; - int ret; - struct memsegment *segment; - - /* Check at least that we can write to the last address */ - segment = - find_segment(mem_layout, dwElementAddress + dwElementSize - 1); - if (!segment || !(segment->memtype & DFUSE_WRITEABLE)) { - errx(EX_IOERR, "Last page at 0x%08x is not writeable", - dwElementAddress + dwElementSize - 1); - } - - dfu_progress_bar("Download", 0, 1); - - for (p = 0; p < (int)dwElementSize; p += xfer_size) { - int page_size; - unsigned int erase_address; - unsigned int address = dwElementAddress + p; - int chunk_size = xfer_size; - - segment = find_segment(mem_layout, address); - if (!segment || !(segment->memtype & DFUSE_WRITEABLE)) { - errx(EX_IOERR, "Page at 0x%08x is not writeable", - address); - } - page_size = segment->pagesize; - - /* check if this is the last chunk */ - if (p + chunk_size > (int)dwElementSize) - chunk_size = dwElementSize - p; - - /* Erase only for flash memory downloads */ - if ((segment->memtype & DFUSE_ERASABLE) && !dfuse_mass_erase) { - /* erase all involved pages */ - for (erase_address = address; - erase_address < address + chunk_size; - erase_address += page_size) - if ((erase_address & ~(page_size - 1)) != - last_erased_page) - dfuse_special_command(dif, - erase_address, - ERASE_PAGE); - - if (((address + chunk_size - 1) & ~(page_size - 1)) != - last_erased_page) { - if (verbose > 2) - printf(" Chunk extends into next page," - " erase it as well\n"); - dfuse_special_command(dif, - address + chunk_size - 1, - ERASE_PAGE); - } - } - - if (verbose) { - printf(" Download from image offset " - "%08x to memory %08x-%08x, size %i\n", - p, address, address + chunk_size - 1, - chunk_size); - } else { - dfu_progress_bar("Download", p, dwElementSize); - } - - dfuse_special_command(dif, address, SET_ADDRESS); - - /* transaction = 2 for no address offset */ - ret = dfuse_dnload_chunk(dif, data + p, chunk_size, 2); - if (ret != chunk_size) { - errx(EX_IOERR, "Failed to write whole chunk: " - "%i of %i bytes", ret, chunk_size); - return -EINVAL; - } - } - if (!verbose) - dfu_progress_bar("Download", dwElementSize, dwElementSize); - return 0; -} - -static void -dfuse_memcpy(unsigned char *dst, unsigned char **src, int *rem, int size) -{ - if (size > *rem) { - errx(EX_IOERR, "Corrupt DfuSe file: " - "Cannot read %d bytes from %d bytes", size, *rem); - } - if (dst != NULL) - memcpy(dst, *src, size); - (*src) += size; - (*rem) -= size; -} - -/* Download raw binary file to DfuSe device */ -int dfuse_do_bin_dnload(struct dfu_if *dif, int xfer_size, - struct dfu_file *file, unsigned int start_address) -{ - unsigned int dwElementAddress; - unsigned int dwElementSize; - unsigned char *data; - int ret; - - dwElementAddress = start_address; - dwElementSize = file->size.total - - file->size.suffix - file->size.prefix; - - printf("Downloading to address = 0x%08x, size = %i\n", - dwElementAddress, dwElementSize); - - data = file->firmware + file->size.prefix; - - ret = dfuse_dnload_element(dif, dwElementAddress, dwElementSize, data, - xfer_size); - if (ret != 0) - goto out_free; - - printf("File downloaded successfully\n"); - ret = dwElementSize; - - out_free: - return ret; -} - -/* Parse a DfuSe file and download contents to device */ -int dfuse_do_dfuse_dnload(struct dfu_if *dif, int xfer_size, - struct dfu_file *file) -{ - uint8_t dfuprefix[11]; - uint8_t targetprefix[274]; - uint8_t elementheader[8]; - int image; - int element; - int bTargets; - int bAlternateSetting; - int dwNbElements; - unsigned int dwElementAddress; - unsigned int dwElementSize; - uint8_t *data; - int ret; - int rem; - int bFirstAddressSaved = 0; - - rem = file->size.total - file->size.prefix - file->size.suffix; - data = file->firmware + file->size.prefix; - - /* Must be larger than a minimal DfuSe header and suffix */ - if (rem < (int)(sizeof(dfuprefix) + - sizeof(targetprefix) + sizeof(elementheader))) { - errx(EX_SOFTWARE, "File too small for a DfuSe file"); - } - - dfuse_memcpy(dfuprefix, &data, &rem, sizeof(dfuprefix)); - - if (strncmp((char *)dfuprefix, "DfuSe", 5)) { - errx(EX_IOERR, "No valid DfuSe signature"); - return -EINVAL; - } - if (dfuprefix[5] != 0x01) { - errx(EX_IOERR, "DFU format revision %i not supported", - dfuprefix[5]); - return -EINVAL; - } - bTargets = dfuprefix[10]; - printf("file contains %i DFU images\n", bTargets); - - for (image = 1; image <= bTargets; image++) { - printf("parsing DFU image %i\n", image); - dfuse_memcpy(targetprefix, &data, &rem, sizeof(targetprefix)); - if (strncmp((char *)targetprefix, "Target", 6)) { - errx(EX_IOERR, "No valid target signature"); - return -EINVAL; - } - bAlternateSetting = targetprefix[6]; - dwNbElements = quad2uint((unsigned char *)targetprefix + 270); - printf("image for alternate setting %i, ", bAlternateSetting); - printf("(%i elements, ", dwNbElements); - printf("total size = %i)\n", - quad2uint((unsigned char *)targetprefix + 266)); - if (bAlternateSetting != dif->altsetting) - printf("Warning: Image does not match current alternate" - " setting.\n" - "Please rerun with the correct -a option setting" - " to download this image!\n"); - for (element = 1; element <= dwNbElements; element++) { - printf("parsing element %i, ", element); - dfuse_memcpy(elementheader, &data, &rem, sizeof(elementheader)); - dwElementAddress = - quad2uint((unsigned char *)elementheader); - dwElementSize = - quad2uint((unsigned char *)elementheader + 4); - printf("address = 0x%08x, ", dwElementAddress); - printf("size = %i\n", dwElementSize); - - if (!bFirstAddressSaved) { - bFirstAddressSaved = 1; - dfuse_address = dwElementAddress; - } - /* sanity check */ - if ((int)dwElementSize > rem) - errx(EX_SOFTWARE, "File too small for element size"); - - if (bAlternateSetting == dif->altsetting) { - ret = dfuse_dnload_element(dif, dwElementAddress, - dwElementSize, data, xfer_size); - } else { - ret = 0; - } - - /* advance read pointer */ - dfuse_memcpy(NULL, &data, &rem, dwElementSize); - - if (ret != 0) - return ret; - } - } - - if (rem != 0) - warnx("%d bytes leftover", rem); - - printf("done parsing DfuSe file\n"); - - return 0; -} - -int dfuse_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file, - const char *dfuse_options) -{ - int ret; - - if (dfuse_options) - dfuse_parse_options(dfuse_options); - mem_layout = parse_memory_layout((char *)dif->alt_name); - if (!mem_layout) { - errx(EX_IOERR, "Failed to parse memory layout"); - } - if (dfuse_unprotect) { - if (!dfuse_force) { - errx(EX_IOERR, "The read unprotect command " - "will erase the flash memory" - "and can only be used with force\n"); - } - dfuse_special_command(dif, 0, READ_UNPROTECT); - printf("Device disconnects, erases flash and resets now\n"); - exit(0); - } - if (dfuse_mass_erase) { - if (!dfuse_force) { - errx(EX_IOERR, "The mass erase command " - "can only be used with force"); - } - printf("Performing mass erase, this can take a moment\n"); - dfuse_special_command(dif, 0, MASS_ERASE); - } - if (dfuse_address) { - if (file->bcdDFU == 0x11a) { - errx(EX_IOERR, "This is a DfuSe file, not " - "meant for raw download"); - } - ret = dfuse_do_bin_dnload(dif, xfer_size, file, dfuse_address); - } else { - if (file->bcdDFU != 0x11a) { - warnx("Only DfuSe file version 1.1a is supported"); - errx(EX_IOERR, "(for raw binary download, use the " - "--dfuse-address option)"); - } - ret = dfuse_do_dfuse_dnload(dif, xfer_size, file); - } - free_segment_list(mem_layout); - - dfu_abort_to_idle(dif); - - if (dfuse_leave) { - dfuse_special_command(dif, dfuse_address, SET_ADDRESS); - dfuse_dnload_chunk(dif, NULL, 0, 2); /* Zero-size */ - } - return ret; -} diff --git a/linux/src/dfu-util/src/dfuse.h b/linux/src/dfu-util/src/dfuse.h deleted file mode 100644 index ed1108cfc..000000000 --- a/linux/src/dfu-util/src/dfuse.h +++ /dev/null @@ -1,35 +0,0 @@ -/* This implements the ST Microsystems DFU extensions (DfuSe) - * as per the DfuSe 1.1a specification (Document UM0391) - * - * (C) 2010-2012 Tormod Volden - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef DFUSE_H -#define DFUSE_H - -#include "dfu.h" - -enum dfuse_command { SET_ADDRESS, ERASE_PAGE, MASS_ERASE, READ_UNPROTECT }; - -int dfuse_special_command(struct dfu_if *dif, unsigned int address, - enum dfuse_command command); -int dfuse_do_upload(struct dfu_if *dif, int xfer_size, int fd, - const char *dfuse_options); -int dfuse_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file, - const char *dfuse_options); - -#endif /* DFUSE_H */ diff --git a/linux/src/dfu-util/src/dfuse_mem.c b/linux/src/dfu-util/src/dfuse_mem.c deleted file mode 100644 index a91aacf5f..000000000 --- a/linux/src/dfu-util/src/dfuse_mem.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Helper functions for reading the memory map of a device - * following the ST DfuSe 1.1a specification. - * - * Copyright 2011-2014 Tormod Volden - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#include "portable.h" -#include "dfu_file.h" -#include "dfuse_mem.h" - -int add_segment(struct memsegment **segment_list, struct memsegment segment) -{ - struct memsegment *new_element; - - new_element = dfu_malloc(sizeof(struct memsegment)); - *new_element = segment; - new_element->next = NULL; - - if (*segment_list == NULL) - /* list can be empty on first call */ - *segment_list = new_element; - else { - struct memsegment *next_element; - - /* find last element in list */ - next_element = *segment_list; - while (next_element->next != NULL) - next_element = next_element->next; - next_element->next = new_element; - } - return 0; -} - -struct memsegment *find_segment(struct memsegment *segment_list, - unsigned int address) -{ - while (segment_list != NULL) { - if (segment_list->start <= address && - segment_list->end >= address) - return segment_list; - segment_list = segment_list->next; - } - return NULL; -} - -void free_segment_list(struct memsegment *segment_list) -{ - struct memsegment *next_element; - - while (segment_list->next != NULL) { - next_element = segment_list->next; - free(segment_list); - segment_list = next_element; - } - free(segment_list); -} - -/* Parse memory map from interface descriptor string - * encoded as per ST document UM0424 section 4.3.2. - */ -struct memsegment *parse_memory_layout(char *intf_desc) -{ - - char multiplier, memtype; - unsigned int address; - int sectors, size; - char *name, *typestring; - int ret; - int count = 0; - char separator; - int scanned; - struct memsegment *segment_list = NULL; - struct memsegment segment; - - name = dfu_malloc(strlen(intf_desc)); - - ret = sscanf(intf_desc, "@%[^/]%n", name, &scanned); - if (ret < 1) { - free(name); - warnx("Could not read name, sscanf returned %d", ret); - return NULL; - } - printf("DfuSe interface name: \"%s\"\n", name); - - intf_desc += scanned; - typestring = dfu_malloc(strlen(intf_desc)); - - while (ret = sscanf(intf_desc, "/0x%x/%n", &address, &scanned), - ret > 0) { - - intf_desc += scanned; - while (ret = sscanf(intf_desc, "%d*%d%c%[^,/]%n", - §ors, &size, &multiplier, typestring, - &scanned), ret > 2) { - intf_desc += scanned; - - count++; - memtype = 0; - if (ret == 4) { - if (strlen(typestring) == 1 - && typestring[0] != '/') - memtype = typestring[0]; - else { - warnx("Parsing type identifier '%s' " - "failed for segment %i", - typestring, count); - continue; - } - } - - /* Quirk for STM32F4 devices */ - if (strcmp(name, "Device Feature") == 0) - memtype = 'e'; - - switch (multiplier) { - case 'B': - break; - case 'K': - size *= 1024; - break; - case 'M': - size *= 1024 * 1024; - break; - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - case 'g': - if (!memtype) { - warnx("Non-valid multiplier '%c', " - "interpreted as type " - "identifier instead", - multiplier); - memtype = multiplier; - break; - } - /* fallthrough if memtype was already set */ - default: - warnx("Non-valid multiplier '%c', " - "assuming bytes", multiplier); - } - - if (!memtype) { - warnx("No valid type for segment %d\n", count); - continue; - } - - segment.start = address; - segment.end = address + sectors * size - 1; - segment.pagesize = size; - segment.memtype = memtype & 7; - add_segment(&segment_list, segment); - - if (verbose) - printf("Memory segment at 0x%08x %3d x %4d = " - "%5d (%s%s%s)\n", - address, sectors, size, sectors * size, - memtype & DFUSE_READABLE ? "r" : "", - memtype & DFUSE_ERASABLE ? "e" : "", - memtype & DFUSE_WRITEABLE ? "w" : ""); - - address += sectors * size; - - separator = *intf_desc; - if (separator == ',') - intf_desc += 1; - else - break; - } /* while per segment */ - - } /* while per address */ - free(name); - free(typestring); - - return segment_list; -} diff --git a/linux/src/dfu-util/src/dfuse_mem.h b/linux/src/dfu-util/src/dfuse_mem.h deleted file mode 100644 index 0181f0c16..000000000 --- a/linux/src/dfu-util/src/dfuse_mem.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Helper functions for reading the memory map in a device - * following the ST DfuSe 1.1a specification. - * - * (C) 2011 Tormod Volden - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef DFUSE_MEM_H -#define DFUSE_MEM_H - -#define DFUSE_READABLE 1 -#define DFUSE_ERASABLE 2 -#define DFUSE_WRITEABLE 4 - -struct memsegment { - unsigned int start; - unsigned int end; - int pagesize; - int memtype; - struct memsegment *next; -}; - -int add_segment(struct memsegment **list, struct memsegment new_element); - -struct memsegment *find_segment(struct memsegment *list, unsigned int address); - -void free_segment_list(struct memsegment *list); - -struct memsegment *parse_memory_layout(char *intf_desc_str); - -#endif /* DFUSE_MEM_H */ diff --git a/linux/src/dfu-util/src/main.c b/linux/src/dfu-util/src/main.c deleted file mode 100644 index acaed2f08..000000000 --- a/linux/src/dfu-util/src/main.c +++ /dev/null @@ -1,699 +0,0 @@ -/* - * dfu-util - * - * Copyright 2007-2008 by OpenMoko, Inc. - * Copyright 2013-2014 Hans Petter Selasky - * - * Written by Harald Welte - * - * Based on existing code of dfu-programmer-0.4 - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "portable.h" -#include "dfu.h" -#include "usb_dfu.h" -#include "dfu_file.h" -#include "dfu_load.h" -#include "dfu_util.h" -#include "dfuse.h" -#include "quirks.h" - -#ifdef HAVE_USBPATH_H -#include -#endif - -int verbose = 0; - -struct dfu_if *dfu_root = NULL; - -int match_bus = -1; -int match_device = -1; -int match_vendor = -1; -int match_product = -1; -int match_vendor_dfu = -1; -int match_product_dfu = -1; -int match_config_index = -1; -int match_iface_index = -1; -int match_iface_alt_index = -1; -const char *match_iface_alt_name = NULL; -const char *match_serial = NULL; -const char *match_serial_dfu = NULL; - -static int parse_match_value(const char *str, int default_value) -{ - char *remainder; - int value; - - if (str == NULL) { - value = default_value; - } else if (*str == '*') { - value = -1; /* Match anything */ - } else if (*str == '-') { - value = 0x10000; /* Impossible vendor/product ID */ - } else { - value = strtoul(str, &remainder, 16); - if (remainder == str) { - value = default_value; - } - } - return value; -} - -static void parse_vendprod(const char *str) -{ - const char *comma; - const char *colon; - - /* Default to match any DFU device in runtime or DFU mode */ - match_vendor = -1; - match_product = -1; - match_vendor_dfu = -1; - match_product_dfu = -1; - - comma = strchr(str, ','); - if (comma == str) { - /* DFU mode vendor/product being specified without any runtime - * vendor/product specification, so don't match any runtime device */ - match_vendor = match_product = 0x10000; - } else { - colon = strchr(str, ':'); - if (colon != NULL) { - ++colon; - if ((comma != NULL) && (colon > comma)) { - colon = NULL; - } - } - match_vendor = parse_match_value(str, match_vendor); - match_product = parse_match_value(colon, match_product); - if (comma != NULL) { - /* Both runtime and DFU mode vendor/product specifications are - * available, so default DFU mode match components to the given - * runtime match components */ - match_vendor_dfu = match_vendor; - match_product_dfu = match_product; - } - } - if (comma != NULL) { - ++comma; - colon = strchr(comma, ':'); - if (colon != NULL) { - ++colon; - } - match_vendor_dfu = parse_match_value(comma, match_vendor_dfu); - match_product_dfu = parse_match_value(colon, match_product_dfu); - } -} - -static void parse_serial(char *str) -{ - char *comma; - - match_serial = str; - comma = strchr(str, ','); - if (comma == NULL) { - match_serial_dfu = match_serial; - } else { - *comma++ = 0; - match_serial_dfu = comma; - } - if (*match_serial == 0) match_serial = NULL; - if (*match_serial_dfu == 0) match_serial_dfu = NULL; -} - -#ifdef HAVE_USBPATH_H - -static int resolve_device_path(char *path) -{ - int res; - - res = usb_path2devnum(path); - if (res < 0) - return -EINVAL; - if (!res) - return 0; - - match_bus = atoi(path); - match_device = res; - - return 0; -} - -#else /* HAVE_USBPATH_H */ - -static int resolve_device_path(char *path) -{ - (void)path; /* Eliminate unused variable warning */ - errx(EX_SOFTWARE, "USB device paths are not supported by this dfu-util.\n"); -} - -#endif /* !HAVE_USBPATH_H */ - -static void help(void) -{ - fprintf(stderr, "Usage: dfu-util [options] ...\n" - " -h --help\t\t\tPrint this help message\n" - " -V --version\t\t\tPrint the version number\n" - " -v --verbose\t\t\tPrint verbose debug statements\n" - " -l --list\t\t\tList currently attached DFU capable devices\n"); - fprintf(stderr, " -e --detach\t\t\tDetach currently attached DFU capable devices\n" - " -E --detach-delay seconds\tTime to wait before reopening a device after detach\n" - " -d --device :[,:]\n" - "\t\t\t\tSpecify Vendor/Product ID(s) of DFU device\n" - " -p --path \tSpecify path to DFU device\n" - " -c --cfg \t\tSpecify the Configuration of DFU device\n" - " -i --intf \t\tSpecify the DFU Interface number\n" - " -S --serial [,]\n" - "\t\t\t\tSpecify Serial String of DFU device\n" - " -a --alt \t\tSpecify the Altsetting of the DFU Interface\n" - "\t\t\t\tby name or by number\n"); - fprintf(stderr, " -t --transfer-size \tSpecify the number of bytes per USB Transfer\n" - " -U --upload \t\tRead firmware from device into \n" - " -Z --upload-size \tSpecify the expected upload size in bytes\n" - " -D --download \t\tWrite firmware from into device\n" - " -R --reset\t\t\tIssue USB Reset signalling once we're finished\n" - " -s --dfuse-address
\tST DfuSe mode, specify target address for\n" - "\t\t\t\traw file download or upload. Not applicable for\n" - "\t\t\t\tDfuSe file (.dfu) downloads\n" - ); - exit(EX_USAGE); -} - -static void print_version(void) -{ - printf(PACKAGE_STRING "\n\n"); - printf("Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.\n" - "Copyright 2010-2014 Tormod Volden and Stefan Schmidt\n" - "This program is Free Software and has ABSOLUTELY NO WARRANTY\n" - "Please report bugs to " PACKAGE_BUGREPORT "\n\n"); -} - -static struct option opts[] = { - { "help", 0, 0, 'h' }, - { "version", 0, 0, 'V' }, - { "verbose", 0, 0, 'v' }, - { "list", 0, 0, 'l' }, - { "detach", 0, 0, 'e' }, - { "detach-delay", 1, 0, 'E' }, - { "device", 1, 0, 'd' }, - { "path", 1, 0, 'p' }, - { "configuration", 1, 0, 'c' }, - { "cfg", 1, 0, 'c' }, - { "interface", 1, 0, 'i' }, - { "intf", 1, 0, 'i' }, - { "altsetting", 1, 0, 'a' }, - { "alt", 1, 0, 'a' }, - { "serial", 1, 0, 'S' }, - { "transfer-size", 1, 0, 't' }, - { "upload", 1, 0, 'U' }, - { "upload-size", 1, 0, 'Z' }, - { "download", 1, 0, 'D' }, - { "reset", 0, 0, 'R' }, - { "dfuse-address", 1, 0, 's' }, - { 0, 0, 0, 0 } -}; - -int main(int argc, char **argv) -{ - int expected_size = 0; - unsigned int transfer_size = 0; - enum mode mode = MODE_NONE; - struct dfu_status status; - libusb_context *ctx; - struct dfu_file file; - char *end; - int final_reset = 0; - int ret; - int dfuse_device = 0; - int fd; - const char *dfuse_options = NULL; - int detach_delay = 5; - uint16_t runtime_vendor; - uint16_t runtime_product; - - memset(&file, 0, sizeof(file)); - - /* make sure all prints are flushed */ - setvbuf(stdout, NULL, _IONBF, 0); - - while (1) { - int c, option_index = 0; - c = getopt_long(argc, argv, "hVvleE:d:p:c:i:a:S:t:U:D:Rs:Z:", opts, - &option_index); - if (c == -1) - break; - - switch (c) { - case 'h': - help(); - break; - case 'V': - mode = MODE_VERSION; - break; - case 'v': - verbose++; - break; - case 'l': - mode = MODE_LIST; - break; - case 'e': - mode = MODE_DETACH; - match_iface_alt_index = 0; - match_iface_index = 0; - break; - case 'E': - detach_delay = atoi(optarg); - break; - case 'd': - parse_vendprod(optarg); - break; - case 'p': - /* Parse device path */ - ret = resolve_device_path(optarg); - if (ret < 0) - errx(EX_SOFTWARE, "Unable to parse '%s'", optarg); - if (!ret) - errx(EX_SOFTWARE, "Cannot find '%s'", optarg); - break; - case 'c': - /* Configuration */ - match_config_index = atoi(optarg); - break; - case 'i': - /* Interface */ - match_iface_index = atoi(optarg); - break; - case 'a': - /* Interface Alternate Setting */ - match_iface_alt_index = strtoul(optarg, &end, 0); - if (*end) { - match_iface_alt_name = optarg; - match_iface_alt_index = -1; - } - break; - case 'S': - parse_serial(optarg); - break; - case 't': - transfer_size = atoi(optarg); - break; - case 'U': - mode = MODE_UPLOAD; - file.name = optarg; - break; - case 'Z': - expected_size = atoi(optarg); - break; - case 'D': - mode = MODE_DOWNLOAD; - file.name = optarg; - break; - case 'R': - final_reset = 1; - break; - case 's': - dfuse_options = optarg; - break; - default: - help(); - break; - } - } - - print_version(); - if (mode == MODE_VERSION) { - exit(0); - } - - if (mode == MODE_NONE) { - fprintf(stderr, "You need to specify one of -D or -U\n"); - help(); - } - - if (match_config_index == 0) { - /* Handle "-c 0" (unconfigured device) as don't care */ - match_config_index = -1; - } - - if (mode == MODE_DOWNLOAD) { - dfu_load_file(&file, MAYBE_SUFFIX, MAYBE_PREFIX); - /* If the user didn't specify product and/or vendor IDs to match, - * use any IDs from the file suffix for device matching */ - if (match_vendor < 0 && file.idVendor != 0xffff) { - match_vendor = file.idVendor; - printf("Match vendor ID from file: %04x\n", match_vendor); - } - if (match_product < 0 && file.idProduct != 0xffff) { - match_product = file.idProduct; - printf("Match product ID from file: %04x\n", match_product); - } - } - - ret = libusb_init(&ctx); - if (ret) - errx(EX_IOERR, "unable to initialize libusb: %i", ret); - - if (verbose > 2) { - libusb_set_debug(ctx, 255); - } - - probe_devices(ctx); - - if (mode == MODE_LIST) { - list_dfu_interfaces(); - exit(0); - } - - if (dfu_root == NULL) { - errx(EX_IOERR, "No DFU capable USB device available"); - } else if (dfu_root->next != NULL) { - /* We cannot safely support more than one DFU capable device - * with same vendor/product ID, since during DFU we need to do - * a USB bus reset, after which the target device will get a - * new address */ - errx(EX_IOERR, "More than one DFU capable USB device found! " - "Try `--list' and specify the serial number " - "or disconnect all but one device\n"); - } - - /* We have exactly one device. Its libusb_device is now in dfu_root->dev */ - - printf("Opening DFU capable USB device...\n"); - ret = libusb_open(dfu_root->dev, &dfu_root->dev_handle); - if (ret || !dfu_root->dev_handle) - errx(EX_IOERR, "Cannot open device"); - - printf("ID %04x:%04x\n", dfu_root->vendor, dfu_root->product); - - printf("Run-time device DFU version %04x\n", - libusb_le16_to_cpu(dfu_root->func_dfu.bcdDFUVersion)); - - /* Transition from run-Time mode to DFU mode */ - if (!(dfu_root->flags & DFU_IFF_DFU)) { - int err; - /* In the 'first round' during runtime mode, there can only be one - * DFU Interface descriptor according to the DFU Spec. */ - - /* FIXME: check if the selected device really has only one */ - - runtime_vendor = dfu_root->vendor; - runtime_product = dfu_root->product; - - printf("Claiming USB DFU Runtime Interface...\n"); - if (libusb_claim_interface(dfu_root->dev_handle, dfu_root->interface) < 0) { - errx(EX_IOERR, "Cannot claim interface %d", - dfu_root->interface); - } - - if (libusb_set_interface_alt_setting(dfu_root->dev_handle, dfu_root->interface, 0) < 0) { - errx(EX_IOERR, "Cannot set alt interface zero"); - } - - printf("Determining device status: "); - - err = dfu_get_status(dfu_root, &status); - if (err == LIBUSB_ERROR_PIPE) { - printf("Device does not implement get_status, assuming appIDLE\n"); - status.bStatus = DFU_STATUS_OK; - status.bwPollTimeout = 0; - status.bState = DFU_STATE_appIDLE; - status.iString = 0; - } else if (err < 0) { - errx(EX_IOERR, "error get_status"); - } else { - printf("state = %s, status = %d\n", - dfu_state_to_string(status.bState), status.bStatus); - } - milli_sleep(status.bwPollTimeout); - - switch (status.bState) { - case DFU_STATE_appIDLE: - case DFU_STATE_appDETACH: - printf("Device really in Runtime Mode, send DFU " - "detach request...\n"); - if (dfu_detach(dfu_root->dev_handle, - dfu_root->interface, 1000) < 0) { - warnx("error detaching"); - } - if (dfu_root->func_dfu.bmAttributes & USB_DFU_WILL_DETACH) { - printf("Device will detach and reattach...\n"); - } else { - printf("Resetting USB...\n"); - ret = libusb_reset_device(dfu_root->dev_handle); - if (ret < 0 && ret != LIBUSB_ERROR_NOT_FOUND) - errx(EX_IOERR, "error resetting " - "after detach"); - } - break; - case DFU_STATE_dfuERROR: - printf("dfuERROR, clearing status\n"); - if (dfu_clear_status(dfu_root->dev_handle, - dfu_root->interface) < 0) { - errx(EX_IOERR, "error clear_status"); - } - /* fall through */ - default: - warnx("WARNING: Runtime device already in DFU state ?!?"); - libusb_release_interface(dfu_root->dev_handle, - dfu_root->interface); - goto dfustate; - } - libusb_release_interface(dfu_root->dev_handle, - dfu_root->interface); - libusb_close(dfu_root->dev_handle); - dfu_root->dev_handle = NULL; - - if (mode == MODE_DETACH) { - libusb_exit(ctx); - exit(0); - } - - /* keeping handles open might prevent re-enumeration */ - disconnect_devices(); - - milli_sleep(detach_delay * 1000); - - /* Change match vendor and product to impossible values to force - * only DFU mode matches in the following probe */ - match_vendor = match_product = 0x10000; - - probe_devices(ctx); - - if (dfu_root == NULL) { - errx(EX_IOERR, "Lost device after RESET?"); - } else if (dfu_root->next != NULL) { - errx(EX_IOERR, "More than one DFU capable USB device found! " - "Try `--list' and specify the serial number " - "or disconnect all but one device"); - } - - /* Check for DFU mode device */ - if (!(dfu_root->flags | DFU_IFF_DFU)) - errx(EX_SOFTWARE, "Device is not in DFU mode"); - - printf("Opening DFU USB Device...\n"); - ret = libusb_open(dfu_root->dev, &dfu_root->dev_handle); - if (ret || !dfu_root->dev_handle) { - errx(EX_IOERR, "Cannot open device"); - } - } else { - /* we're already in DFU mode, so we can skip the detach/reset - * procedure */ - /* If a match vendor/product was specified, use that as the runtime - * vendor/product, otherwise use the DFU mode vendor/product */ - runtime_vendor = match_vendor < 0 ? dfu_root->vendor : match_vendor; - runtime_product = match_product < 0 ? dfu_root->product : match_product; - } - -dfustate: -#if 0 - printf("Setting Configuration %u...\n", dfu_root->configuration); - if (libusb_set_configuration(dfu_root->dev_handle, dfu_root->configuration) < 0) { - errx(EX_IOERR, "Cannot set configuration"); - } -#endif - printf("Claiming USB DFU Interface...\n"); - if (libusb_claim_interface(dfu_root->dev_handle, dfu_root->interface) < 0) { - errx(EX_IOERR, "Cannot claim interface"); - } - - printf("Setting Alternate Setting #%d ...\n", dfu_root->altsetting); - if (libusb_set_interface_alt_setting(dfu_root->dev_handle, dfu_root->interface, dfu_root->altsetting) < 0) { - errx(EX_IOERR, "Cannot set alternate interface"); - } - -status_again: - printf("Determining device status: "); - if (dfu_get_status(dfu_root, &status ) < 0) { - errx(EX_IOERR, "error get_status"); - } - printf("state = %s, status = %d\n", - dfu_state_to_string(status.bState), status.bStatus); - - milli_sleep(status.bwPollTimeout); - - switch (status.bState) { - case DFU_STATE_appIDLE: - case DFU_STATE_appDETACH: - errx(EX_IOERR, "Device still in Runtime Mode!"); - break; - case DFU_STATE_dfuERROR: - printf("dfuERROR, clearing status\n"); - if (dfu_clear_status(dfu_root->dev_handle, dfu_root->interface) < 0) { - errx(EX_IOERR, "error clear_status"); - } - goto status_again; - break; - case DFU_STATE_dfuDNLOAD_IDLE: - case DFU_STATE_dfuUPLOAD_IDLE: - printf("aborting previous incomplete transfer\n"); - if (dfu_abort(dfu_root->dev_handle, dfu_root->interface) < 0) { - errx(EX_IOERR, "can't send DFU_ABORT"); - } - goto status_again; - break; - case DFU_STATE_dfuIDLE: - printf("dfuIDLE, continuing\n"); - break; - default: - break; - } - - if (DFU_STATUS_OK != status.bStatus ) { - printf("WARNING: DFU Status: '%s'\n", - dfu_status_to_string(status.bStatus)); - /* Clear our status & try again. */ - if (dfu_clear_status(dfu_root->dev_handle, dfu_root->interface) < 0) - errx(EX_IOERR, "USB communication error"); - if (dfu_get_status(dfu_root, &status) < 0) - errx(EX_IOERR, "USB communication error"); - if (DFU_STATUS_OK != status.bStatus) - errx(EX_SOFTWARE, "Status is not OK: %d", status.bStatus); - - milli_sleep(status.bwPollTimeout); - } - - printf("DFU mode device DFU version %04x\n", - libusb_le16_to_cpu(dfu_root->func_dfu.bcdDFUVersion)); - - if (dfu_root->func_dfu.bcdDFUVersion == libusb_cpu_to_le16(0x11a)) - dfuse_device = 1; - - /* If not overridden by the user */ - if (!transfer_size) { - transfer_size = libusb_le16_to_cpu( - dfu_root->func_dfu.wTransferSize); - if (transfer_size) { - printf("Device returned transfer size %i\n", - transfer_size); - } else { - errx(EX_IOERR, "Transfer size must be specified"); - } - } - -#ifdef HAVE_GETPAGESIZE -/* autotools lie when cross-compiling for Windows using mingw32/64 */ -#ifndef __MINGW32__ - /* limitation of Linux usbdevio */ - if ((int)transfer_size > getpagesize()) { - transfer_size = getpagesize(); - printf("Limited transfer size to %i\n", transfer_size); - } -#endif /* __MINGW32__ */ -#endif /* HAVE_GETPAGESIZE */ - - if (transfer_size < dfu_root->bMaxPacketSize0) { - transfer_size = dfu_root->bMaxPacketSize0; - printf("Adjusted transfer size to %i\n", transfer_size); - } - - switch (mode) { - case MODE_UPLOAD: - /* open for "exclusive" writing */ - fd = open(file.name, O_WRONLY | O_BINARY | O_CREAT | O_EXCL | O_TRUNC, 0666); - if (fd < 0) - err(EX_IOERR, "Cannot open file %s for writing", file.name); - - if (dfuse_device || dfuse_options) { - if (dfuse_do_upload(dfu_root, transfer_size, fd, - dfuse_options) < 0) - exit(1); - } else { - if (dfuload_do_upload(dfu_root, transfer_size, - expected_size, fd) < 0) { - exit(1); - } - } - close(fd); - break; - - case MODE_DOWNLOAD: - if (((file.idVendor != 0xffff && file.idVendor != runtime_vendor) || - (file.idProduct != 0xffff && file.idProduct != runtime_product)) && - ((file.idVendor != 0xffff && file.idVendor != dfu_root->vendor) || - (file.idProduct != 0xffff && file.idProduct != dfu_root->product))) { - errx(EX_IOERR, "Error: File ID %04x:%04x does " - "not match device (%04x:%04x or %04x:%04x)", - file.idVendor, file.idProduct, - runtime_vendor, runtime_product, - dfu_root->vendor, dfu_root->product); - } - if (dfuse_device || dfuse_options || file.bcdDFU == 0x11a) { - if (dfuse_do_dnload(dfu_root, transfer_size, &file, - dfuse_options) < 0) - exit(1); - } else { - if (dfuload_do_dnload(dfu_root, transfer_size, &file) < 0) - exit(1); - } - break; - case MODE_DETACH: - if (dfu_detach(dfu_root->dev_handle, dfu_root->interface, 1000) < 0) { - warnx("can't detach"); - } - break; - default: - errx(EX_IOERR, "Unsupported mode: %u", mode); - break; - } - - if (final_reset) { - if (dfu_detach(dfu_root->dev_handle, dfu_root->interface, 1000) < 0) { - /* Even if detach failed, just carry on to leave the - device in a known state */ - warnx("can't detach"); - } - printf("Resetting USB to switch back to runtime mode\n"); - ret = libusb_reset_device(dfu_root->dev_handle); - if (ret < 0 && ret != LIBUSB_ERROR_NOT_FOUND) { - errx(EX_IOERR, "error resetting after download"); - } - } - - libusb_close(dfu_root->dev_handle); - dfu_root->dev_handle = NULL; - libusb_exit(ctx); - - return (0); -} diff --git a/linux/src/dfu-util/src/portable.h b/linux/src/dfu-util/src/portable.h deleted file mode 100644 index cf8d5df38..000000000 --- a/linux/src/dfu-util/src/portable.h +++ /dev/null @@ -1,72 +0,0 @@ - -#ifndef PORTABLE_H -#define PORTABLE_H - -#ifdef HAVE_CONFIG_H -# include "config.h" -#else -# define PACKAGE "dfu-util" -# define PACKAGE_VERSION "0.8-msvc" -# define PACKAGE_STRING "dfu-util 0.8-msvc" -# define PACKAGE_BUGREPORT "dfu-util@lists.gnumonks.org" -#endif /* HAVE_CONFIG_H */ - -#ifdef HAVE_FTRUNCATE -# include -#else -# include -#endif /* HAVE_FTRUNCATE */ - -#ifdef HAVE_NANOSLEEP -# include -# define milli_sleep(msec) do {\ - if (msec) {\ - struct timespec nanosleepDelay = { (msec) / 1000, ((msec) % 1000) * 1000000 };\ - nanosleep(&nanosleepDelay, NULL);\ - } } while (0) -#elif defined HAVE_WINDOWS_H -# define milli_sleep(msec) do {\ - if (msec) {\ - Sleep(msec);\ - } } while (0) -#else -# error "Can't get no sleep! Please report" -#endif /* HAVE_NANOSLEEP */ - -#ifdef HAVE_ERR -# include -#else -# include -# include -# define warnx(...) do {\ - fprintf(stderr, __VA_ARGS__);\ - fprintf(stderr, "\n"); } while (0) -# define errx(eval, ...) do {\ - warnx(__VA_ARGS__);\ - exit(eval); } while (0) -# define warn(...) do {\ - fprintf(stderr, "%s: ", strerror(errno));\ - warnx(__VA_ARGS__); } while (0) -# define err(eval, ...) do {\ - warn(__VA_ARGS__);\ - exit(eval); } while (0) -#endif /* HAVE_ERR */ - -#ifdef HAVE_SYSEXITS_H -# include -#else -# define EX_OK 0 /* successful termination */ -# define EX_USAGE 64 /* command line usage error */ -# define EX_SOFTWARE 70 /* internal software error */ -# define EX_IOERR 74 /* input/output error */ -#endif /* HAVE_SYSEXITS_H */ - -#ifndef O_BINARY -# define O_BINARY 0 -#endif - -#ifndef off_t -# define off_t long int -#endif - -#endif /* PORTABLE_H */ diff --git a/linux/src/dfu-util/src/prefix.c b/linux/src/dfu-util/src/prefix.c deleted file mode 100644 index be8e3faf3..000000000 --- a/linux/src/dfu-util/src/prefix.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * dfu-prefix - * - * Copyright 2011-2012 Stefan Schmidt - * Copyright 2013 Hans Petter Selasky - * Copyright 2014 Uwe Bonnes - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#include "portable.h" -#include "dfu_file.h" - -enum mode { - MODE_NONE, - MODE_ADD, - MODE_DEL, - MODE_CHECK -}; - -int verbose; - -static void help(void) -{ - fprintf(stderr, "Usage: dfu-prefix [options] ...\n" - " -h --help\t\t\tPrint this help message\n" - " -V --version\t\t\tPrint the version number\n" - " -c --check \t\tCheck DFU prefix of \n" - " -D --delete \t\tDelete DFU prefix from \n" - " -a --add \t\tAdd DFU prefix to \n" - "In combination with -a:\n" - ); - fprintf(stderr, " -s --stellaris-address
Add TI Stellaris address prefix to \n" - "In combination with -D or -c:\n" - " -T --stellaris\t\tAct on TI Stellaris address prefix of \n" - "In combination with -a or -D or -c:\n" - " -L --lpc-prefix\t\tUse NXP LPC DFU prefix format\n" - ); - exit(EX_USAGE); -} - -static void print_version(void) -{ - printf("dfu-prefix (%s) %s\n\n", PACKAGE, PACKAGE_VERSION); - printf("Copyright 2011-2012 Stefan Schmidt, 2014 Uwe Bonnes\n" - "This program is Free Software and has ABSOLUTELY NO WARRANTY\n" - "Please report bugs to %s\n\n", PACKAGE_BUGREPORT); - -} - -static struct option opts[] = { - { "help", 0, 0, 'h' }, - { "version", 0, 0, 'V' }, - { "check", 1, 0, 'c' }, - { "add", 1, 0, 'a' }, - { "delete", 1, 0, 'D' }, - { "stellaris-address", 1, 0, 's' }, - { "stellaris", 0, 0, 'T' }, - { "LPC", 0, 0, 'L' }, -}; -int main(int argc, char **argv) -{ - struct dfu_file file; - enum mode mode = MODE_NONE; - enum prefix_type type = ZERO_PREFIX; - uint32_t lmdfu_flash_address = 0; - char *end; - - /* make sure all prints are flushed */ - setvbuf(stdout, NULL, _IONBF, 0); - - print_version(); - - memset(&file, 0, sizeof(file)); - - while (1) { - int c, option_index = 0; - c = getopt_long(argc, argv, "hVc:a:D:p:v:d:s:TL", opts, - &option_index); - if (c == -1) - break; - - switch (c) { - case 'h': - help(); - break; - case 'V': - exit(0); - break; - case 'D': - file.name = optarg; - mode = MODE_DEL; - break; - case 'c': - file.name = optarg; - mode = MODE_CHECK; - break; - case 'a': - file.name = optarg; - mode = MODE_ADD; - break; - case 's': - lmdfu_flash_address = strtoul(optarg, &end, 0); - if (*end) { - errx(EX_IOERR, "Invalid lmdfu " - "address: %s", optarg); - } - /* fall-through */ - case 'T': - type = LMDFU_PREFIX; - break; - case 'L': - type = LPCDFU_UNENCRYPTED_PREFIX; - break; - default: - help(); - break; - } - } - - if (!file.name) { - fprintf(stderr, "You need to specify a filename\n"); - help(); - } - - switch(mode) { - case MODE_ADD: - if (type == ZERO_PREFIX) - errx(EX_IOERR, "Prefix type must be specified"); - dfu_load_file(&file, MAYBE_SUFFIX, NO_PREFIX); - file.lmdfu_address = lmdfu_flash_address; - file.prefix_type = type; - printf("Adding prefix to file\n"); - dfu_store_file(&file, file.size.suffix != 0, 1); - break; - - case MODE_CHECK: - dfu_load_file(&file, MAYBE_SUFFIX, MAYBE_PREFIX); - show_suffix_and_prefix(&file); - if (type > ZERO_PREFIX && file.prefix_type != type) - errx(EX_IOERR, "No prefix of requested type"); - break; - - case MODE_DEL: - dfu_load_file(&file, MAYBE_SUFFIX, NEEDS_PREFIX); - if (type > ZERO_PREFIX && file.prefix_type != type) - errx(EX_IOERR, "No prefix of requested type"); - printf("Removing prefix from file\n"); - /* if there was a suffix, rewrite it */ - dfu_store_file(&file, file.size.suffix != 0, 0); - break; - - default: - help(); - break; - } - return (0); -} diff --git a/linux/src/dfu-util/src/quirks.c b/linux/src/dfu-util/src/quirks.c deleted file mode 100644 index de394a615..000000000 --- a/linux/src/dfu-util/src/quirks.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Simple quirk system for dfu-util - * - * Copyright 2010-2014 Tormod Volden - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include "quirks.h" - -uint16_t get_quirks(uint16_t vendor, uint16_t product, uint16_t bcdDevice) -{ - uint16_t quirks = 0; - - /* Device returns bogus bwPollTimeout values */ - if ((vendor == VENDOR_OPENMOKO || vendor == VENDOR_FIC) && - product >= PRODUCT_FREERUNNER_FIRST && - product <= PRODUCT_FREERUNNER_LAST) - quirks |= QUIRK_POLLTIMEOUT; - - if (vendor == VENDOR_VOTI && - product == PRODUCT_OPENPCD) - quirks |= QUIRK_POLLTIMEOUT; - - /* Reports wrong DFU version in DFU descriptor */ - if (vendor == VENDOR_LEAFLABS && - product == PRODUCT_MAPLE3 && - bcdDevice == 0x0200) - quirks |= QUIRK_FORCE_DFU11; - - /* old devices(bcdDevice == 0) return bogus bwPollTimeout values */ - if (vendor == VENDOR_SIEMENS && - (product == PRODUCT_PXM40 || product == PRODUCT_PXM50) && - bcdDevice == 0) - quirks |= QUIRK_POLLTIMEOUT; - - /* M-Audio Transit returns bogus bwPollTimeout values */ - if (vendor == VENDOR_MIDIMAN && - product == PRODUCT_TRANSIT) - quirks |= QUIRK_POLLTIMEOUT; - - return (quirks); -} diff --git a/linux/src/dfu-util/src/quirks.h b/linux/src/dfu-util/src/quirks.h deleted file mode 100644 index 0e4b3ec58..000000000 --- a/linux/src/dfu-util/src/quirks.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef DFU_QUIRKS_H -#define DFU_QUIRKS_H - -#define VENDOR_OPENMOKO 0x1d50 /* Openmoko Freerunner / GTA02 */ -#define VENDOR_FIC 0x1457 /* Openmoko Freerunner / GTA02 */ -#define VENDOR_VOTI 0x16c0 /* OpenPCD Reader */ -#define VENDOR_LEAFLABS 0x1eaf /* Maple */ -#define VENDOR_SIEMENS 0x0908 /* Siemens AG */ -#define VENDOR_MIDIMAN 0x0763 /* Midiman */ - -#define PRODUCT_FREERUNNER_FIRST 0x5117 -#define PRODUCT_FREERUNNER_LAST 0x5126 -#define PRODUCT_OPENPCD 0x076b -#define PRODUCT_MAPLE3 0x0003 /* rev 3 and 5 */ -#define PRODUCT_PXM40 0x02c4 /* Siemens AG, PXM 40 */ -#define PRODUCT_PXM50 0x02c5 /* Siemens AG, PXM 50 */ -#define PRODUCT_TRANSIT 0x2806 /* M-Audio Transit (Midiman) */ - -#define QUIRK_POLLTIMEOUT (1<<0) -#define QUIRK_FORCE_DFU11 (1<<1) - -/* Fallback value, works for OpenMoko */ -#define DEFAULT_POLLTIMEOUT 5 - -uint16_t get_quirks(uint16_t vendor, uint16_t product, uint16_t bcdDevice); - -#endif /* DFU_QUIRKS_H */ diff --git a/linux/src/dfu-util/src/suffix.c b/linux/src/dfu-util/src/suffix.c deleted file mode 100644 index 0df248f51..000000000 --- a/linux/src/dfu-util/src/suffix.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * dfu-suffix - * - * Copyright 2011-2012 Stefan Schmidt - * Copyright 2013 Hans Petter Selasky - * Copyright 2014 Tormod Volden - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#include "portable.h" -#include "dfu_file.h" - -enum mode { - MODE_NONE, - MODE_ADD, - MODE_DEL, - MODE_CHECK -}; - -int verbose; - -static void help(void) -{ - fprintf(stderr, "Usage: dfu-suffix [options] ...\n" - " -h --help\t\t\tPrint this help message\n" - " -V --version\t\t\tPrint the version number\n" - " -c --check \t\tCheck DFU suffix of \n" - " -a --add \t\tAdd DFU suffix to \n" - " -D --delete \t\tDelete DFU suffix from \n" - " -p --pid \t\tAdd product ID into DFU suffix in \n" - " -v --vid \t\tAdd vendor ID into DFU suffix in \n" - " -d --did \t\tAdd device ID into DFU suffix in \n" - " -S --spec \t\tAdd DFU specification ID into DFU suffix in \n" - ); - exit(EX_USAGE); -} - -static void print_version(void) -{ - printf("dfu-suffix (%s) %s\n\n", PACKAGE, PACKAGE_VERSION); - printf("Copyright 2011-2012 Stefan Schmidt, 2013-2014 Tormod Volden\n" - "This program is Free Software and has ABSOLUTELY NO WARRANTY\n" - "Please report bugs to %s\n\n", PACKAGE_BUGREPORT); - -} - -static struct option opts[] = { - { "help", 0, 0, 'h' }, - { "version", 0, 0, 'V' }, - { "check", 1, 0, 'c' }, - { "add", 1, 0, 'a' }, - { "delete", 1, 0, 'D' }, - { "pid", 1, 0, 'p' }, - { "vid", 1, 0, 'v' }, - { "did", 1, 0, 'd' }, - { "spec", 1, 0, 'S' }, -}; - -int main(int argc, char **argv) -{ - struct dfu_file file; - int pid, vid, did, spec; - enum mode mode = MODE_NONE; - - /* make sure all prints are flushed */ - setvbuf(stdout, NULL, _IONBF, 0); - - print_version(); - - pid = vid = did = 0xffff; - spec = 0x0100; /* Default to bcdDFU version 1.0 */ - memset(&file, 0, sizeof(file)); - - while (1) { - int c, option_index = 0; - c = getopt_long(argc, argv, "hVc:a:D:p:v:d:S:s:T", opts, - &option_index); - if (c == -1) - break; - - switch (c) { - case 'h': - help(); - break; - case 'V': - exit(0); - break; - case 'D': - file.name = optarg; - mode = MODE_DEL; - break; - case 'p': - pid = strtol(optarg, NULL, 16); - break; - case 'v': - vid = strtol(optarg, NULL, 16); - break; - case 'd': - did = strtol(optarg, NULL, 16); - break; - case 'S': - spec = strtol(optarg, NULL, 16); - break; - case 'c': - file.name = optarg; - mode = MODE_CHECK; - break; - case 'a': - file.name = optarg; - mode = MODE_ADD; - break; - default: - help(); - break; - } - } - - if (!file.name) { - fprintf(stderr, "You need to specify a filename\n"); - help(); - } - - if (spec != 0x0100 && spec != 0x011a) { - fprintf(stderr, "Only DFU specification 0x0100 and 0x011a supported\n"); - help(); - } - - switch(mode) { - case MODE_ADD: - dfu_load_file(&file, NO_SUFFIX, MAYBE_PREFIX); - file.idVendor = vid; - file.idProduct = pid; - file.bcdDevice = did; - file.bcdDFU = spec; - /* always write suffix, rewrite prefix if there was one */ - dfu_store_file(&file, 1, file.size.prefix != 0); - printf("Suffix successfully added to file\n"); - break; - - case MODE_CHECK: - dfu_load_file(&file, NEEDS_SUFFIX, MAYBE_PREFIX); - show_suffix_and_prefix(&file); - break; - - case MODE_DEL: - dfu_load_file(&file, NEEDS_SUFFIX, MAYBE_PREFIX); - dfu_store_file(&file, 0, file.size.prefix != 0); - if (file.size.suffix) /* had a suffix */ - printf("Suffix successfully removed from file\n"); - break; - - default: - help(); - break; - } - return (0); -} diff --git a/linux/src/dfu-util/src/usb_dfu.h b/linux/src/dfu-util/src/usb_dfu.h deleted file mode 100644 index 660bedcbf..000000000 --- a/linux/src/dfu-util/src/usb_dfu.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef USB_DFU_H -#define USB_DFU_H -/* USB Device Firmware Update Implementation for OpenPCD - * (C) 2006 by Harald Welte - * - * Protocol definitions for USB DFU - * - * This ought to be compliant to the USB DFU Spec 1.0 as available from - * http://www.usb.org/developers/devclass_docs/usbdfu10.pdf - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#define USB_DT_DFU 0x21 - -#ifdef _MSC_VER -# pragma pack(push) -# pragma pack(1) -#endif /* _MSC_VER */ -struct usb_dfu_func_descriptor { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bmAttributes; -#define USB_DFU_CAN_DOWNLOAD (1 << 0) -#define USB_DFU_CAN_UPLOAD (1 << 1) -#define USB_DFU_MANIFEST_TOL (1 << 2) -#define USB_DFU_WILL_DETACH (1 << 3) - uint16_t wDetachTimeOut; - uint16_t wTransferSize; - uint16_t bcdDFUVersion; -#ifdef _MSC_VER -}; -# pragma pack(pop) -#elif defined __GNUC__ -} __attribute__ ((packed)); -#else - #warning "No way to pack struct on this compiler? This will break!" -#endif /* _MSC_VER */ - -#define USB_DT_DFU_SIZE 9 - -#define USB_TYPE_DFU (LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE) - -/* DFU class-specific requests (Section 3, DFU Rev 1.1) */ -#define USB_REQ_DFU_DETACH 0x00 -#define USB_REQ_DFU_DNLOAD 0x01 -#define USB_REQ_DFU_UPLOAD 0x02 -#define USB_REQ_DFU_GETSTATUS 0x03 -#define USB_REQ_DFU_CLRSTATUS 0x04 -#define USB_REQ_DFU_GETSTATE 0x05 -#define USB_REQ_DFU_ABORT 0x06 - -/* DFU_GETSTATUS bStatus values (Section 6.1.2, DFU Rev 1.1) */ -#define DFU_STATUS_OK 0x00 -#define DFU_STATUS_errTARGET 0x01 -#define DFU_STATUS_errFILE 0x02 -#define DFU_STATUS_errWRITE 0x03 -#define DFU_STATUS_errERASE 0x04 -#define DFU_STATUS_errCHECK_ERASED 0x05 -#define DFU_STATUS_errPROG 0x06 -#define DFU_STATUS_errVERIFY 0x07 -#define DFU_STATUS_errADDRESS 0x08 -#define DFU_STATUS_errNOTDONE 0x09 -#define DFU_STATUS_errFIRMWARE 0x0a -#define DFU_STATUS_errVENDOR 0x0b -#define DFU_STATUS_errUSBR 0x0c -#define DFU_STATUS_errPOR 0x0d -#define DFU_STATUS_errUNKNOWN 0x0e -#define DFU_STATUS_errSTALLEDPKT 0x0f - -enum dfu_state { - DFU_STATE_appIDLE = 0, - DFU_STATE_appDETACH = 1, - DFU_STATE_dfuIDLE = 2, - DFU_STATE_dfuDNLOAD_SYNC = 3, - DFU_STATE_dfuDNBUSY = 4, - DFU_STATE_dfuDNLOAD_IDLE = 5, - DFU_STATE_dfuMANIFEST_SYNC = 6, - DFU_STATE_dfuMANIFEST = 7, - DFU_STATE_dfuMANIFEST_WAIT_RST = 8, - DFU_STATE_dfuUPLOAD_IDLE = 9, - DFU_STATE_dfuERROR = 10 -}; - -#endif /* USB_DFU_H */ diff --git a/linux/src/dfu-util/www/build.html b/linux/src/dfu-util/www/build.html deleted file mode 100644 index f3036e40c..000000000 --- a/linux/src/dfu-util/www/build.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - Building dfu-util from source - - - - - - - - - -
-

How to build dfu-util from source

- -

Prerequisites for building from git

-

Mac OS X

-

-First install MacPorts (and if you are on 10.6 or older, the Java Developer Package) and then run: -

-
-	sudo port install libusb-devel git-core
-
- -

FreeBSD

-
-	sudo pkg_add -r git pkgconf
-
- -

Ubuntu and Debian and derivatives

-
-	sudo apt-get build-dep dfu-util
-	sudo apt-get install libusb-1.0-0-dev
-
- -

Get the source code and build it

-

-The first time you will have to clone the git repository: -

-
-	git clone git://gitorious.org/dfu-util/dfu-util.git
-	cd dfu-util
-
-

-If you later want to update to latest git version, just run this: -

-
-	make maintainer-clean
-	git pull
-
-

-To build the source: -

-
-	./autogen.sh
-	./configure  # on most systems
-	make
-
- -

-If you are building on Mac OS X, replace the ./configure command with: -

-
-	./configure --libdir=/opt/local/lib --includedir=/opt/local/include  # on MacOSX only
-
- -

-Your dfu-util binary will be inside the src folder. Use it from there, or install it to /usr/local/bin by running "sudo make install". -

- -

Cross-building for Windows

- -

-Windows binaries can be built in a MinGW -environment, on a Windows computer or cross-hosted in another OS. -To build it on a Debian or Ubuntu host, first install build dependencies: -

-
-	sudo apt-get build-dep libusb-1.0-0 dfu-util
-	sudo apt-get install mingw32
-
- -

-The below example builds dfu-util 0.8 and libusb 1.0.19 from unpacked release -tarballs. If you instead build from git, you will have to run "./autogen.sh" -before running the "./configure" steps. -

- -
-mkdir -p build
-cd libusb-1.0.19
-PKG_CONFIG_PATH=$PWD/../build/lib/pkgconfig ./configure \
-    --host=i586-mingw32msvc --prefix=$PWD/../build
-# WINVER workaround needed for 1.0.19 only
-make CFLAGS="-DWINVER=0x0501"
-make install
-cd ..
-
-cd dfu-util-0.8
-PKG_CONFIG_PATH=$PWD/../build/lib/pkgconfig ./configure \
-    --host=i586-mingw32msvc --prefix=$PWD/../build
-make
-make install
-cd ..
-
-The build files will now be in build/bin. -

- -

Building on Windows using MinGW

-This assumes using release tarballs or having run ./autogen.sh on -the git sources. -
-cd libusb-1.0.19
-./configure --prefix=$HOME
-# WINVER workaround needed for 1.0.19 only
-# MKDIR_P setting should not really be needed...
-make CFLAGS="-DWINVER=0x0501" MKDIR_P="mkdir -p"
-make install
-cd ..
-
-cd dfu-util-0.8
-./configure USB_CFLAGS="-I$HOME/include/libusb-1.0" \
-            USB_LIBS="-L $HOME/lib -lusb-1.0" PKG_CONFIG=true
-make
-make install
-cd ..
-
-To link libusb statically into dfu-util.exe use instead of "make": -
-make LDFLAGS=-static
-
-The built executables (and DLL) will now be under $HOME/bin. - -

-[Back to dfu-util main page] -

- -
- - diff --git a/linux/src/dfu-util/www/dfu-util.1.html b/linux/src/dfu-util/www/dfu-util.1.html deleted file mode 100644 index 62ca40b5d..000000000 --- a/linux/src/dfu-util/www/dfu-util.1.html +++ /dev/null @@ -1,411 +0,0 @@ - - -Man page of DFU-UTIL - - -

DFU-UTIL(1)

- -  -

NAME

- -dfu-util - Device firmware update (DFU) USB programmer -  -

SYNOPSIS

- - -
-
-dfu-util - --l - -[-v] - -[-d - -vid:pid[,vid:pid]] - -[-p - -path] - -[-c - -configuration] - -[-i - -interface] - -[-a - -alt-intf] - -[-S - -serial[,serial]] - - -
-dfu-util - -[-v] - -[-d - -vid:pid[,vid:pid]] - -[-p - -path] - -[-c - -configuration] - -[-i - -interface] - -[-a - -alt-intf] - -[-S - -serial[,serial]] - -[-t - -size] - -[-Z - -size] - -[-s - -address] - -[-R] - -[-D|-U - -file] - - -
-dfu-util - -[-hV] - -
-  -

DESCRIPTION

- -dfu-util - -is a program that implements the host (computer) side of the USB DFU -(Universal Serial Bus Device Firmware Upgrade) protocol. -

-dfu-util communicates with devices that implement the device side of the -USB DFU protocol, and is often used to upgrade the firmware of such -devices. -  -

OPTIONS

- -
-
-l, --list - -
-List the currently attached DFU capable USB devices. -
-d, --device [Run-Time VENDOR]:[Run-Time PRODUCT][,[DFU Mode VENDOR]:[DFU Mode PRODUCT]] - -
-
-Specify run-time and/or DFU mode vendor and/or product IDs of the DFU device -to work with. VENDOR and PRODUCT are hexadecimal numbers (no prefix -needed), "*" (match any), or "-" (match nothing). By default, any DFU capable -device in either run-time or DFU mode will be considered. -

-If you only have one standards-compliant DFU device attached to your computer, -this parameter is optional. However, as soon as you have multiple DFU devices -connected, dfu-util will detect this and abort, asking you to specify which -device to use. -

-If only run-time IDs are specified (e.g. "--device 1457:51ab"), then in -addition to the specified run-time IDs, any DFU mode devices will also be -considered. This is beneficial to allow a DFU capable device to be found -again after a switch to DFU mode, since the vendor and/or product ID of a -device usually changes in DFU mode. -

-If only DFU mode IDs are specified (e.g. "--device ,951:26"), then all -run-time devices will be ignored, making it easy to target a specific device in -DFU mode. -

-If both run-time and DFU mode IDs are specified (e.g. "--device -1457:51ab,:2bc"), then unspecified DFU mode components will use the run-time -value specified. -

-Examples: -

-
--device 1457:51ab,951:26 - -
-
- -Work with a device in run-time mode with -vendor ID 0x1457 and product ID 0x51ab, or in DFU mode with vendor ID 0x0951 -and product ID 0x0026 -

-

--device 1457:51ab,:2bc - -
-
- -Work with a device in run-time mode with vendor ID 0x1457 and product ID -0x51ab, or in DFU mode with vendor ID 0x1457 and product ID 0x02bc -

-

--device 1457:51ab - -
-
- -Work with a device in run-time mode with vendor ID 0x1457 and product ID -0x51ab, or in DFU mode with any vendor and product ID -

-

--device ,951:26 - -
-
- -Work with a device in DFU mode with vendor ID 0x0951 and product ID 0x0026 -

-

--device *,- - -
-
- -Work with any device in run-time mode, and ignore any device in DFU mode -

-

--device , - -
-
- -Ignore any device in run-time mode, and Work with any device in DFU mode -
-
- -
-p, --path BUS-PORT. ... .PORT - -
-Specify the path to the DFU device. -
-c, --cfg CONFIG-NR - -
-Specify the configuration of the DFU device. Note that this is only used for matching, the configuration is not set by dfu-util. -
-i, --intf INTF-NR - -
-Specify the DFU interface number. -
-a, --alt ALT - -
-Specify the altsetting of the DFU interface by name or by number. -
-S, --serial [Run-Time SERIAL][,[DFU Mode SERIAL]] - -
-Specify the run-time and DFU mode serial numbers used to further restrict -device matches. If multiple, identical DFU devices are simultaneously -connected to a system then vendor and product ID will be insufficient for -targeting a single device. In this situation, it may be possible to use this -parameter to specify a serial number which also must match. -

-If only a single serial number is specified, then the same serial number is -used in both run-time and DFU mode. An empty serial number will match any -serial number in the corresponding mode. -

-t, --transfer-size SIZE - -
-Specify the number of bytes per USB transfer. The optimal value is -usually determined automatically so this option is rarely useful. If -you need to use this option for a device, please report it as a bug. -
-Z, --upload-size SIZE - -
-Specify the expected upload size, in bytes. -
-U, --upload FILE - -
-Read firmware from device into -FILE. - -
-D, --download FILE - -
-Write firmware from -FILE - -into device. -
-R, --reset - -
-Issue USB reset signalling after upload or download has finished. -
-s, --dfuse-address address - -
-Specify target address for raw binary download/upload on DfuSe devices. Do -not - -use this for downloading DfuSe (.dfu) files. Modifiers can be added -to the address, separated by a colon, to perform special DfuSE commands such -as "leave" DFU mode, "unprotect" and "mass-erase" flash memory. -
-v, --verbose - -
-Print more information about dfu-util's operation. A second --v - -will turn on verbose logging of USB requests. Repeat this option to further -increase verbosity. -
-h, --help - -
-Show a help text and exit. -
-V, --version - -
-Show version information and exit. -
-  -

EXAMPLES

- -  -

Using dfu-util in the OpenMoko project

- -(with the Neo1973 hardware) -

- -Flashing the rootfs: -
- - $ dfu-util -a rootfs -R -D /path/to/openmoko-devel-image.jffs2 - -

- -Flashing the kernel: -
- - $ dfu-util -a kernel -R -D /path/to/uImage - -

- -Flashing the bootloader: -
- - $ dfu-util -a u-boot -R -D /path/to/u-boot.bin - -

- -Copying a kernel into RAM: -
- - $ dfu-util -a 0 -R -D /path/to/uImage - -

-Once this has finished, the kernel will be available at the default load -address of 0x32000000 in Neo1973 RAM. -Note: - -You cannot transfer more than 2MB of data into RAM using this method. -

-  -

Using dfu-util with a DfuSe device

- -

- -Flashing a -.dfu - -(special DfuSe format) file to the device: -
- - $ dfu-util -a 0 -D /path/to/dfuse-image.dfu - -

- -Reading out 1 KB of flash starting at address 0x8000000: -
- - $ dfu-util -a 0 -s 0x08000000:1024 -U newfile.bin - -

- -Flashing a binary file to address 0x8004000 of device memory and -ask the device to leave DFU mode: -
- - $ dfu-util -a 0 -s 0x08004000:leave -D /path/to/image.bin - - -  -

BUGS

- -Please report any bugs to the dfu-util mailing list at -dfu-util@lists.gnumonks.org. - -Please use the ---verbose option (repeated as necessary) to provide more - -information in your bug report. -  -

SEE ALSO

- -The dfu-util home page is -http://dfu-util.gnumonks.org - -  -

HISTORY

- -dfu-util was originally written for the OpenMoko project by -Weston Schmidt <weston_schmidt@yahoo.com> and -Harald Welte <hwelte@hmw-consulting.de>. Over time, nearly complete -support of DFU 1.0, DFU 1.1 and DfuSe ("1.1a") has been added. -  -

LICENCE

- -dfu-util - -is covered by the GNU General Public License (GPL), version 2 or later. -  -

COPYRIGHT

- -This manual page was originally written by Uwe Hermann <uwe@hermann-uwe.de>, -and is now part of the dfu-util project. -

- -


- 

Index

-
-
NAME
-
SYNOPSIS
-
DESCRIPTION
-
OPTIONS
-
EXAMPLES
-
-
Using dfu-util in the OpenMoko project
-
Using dfu-util with a DfuSe device
-
-
BUGS
-
SEE ALSO
-
HISTORY
-
LICENCE
-
COPYRIGHT
-
-
-This document was created by man2html, -using the doc/dfu-util.1 manual page from dfu-util 0.8.
-Time: 14:40:57 GMT, September 13, 2014 - - diff --git a/linux/src/dfu-util/www/dfuse.html b/linux/src/dfu-util/www/dfuse.html deleted file mode 100644 index 35e4ffa9f..000000000 --- a/linux/src/dfu-util/www/dfuse.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - DfuSe and dfu-util - - - - - - - - - -
-

Using dfu-util with DfuSe devices

-

DfuSe

-

- DfuSe (DFU with ST Microsystems extensions) is a protocol based on - DFU 1.1. However, in expanding the functionality of the DFU protocol, - ST Microsystems broke all compatibility with the DFU 1.1 standard. - DfuSe devices report the DFU version as "1.1a". -

-

- DfuSe can be used to download firmware and other data - from a host computer to a conforming device (or upload in the - opposite direction) over USB similar to standard DFU. -

-

- The main difference from standard DFU is that the target address in - the device (flash) memory is specified by the host, so that a - download can be performed to parts of the device memory. The host - program is also responsible for erasing flash pages before they - are written to. -

-

.dfu files

-

- A special file format is defined by ST Microsystems to carry firmware - for DfuSe devices. The file contains target information such as address - and alternate interface information in addition to the binary data. - Several blocks of binary data can be combined in one .dfu file. -

-

Alternate interfaces

-

- Different memory locations of the device may have different - characteristics that the host program (dfu-util) has to take - into considerations, such as flash memory page size, read-only - versus read-write segments, the need to erase, and so on. - These parameters are reported by the device in the string - descriptors meant for describing the USB interfaces. - The host program decodes these strings to build a memory map of - the device. Different memory units or address spaces are listed - in separate alternate interface settings that must be selected - according to the memory unit to access. -

-

- Note that dfu-util leaves it to the user to select alternate - interface. When parsing a .dfu file it will skip file segments - not matching the selected alternate interface. Also, some - DfuSe device firmware implementations ignore the setting of - alternate interface and deduct the memory unit from the - address, since they have no address space overlap. -

-

DfuSe special commands

-

- DfuSe special commands are used by the host program during normal - downloads or uploads, such as SET_ADDRESS and ERASE_PAGE. Also - the normal DFU_DNLOAD and DFU_UPLOAD commands have special - implementations in DfuSe. - Many DfuSe devices also support commands to leave DFU mode, - read unprotect the flash memory or mass erase the flash memory. - dfu-util (from version 0.7) - supports adding "leave", "unprotect", or "mass-erase" - to the -s option argument to send such requests in combination - with a download request. These modifiers are separated with a colon. -

-

- Some DfuSe devices have their DfuSe bootloader running from flash - memory. Erasing the whole flash memory would therefore destroy - the DfuSe bootloader itself and practically brick the device - for most users. Any use of modifiers such as "unprotect" - and "mass-erase" therefore needs to be combined with the "force" - modifer. This is not included in the examples, to not encourage - ignorant users to copy and paste such instructions and shoot - themselves in the foot. -

-

- Devices based on for instance STM32F103 all run the bootloader - from flash, since there is no USB bootloader in ROM. -

-

- For instance STM32F107, STM32F2xx and STM32F4xx devices have a - DfuSe bootloader in ROM, so the flash can be erased while - keeping the device available for USB DFU transfers as long - as the device designers use this built-in bootloader and have - not implemented another DfuSe bootloader in flash that the user is - dependent upon. -

-

- Well-written bootloaders running from flash will report their - own memory region as read-only and not eraseable, but this does - not prevent dfu-util from sending a "unprotect" or "mass-erase" - request which overrides this, if the user insists. -

-

Example usage

-

- Flashing a .dfu (special DfuSe format) file to the device: -

-
-         $ dfu-util -a 0 -D /path/to/dfuse-image.dfu
-	
-

- Reading out 1 KB of flash starting at address 0x8000000: -

-
-         $ dfu-util -a 0 -s 0x08000000:1024 -U newfile.bin
-	
-

- Flashing a binary file to address 0x8004000 of device memory and ask - the device to leave DFU mode: -

-
-         $ dfu-util -a 0 -s 0x08004000:leave -D /path/to/image.bin
-	
-

- [Back to dfu-util main page] -

- -
- - diff --git a/linux/src/dfu-util/www/index.html b/linux/src/dfu-util/www/index.html deleted file mode 100644 index 108ddaf66..000000000 --- a/linux/src/dfu-util/www/index.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - dfu-util Homepage - - - - - - - - - -
-

dfu-util - Device Firmware Upgrade Utilities

-

Description

-

- dfu-util is a host side implementation of the DFU 1.0 and DFU 1.1 specifications of the USB forum. - - DFU is intended to download and upload firmware to/from devices connected - over USB. It ranges from small devices like micro-controller boards - to mobile phones. Using dfu-util you can download firmware to your - DFU-enabled device or upload firmware from it. dfu-util has been - tested with the Openmoko Neo1973 and Freerunner and many other devices. -

-

- See the manual page for examples of use. -

-

Supported Devices

- -

Releases

-

- Releases of the dfu-util software can be found in the - releases folder. - The current release is 0.8. -

-

- We offer binaries for Microsoft Windows and some other platforms. - dfu-util uses libusb 1.0 to access your device, so - on Windows you have to register the device with the WinUSB driver - (alternatively libusb-win32 or libusbK), please see the libusbx wiki - for more details. -

-

- Mac OS X users can also get dfu-util from Homebrew with "brew install dfu-util" or from MacPorts. -

-

- Most Linux distributions ship dfu-util in binary packages for those - who do not want to compile dfu-util from source. - On Debian, Ubuntu, Fedora and Gentoo you can install it through the - normal software package tools. For other distributions -(namely OpenSuSe, Mandriva, and CentOS) Holger Freyther was kind enough to -provide binary packages through the Open Build Service. -

-

Development

-

- Development happens in a GIT repository. Browse it via the web -interface or clone it with: -

-
-	git clone git://gitorious.org/dfu-util/dfu-util.git
-	
-

- See our build instructions for how to - build the source on different platforms. -

-

License

-

- This software is licensed under the GPL version 2. -

-

Contact

-

- If you have questions about the development or use of dfu-util please - send an e-mail to our dedicated -mailing list for dfu-util. -

-

People

-

- dfu-util was originally written by - Harald Welte partially based on code from - dfu-programmer 0.4 and is currently maintained by Stefan Schmidt and - Tormod Volden. -

- -
- - diff --git a/linux/src/dfu-util/www/simple.css b/linux/src/dfu-util/www/simple.css deleted file mode 100644 index 98100bc5c..000000000 --- a/linux/src/dfu-util/www/simple.css +++ /dev/null @@ -1,56 +0,0 @@ -body { - margin: 10px; - font-size: 0.82em; - background-color: #EEE; -} - -h1 { - clear: both; - padding: 0 0 12px 0; - margin: 0; - font-size: 2em; - font-weight: bold; -} - -h2 { - clear: both; - margin: 0; - font-size: 1.5em; - font-weight: normal; -} - -h3 { - clear: both; - margin: 15px 0 0 0; - font-size: 1.0em; - font-weight: bold; -} - -p { - line-height: 20px; - padding: 8px 0 8px 0; - margin: 0; - font-size: 1.1em; -} - -pre { - white-space: pre-wrap; - background-color: #CCC; - padding: 3px; -} - -a:hover { - background-color: #DDD; -} - -#middlebox { - width: 600px; - margin: 0px auto; - text-align: left; -} - -#footer { - height: 100px; - padding: 28px 3px 0 0; - margin: 20px 0 20px 0; -} diff --git a/linux/upload-reset b/linux/upload_reset similarity index 100% rename from linux/upload-reset rename to linux/upload_reset diff --git a/macosx/dfu-util.sh b/macosx/dfu-util.sh deleted file mode 100644 index 77bd42617..000000000 --- a/macosx/dfu-util.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# Get the directory where the script is running. -DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -DFU_UTIL=${DIR}/dfu-util/dfu-util -if [ ! -x "${DFU_UTIL}" ]; then - DFU_UTIL=/opt/local/bin/dfu-util -fi - -# Not found! -if [ ! -x "${DFU_UTIL}" ]; then - echo "$0: error: cannot find ${DFU_UTIL}" >&2 - exit 2 -fi - -# Pass all parameters through -"${DFU_UTIL}" "$@" diff --git a/macosx/maple_upload.sh b/macosx/maple_upload.sh deleted file mode 100755 index 37d21ce20..000000000 --- a/macosx/maple_upload.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash - -set -e - -if [ $# -lt 4 ]; then - echo "Usage: $0 $# " >&2 - exit 1 -fi -altID="$2" -usbID="$3" -binfile="$4" -dummy_port_fullpath="/dev/$1" -if [ $# -eq 5 ]; then - dfuse_addr="--dfuse-address $5" -else - dfuse_addr="" -fi - -# Get the directory where the script is running. -DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - -# ----------------- IMPORTANT ----------------- -# The 2nd parameter to upload-reset is the delay after resetting before it exits -# This value is in milliseonds -# You may need to tune this to your system -# 750ms to 1500ms seems to work on my Mac -# This is less critical now that we automatically retry dfu-util - -if ! "${DIR}/upload-reset" "${dummy_port_fullpath}" 750; then - echo "****************************************" >&2 - echo "* Could not automatically reset device *" >&2 - echo "* Please manually reset device! *" >&2 - echo "****************************************" >&2 - sleep 2 # Wait for user to see message. -fi - -COUNTER=5 -while - "${DIR}/dfu-util.sh" -d "${usbID}" -a "${altID}" -D "${binfile}" "${dfuse_addr}" -R - ((ret = $?)) -do - if [ $ret -eq 74 ] && [ $((--COUNTER)) -gt 0 ]; then - # I/O error, probably because no DFU device was found - echo "Trying ${COUNTER} more time(s)" >&2 - sleep 1 - else - exit $ret - fi -done - -echo -n "Waiting for ${dummy_port_fullpath} serial..." >&2 - -COUNTER=40 -while [ ! -r "${dummy_port_fullpath}" ] && ((COUNTER--)); do - echo -n "." >&2 - sleep 0.1 -done - -if [ $COUNTER -eq -1 ]; then - echo " Timed out." >&2 - exit 1 -else - echo " Done." >&2 -fi diff --git a/macosx/src/build_dfu-util.sh b/macosx/src/build_dfu-util.sh deleted file mode 100644 index 3563f576c..000000000 --- a/macosx/src/build_dfu-util.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -sudo apt-get build-dep dfu-util -sudo apt-get install build-essentials -sudo apt-get install libusb-1.0-0-dev -sudo apt-get install autoconf automake autotools-dev - -cd dfu-util -./autogen.sh -./configure -make -cp src/dfu-util ../../linux/dfu-util -cp src/dfu-suffix ../../linux/dfu-util -cp src/dfu-prefix ../../linux/dfu-util - diff --git a/macosx/src/dfu-util/AUTHORS b/macosx/src/dfu-util/AUTHORS deleted file mode 100644 index 1b36c739c..000000000 --- a/macosx/src/dfu-util/AUTHORS +++ /dev/null @@ -1,30 +0,0 @@ -Authors ordered by first contribution. - -Harald Welte -Werner Almesberger -Michael Lauer -Jim Huang -Stefan Schmidt -Daniel Willmann -Mike Frysinger -Uwe Hermann -C. Scott Ananian -Bernard Blackham -Holger Freyther -Marc Singer -James Perkins -Tommi Keisala -Pascal Schweizer -Bradley Scott -Uwe Bonnes -Andrey Smirnov -Jussi Timperi -Hans Petter Selasky -Bo Shen -Henrique de Almeida Mendonca -Bernd Krumboeck -Dennis Meier -Veli-Pekka Peltola -Dave Hylands -Michael Grzeschik -Paul Fertser diff --git a/macosx/src/dfu-util/COPYING b/macosx/src/dfu-util/COPYING deleted file mode 100644 index d60c31a97..000000000 --- a/macosx/src/dfu-util/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/macosx/src/dfu-util/ChangeLog b/macosx/src/dfu-util/ChangeLog deleted file mode 100644 index 37f1addba..000000000 --- a/macosx/src/dfu-util/ChangeLog +++ /dev/null @@ -1,93 +0,0 @@ -0.8: - o New, separate dfu-prefix tool (Uwe Bonnes) - o Allow filtering on serial number (Uwe Bonnes) - o Improved VID/PID/serial filtering (Bradley Scott) - o Support reading firmware from stdin (Tormod Volden) - o Warn if missing DFU suffix (Tormod Volden) - o Improved progress bar (Hans Petter Selasky) - o Fix dfuse leave option (Uwe Bonnes) - o Major code rework (Hans Petter Selasky) - o MS Visual Studio build support (Henrique Mendonca) - o dfuse-pack.py tool for .dfu files (Antonio Galeo) - o Many other fixes from many people - -2014-09-13: Tormod Volden - -0.7: - o Support for TI Stellaris devices (Tommi Keisala) - o Fix libusb detection on MacOSX (Marc Singer) - o Fix libusb detection on FreeBSD (Tormod Volden) - o Improved DfuSe support (Tormod Volden) - o Support all special commands (leave, unprotect, mass-erase) - o Arbitrary upload lengths - o "force" option for various possible (dangerous) overrides - -2012-10-07: Tormod Volden - -0.6: - o Add detach mode (Stefan Schmidt) - o Check return value on all libusb calls (Tormod Volden) - o Fix segmentation fault with -s option (Tormod Volden) - o Add DFU suffix manipulation tool (Stefan Schmidt) - o Port to Windows: (Tormod Volden, some parts based on work from Satz - Klauer) - o Port file handling to stdio streams - o Sleep() macros - o C99 types - o Pack structs - o Detect DfuSe device correctly on big-endian architectures (Tormod - Volden) - o Add dfuse progress indication on download (Tormod Volden) - o Cleanup: gcc pedantic, gcc extension, ... (Tormod Volden) - o Rely on page size from functional descriptor. Please report if you get - an error about it. (Tormod Volden) - o Add quirk for Maple since it reports wrong DFU version (Tormod Volden) - -2012-04-22: Stefan Schmidt - -0.5: - o DfuSe extension support for ST devices (Tormod Volden) - o Add initial support for bitWillDetach flag from DFU 1.1 (Tormod - Volden) - o Internal cleanup and some manual page fixes (Tormod Volden) - -2011-11-02: Stefan Schmidt - -0.4: - o Rework to use libusb-1.0 (Stefan Schmidt) - o DFU suffix support (Tormod Volden, Stefan Schmidt) - o Sspeed up DFU downloads directly into memory (Bernard Blackham) - o More flexible -d vid:pid parsing (Tormod Volden) - o Many bug fixes and cleanups - -2011-07-20: Stefan Schmidt - -0.3: - o quirks: Add OpenOCD to the poll timeout quirk table. - -2010-12-22: Stefan Schmidt - -0.2: - o Fix some typos on the website and the README (Antonio Ospite, Uwe - Hermann) - o Remove build rule for a static binary. We can use autotools for this. - (Mike Frysinger) - o Fix infinite loop in download error path (C. Scott Ananian) - o Break out to show the 'finished' in upload (C. Scott Ananian) - o Add GPLv2+ headers (Harald Welte) - o Remove dead code (commands.[ch]) remnescent of dfu-programmer (Harald - Welte) - o Simple quirk system with Openmoko quirk for missing bwPollTimeout (Tormod Volden) - o New default (1024) and clamping of transfer size (Tormod Volden) - o Verify sending of completion packet (Tormod Volden) - o Look for DFU functional descriptor among all descriptors (Tormod - Volden) - o Print out in which direction we are transferring data - o Abort in upload if the file already exists - -2010-11-17 Stefan Schmidt - -0.1: - Initial release - -2010-05-23 Stefan Schmidt diff --git a/macosx/src/dfu-util/DEVICES.txt b/macosx/src/dfu-util/DEVICES.txt deleted file mode 100644 index bdd9f1f2e..000000000 --- a/macosx/src/dfu-util/DEVICES.txt +++ /dev/null @@ -1,20 +0,0 @@ -List of supported software and hardware products: - -Software user (bootloader, etc) -------------------------------- -- Sam7DFU: http://www.openpcd.org/Sam7dfu -- U-boot: DFU patches -- Barebox: http://www.barebox.org/ -- Leaflabs: http://code.google.com/p/leaflabs/ -- Blackmagic DFU - -Products using DFU ------------------- -- OpenPCD (sam7dfu) -- Openmoko Neo 1973 and Freerunner (u-boot with DFU patches) -- Leaflabs Maple -- ATUSB from Qi Hardware -- STM32F105/7, STM32F2/F3/F4 in System Bootloader -- Blackmagic debug probe -- NXP LPC31xx/LPC43XX, e.g. LPC-Link and LPC-Link2, need binaries - with LPC prefix and encoding (LPC-Link) diff --git a/macosx/src/dfu-util/Makefile.am b/macosx/src/dfu-util/Makefile.am deleted file mode 100644 index 641dda58a..000000000 --- a/macosx/src/dfu-util/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = src doc - -EXTRA_DIST = autogen.sh TODO DEVICES.txt dfuse-pack.py diff --git a/macosx/src/dfu-util/README b/macosx/src/dfu-util/README deleted file mode 100644 index 0f8f2621a..000000000 --- a/macosx/src/dfu-util/README +++ /dev/null @@ -1,20 +0,0 @@ -Dfu-util - Device Firmware Upgrade Utilities - -Dfu-util is the host side implementation of the DFU 1.0 [1] and DFU 1.1 [2] -specification of the USB forum. - -DFU is intended to download and upload firmware to devices connected over -USB. It ranges from small devices like micro-controller boards up to mobile -phones. With dfu-util you are able to download firmware to your device or -upload firmware from it. - -dfu-util has been tested with Openmoko Neo1973 and Freerunner and many -other devices. - -[1] DFU 1.0 spec: http://www.usb.org/developers/devclass_docs/usbdfu10.pdf -[2] DFU 1.1 spec: http://www.usb.org/developers/devclass_docs/DFU_1.1.pdf - -The official website is: - - http://dfu-util.gnumonks.org/ - diff --git a/macosx/src/dfu-util/TODO b/macosx/src/dfu-util/TODO deleted file mode 100644 index 900c30c29..000000000 --- a/macosx/src/dfu-util/TODO +++ /dev/null @@ -1,14 +0,0 @@ -DfuSe: -- Do erase and write in two separate passes when downloading -- Skip "Set Address" command when downloading contiguous blocks -- Implement "Get Commands" command - -Devices: -- Research iPhone/iPod/iPad support - Heavily modified dfu-util fork here: - https://github.com/planetbeing/xpwn/tree/master/dfu-util -- Test against Niftylights - -Non-Code: -- Logo -- Re-License as LGPL for usage as library? diff --git a/macosx/src/dfu-util/autogen.sh b/macosx/src/dfu-util/autogen.sh deleted file mode 100644 index e67aed39a..000000000 --- a/macosx/src/dfu-util/autogen.sh +++ /dev/null @@ -1,2 +0,0 @@ -#! /bin/sh -autoreconf -v -i diff --git a/macosx/src/dfu-util/configure.ac b/macosx/src/dfu-util/configure.ac deleted file mode 100644 index 86221143f..000000000 --- a/macosx/src/dfu-util/configure.ac +++ /dev/null @@ -1,41 +0,0 @@ -# -*- Autoconf -*- -# Process this file with autoconf to produce a configure script. - -AC_PREREQ(2.59) -AC_INIT([dfu-util],[0.8],[dfu-util@lists.gnumonks.org],,[http://dfu-util.gnumonks.org]) -AC_CONFIG_AUX_DIR(m4) -AM_INIT_AUTOMAKE([foreign]) -AC_CONFIG_HEADERS([config.h]) - -# Test for new silent rules and enable only if they are available -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) - -# Checks for programs. -AC_PROG_CC - -# Checks for libraries. -# On FreeBSD the libusb-1.0 is called libusb and resides in system location -AC_CHECK_LIB([usb], [libusb_init],, [native_libusb=no],) -AS_IF([test x$native_libusb = xno], [ - PKG_CHECK_MODULES([USB], [libusb-1.0 >= 1.0.0],, - AC_MSG_ERROR([*** Required libusb-1.0 >= 1.0.0 not installed ***])) -]) -AC_CHECK_LIB([usbpath],[usb_path2devnum],,,-lusb) - -LIBS="$LIBS $USB_LIBS" -CFLAGS="$CFLAGS $USB_CFLAGS" - -# Checks for header files. -AC_HEADER_STDC -AC_CHECK_HEADERS([usbpath.h windows.h sysexits.h]) - -# Checks for typedefs, structures, and compiler characteristics. -AC_C_CONST -AC_TYPE_SIZE_T - -# Checks for library functions. -AC_FUNC_MEMCMP -AC_CHECK_FUNCS([ftruncate getpagesize nanosleep err]) - -AC_CONFIG_FILES(Makefile src/Makefile doc/Makefile) -AC_OUTPUT diff --git a/macosx/src/dfu-util/device-logs/README b/macosx/src/dfu-util/device-logs/README deleted file mode 100644 index 00d3d1a96..000000000 --- a/macosx/src/dfu-util/device-logs/README +++ /dev/null @@ -1,77 +0,0 @@ -Device: -------- -qi-hardware-atusb: -- Qi Hardware ben-wpan -- DFU implementation: - http://projects.qi-hardware.com/index.php/p/ben-wpan/source/tree/master/atusb/fw/usb -- Tester: Stefan Schmidt - -openpcd: -- OpenPCD RFID reader -- DFU implementation: SAM7DFU - http://www.openpcd.org/Sam7dfu, git://git.gnumonks.org/openpcd.git -- Tester: Stefan Schmidt - -simtrace: -- Sysmocom SimTrace -- DFU implementation: SAM7DFU - http://www.openpcd.org/Sam7dfu, git://git.gnumonks.org/openpcd.git -- Tester: Stefan Schmidt - -openmoko-freerunner: -- Openmoko Freerunner -- DFU implementation: Old U-Boot - http://git.openmoko.org/?p=u-boot.git;a=shortlog;h=refs/heads/mokopatches -- Tester: Stefan Schmidt - -openmoko-neo1973: -- Openmoko Neo1073 -- DFU implementation: Old U-Boot - http://git.openmoko.org/?p=u-boot.git;a=shortlog;h=refs/heads/mokopatches -- Tester: Stefan Schmidt - -tdk-bluetooth: -- TDK Corp. Bluetooth Adapter -- DFU implementation: closed soure -- Only upload has been tested -- Tester: Stefan Schmidt - -stm32f107: -- STM32 microcontrollers with built-in (ROM) DFU loader -- DFU implementation: Closed source but probably similar to the one - in their USB device libraries. Some relevant application notes: - http://www.st.com -> AN3156 and AN2606 -- Tested by Uwe Bonnes - -stm32f4discovery: -- STM32 microcontroller board with built-in (ROM) DFU loader -- DFU implementation: Closed source, probably similar to stm32f107. -- Tested by Joe Rothweiler - -dso-nano: -- DSO Nano pocket oscilloscope -- DFU implementation: Based on ST Microelectronics USB FS Library 1.0 - http://dsonano.googlecode.com/files/DS0201_OpenSource.rar -- Tester: Tormod Volden - -opc-20: -- Custom devices based on STM32F1xx -- DFU implementation: ST Microelectronics USB FS Device Library 3.1.0 - http://www.st.com -> um0424.zip -- Tester: Tormod Volden - -lpc-link, lpclink2: -- NXP LPCXpresso debug adapters -- Proprietary DFU implementation, uses special download files with - LPC prefix and encoding of the target firmware code -- Tested by Uwe Bonnes - -Adding the lsusb output and a download log of your device here helps -us to avoid regressions for hardware we cannot test while working on -the code. To extract the lsusb output use this command: -sudo lsusb -v -d $USBID > $DEVICE.lsusb -Prepare a description snippet as above, and send it to us. A log -(copy-paste of the command window) of a firmware download is also -nice, please use the double verbose option -v -v and include the -command line in the log file. - diff --git a/macosx/src/dfu-util/device-logs/dsonano.lsusb b/macosx/src/dfu-util/device-logs/dsonano.lsusb deleted file mode 100644 index 140a7bc6c..000000000 --- a/macosx/src/dfu-util/device-logs/dsonano.lsusb +++ /dev/null @@ -1,60 +0,0 @@ - -Bus 002 Device 004: ID 0483:df11 SGS Thomson Microelectronics -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x0483 SGS Thomson Microelectronics - idProduct 0xdf11 - bcdDevice 1.1a - iManufacturer 1 STMicroelectronics - iProduct 2 STM32 DFU - iSerial 3 001 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 36 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0x80 - (Bus Powered) - MaxPower 64mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 0 - iInterface 4 @Internal Flash /0x08000000/12*001Ka,116*001Kg - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 1 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 0 - iInterface 5 @SPI Flash : M25P64/0x00000000/64*064Kg,64*064Kg - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 11 - Will Detach - Manifestation Intolerant - Upload Supported - Download Supported - wDetachTimeout 255 milliseconds - wTransferSize 1024 bytes - bcdDFUVersion 1.1a -Device Status: 0x0000 - (Bus Powered) diff --git a/macosx/src/dfu-util/device-logs/lpclink.log b/macosx/src/dfu-util/device-logs/lpclink.log deleted file mode 100644 index 7de4dd3e6..000000000 --- a/macosx/src/dfu-util/device-logs/lpclink.log +++ /dev/null @@ -1,59 +0,0 @@ -(The on-board LPC3154 has some encryption key set and LPCXpressoWIN.enc -is encrypted.) - -$ lsusb | grep NXP -Bus 003 Device 011: ID 0471:df55 Philips (or NXP) LPCXpresso LPC-Link - -$ dfu-util -v -v -v -R -D /opt/lpc/lpcxpresso/bin/LPCXpressoWIN.enc - -dfu-util 0.7 - -Copyright 2005-2008 Weston Schmidt, Harald Welte and OpenMoko Inc. -Copyright 2010-2012 Tormod Volden and Stefan Schmidt -This program is Free Software and has ABSOLUTELY NO WARRANTY -Please report bugs to dfu-util@lists.gnumonks.org - -dfu-util: Invalid DFU suffix signature -dfu-util: A valid DFU suffix will be required in a future dfu-util release!!! -Deducing device DFU version from functional descriptor length -Opening DFU capable USB device... -ID 0471:df55 -Run-time device DFU version 0100 -Claiming USB DFU Runtime Interface... -Determining device status: -state = dfuIDLE, status = 0 -dfu-util: WARNING: Runtime device already in DFU state ?!? -Claiming USB DFU Interface... -Setting Alternate Setting #0 ... -Determining device status: -state = dfuIDLE, status = 0 -dfuIDLE, continuing -DFU mode device DFU version 0100 -Device returned transfer size 2048 -Copying data from PC to DFU device -Download [ ] 0% 0 bytes -Download [= ] 6% 2048 bytes -Download [=== ] 13% 4096 bytes -Download [==== ] 19% 6144 bytes -Download [====== ] 26% 8192 bytes -Download [======== ] 32% 10240 bytes -Download [========= ] 39% 12288 bytes -Download [=========== ] 45% 14336 bytes -Download [============= ] 52% 16384 bytes -Download [============== ] 59% 18432 bytes -Download [================ ] 65% 20480 bytes -Download [================== ] 72% 22528 bytes -Download [=================== ] 78% 24576 bytes -Download [===================== ] 85% 26624 bytes -Download [====================== ] 91% 28672 bytes -Download [======================== ] 98% 29192 bytes -Download [=========================] 100% 29192 bytes -Download done. -Sent a total of 29192 bytes -state(8) = dfuMANIFEST-WAIT-RESET, status(0) = No error condition is present -Done! -dfu-util: can't detach -Resetting USB to switch back to runtime mode - -$ lsusb | grep NXP -Bus 003 Device 012: ID 1fc9:0009 NXP Semiconductors diff --git a/macosx/src/dfu-util/device-logs/lpclink.lsusb b/macosx/src/dfu-util/device-logs/lpclink.lsusb deleted file mode 100644 index 867b2a2c5..000000000 --- a/macosx/src/dfu-util/device-logs/lpclink.lsusb +++ /dev/null @@ -1,58 +0,0 @@ - -Bus 003 Device 008: ID 0471:df55 Philips (or NXP) LPCXpresso LPC-Link -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 2.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x0471 Philips (or NXP) - idProduct 0xdf55 LPCXpresso LPC-Link - bcdDevice 0.01 - iManufacturer 0 - iProduct 0 - iSerial 0 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 25 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0x80 - (Bus Powered) - MaxPower 100mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 0 - iInterface 0 - Device Firmware Upgrade Interface Descriptor: - bLength 7 - bDescriptorType 33 - bmAttributes 1 - Will Not Detach - Manifestation Intolerant - Upload Unsupported - Download Supported - wDetachTimeout 65535 milliseconds - wTransferSize 2048 bytes -Device Qualifier (for other device speed): - bLength 10 - bDescriptorType 6 - bcdUSB 2.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - bNumConfigurations 1 -Device Status: 0x0000 - (Bus Powered) diff --git a/macosx/src/dfu-util/device-logs/lpclink2.log b/macosx/src/dfu-util/device-logs/lpclink2.log deleted file mode 100644 index 4681eff7d..000000000 --- a/macosx/src/dfu-util/device-logs/lpclink2.log +++ /dev/null @@ -1,59 +0,0 @@ -$ lsusb | grep NXP -Bus 003 Device 013: ID 1fc9:000c NXP Semiconductors - -$ dfu-util -D ~/devel/dfu-util/firmware.bin.qthdr - -dfu-util 0.7 - -Copyright 2005-2008 Weston Schmidt, Harald Welte and OpenMoko Inc. -Copyright 2010-2012 Tormod Volden and Stefan Schmidt -This program is Free Software and has ABSOLUTELY NO WARRANTY -Please report bugs to dfu-util@lists.gnumonks.org - -dfu-util: Invalid DFU suffix signature -dfu-util: A valid DFU suffix will be required in a future dfu-util release!!! -Possible unencryptes NXP LPC DFU prefix with the following properties -Payload length: 39 kiByte -Opening DFU capable USB device... -ID 1fc9:000c -Run-time device DFU version 0100 -Claiming USB DFU Runtime Interface... -Determining device status: -state = dfuIDLE, status = 0 -dfu-util: WARNING: Runtime device already in DFU state ?!? -Claiming USB DFU Interface... -Setting Alternate Setting #0 ... -Determining device status: -state = dfuIDLE, status = 0 -dfuIDLE, continuing -DFU mode device DFU version 0100 -Device returned transfer size 2048 -Copying data from PC to DFU device -Download [ ] 0% 0 bytes -Download [= ] 4% 2048 bytes -Download [== ] 9% 4096 bytes -Download [=== ] 14% 6144 bytes -Download [==== ] 19% 8192 bytes -Download [====== ] 24% 10240 bytes -Download [======= ] 28% 12288 bytes -Download [======== ] 33% 14336 bytes -Download [========= ] 38% 16384 bytes -Download [========== ] 43% 18432 bytes -Download [============ ] 48% 20480 bytes -Download [============= ] 53% 22528 bytes -Download [============== ] 57% 24576 bytes -Download [=============== ] 62% 26624 bytes -Download [================ ] 67% 28672 bytes -Download [================== ] 72% 30720 bytes -Download [=================== ] 77% 32768 bytes -Download [==================== ] 82% 34816 bytes -Download [===================== ] 86% 36864 bytes -Download [====================== ] 91% 38912 bytes -Download [======================== ] 96% 40356 bytes -Download [=========================] 100% 40356 bytes -Download done. -Sent a total of 40356 bytes -dfu-util: unable to read DFU status - -$ lsusb | grep NXP -Bus 003 Device 014: ID 1fc9:0018 NXP Semiconductors diff --git a/macosx/src/dfu-util/device-logs/lpclink2.lsusb b/macosx/src/dfu-util/device-logs/lpclink2.lsusb deleted file mode 100644 index b833fca77..000000000 --- a/macosx/src/dfu-util/device-logs/lpclink2.lsusb +++ /dev/null @@ -1,203 +0,0 @@ - -Bus 003 Device 007: ID 0c72:000c PEAK System PCAN-USB -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 16 - idVendor 0x0c72 PEAK System - idProduct 0x000c PCAN-USB - bcdDevice 1c.ff - iManufacturer 0 - iProduct 3 VER1:PEAK -VER2:02.8.01 -DAT :06.05.2004 -TIME:09:35:37 - ... - iSerial 0 - bNumConfigurations 3 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 46 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0x80 - (Bus Powered) - MaxPower 200mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 4 - bInterfaceClass 0 (Defined at Interface level) - bInterfaceSubClass 0 - bInterfaceProtocol 0 - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 20 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x01 EP 1 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 20 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x82 EP 2 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x02 EP 2 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 46 - bNumInterfaces 1 - bConfigurationValue 2 - iConfiguration 0 - bmAttributes 0x80 - (Bus Powered) - MaxPower 394mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 4 - bInterfaceClass 0 (Defined at Interface level) - bInterfaceSubClass 0 - bInterfaceProtocol 0 - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 20 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x01 EP 1 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 20 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x82 EP 2 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x02 EP 2 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 46 - bNumInterfaces 1 - bConfigurationValue 3 - iConfiguration 0 - bmAttributes 0x80 - (Bus Powered) - MaxPower 200mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 4 - bInterfaceClass 0 (Defined at Interface level) - bInterfaceSubClass 0 - bInterfaceProtocol 0 - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 3 - Transfer Type Interrupt - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x01 EP 1 OUT - bmAttributes 3 - Transfer Type Interrupt - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x82 EP 2 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x02 EP 2 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 1 -Device Status: 0x0001 - Self Powered diff --git a/macosx/src/dfu-util/device-logs/opc-20.lsusb b/macosx/src/dfu-util/device-logs/opc-20.lsusb deleted file mode 100644 index 580df90e5..000000000 --- a/macosx/src/dfu-util/device-logs/opc-20.lsusb +++ /dev/null @@ -1,60 +0,0 @@ - -Bus 001 Device 004: ID 0483:df11 SGS Thomson Microelectronics -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x0483 SGS Thomson Microelectronics - idProduct 0xdf11 - bcdDevice 2.00 - iManufacturer 1 STMicroelectronics - iProduct 2 STM32 DFU - iSerial 3 ������������ - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 36 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0xc0 - Self Powered - MaxPower 100mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 4 @Internal Flash /0x08000000/12*001Ka,116*001Kg - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 1 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 5 @SPI Flash : M25P64/0x00000000/128*64Kg - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 11 - Will Detach - Manifestation Intolerant - Upload Supported - Download Supported - wDetachTimeout 255 milliseconds - wTransferSize 1024 bytes - bcdDFUVersion 1a.01 -Device Status: 0x0001 - Self Powered diff --git a/macosx/src/dfu-util/device-logs/openmoko-freerunner-dfumode.lsusb b/macosx/src/dfu-util/device-logs/openmoko-freerunner-dfumode.lsusb deleted file mode 100644 index 4c0abfb06..000000000 --- a/macosx/src/dfu-util/device-logs/openmoko-freerunner-dfumode.lsusb +++ /dev/null @@ -1,109 +0,0 @@ -Bus 003 Device 017: ID 1d50:5119 OpenMoko, Inc. GTA01/GTA02 U-Boot Bootloader -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 16 - idVendor 0x1d50 OpenMoko, Inc. - idProduct 0x5119 GTA01/GTA02 U-Boot Bootloader - bcdDevice 0.00 - iManufacturer 1 OpenMoko, Inc - iProduct 2 Neo1973 Bootloader U-Boot 1.3.2-moko12 - iSerial 3 0000000 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 81 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 7 USB Device Firmware Upgrade - bmAttributes 0x80 - (Bus Powered) - MaxPower 100mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 8 RAM 0x32000000 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 1 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 9 u-boot - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 2 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 10 u-boot_env - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 3 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 11 kernel - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 4 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 12 splash - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 5 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 13 factory - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 6 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 14 rootfs - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 7 - Will Not Detach - Manifestation Tolerant - Upload Supported - Download Supported - wDetachTimeout 65280 milliseconds - wTransferSize 4096 bytes - bcdDFUVersion 1.00 -Device Status: 0x0a00 - (Bus Powered) diff --git a/macosx/src/dfu-util/device-logs/openmoko-freerunner.lsusb b/macosx/src/dfu-util/device-logs/openmoko-freerunner.lsusb deleted file mode 100644 index 835708dd8..000000000 --- a/macosx/src/dfu-util/device-logs/openmoko-freerunner.lsusb +++ /dev/null @@ -1,179 +0,0 @@ -Bus 005 Device 033: ID 1d50:5119 OpenMoko, Inc. GTA01/GTA02 U-Boot Bootloader -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.10 - bDeviceClass 2 Communications - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 16 - idVendor 0x1d50 OpenMoko, Inc. - idProduct 0x5119 GTA01/GTA02 U-Boot Bootloader - bcdDevice 0.00 - iManufacturer 1 OpenMoko, Inc - iProduct 2 Neo1973 Bootloader U-Boot 1.3.2-moko12 - iSerial 3 0000000 - bNumConfigurations 2 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 85 - bNumInterfaces 3 - bConfigurationValue 1 - iConfiguration 4 TTY via USB - bmAttributes 0x80 - (Bus Powered) - MaxPower 500mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 1 - bInterfaceClass 2 Communications - bInterfaceSubClass 2 Abstract (modem) - bInterfaceProtocol 1 AT-commands (v.25ter) - iInterface 6 Control Interface - CDC Header: - bcdCDC 0.6e - CDC Call Management: - bmCapabilities 0x00 - bDataInterface 1 - CDC ACM: - bmCapabilities 0x00 - CDC Union: - bMasterInterface 0 - bSlaveInterface 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 3 - Transfer Type Interrupt - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 0 - bNumEndpoints 2 - bInterfaceClass 10 CDC Data - bInterfaceSubClass 0 Unused - bInterfaceProtocol 0 - iInterface 5 Bulk Data Interface - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x02 EP 2 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 2 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 1 - iInterface 7 USB Device Firmware Upgrade - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 7 - Will Not Detach - Manifestation Tolerant - Upload Supported - Download Supported - wDetachTimeout 65280 milliseconds - wTransferSize 4096 bytes - bcdDFUVersion 1.00 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 67 - bNumInterfaces 2 - bConfigurationValue 2 - iConfiguration 4 TTY via USB - bmAttributes 0x80 - (Bus Powered) - MaxPower 100mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 1 - bInterfaceClass 2 Communications - bInterfaceSubClass 2 Abstract (modem) - bInterfaceProtocol 1 AT-commands (v.25ter) - iInterface 6 Control Interface - CDC Header: - bcdCDC 0.6e - CDC Call Management: - bmCapabilities 0x00 - bDataInterface 1 - CDC ACM: - bmCapabilities 0x00 - CDC Union: - bMasterInterface 0 - bSlaveInterface 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 3 - Transfer Type Interrupt - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 0 - bNumEndpoints 2 - bInterfaceClass 10 CDC Data - bInterfaceSubClass 0 Unused - bInterfaceProtocol 0 - iInterface 5 Bulk Data Interface - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x02 EP 2 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 -Device Status: 0x9a00 - (Bus Powered) diff --git a/macosx/src/dfu-util/device-logs/openmoko-neo1973.lsusb b/macosx/src/dfu-util/device-logs/openmoko-neo1973.lsusb deleted file mode 100644 index 07789506a..000000000 --- a/macosx/src/dfu-util/device-logs/openmoko-neo1973.lsusb +++ /dev/null @@ -1,182 +0,0 @@ - -Bus 006 Device 020: ID 1457:5119 First International Computer, Inc. OpenMoko Neo1973 u-boot cdc_acm serial port -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.10 - bDeviceClass 2 Communications - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 16 - idVendor 0x1457 First International Computer, Inc. - idProduct 0x5119 OpenMoko Neo1973 u-boot cdc_acm serial port - bcdDevice 0.00 - iManufacturer 1 - iProduct 2 - iSerial 3 - bNumConfigurations 2 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 85 - bNumInterfaces 3 - bConfigurationValue 1 - iConfiguration 4 - bmAttributes 0x80 - (Bus Powered) - MaxPower 500mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 1 - bInterfaceClass 2 Communications - bInterfaceSubClass 2 Abstract (modem) - bInterfaceProtocol 1 AT-commands (v.25ter) - iInterface 6 - CDC Header: - bcdCDC 0.6e - CDC Call Management: - bmCapabilities 0x00 - bDataInterface 1 - CDC ACM: - bmCapabilities 0x00 - CDC Union: - bMasterInterface 0 - bSlaveInterface 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 3 - Transfer Type Interrupt - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 0 - bNumEndpoints 2 - bInterfaceClass 10 CDC Data - bInterfaceSubClass 0 Unused - bInterfaceProtocol 0 - iInterface 5 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x02 EP 2 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 2 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 1 - iInterface 7 - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 7 - Will Not Detach - Manifestation Tolerant - Upload Supported - Download Supported - wDetachTimeout 65280 milliseconds - wTransferSize 4096 bytes - bcdDFUVersion 1.00 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 67 - bNumInterfaces 2 - bConfigurationValue 2 - iConfiguration 4 - bmAttributes 0x80 - (Bus Powered) - MaxPower 100mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 1 - bInterfaceClass 2 Communications - bInterfaceSubClass 2 Abstract (modem) - bInterfaceProtocol 1 AT-commands (v.25ter) - iInterface 6 - CDC Header: - bcdCDC 0.6e - CDC Call Management: - bmCapabilities 0x00 - bDataInterface 1 - CDC ACM: - bmCapabilities 0x00 - CDC Union: - bMasterInterface 0 - bSlaveInterface 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 3 - Transfer Type Interrupt - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 0 - bNumEndpoints 2 - bInterfaceClass 10 CDC Data - bInterfaceSubClass 0 Unused - bInterfaceProtocol 0 - iInterface 5 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x02 EP 2 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 255 -Device Status: 0x0006 - (Bus Powered) - Remote Wakeup Enabled - Test Mode diff --git a/macosx/src/dfu-util/device-logs/openpcd.lsusb b/macosx/src/dfu-util/device-logs/openpcd.lsusb deleted file mode 100644 index f6255a943..000000000 --- a/macosx/src/dfu-util/device-logs/openpcd.lsusb +++ /dev/null @@ -1,60 +0,0 @@ - -Bus 006 Device 016: ID 16c0:076b VOTI OpenPCD 13.56MHz RFID Reader -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 8 - idVendor 0x16c0 VOTI - idProduct 0x076b OpenPCD 13.56MHz RFID Reader - bcdDevice 0.00 - iManufacturer 1 - iProduct 2 OpenPCD RFID Simulator - DFU Mode - iSerial 0 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 36 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0x80 - (Bus Powered) - MaxPower 200mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 0 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 1 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 0 - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 3 - Will Not Detach - Manifestation Intolerant - Upload Supported - Download Supported - wDetachTimeout 65280 milliseconds - wTransferSize 256 bytes - bcdDFUVersion 1.00 -Device Status: 0x0000 - (Bus Powered) diff --git a/macosx/src/dfu-util/device-logs/qi-hardware-atusb.lsusb b/macosx/src/dfu-util/device-logs/qi-hardware-atusb.lsusb deleted file mode 100644 index bfc1701e1..000000000 --- a/macosx/src/dfu-util/device-logs/qi-hardware-atusb.lsusb +++ /dev/null @@ -1,59 +0,0 @@ - -Bus 006 Device 013: ID 20b7:1540 Qi Hardware ben-wpan, AT86RF230-based -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 2.00 - bDeviceClass 255 Vendor Specific Class - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x20b7 Qi Hardware - idProduct 0x1540 ben-wpan, AT86RF230-based - bcdDevice 0.01 - iManufacturer 0 - iProduct 0 - iSerial 1 4630333438371508231a - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 34 - bNumInterfaces 2 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0x80 - (Bus Powered) - MaxPower 40mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 1 - bInterfaceClass 255 Vendor Specific Class - bInterfaceSubClass 0 - bInterfaceProtocol 0 - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 0 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 1 - iInterface 0 -Device Status: 0x0000 - (Bus Powered) diff --git a/macosx/src/dfu-util/device-logs/simtrace.lsusb b/macosx/src/dfu-util/device-logs/simtrace.lsusb deleted file mode 100644 index 578ddf0e1..000000000 --- a/macosx/src/dfu-util/device-logs/simtrace.lsusb +++ /dev/null @@ -1,70 +0,0 @@ - -Bus 006 Device 017: ID 16c0:0762 VOTI -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 8 - idVendor 0x16c0 VOTI - idProduct 0x0762 - bcdDevice 0.00 - iManufacturer 1 sysmocom - systems for mobile communications GmbH - iProduct 2 SimTrace SIM Sniffer - DFU Mode - iSerial 0 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 45 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 3 SimTrace DFU Configuration - bmAttributes 0x80 - (Bus Powered) - MaxPower 200mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 4 SimTrace DFU Interface - Application Partition - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 1 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 5 SimTrace DFU Interface - Bootloader Partition - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 2 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 6 SimTrace DFU Interface - RAM - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 3 - Will Not Detach - Manifestation Intolerant - Upload Supported - Download Supported - wDetachTimeout 65280 milliseconds - wTransferSize 256 bytes - bcdDFUVersion 1.00 -Device Status: 0x0000 - (Bus Powered) diff --git a/macosx/src/dfu-util/device-logs/sparkcore.lsusb b/macosx/src/dfu-util/device-logs/sparkcore.lsusb deleted file mode 100644 index b6029ffa5..000000000 --- a/macosx/src/dfu-util/device-logs/sparkcore.lsusb +++ /dev/null @@ -1,60 +0,0 @@ - -Bus 001 Device 008: ID 1d50:607f OpenMoko, Inc. -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x1d50 OpenMoko, Inc. - idProduct 0x607f - bcdDevice 2.00 - iManufacturer 1 Spark Devices - iProduct 2 CORE DFU - iSerial 3 8D80527B5055 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 36 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0xc0 - Self Powered - MaxPower 100mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 4 @Internal Flash /0x08000000/20*001Ka,108*001Kg - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 1 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 5 @SPI Flash : SST25x/0x00000000/512*04Kg - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 11 - Will Detach - Manifestation Intolerant - Upload Supported - Download Supported - wDetachTimeout 255 milliseconds - wTransferSize 1024 bytes - bcdDFUVersion 1.1a -Device Status: 0x0001 - Self Powered diff --git a/macosx/src/dfu-util/device-logs/stm32f107.bin-download b/macosx/src/dfu-util/device-logs/stm32f107.bin-download deleted file mode 100644 index 45b714f83..000000000 --- a/macosx/src/dfu-util/device-logs/stm32f107.bin-download +++ /dev/null @@ -1,48 +0,0 @@ -> src/dfu-util --intf 0 --alt 0 -v -v -v -s 0x8000000 -D test3 -dfu-util 0.4 - -(C) 2005-2008 by Weston Schmidt, Harald Welte and OpenMoko Inc. -(C) 2010-2011 Tormod Volden (DfuSe support) -This program is Free Software and has ABSOLUTELY NO WARRANTY - -dfu-util does currently only support DFU version 1.0 - -Opening DFU USB device... ID 0483:df11 -Run-time device DFU version 011a -Found DFU: [0483:df11] devnum=0, cfg=1, intf=0, alt=0, name="@Internal Flash /0x08000000/128*002Kg" -Claiming USB DFU Interface... -Setting Alternate Setting #0 ... -Determining device status: state = dfuIDLE, status = 0 -dfuIDLE, continuing -DFU mode device DFU version 011a -Device returned transfer size 2048 -No valid DFU suffix signature -Warning: File has no DFU suffix -DfuSe interface name: "Internal Flash " -Memory segment at 0x08000000 128 x 2048 = 262144 (rew) -Uploading to address = 0x08000000, size = 16384 -Erasing page size 2048 at address 0x08000000, page starting at 0x08000000 - Download from image offset 00000000 to memory 08000000-080007ff, size 2048 - Setting address pointer to 0x08000000 -Erasing page size 2048 at address 0x08000800, page starting at 0x08000800 - Download from image offset 00000800 to memory 08000800-08000fff, size 2048 - Setting address pointer to 0x08000800 -Erasing page size 2048 at address 0x08001000, page starting at 0x08001000 - Download from image offset 00001000 to memory 08001000-080017ff, size 2048 - Setting address pointer to 0x08001000 -Erasing page size 2048 at address 0x08001800, page starting at 0x08001800 - Download from image offset 00001800 to memory 08001800-08001fff, size 2048 - Setting address pointer to 0x08001800 -Erasing page size 2048 at address 0x08002000, page starting at 0x08002000 - Download from image offset 00002000 to memory 08002000-080027ff, size 2048 - Setting address pointer to 0x08002000 -Erasing page size 2048 at address 0x08002800, page starting at 0x08002800 - Download from image offset 00002800 to memory 08002800-08002fff, size 2048 - Setting address pointer to 0x08002800 -Erasing page size 2048 at address 0x08003000, page starting at 0x08003000 - Download from image offset 00003000 to memory 08003000-080037ff, size 2048 - Setting address pointer to 0x08003000 -Erasing page size 2048 at address 0x08003800, page starting at 0x08003800 - Download from image offset 00003800 to memory 08003800-08003fff, size 2048 - Setting address pointer to 0x08003800 - diff --git a/macosx/src/dfu-util/device-logs/stm32f107.lsusb b/macosx/src/dfu-util/device-logs/stm32f107.lsusb deleted file mode 100644 index 14b45cda0..000000000 --- a/macosx/src/dfu-util/device-logs/stm32f107.lsusb +++ /dev/null @@ -1,60 +0,0 @@ - -Bus 001 Device 028: ID 0483:df11 SGS Thomson Microelectronics STM Device in DFU Mode -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x0483 SGS Thomson Microelectronics - idProduct 0xdf11 STM Device in DFU Mode - bcdDevice 20.00 - iManufacturer 1 STMicroelectronics - iProduct 2 STM32 0x418 DFU Bootloader - iSerial 3 STM32 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 36 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0xc0 - Self Powered - MaxPower 100mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 4 @Internal Flash /0x08000000/128*002Kg - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 1 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 5 @Option Bytes /0x1FFFF800/01*016 g - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 11 - Will Detach - Manifestation Intolerant - Upload Supported - Download Supported - wDetachTimeout 255 milliseconds - wTransferSize 2048 bytes - bcdDFUVersion 1.1a -Device Status: 0x0000 - (Bus Powered) diff --git a/macosx/src/dfu-util/device-logs/stm32f4discovery.bin-download b/macosx/src/dfu-util/device-logs/stm32f4discovery.bin-download deleted file mode 100644 index 96e172216..000000000 --- a/macosx/src/dfu-util/device-logs/stm32f4discovery.bin-download +++ /dev/null @@ -1,36 +0,0 @@ -dfu-util --device 0483:df11 --alt 0 \ - --dfuse-address 0x08000000 \ - -v -v -v \ - --download arm/iotoggle.bin -No valid DFU suffix signature -Warning: File has no DFU suffix -dfu-util 0.5 - -(C) 2005-2008 by Weston Schmidt, Harald Welte and OpenMoko Inc. -(C) 2010-2011 Tormod Volden (DfuSe support) -This program is Free Software and has ABSOLUTELY NO WARRANTY - -dfu-util does currently only support DFU version 1.0 - -Filter on vendor = 0x0483 product = 0xdf11 -Opening DFU capable USB device... ID 0483:df11 -Run-time device DFU version 011a -Found DFU: [0483:df11] devnum=0, cfg=1, intf=0, alt=0, name="@Internal Flash /0x08000000/04*016Kg,01*064Kg,07*128Kg" -Claiming USB DFU Interface... -Setting Alternate Setting #0 ... -Determining device status: state = dfuERROR, status = 10 -dfuERROR, clearing status -Determining device status: state = dfuIDLE, status = 0 -dfuIDLE, continuing -DFU mode device DFU version 011a -Device returned transfer size 2048 -DfuSe interface name: "Internal Flash " -Memory segment at 0x08000000 4 x 16384 = 65536 (rew) -Memory segment at 0x08010000 1 x 65536 = 65536 (rew) -Memory segment at 0x08020000 7 x 131072 = 917504 (rew) -Uploading to address = 0x08000000, size = 2308 -Erasing page size 16384 at address 0x08000000, page starting at 0x08000000 - Download from image offset 00000000 to memory 08000000-080007ff, size 2048 - Setting address pointer to 0x08000000 - Download from image offset 00000800 to memory 08000800-08000903, size 260 - Setting address pointer to 0x08000800 diff --git a/macosx/src/dfu-util/device-logs/stm32f4discovery.lsusb b/macosx/src/dfu-util/device-logs/stm32f4discovery.lsusb deleted file mode 100644 index 0b870de91..000000000 --- a/macosx/src/dfu-util/device-logs/stm32f4discovery.lsusb +++ /dev/null @@ -1,80 +0,0 @@ - -Bus 001 Device 010: ID 0483:df11 SGS Thomson Microelectronics STM Device in DFU Mode -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 1.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x0483 SGS Thomson Microelectronics - idProduct 0xdf11 STM Device in DFU Mode - bcdDevice 21.00 - iManufacturer 1 STMicroelectronics - iProduct 2 STM32 BOOTLOADER - iSerial 3 315A28A0B956 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 54 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0xc0 - Self Powered - MaxPower 100mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 4 @Internal Flash /0x08000000/04*016Kg,01*064Kg,07*128Kg - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 1 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 5 @Option Bytes /0x1FFFC000/01*016 g - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 2 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 6 @OTP Memory /0x1FFF7800/01*512 g,01*016 g - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 3 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 2 - iInterface 7 @Device Feature/0xFFFF0000/01*004 g - Device Firmware Upgrade Interface Descriptor: - bLength 9 - bDescriptorType 33 - bmAttributes 11 - Will Detach - Manifestation Intolerant - Upload Supported - Download Supported - wDetachTimeout 255 milliseconds - wTransferSize 2048 bytes - bcdDFUVersion 1.1a -Device Status: 0x0001 - Self Powered diff --git a/macosx/src/dfu-util/device-logs/tdk-bluetooth.lsusb b/macosx/src/dfu-util/device-logs/tdk-bluetooth.lsusb deleted file mode 100644 index c0cfaceb6..000000000 --- a/macosx/src/dfu-util/device-logs/tdk-bluetooth.lsusb +++ /dev/null @@ -1,269 +0,0 @@ - -Bus 006 Device 014: ID 04bf:0320 TDK Corp. Bluetooth Adapter -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 2.00 - bDeviceClass 224 Wireless - bDeviceSubClass 1 Radio Frequency - bDeviceProtocol 1 Bluetooth - bMaxPacketSize0 64 - idVendor 0x04bf TDK Corp. - idProduct 0x0320 Bluetooth Adapter - bcdDevice 26.52 - iManufacturer 1 Ezurio - iProduct 2 Turbo Bluetooth Adapter - iSerial 3 008098D4FFBD - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 193 - bNumInterfaces 3 - bConfigurationValue 1 - iConfiguration 0 - bmAttributes 0x80 - (Bus Powered) - MaxPower 64mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 3 - bInterfaceClass 224 Wireless - bInterfaceSubClass 1 Radio Frequency - bInterfaceProtocol 1 Bluetooth - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 3 - Transfer Type Interrupt - Synch Type None - Usage Type Data - wMaxPacketSize 0x0010 1x 16 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x02 EP 2 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x82 EP 2 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0040 1x 64 bytes - bInterval 1 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 0 - bNumEndpoints 2 - bInterfaceClass 224 Wireless - bInterfaceSubClass 1 Radio Frequency - bInterfaceProtocol 1 Bluetooth - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x03 EP 3 OUT - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0000 1x 0 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0000 1x 0 bytes - bInterval 1 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 1 - bNumEndpoints 2 - bInterfaceClass 224 Wireless - bInterfaceSubClass 1 Radio Frequency - bInterfaceProtocol 1 Bluetooth - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x03 EP 3 OUT - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0009 1x 9 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0009 1x 9 bytes - bInterval 1 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 2 - bNumEndpoints 2 - bInterfaceClass 224 Wireless - bInterfaceSubClass 1 Radio Frequency - bInterfaceProtocol 1 Bluetooth - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x03 EP 3 OUT - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0011 1x 17 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0011 1x 17 bytes - bInterval 1 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 3 - bNumEndpoints 2 - bInterfaceClass 224 Wireless - bInterfaceSubClass 1 Radio Frequency - bInterfaceProtocol 1 Bluetooth - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x03 EP 3 OUT - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0019 1x 25 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0019 1x 25 bytes - bInterval 1 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 4 - bNumEndpoints 2 - bInterfaceClass 224 Wireless - bInterfaceSubClass 1 Radio Frequency - bInterfaceProtocol 1 Bluetooth - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x03 EP 3 OUT - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0021 1x 33 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0021 1x 33 bytes - bInterval 1 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 1 - bAlternateSetting 5 - bNumEndpoints 2 - bInterfaceClass 224 Wireless - bInterfaceSubClass 1 Radio Frequency - bInterfaceProtocol 1 Bluetooth - iInterface 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x03 EP 3 OUT - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0031 1x 49 bytes - bInterval 1 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x83 EP 3 IN - bmAttributes 1 - Transfer Type Isochronous - Synch Type None - Usage Type Data - wMaxPacketSize 0x0031 1x 49 bytes - bInterval 1 - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 2 - bAlternateSetting 0 - bNumEndpoints 0 - bInterfaceClass 254 Application Specific Interface - bInterfaceSubClass 1 Device Firmware Update - bInterfaceProtocol 0 - iInterface 0 - Device Firmware Upgrade Interface Descriptor: - bLength 7 - bDescriptorType 33 - bmAttributes 7 - Will Not Detach - Manifestation Tolerant - Upload Supported - Download Supported - wDetachTimeout 5000 milliseconds - wTransferSize 1023 bytes -Device Status: 0x0000 - (Bus Powered) diff --git a/macosx/src/dfu-util/dfuse-pack.py b/macosx/src/dfu-util/dfuse-pack.py deleted file mode 100644 index 875cc5c6e..000000000 --- a/macosx/src/dfu-util/dfuse-pack.py +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/python - -# Written by Antonio Galea - 2010/11/18 -# Distributed under Gnu LGPL 3.0 -# see http://www.gnu.org/licenses/lgpl-3.0.txt - -import sys,struct,zlib,os -from optparse import OptionParser - -DEFAULT_DEVICE="0x0483:0xdf11" - -def named(tuple,names): - return dict(zip(names.split(),tuple)) -def consume(fmt,data,names): - n = struct.calcsize(fmt) - return named(struct.unpack(fmt,data[:n]),names),data[n:] -def cstring(string): - return string.split('\0',1)[0] -def compute_crc(data): - return 0xFFFFFFFF & -zlib.crc32(data) -1 - -def parse(file,dump_images=False): - print 'File: "%s"' % file - data = open(file,'rb').read() - crc = compute_crc(data[:-4]) - prefix, data = consume('<5sBIB',data,'signature version size targets') - print '%(signature)s v%(version)d, image size: %(size)d, targets: %(targets)d' % prefix - for t in range(prefix['targets']): - tprefix, data = consume('<6sBI255s2I',data,'signature altsetting named name size elements') - tprefix['num'] = t - if tprefix['named']: - tprefix['name'] = cstring(tprefix['name']) - else: - tprefix['name'] = '' - print '%(signature)s %(num)d, alt setting: %(altsetting)s, name: "%(name)s", size: %(size)d, elements: %(elements)d' % tprefix - tsize = tprefix['size'] - target, data = data[:tsize], data[tsize:] - for e in range(tprefix['elements']): - eprefix, target = consume('<2I',target,'address size') - eprefix['num'] = e - print ' %(num)d, address: 0x%(address)08x, size: %(size)d' % eprefix - esize = eprefix['size'] - image, target = target[:esize], target[esize:] - if dump_images: - out = '%s.target%d.image%d.bin' % (file,t,e) - open(out,'wb').write(image) - print ' DUMPED IMAGE TO "%s"' % out - if len(target): - print "target %d: PARSE ERROR" % t - suffix = named(struct.unpack('<4H3sBI',data[:16]),'device product vendor dfu ufd len crc') - print 'usb: %(vendor)04x:%(product)04x, device: 0x%(device)04x, dfu: 0x%(dfu)04x, %(ufd)s, %(len)d, 0x%(crc)08x' % suffix - if crc != suffix['crc']: - print "CRC ERROR: computed crc32 is 0x%08x" % crc - data = data[16:] - if data: - print "PARSE ERROR" - -def build(file,targets,device=DEFAULT_DEVICE): - data = '' - for t,target in enumerate(targets): - tdata = '' - for image in target: - tdata += struct.pack('<2I',image['address'],len(image['data']))+image['data'] - tdata = struct.pack('<6sBI255s2I','Target',0,1,'ST...',len(tdata),len(target)) + tdata - data += tdata - data = struct.pack('<5sBIB','DfuSe',1,len(data)+11,len(targets)) + data - v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1)) - data += struct.pack('<4H3sB',0,d,v,0x011a,'UFD',16) - crc = compute_crc(data) - data += struct.pack(' and -Harald Welte . Over time, nearly complete -support of DFU 1.0, DFU 1.1 and DfuSe ("1.1a") has been added. -.SH LICENCE -.B dfu-util -is covered by the GNU General Public License (GPL), version 2 or later. -.SH COPYRIGHT -This manual page was originally written by Uwe Hermann , -and is now part of the dfu-util project. diff --git a/macosx/src/dfu-util/msvc/README_msvc.txt b/macosx/src/dfu-util/msvc/README_msvc.txt deleted file mode 100644 index 6e68ec6ff..000000000 --- a/macosx/src/dfu-util/msvc/README_msvc.txt +++ /dev/null @@ -1,10 +0,0 @@ -# (C) Roger Meier -# (C) Pascal Schweizer -# msvc folder is GPL-2.0+, LGPL-2.1+, BSD-3-Clause or MIT license(SPDX) - -Building dfu-util native on Windows with Visual Studio - -3rd party dependencies: -- libusbx ( git clone https://github.com/libusbx/libusbx.git ) - - getopt (part of libusbx: libusbx/examples/getopt) - diff --git a/macosx/src/dfu-util/msvc/dfu-suffix_2010.vcxproj b/macosx/src/dfu-util/msvc/dfu-suffix_2010.vcxproj deleted file mode 100644 index 0c316c2e5..000000000 --- a/macosx/src/dfu-util/msvc/dfu-suffix_2010.vcxproj +++ /dev/null @@ -1,100 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {8F7600A2-3B37-4956-B39B-A1D43EF29EDA} - dfusuffix - dfu-suffix - - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - $(SolutionDir)..\..\libusbx\examples\getopt;$(SolutionDir)..\..\libusbx\libusb;$(IncludePath) - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\dll;$(LibraryPath) - $(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib - $(ExecutablePath) - - - $(ExecutablePath) - $(SolutionDir)..\..\libusbx\examples\getopt;$(SolutionDir)..\..\libusbx\libusb;$(IncludePath) - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\dll;$(LibraryPath) - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - - - - Level3 - Disabled - HAVE_WINDOWS_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDebug - - - true - - - - - Level3 - MaxSpeed - true - true - HAVE_WINDOWS_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - - - - - - - - - - - {a2169bc8-cf99-40bf-83f3-b0e38f7067bd} - - - {349ee8f9-7d25-4909-aaf5-ff3fade72187} - - - - - - \ No newline at end of file diff --git a/macosx/src/dfu-util/msvc/dfu-util_2010.sln b/macosx/src/dfu-util/msvc/dfu-util_2010.sln deleted file mode 100644 index ef797239b..000000000 --- a/macosx/src/dfu-util/msvc/dfu-util_2010.sln +++ /dev/null @@ -1,54 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dfu-util", "dfu-util_2010.vcxproj", "{0E071A60-7EF2-4427-BAA8-9143CACB5BCB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C4F8746D-B27E-4806-95E5-2052174E923B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dfu-suffix", "dfu-suffix_2010.vcxproj", "{8F7600A2-3B37-4956-B39B-A1D43EF29EDA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "getopt_2010", "..\..\libusbx\msvc\getopt_2010.vcxproj", "{AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libusb-1.0 (static)", "..\..\libusbx\msvc\libusb_static_2010.vcxproj", "{349EE8F9-7D25-4909-AAF5-FF3FADE72187}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Debug|Win32.ActiveCfg = Debug|Win32 - {0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Debug|Win32.Build.0 = Debug|Win32 - {0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Debug|x64.ActiveCfg = Debug|Win32 - {0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Release|Win32.ActiveCfg = Release|Win32 - {0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Release|Win32.Build.0 = Release|Win32 - {0E071A60-7EF2-4427-BAA8-9143CACB5BCB}.Release|x64.ActiveCfg = Release|Win32 - {8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Debug|Win32.ActiveCfg = Debug|Win32 - {8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Debug|Win32.Build.0 = Debug|Win32 - {8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Debug|x64.ActiveCfg = Debug|Win32 - {8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Release|Win32.ActiveCfg = Release|Win32 - {8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Release|Win32.Build.0 = Release|Win32 - {8F7600A2-3B37-4956-B39B-A1D43EF29EDA}.Release|x64.ActiveCfg = Release|Win32 - {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|Win32.ActiveCfg = Debug|Win32 - {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|Win32.Build.0 = Debug|Win32 - {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|x64.ActiveCfg = Debug|x64 - {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Debug|x64.Build.0 = Debug|x64 - {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|Win32.ActiveCfg = Release|Win32 - {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|Win32.Build.0 = Release|Win32 - {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|x64.ActiveCfg = Release|x64 - {AE83E1B4-CE06-47EE-B7A3-C3A1D7C2D71E}.Release|x64.Build.0 = Release|x64 - {349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|Win32.ActiveCfg = Debug|Win32 - {349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|Win32.Build.0 = Debug|Win32 - {349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|x64.ActiveCfg = Debug|x64 - {349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Debug|x64.Build.0 = Debug|x64 - {349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|Win32.ActiveCfg = Release|Win32 - {349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|Win32.Build.0 = Release|Win32 - {349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|x64.ActiveCfg = Release|x64 - {349EE8F9-7D25-4909-AAF5-FF3FADE72187}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/macosx/src/dfu-util/msvc/dfu-util_2010.vcxproj b/macosx/src/dfu-util/msvc/dfu-util_2010.vcxproj deleted file mode 100644 index 17a8bee1b..000000000 --- a/macosx/src/dfu-util/msvc/dfu-util_2010.vcxproj +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {0E071A60-7EF2-4427-BAA8-9143CACB5BCB} - dfuutil - dfu-util - - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - $(SolutionDir)..\..\libusbx\examples\getopt;$(SolutionDir)..\..\libusbx\libusb;$(IncludePath) - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\$(Platform)\getopt\$(Configuration);$(LibraryPath) - $(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib - $(ExecutablePath) - - - $(ExecutablePath) - $(SolutionDir)..\..\libusbx\examples\getopt;$(SolutionDir)..\..\libusbx\libusb;$(IncludePath) - $(SolutionDir)..\$(Platform)\getopt\$(Configuration);$(LibraryPath) - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - - - - Level3 - Disabled - HAVE_WINDOWS_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreadedDebug - - - true - - - - - - - - - Level3 - MaxSpeed - true - true - HAVE_WINDOWS_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - MultiThreaded - - - true - true - true - - - copy $(SolutionDir)..\$(Platform)\$(Configuration)\dll\libusb-1.0.dll $(SolutionDir)..\$(Platform)\$(ProjectName)\$(Configuration)\ - - - - - - - - - - - - - - - - - - - - - - - - - - {a2169bc8-cf99-40bf-83f3-b0e38f7067bd} - - - {349ee8f9-7d25-4909-aaf5-ff3fade72187} - - - - - - \ No newline at end of file diff --git a/macosx/src/dfu-util/src/Makefile.am b/macosx/src/dfu-util/src/Makefile.am deleted file mode 100644 index 70179c411..000000000 --- a/macosx/src/dfu-util/src/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -AM_CFLAGS = -Wall -Wextra - -bin_PROGRAMS = dfu-util dfu-suffix dfu-prefix -dfu_util_SOURCES = main.c \ - portable.h \ - dfu_load.c \ - dfu_load.h \ - dfu_util.c \ - dfu_util.h \ - dfuse.c \ - dfuse.h \ - dfuse_mem.c \ - dfuse_mem.h \ - dfu.c \ - dfu.h \ - usb_dfu.h \ - dfu_file.c \ - dfu_file.h \ - quirks.c \ - quirks.h - -dfu_suffix_SOURCES = suffix.c \ - dfu_file.h \ - dfu_file.c - -dfu_prefix_SOURCES = prefix.c \ - dfu_file.h \ - dfu_file.c diff --git a/macosx/src/dfu-util/src/dfu.c b/macosx/src/dfu-util/src/dfu.c deleted file mode 100644 index 14d7673d1..000000000 --- a/macosx/src/dfu-util/src/dfu.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Low-level DFU communication routines, originally taken from - * $Id: dfu.c,v 1.3 2006/06/20 06:28:04 schmidtw Exp $ - * (part of dfu-programmer). - * - * Copyright 2005-2006 Weston Schmidt - * Copyright 2011-2014 Tormod Volden - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include - -#include "portable.h" -#include "dfu.h" -#include "quirks.h" - -static int dfu_timeout = 5000; /* 5 seconds - default */ - -/* - * DFU_DETACH Request (DFU Spec 1.0, Section 5.1) - * - * device - the usb_dev_handle to communicate with - * interface - the interface to communicate with - * timeout - the timeout in ms the USB device should wait for a pending - * USB reset before giving up and terminating the operation - * - * returns 0 or < 0 on error - */ -int dfu_detach( libusb_device_handle *device, - const unsigned short interface, - const unsigned short timeout ) -{ - return libusb_control_transfer( device, - /* bmRequestType */ LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_DETACH, - /* wValue */ timeout, - /* wIndex */ interface, - /* Data */ NULL, - /* wLength */ 0, - dfu_timeout ); -} - - -/* - * DFU_DNLOAD Request (DFU Spec 1.0, Section 6.1.1) - * - * device - the usb_dev_handle to communicate with - * interface - the interface to communicate with - * length - the total number of bytes to transfer to the USB - * device - must be less than wTransferSize - * data - the data to transfer - * - * returns the number of bytes written or < 0 on error - */ -int dfu_download( libusb_device_handle *device, - const unsigned short interface, - const unsigned short length, - const unsigned short transaction, - unsigned char* data ) -{ - int status; - - status = libusb_control_transfer( device, - /* bmRequestType */ LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_DNLOAD, - /* wValue */ transaction, - /* wIndex */ interface, - /* Data */ data, - /* wLength */ length, - dfu_timeout ); - return status; -} - - -/* - * DFU_UPLOAD Request (DFU Spec 1.0, Section 6.2) - * - * device - the usb_dev_handle to communicate with - * interface - the interface to communicate with - * length - the maximum number of bytes to receive from the USB - * device - must be less than wTransferSize - * data - the buffer to put the received data in - * - * returns the number of bytes received or < 0 on error - */ -int dfu_upload( libusb_device_handle *device, - const unsigned short interface, - const unsigned short length, - const unsigned short transaction, - unsigned char* data ) -{ - int status; - - status = libusb_control_transfer( device, - /* bmRequestType */ LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_UPLOAD, - /* wValue */ transaction, - /* wIndex */ interface, - /* Data */ data, - /* wLength */ length, - dfu_timeout ); - return status; -} - - -/* - * DFU_GETSTATUS Request (DFU Spec 1.0, Section 6.1.2) - * - * device - the usb_dev_handle to communicate with - * interface - the interface to communicate with - * status - the data structure to be populated with the results - * - * return the number of bytes read in or < 0 on an error - */ -int dfu_get_status( struct dfu_if *dif, struct dfu_status *status ) -{ - unsigned char buffer[6]; - int result; - - /* Initialize the status data structure */ - status->bStatus = DFU_STATUS_ERROR_UNKNOWN; - status->bwPollTimeout = 0; - status->bState = STATE_DFU_ERROR; - status->iString = 0; - - result = libusb_control_transfer( dif->dev_handle, - /* bmRequestType */ LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_GETSTATUS, - /* wValue */ 0, - /* wIndex */ dif->interface, - /* Data */ buffer, - /* wLength */ 6, - dfu_timeout ); - - if( 6 == result ) { - status->bStatus = buffer[0]; - if (dif->quirks & QUIRK_POLLTIMEOUT) - status->bwPollTimeout = DEFAULT_POLLTIMEOUT; - else - status->bwPollTimeout = ((0xff & buffer[3]) << 16) | - ((0xff & buffer[2]) << 8) | - (0xff & buffer[1]); - status->bState = buffer[4]; - status->iString = buffer[5]; - } - - return result; -} - - -/* - * DFU_CLRSTATUS Request (DFU Spec 1.0, Section 6.1.3) - * - * device - the usb_dev_handle to communicate with - * interface - the interface to communicate with - * - * return 0 or < 0 on an error - */ -int dfu_clear_status( libusb_device_handle *device, - const unsigned short interface ) -{ - return libusb_control_transfer( device, - /* bmRequestType */ LIBUSB_ENDPOINT_OUT| LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_CLRSTATUS, - /* wValue */ 0, - /* wIndex */ interface, - /* Data */ NULL, - /* wLength */ 0, - dfu_timeout ); -} - - -/* - * DFU_GETSTATE Request (DFU Spec 1.0, Section 6.1.5) - * - * device - the usb_dev_handle to communicate with - * interface - the interface to communicate with - * length - the maximum number of bytes to receive from the USB - * device - must be less than wTransferSize - * data - the buffer to put the received data in - * - * returns the state or < 0 on error - */ -int dfu_get_state( libusb_device_handle *device, - const unsigned short interface ) -{ - int result; - unsigned char buffer[1]; - - result = libusb_control_transfer( device, - /* bmRequestType */ LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_GETSTATE, - /* wValue */ 0, - /* wIndex */ interface, - /* Data */ buffer, - /* wLength */ 1, - dfu_timeout ); - - /* Return the error if there is one. */ - if (result < 1) - return -1; - - /* Return the state. */ - return buffer[0]; -} - - -/* - * DFU_ABORT Request (DFU Spec 1.0, Section 6.1.4) - * - * device - the usb_dev_handle to communicate with - * interface - the interface to communicate with - * - * returns 0 or < 0 on an error - */ -int dfu_abort( libusb_device_handle *device, - const unsigned short interface ) -{ - return libusb_control_transfer( device, - /* bmRequestType */ LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_ABORT, - /* wValue */ 0, - /* wIndex */ interface, - /* Data */ NULL, - /* wLength */ 0, - dfu_timeout ); -} - - -const char* dfu_state_to_string( int state ) -{ - const char *message; - - switch (state) { - case STATE_APP_IDLE: - message = "appIDLE"; - break; - case STATE_APP_DETACH: - message = "appDETACH"; - break; - case STATE_DFU_IDLE: - message = "dfuIDLE"; - break; - case STATE_DFU_DOWNLOAD_SYNC: - message = "dfuDNLOAD-SYNC"; - break; - case STATE_DFU_DOWNLOAD_BUSY: - message = "dfuDNBUSY"; - break; - case STATE_DFU_DOWNLOAD_IDLE: - message = "dfuDNLOAD-IDLE"; - break; - case STATE_DFU_MANIFEST_SYNC: - message = "dfuMANIFEST-SYNC"; - break; - case STATE_DFU_MANIFEST: - message = "dfuMANIFEST"; - break; - case STATE_DFU_MANIFEST_WAIT_RESET: - message = "dfuMANIFEST-WAIT-RESET"; - break; - case STATE_DFU_UPLOAD_IDLE: - message = "dfuUPLOAD-IDLE"; - break; - case STATE_DFU_ERROR: - message = "dfuERROR"; - break; - default: - message = NULL; - break; - } - - return message; -} - -/* Chapter 6.1.2 */ -static const char *dfu_status_names[] = { - /* DFU_STATUS_OK */ - "No error condition is present", - /* DFU_STATUS_errTARGET */ - "File is not targeted for use by this device", - /* DFU_STATUS_errFILE */ - "File is for this device but fails some vendor-specific test", - /* DFU_STATUS_errWRITE */ - "Device is unable to write memory", - /* DFU_STATUS_errERASE */ - "Memory erase function failed", - /* DFU_STATUS_errCHECK_ERASED */ - "Memory erase check failed", - /* DFU_STATUS_errPROG */ - "Program memory function failed", - /* DFU_STATUS_errVERIFY */ - "Programmed memory failed verification", - /* DFU_STATUS_errADDRESS */ - "Cannot program memory due to received address that is out of range", - /* DFU_STATUS_errNOTDONE */ - "Received DFU_DNLOAD with wLength = 0, but device does not think that it has all data yet", - /* DFU_STATUS_errFIRMWARE */ - "Device's firmware is corrupt. It cannot return to run-time (non-DFU) operations", - /* DFU_STATUS_errVENDOR */ - "iString indicates a vendor specific error", - /* DFU_STATUS_errUSBR */ - "Device detected unexpected USB reset signalling", - /* DFU_STATUS_errPOR */ - "Device detected unexpected power on reset", - /* DFU_STATUS_errUNKNOWN */ - "Something went wrong, but the device does not know what it was", - /* DFU_STATUS_errSTALLEDPKT */ - "Device stalled an unexpected request" -}; - - -const char *dfu_status_to_string(int status) -{ - if (status > DFU_STATUS_errSTALLEDPKT) - return "INVALID"; - return dfu_status_names[status]; -} - -int dfu_abort_to_idle(struct dfu_if *dif) -{ - int ret; - struct dfu_status dst; - - ret = dfu_abort(dif->dev_handle, dif->interface); - if (ret < 0) { - errx(EX_IOERR, "Error sending dfu abort request"); - exit(1); - } - ret = dfu_get_status(dif, &dst); - if (ret < 0) { - errx(EX_IOERR, "Error during abort get_status"); - exit(1); - } - if (dst.bState != DFU_STATE_dfuIDLE) { - errx(EX_IOERR, "Failed to enter idle state on abort"); - exit(1); - } - milli_sleep(dst.bwPollTimeout); - return ret; -} diff --git a/macosx/src/dfu-util/src/dfu.h b/macosx/src/dfu-util/src/dfu.h deleted file mode 100644 index 8e3caeb7b..000000000 --- a/macosx/src/dfu-util/src/dfu.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * dfu-programmer - * - * $Id: dfu.h,v 1.2 2005/09/25 01:27:42 schmidtw Exp $ - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef DFU_H -#define DFU_H - -#include -#include "usb_dfu.h" - -/* DFU states */ -#define STATE_APP_IDLE 0x00 -#define STATE_APP_DETACH 0x01 -#define STATE_DFU_IDLE 0x02 -#define STATE_DFU_DOWNLOAD_SYNC 0x03 -#define STATE_DFU_DOWNLOAD_BUSY 0x04 -#define STATE_DFU_DOWNLOAD_IDLE 0x05 -#define STATE_DFU_MANIFEST_SYNC 0x06 -#define STATE_DFU_MANIFEST 0x07 -#define STATE_DFU_MANIFEST_WAIT_RESET 0x08 -#define STATE_DFU_UPLOAD_IDLE 0x09 -#define STATE_DFU_ERROR 0x0a - - -/* DFU status */ -#define DFU_STATUS_OK 0x00 -#define DFU_STATUS_ERROR_TARGET 0x01 -#define DFU_STATUS_ERROR_FILE 0x02 -#define DFU_STATUS_ERROR_WRITE 0x03 -#define DFU_STATUS_ERROR_ERASE 0x04 -#define DFU_STATUS_ERROR_CHECK_ERASED 0x05 -#define DFU_STATUS_ERROR_PROG 0x06 -#define DFU_STATUS_ERROR_VERIFY 0x07 -#define DFU_STATUS_ERROR_ADDRESS 0x08 -#define DFU_STATUS_ERROR_NOTDONE 0x09 -#define DFU_STATUS_ERROR_FIRMWARE 0x0a -#define DFU_STATUS_ERROR_VENDOR 0x0b -#define DFU_STATUS_ERROR_USBR 0x0c -#define DFU_STATUS_ERROR_POR 0x0d -#define DFU_STATUS_ERROR_UNKNOWN 0x0e -#define DFU_STATUS_ERROR_STALLEDPKT 0x0f - -/* DFU commands */ -#define DFU_DETACH 0 -#define DFU_DNLOAD 1 -#define DFU_UPLOAD 2 -#define DFU_GETSTATUS 3 -#define DFU_CLRSTATUS 4 -#define DFU_GETSTATE 5 -#define DFU_ABORT 6 - -/* DFU interface */ -#define DFU_IFF_DFU 0x0001 /* DFU Mode, (not Runtime) */ - -/* This is based off of DFU_GETSTATUS - * - * 1 unsigned byte bStatus - * 3 unsigned byte bwPollTimeout - * 1 unsigned byte bState - * 1 unsigned byte iString -*/ - -struct dfu_status { - unsigned char bStatus; - unsigned int bwPollTimeout; - unsigned char bState; - unsigned char iString; -}; - -struct dfu_if { - struct usb_dfu_func_descriptor func_dfu; - uint16_t quirks; - uint16_t busnum; - uint16_t devnum; - uint16_t vendor; - uint16_t product; - uint16_t bcdDevice; - uint8_t configuration; - uint8_t interface; - uint8_t altsetting; - uint8_t flags; - uint8_t bMaxPacketSize0; - char *alt_name; - char *serial_name; - libusb_device *dev; - libusb_device_handle *dev_handle; - struct dfu_if *next; -}; - -int dfu_detach( libusb_device_handle *device, - const unsigned short interface, - const unsigned short timeout ); -int dfu_download( libusb_device_handle *device, - const unsigned short interface, - const unsigned short length, - const unsigned short transaction, - unsigned char* data ); -int dfu_upload( libusb_device_handle *device, - const unsigned short interface, - const unsigned short length, - const unsigned short transaction, - unsigned char* data ); -int dfu_get_status( struct dfu_if *dif, - struct dfu_status *status ); -int dfu_clear_status( libusb_device_handle *device, - const unsigned short interface ); -int dfu_get_state( libusb_device_handle *device, - const unsigned short interface ); -int dfu_abort( libusb_device_handle *device, - const unsigned short interface ); -int dfu_abort_to_idle( struct dfu_if *dif); - -const char *dfu_state_to_string( int state ); - -const char *dfu_status_to_string( int status ); - -#endif /* DFU_H */ diff --git a/macosx/src/dfu-util/src/dfu_file.c b/macosx/src/dfu-util/src/dfu_file.c deleted file mode 100644 index 7c897d4f6..000000000 --- a/macosx/src/dfu-util/src/dfu_file.c +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Load or store DFU files including suffix and prefix - * - * Copyright 2014 Tormod Volden - * Copyright 2012 Stefan Schmidt - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "portable.h" -#include "dfu_file.h" - -#define DFU_SUFFIX_LENGTH 16 -#define LMDFU_PREFIX_LENGTH 8 -#define LPCDFU_PREFIX_LENGTH 16 -#define PROGRESS_BAR_WIDTH 25 -#define STDIN_CHUNK_SIZE 65536 - -static const unsigned long crc32_table[] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, - 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, - 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, - 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, - 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, - 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, - 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, - 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, - 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, - 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, - 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, - 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, - 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, - 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, - 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, - 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, - 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, - 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}; - -static uint32_t crc32_byte(uint32_t accum, uint8_t delta) -{ - return crc32_table[(accum ^ delta) & 0xff] ^ (accum >> 8); -} - -static int probe_prefix(struct dfu_file *file) -{ - uint8_t *prefix = file->firmware; - - if (file->size.total < LMDFU_PREFIX_LENGTH) - return 1; - if ((prefix[0] == 0x01) && (prefix[1] == 0x00)) { - file->prefix_type = LMDFU_PREFIX; - file->size.prefix = LMDFU_PREFIX_LENGTH; - file->lmdfu_address = 1024 * ((prefix[3] << 8) | prefix[2]); - } - else if (((prefix[0] & 0x3f) == 0x1a) && ((prefix[1] & 0x3f)== 0x3f)) { - file->prefix_type = LPCDFU_UNENCRYPTED_PREFIX; - file->size.prefix = LPCDFU_PREFIX_LENGTH; - } - - if (file->size.prefix + file->size.suffix > file->size.total) - return 1; - return 0; -} - -void dfu_progress_bar(const char *desc, unsigned long long curr, - unsigned long long max) -{ - static char buf[PROGRESS_BAR_WIDTH + 1]; - static unsigned long long last_progress = -1; - static time_t last_time; - time_t curr_time = time(NULL); - unsigned long long progress; - unsigned long long x; - - /* check for not known maximum */ - if (max < curr) - max = curr + 1; - /* make none out of none give zero */ - if (max == 0 && curr == 0) - max = 1; - - /* compute completion */ - progress = (PROGRESS_BAR_WIDTH * curr) / max; - if (progress > PROGRESS_BAR_WIDTH) - progress = PROGRESS_BAR_WIDTH; - if (progress == last_progress && - curr_time == last_time) - return; - last_progress = progress; - last_time = curr_time; - - for (x = 0; x != PROGRESS_BAR_WIDTH; x++) { - if (x < progress) - buf[x] = '='; - else - buf[x] = ' '; - } - buf[x] = 0; - - printf("\r%s\t[%s] %3lld%% %12lld bytes", desc, buf, - (100ULL * curr) / max, curr); - - if (progress == PROGRESS_BAR_WIDTH) - printf("\n%s done.\n", desc); -} - -void *dfu_malloc(size_t size) -{ - void *ptr = malloc(size); - if (ptr == NULL) - errx(EX_SOFTWARE, "Cannot allocate memory of size %d bytes", (int)size); - return (ptr); -} - -uint32_t dfu_file_write_crc(int f, uint32_t crc, const void *buf, int size) -{ - int x; - - /* compute CRC */ - for (x = 0; x != size; x++) - crc = crc32_byte(crc, ((uint8_t *)buf)[x]); - - /* write data */ - if (write(f, buf, size) != size) - err(EX_IOERR, "Could not write %d bytes to file %d", size, f); - - return (crc); -} - -void dfu_load_file(struct dfu_file *file, enum suffix_req check_suffix, enum prefix_req check_prefix) -{ - off_t offset; - int f; - int i; - int res; - - file->size.prefix = 0; - file->size.suffix = 0; - - /* default values, if no valid suffix is found */ - file->bcdDFU = 0; - file->idVendor = 0xffff; /* wildcard value */ - file->idProduct = 0xffff; /* wildcard value */ - file->bcdDevice = 0xffff; /* wildcard value */ - - /* default values, if no valid prefix is found */ - file->lmdfu_address = 0; - - free(file->firmware); - - if (!strcmp(file->name, "-")) { - int read_bytes; - -#ifdef WIN32 - _setmode( _fileno( stdin ), _O_BINARY ); -#endif - file->firmware = (uint8_t*) dfu_malloc(STDIN_CHUNK_SIZE); - read_bytes = fread(file->firmware, 1, STDIN_CHUNK_SIZE, stdin); - file->size.total = read_bytes; - while (read_bytes == STDIN_CHUNK_SIZE) { - file->firmware = (uint8_t*) realloc(file->firmware, file->size.total + STDIN_CHUNK_SIZE); - if (!file->firmware) - err(EX_IOERR, "Could not allocate firmware buffer"); - read_bytes = fread(file->firmware + file->size.total, 1, STDIN_CHUNK_SIZE, stdin); - file->size.total += read_bytes; - } - if (verbose) - printf("Read %i bytes from stdin\n", file->size.total); - /* Never require suffix when reading from stdin */ - check_suffix = MAYBE_SUFFIX; - } else { - f = open(file->name, O_RDONLY | O_BINARY); - if (f < 0) - err(EX_IOERR, "Could not open file %s for reading", file->name); - - offset = lseek(f, 0, SEEK_END); - - if ((int)offset < 0 || (int)offset != offset) - err(EX_IOERR, "File size is too big"); - - if (lseek(f, 0, SEEK_SET) != 0) - err(EX_IOERR, "Could not seek to beginning"); - - file->size.total = offset; - file->firmware = dfu_malloc(file->size.total); - - if (read(f, file->firmware, file->size.total) != file->size.total) { - err(EX_IOERR, "Could not read %d bytes from %s", - file->size.total, file->name); - } - close(f); - } - - /* Check for possible DFU file suffix by trying to parse one */ - { - uint32_t crc = 0xffffffff; - const uint8_t *dfusuffix; - int missing_suffix = 0; - const char *reason; - - if (file->size.total < DFU_SUFFIX_LENGTH) { - reason = "File too short for DFU suffix"; - missing_suffix = 1; - goto checked; - } - - dfusuffix = file->firmware + file->size.total - - DFU_SUFFIX_LENGTH; - - for (i = 0; i < file->size.total - 4; i++) - crc = crc32_byte(crc, file->firmware[i]); - - if (dfusuffix[10] != 'D' || - dfusuffix[9] != 'F' || - dfusuffix[8] != 'U') { - reason = "Invalid DFU suffix signature"; - missing_suffix = 1; - goto checked; - } - - file->dwCRC = (dfusuffix[15] << 24) + - (dfusuffix[14] << 16) + - (dfusuffix[13] << 8) + - dfusuffix[12]; - - if (file->dwCRC != crc) { - reason = "DFU suffix CRC does not match"; - missing_suffix = 1; - goto checked; - } - - /* At this point we believe we have a DFU suffix - so we require further checks to succeed */ - - file->bcdDFU = (dfusuffix[7] << 8) + dfusuffix[6]; - - if (verbose) - printf("DFU suffix version %x\n", file->bcdDFU); - - file->size.suffix = dfusuffix[11]; - - if (file->size.suffix < DFU_SUFFIX_LENGTH) { - errx(EX_IOERR, "Unsupported DFU suffix length %d", - file->size.suffix); - } - - if (file->size.suffix > file->size.total) { - errx(EX_IOERR, "Invalid DFU suffix length %d", - file->size.suffix); - } - - file->idVendor = (dfusuffix[5] << 8) + dfusuffix[4]; - file->idProduct = (dfusuffix[3] << 8) + dfusuffix[2]; - file->bcdDevice = (dfusuffix[1] << 8) + dfusuffix[0]; - -checked: - if (missing_suffix) { - if (check_suffix == NEEDS_SUFFIX) { - warnx("%s", reason); - errx(EX_IOERR, "Valid DFU suffix needed"); - } else if (check_suffix == MAYBE_SUFFIX) { - warnx("%s", reason); - warnx("A valid DFU suffix will be required in " - "a future dfu-util release!!!"); - } - } else { - if (check_suffix == NO_SUFFIX) { - errx(EX_SOFTWARE, "Please remove existing DFU suffix before adding a new one.\n"); - } - } - } - res = probe_prefix(file); - if ((res || file->size.prefix == 0) && check_prefix == NEEDS_PREFIX) - errx(EX_IOERR, "Valid DFU prefix needed"); - if (file->size.prefix && check_prefix == NO_PREFIX) - errx(EX_IOERR, "A prefix already exists, please delete it first"); - if (file->size.prefix && verbose) { - uint8_t *data = file->firmware; - if (file->prefix_type == LMDFU_PREFIX) - printf("Possible TI Stellaris DFU prefix with " - "the following properties\n" - "Address: 0x%08x\n" - "Payload length: %d\n", - file->lmdfu_address, - data[4] | (data[5] << 8) | - (data[6] << 16) | (data[7] << 14)); - else if (file->prefix_type == LPCDFU_UNENCRYPTED_PREFIX) - printf("Possible unencrypted NXP LPC DFU prefix with " - "the following properties\n" - "Payload length: %d kiByte\n", - data[2] >>1 | (data[3] << 7) ); - else - errx(EX_IOERR, "Unknown DFU prefix type"); - } -} - -void dfu_store_file(struct dfu_file *file, int write_suffix, int write_prefix) -{ - uint32_t crc = 0xffffffff; - int f; - - f = open(file->name, O_WRONLY | O_BINARY | O_TRUNC | O_CREAT, 0666); - if (f < 0) - err(EX_IOERR, "Could not open file %s for writing", file->name); - - /* write prefix, if any */ - if (write_prefix) { - if (file->prefix_type == LMDFU_PREFIX) { - uint8_t lmdfu_prefix[LMDFU_PREFIX_LENGTH]; - uint32_t addr = file->lmdfu_address / 1024; - - /* lmdfu_dfu_prefix payload length excludes prefix and suffix */ - uint32_t len = file->size.total - - file->size.prefix - file->size.suffix; - - lmdfu_prefix[0] = 0x01; /* STELLARIS_DFU_PROG */ - lmdfu_prefix[1] = 0x00; /* Reserved */ - lmdfu_prefix[2] = (uint8_t)(addr & 0xff); - lmdfu_prefix[3] = (uint8_t)(addr >> 8); - lmdfu_prefix[4] = (uint8_t)(len & 0xff); - lmdfu_prefix[5] = (uint8_t)(len >> 8) & 0xff; - lmdfu_prefix[6] = (uint8_t)(len >> 16) & 0xff; - lmdfu_prefix[7] = (uint8_t)(len >> 24); - - crc = dfu_file_write_crc(f, crc, lmdfu_prefix, LMDFU_PREFIX_LENGTH); - } - if (file->prefix_type == LPCDFU_UNENCRYPTED_PREFIX) { - uint8_t lpcdfu_prefix[LPCDFU_PREFIX_LENGTH] = {0}; - int i; - - /* Payload is firmware and prefix rounded to 512 bytes */ - uint32_t len = (file->size.total - file->size.suffix + 511) /512; - - lpcdfu_prefix[0] = 0x1a; /* Unencypted*/ - lpcdfu_prefix[1] = 0x3f; /* Reserved */ - lpcdfu_prefix[2] = (uint8_t)(len & 0xff); - lpcdfu_prefix[3] = (uint8_t)((len >> 8) & 0xff); - for (i = 12; i < LPCDFU_PREFIX_LENGTH; i++) - lpcdfu_prefix[i] = 0xff; - - crc = dfu_file_write_crc(f, crc, lpcdfu_prefix, LPCDFU_PREFIX_LENGTH); - } - } - /* write firmware binary */ - crc = dfu_file_write_crc(f, crc, file->firmware + file->size.prefix, - file->size.total - file->size.prefix - file->size.suffix); - - /* write suffix, if any */ - if (write_suffix) { - uint8_t dfusuffix[DFU_SUFFIX_LENGTH]; - - dfusuffix[0] = file->bcdDevice & 0xff; - dfusuffix[1] = file->bcdDevice >> 8; - dfusuffix[2] = file->idProduct & 0xff; - dfusuffix[3] = file->idProduct >> 8; - dfusuffix[4] = file->idVendor & 0xff; - dfusuffix[5] = file->idVendor >> 8; - dfusuffix[6] = file->bcdDFU & 0xff; - dfusuffix[7] = file->bcdDFU >> 8; - dfusuffix[8] = 'U'; - dfusuffix[9] = 'F'; - dfusuffix[10] = 'D'; - dfusuffix[11] = DFU_SUFFIX_LENGTH; - - crc = dfu_file_write_crc(f, crc, dfusuffix, - DFU_SUFFIX_LENGTH - 4); - - dfusuffix[12] = crc; - dfusuffix[13] = crc >> 8; - dfusuffix[14] = crc >> 16; - dfusuffix[15] = crc >> 24; - - crc = dfu_file_write_crc(f, crc, dfusuffix + 12, 4); - } - close(f); -} - -void show_suffix_and_prefix(struct dfu_file *file) -{ - if (file->size.prefix == LMDFU_PREFIX_LENGTH) { - printf("The file %s contains a TI Stellaris DFU prefix with the following properties:\n", file->name); - printf("Address:\t0x%08x\n", file->lmdfu_address); - } else if (file->size.prefix == LPCDFU_PREFIX_LENGTH) { - uint8_t * prefix = file->firmware; - printf("The file %s contains a NXP unencrypted LPC DFU prefix with the following properties:\n", file->name); - printf("Size:\t%5d kiB\n", prefix[2]>>1|prefix[3]<<7); - } else if (file->size.prefix != 0) { - printf("The file %s contains an unknown prefix\n", file->name); - } - if (file->size.suffix > 0) { - printf("The file %s contains a DFU suffix with the following properties:\n", file->name); - printf("BCD device:\t0x%04X\n", file->bcdDevice); - printf("Product ID:\t0x%04X\n",file->idProduct); - printf("Vendor ID:\t0x%04X\n", file->idVendor); - printf("BCD DFU:\t0x%04X\n", file->bcdDFU); - printf("Length:\t\t%i\n", file->size.suffix); - printf("CRC:\t\t0x%08X\n", file->dwCRC); - } -} diff --git a/macosx/src/dfu-util/src/dfu_file.h b/macosx/src/dfu-util/src/dfu_file.h deleted file mode 100644 index abebd44f4..000000000 --- a/macosx/src/dfu-util/src/dfu_file.h +++ /dev/null @@ -1,60 +0,0 @@ - -#ifndef DFU_FILE_H -#define DFU_FILE_H - -#include - -struct dfu_file { - /* File name */ - const char *name; - /* Pointer to file loaded into memory */ - uint8_t *firmware; - /* Different sizes */ - struct { - int total; - int prefix; - int suffix; - } size; - /* From prefix fields */ - uint32_t lmdfu_address; - /* From prefix fields */ - uint32_t prefix_type; - - /* From DFU suffix fields */ - uint32_t dwCRC; - uint16_t bcdDFU; - uint16_t idVendor; - uint16_t idProduct; - uint16_t bcdDevice; -}; - -enum suffix_req { - NO_SUFFIX, - NEEDS_SUFFIX, - MAYBE_SUFFIX -}; - -enum prefix_req { - NO_PREFIX, - NEEDS_PREFIX, - MAYBE_PREFIX -}; - -enum prefix_type { - ZERO_PREFIX, - LMDFU_PREFIX, - LPCDFU_UNENCRYPTED_PREFIX -}; - -extern int verbose; - -void dfu_load_file(struct dfu_file *file, enum suffix_req check_suffix, enum prefix_req check_prefix); -void dfu_store_file(struct dfu_file *file, int write_suffix, int write_prefix); - -void dfu_progress_bar(const char *desc, unsigned long long curr, - unsigned long long max); -void *dfu_malloc(size_t size); -uint32_t dfu_file_write_crc(int f, uint32_t crc, const void *buf, int size); -void show_suffix_and_prefix(struct dfu_file *file); - -#endif /* DFU_FILE_H */ diff --git a/macosx/src/dfu-util/src/dfu_load.c b/macosx/src/dfu-util/src/dfu_load.c deleted file mode 100644 index 64f7009df..000000000 --- a/macosx/src/dfu-util/src/dfu_load.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * DFU transfer routines - * - * This is supposed to be a general DFU implementation, as specified in the - * USB DFU 1.0 and 1.1 specification. - * - * The code was originally intended to interface with a USB device running the - * "sam7dfu" firmware (see http://www.openpcd.org/) on an AT91SAM7 processor. - * - * Copyright 2007-2008 Harald Welte - * Copyright 2013 Hans Petter Selasky - * Copyright 2014 Tormod Volden - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#include - -#include "portable.h" -#include "dfu.h" -#include "usb_dfu.h" -#include "dfu_file.h" -#include "dfu_load.h" -#include "quirks.h" - -int dfuload_do_upload(struct dfu_if *dif, int xfer_size, - int expected_size, int fd) -{ - int total_bytes = 0; - unsigned short transaction = 0; - unsigned char *buf; - int ret; - - buf = dfu_malloc(xfer_size); - - printf("Copying data from DFU device to PC\n"); - dfu_progress_bar("Upload", 0, 1); - - while (1) { - int rc; - rc = dfu_upload(dif->dev_handle, dif->interface, - xfer_size, transaction++, buf); - if (rc < 0) { - warnx("Error during upload"); - ret = rc; - goto out_free; - } - - dfu_file_write_crc(fd, 0, buf, rc); - total_bytes += rc; - - if (total_bytes < 0) - errx(EX_SOFTWARE, "Received too many bytes (wraparound)"); - - if (rc < xfer_size) { - /* last block, return */ - ret = total_bytes; - break; - } - dfu_progress_bar("Upload", total_bytes, expected_size); - } - ret = 0; - -out_free: - dfu_progress_bar("Upload", total_bytes, total_bytes); - if (total_bytes == 0) - printf("\nFailed.\n"); - free(buf); - if (verbose) - printf("Received a total of %i bytes\n", total_bytes); - if (expected_size != 0 && total_bytes != expected_size) - errx(EX_SOFTWARE, "Unexpected number of bytes uploaded from device"); - return ret; -} - -int dfuload_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file) -{ - int bytes_sent; - int expected_size; - unsigned char *buf; - unsigned short transaction = 0; - struct dfu_status dst; - int ret; - - printf("Copying data from PC to DFU device\n"); - - buf = file->firmware; - expected_size = file->size.total - file->size.suffix; - bytes_sent = 0; - - dfu_progress_bar("Download", 0, 1); - while (bytes_sent < expected_size) { - int bytes_left; - int chunk_size; - - bytes_left = expected_size - bytes_sent; - if (bytes_left < xfer_size) - chunk_size = bytes_left; - else - chunk_size = xfer_size; - - ret = dfu_download(dif->dev_handle, dif->interface, - chunk_size, transaction++, chunk_size ? buf : NULL); - if (ret < 0) { - warnx("Error during download"); - goto out; - } - bytes_sent += chunk_size; - buf += chunk_size; - - do { - ret = dfu_get_status(dif, &dst); - if (ret < 0) { - errx(EX_IOERR, "Error during download get_status"); - goto out; - } - - if (dst.bState == DFU_STATE_dfuDNLOAD_IDLE || - dst.bState == DFU_STATE_dfuERROR) - break; - - /* Wait while device executes flashing */ - milli_sleep(dst.bwPollTimeout); - - } while (1); - if (dst.bStatus != DFU_STATUS_OK) { - printf(" failed!\n"); - printf("state(%u) = %s, status(%u) = %s\n", dst.bState, - dfu_state_to_string(dst.bState), dst.bStatus, - dfu_status_to_string(dst.bStatus)); - ret = -1; - goto out; - } - dfu_progress_bar("Download", bytes_sent, bytes_sent + bytes_left); - } - - /* send one zero sized download request to signalize end */ - ret = dfu_download(dif->dev_handle, dif->interface, - 0, transaction, NULL); - if (ret < 0) { - errx(EX_IOERR, "Error sending completion packet"); - goto out; - } - - dfu_progress_bar("Download", bytes_sent, bytes_sent); - - if (verbose) - printf("Sent a total of %i bytes\n", bytes_sent); - -get_status: - /* Transition to MANIFEST_SYNC state */ - ret = dfu_get_status(dif, &dst); - if (ret < 0) { - warnx("unable to read DFU status after completion"); - goto out; - } - printf("state(%u) = %s, status(%u) = %s\n", dst.bState, - dfu_state_to_string(dst.bState), dst.bStatus, - dfu_status_to_string(dst.bStatus)); - - milli_sleep(dst.bwPollTimeout); - - /* FIXME: deal correctly with ManifestationTolerant=0 / WillDetach bits */ - switch (dst.bState) { - case DFU_STATE_dfuMANIFEST_SYNC: - case DFU_STATE_dfuMANIFEST: - /* some devices (e.g. TAS1020b) need some time before we - * can obtain the status */ - milli_sleep(1000); - goto get_status; - break; - case DFU_STATE_dfuIDLE: - break; - } - printf("Done!\n"); - -out: - return bytes_sent; -} diff --git a/macosx/src/dfu-util/src/dfu_load.h b/macosx/src/dfu-util/src/dfu_load.h deleted file mode 100644 index be23e9b4f..000000000 --- a/macosx/src/dfu-util/src/dfu_load.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef DFU_LOAD_H -#define DFU_LOAD_H - -int dfuload_do_upload(struct dfu_if *dif, int xfer_size, int expected_size, int fd); -int dfuload_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file); - -#endif /* DFU_LOAD_H */ diff --git a/macosx/src/dfu-util/src/dfu_util.c b/macosx/src/dfu-util/src/dfu_util.c deleted file mode 100644 index b94c7ccd3..000000000 --- a/macosx/src/dfu-util/src/dfu_util.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Functions for detecting DFU USB entities - * - * Written by Harald Welte - * Copyright 2007-2008 by OpenMoko, Inc. - * Copyright 2013 Hans Petter Selasky - * - * Based on existing code of dfu-programmer-0.4 - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#include "portable.h" -#include "dfu.h" -#include "usb_dfu.h" -#include "dfu_file.h" -#include "dfu_load.h" -#include "dfu_util.h" -#include "dfuse.h" -#include "quirks.h" - -#ifdef HAVE_USBPATH_H -#include -#endif - -/* - * Look for a descriptor in a concatenated descriptor list. Will - * return upon the first match of the given descriptor type. Returns length of - * found descriptor, limited to res_size - */ -static int find_descriptor(const uint8_t *desc_list, int list_len, - uint8_t desc_type, void *res_buf, int res_size) -{ - int p = 0; - - if (list_len < 2) - return (-1); - - while (p + 1 < list_len) { - int desclen; - - desclen = (int) desc_list[p]; - if (desclen == 0) { - warnx("Invalid descriptor list"); - return -1; - } - if (desc_list[p + 1] == desc_type) { - if (desclen > res_size) - desclen = res_size; - if (p + desclen > list_len) - desclen = list_len - p; - memcpy(res_buf, &desc_list[p], desclen); - return desclen; - } - p += (int) desc_list[p]; - } - return -1; -} - -static void probe_configuration(libusb_device *dev, struct libusb_device_descriptor *desc) -{ - struct usb_dfu_func_descriptor func_dfu; - libusb_device_handle *devh; - struct dfu_if *pdfu; - struct libusb_config_descriptor *cfg; - const struct libusb_interface_descriptor *intf; - const struct libusb_interface *uif; - char alt_name[MAX_DESC_STR_LEN + 1]; - char serial_name[MAX_DESC_STR_LEN + 1]; - int cfg_idx; - int intf_idx; - int alt_idx; - int ret; - int has_dfu; - - for (cfg_idx = 0; cfg_idx != desc->bNumConfigurations; cfg_idx++) { - memset(&func_dfu, 0, sizeof(func_dfu)); - has_dfu = 0; - - ret = libusb_get_config_descriptor(dev, cfg_idx, &cfg); - if (ret != 0) - return; - if (match_config_index > -1 && match_config_index != cfg->bConfigurationValue) { - libusb_free_config_descriptor(cfg); - continue; - } - - /* - * In some cases, noticably FreeBSD if uid != 0, - * the configuration descriptors are empty - */ - if (!cfg) - return; - - ret = find_descriptor(cfg->extra, cfg->extra_length, - USB_DT_DFU, &func_dfu, sizeof(func_dfu)); - if (ret > -1) - goto found_dfu; - - for (intf_idx = 0; intf_idx < cfg->bNumInterfaces; - intf_idx++) { - uif = &cfg->interface[intf_idx]; - if (!uif) - break; - - for (alt_idx = 0; alt_idx < cfg->interface[intf_idx].num_altsetting; - alt_idx++) { - intf = &uif->altsetting[alt_idx]; - - ret = find_descriptor(intf->extra, intf->extra_length, USB_DT_DFU, - &func_dfu, sizeof(func_dfu)); - if (ret > -1) - goto found_dfu; - - if (intf->bInterfaceClass != 0xfe || - intf->bInterfaceSubClass != 1) - continue; - - has_dfu = 1; - } - } - if (has_dfu) { - /* - * Finally try to retrieve it requesting the - * device directly This is not supported on - * all devices for non-standard types - */ - if (libusb_open(dev, &devh) == 0) { - ret = libusb_get_descriptor(devh, USB_DT_DFU, 0, - (void *)&func_dfu, sizeof(func_dfu)); - libusb_close(devh); - if (ret > -1) - goto found_dfu; - } - warnx("Device has DFU interface, " - "but has no DFU functional descriptor"); - - /* fake version 1.0 */ - func_dfu.bLength = 7; - func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100); - goto found_dfu; - } - libusb_free_config_descriptor(cfg); - continue; - -found_dfu: - if (func_dfu.bLength == 7) { - printf("Deducing device DFU version from functional descriptor " - "length\n"); - func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100); - } else if (func_dfu.bLength < 9) { - printf("Error obtaining DFU functional descriptor\n"); - printf("Please report this as a bug!\n"); - printf("Warning: Assuming DFU version 1.0\n"); - func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100); - printf("Warning: Transfer size can not be detected\n"); - func_dfu.wTransferSize = 0; - } - - for (intf_idx = 0; intf_idx < cfg->bNumInterfaces; - intf_idx++) { - if (match_iface_index > -1 && match_iface_index != intf_idx) - continue; - - uif = &cfg->interface[intf_idx]; - if (!uif) - break; - - for (alt_idx = 0; - alt_idx < uif->num_altsetting; alt_idx++) { - int dfu_mode; - - intf = &uif->altsetting[alt_idx]; - - if (intf->bInterfaceClass != 0xfe || - intf->bInterfaceSubClass != 1) - continue; - - dfu_mode = (intf->bInterfaceProtocol == 2); - /* e.g. DSO Nano has bInterfaceProtocol 0 instead of 2 */ - if (func_dfu.bcdDFUVersion == 0x011a && intf->bInterfaceProtocol == 0) - dfu_mode = 1; - - if (dfu_mode && - match_iface_alt_index > -1 && match_iface_alt_index != alt_idx) - continue; - - if (dfu_mode) { - if ((match_vendor_dfu >= 0 && match_vendor_dfu != desc->idVendor) || - (match_product_dfu >= 0 && match_product_dfu != desc->idProduct)) { - continue; - } - } else { - if ((match_vendor >= 0 && match_vendor != desc->idVendor) || - (match_product >= 0 && match_product != desc->idProduct)) { - continue; - } - } - - if (libusb_open(dev, &devh)) { - warnx("Cannot open DFU device %04x:%04x", desc->idVendor, desc->idProduct); - break; - } - if (intf->iInterface != 0) - ret = libusb_get_string_descriptor_ascii(devh, - intf->iInterface, (void *)alt_name, MAX_DESC_STR_LEN); - else - ret = -1; - if (ret < 1) - strcpy(alt_name, "UNKNOWN"); - if (desc->iSerialNumber != 0) - ret = libusb_get_string_descriptor_ascii(devh, - desc->iSerialNumber, (void *)serial_name, MAX_DESC_STR_LEN); - else - ret = -1; - if (ret < 1) - strcpy(serial_name, "UNKNOWN"); - libusb_close(devh); - - if (dfu_mode && - match_iface_alt_name != NULL && strcmp(alt_name, match_iface_alt_name)) - continue; - - if (dfu_mode) { - if (match_serial_dfu != NULL && strcmp(match_serial_dfu, serial_name)) - continue; - } else { - if (match_serial != NULL && strcmp(match_serial, serial_name)) - continue; - } - - pdfu = dfu_malloc(sizeof(*pdfu)); - - memset(pdfu, 0, sizeof(*pdfu)); - - pdfu->func_dfu = func_dfu; - pdfu->dev = libusb_ref_device(dev); - pdfu->quirks = get_quirks(desc->idVendor, - desc->idProduct, desc->bcdDevice); - pdfu->vendor = desc->idVendor; - pdfu->product = desc->idProduct; - pdfu->bcdDevice = desc->bcdDevice; - pdfu->configuration = cfg->bConfigurationValue; - pdfu->interface = intf->bInterfaceNumber; - pdfu->altsetting = intf->bAlternateSetting; - pdfu->devnum = libusb_get_device_address(dev); - pdfu->busnum = libusb_get_bus_number(dev); - pdfu->alt_name = strdup(alt_name); - if (pdfu->alt_name == NULL) - errx(EX_SOFTWARE, "Out of memory"); - pdfu->serial_name = strdup(serial_name); - if (pdfu->serial_name == NULL) - errx(EX_SOFTWARE, "Out of memory"); - if (dfu_mode) - pdfu->flags |= DFU_IFF_DFU; - if (pdfu->quirks & QUIRK_FORCE_DFU11) { - pdfu->func_dfu.bcdDFUVersion = - libusb_cpu_to_le16(0x0110); - } - pdfu->bMaxPacketSize0 = desc->bMaxPacketSize0; - - /* queue into list */ - pdfu->next = dfu_root; - dfu_root = pdfu; - } - } - libusb_free_config_descriptor(cfg); - } -} - -void probe_devices(libusb_context *ctx) -{ - libusb_device **list; - ssize_t num_devs; - ssize_t i; - - num_devs = libusb_get_device_list(ctx, &list); - for (i = 0; i < num_devs; ++i) { - struct libusb_device_descriptor desc; - struct libusb_device *dev = list[i]; - - if (match_bus > -1 && match_bus != libusb_get_bus_number(dev)) - continue; - if (match_device > -1 && match_device != libusb_get_device_address(dev)) - continue; - if (libusb_get_device_descriptor(dev, &desc)) - continue; - probe_configuration(dev, &desc); - } - libusb_free_device_list(list, 0); -} - -void disconnect_devices(void) -{ - struct dfu_if *pdfu; - struct dfu_if *prev = NULL; - - for (pdfu = dfu_root; pdfu != NULL; pdfu = pdfu->next) { - free(prev); - libusb_unref_device(pdfu->dev); - free(pdfu->alt_name); - free(pdfu->serial_name); - prev = pdfu; - } - free(prev); - dfu_root = NULL; -} - -void print_dfu_if(struct dfu_if *dfu_if) -{ - printf("Found %s: [%04x:%04x] ver=%04x, devnum=%u, cfg=%u, intf=%u, " - "alt=%u, name=\"%s\", serial=\"%s\"\n", - dfu_if->flags & DFU_IFF_DFU ? "DFU" : "Runtime", - dfu_if->vendor, dfu_if->product, - dfu_if->bcdDevice, dfu_if->devnum, - dfu_if->configuration, dfu_if->interface, - dfu_if->altsetting, dfu_if->alt_name, - dfu_if->serial_name); -} - -/* Walk the device tree and print out DFU devices */ -void list_dfu_interfaces(void) -{ - struct dfu_if *pdfu; - - for (pdfu = dfu_root; pdfu != NULL; pdfu = pdfu->next) - print_dfu_if(pdfu); -} diff --git a/macosx/src/dfu-util/src/dfu_util.h b/macosx/src/dfu-util/src/dfu_util.h deleted file mode 100644 index fc0c19dca..000000000 --- a/macosx/src/dfu-util/src/dfu_util.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef DFU_UTIL_H -#define DFU_UTIL_H - -/* USB string descriptor should contain max 126 UTF-16 characters - * but 253 would even accomodate any UTF-8 encoding */ -#define MAX_DESC_STR_LEN 253 - -enum mode { - MODE_NONE, - MODE_VERSION, - MODE_LIST, - MODE_DETACH, - MODE_UPLOAD, - MODE_DOWNLOAD -}; - -extern struct dfu_if *dfu_root; -extern int match_bus; -extern int match_device; -extern int match_vendor; -extern int match_product; -extern int match_vendor_dfu; -extern int match_product_dfu; -extern int match_config_index; -extern int match_iface_index; -extern int match_iface_alt_index; -extern const char *match_iface_alt_name; -extern const char *match_serial; -extern const char *match_serial_dfu; - -void probe_devices(libusb_context *); -void disconnect_devices(void); -void print_dfu_if(struct dfu_if *); -void list_dfu_interfaces(void); - -#endif /* DFU_UTIL_H */ diff --git a/macosx/src/dfu-util/src/dfuse.c b/macosx/src/dfu-util/src/dfuse.c deleted file mode 100644 index fce29fed6..000000000 --- a/macosx/src/dfu-util/src/dfuse.c +++ /dev/null @@ -1,652 +0,0 @@ -/* - * DfuSe specific functions - * - * This implements the ST Microsystems DFU extensions (DfuSe) - * as per the DfuSe 1.1a specification (ST documents AN3156, AN2606) - * The DfuSe file format is described in ST document UM0391. - * - * Copyright 2010-2014 Tormod Volden - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#include "portable.h" -#include "dfu.h" -#include "usb_dfu.h" -#include "dfu_file.h" -#include "dfuse.h" -#include "dfuse_mem.h" - -#define DFU_TIMEOUT 5000 - -extern int verbose; -static unsigned int last_erased_page = 1; /* non-aligned value, won't match */ -static struct memsegment *mem_layout; -static unsigned int dfuse_address = 0; -static unsigned int dfuse_length = 0; -static int dfuse_force = 0; -static int dfuse_leave = 0; -static int dfuse_unprotect = 0; -static int dfuse_mass_erase = 0; - -unsigned int quad2uint(unsigned char *p) -{ - return (*p + (*(p + 1) << 8) + (*(p + 2) << 16) + (*(p + 3) << 24)); -} - -void dfuse_parse_options(const char *options) -{ - char *end; - const char *endword; - unsigned int number; - - /* address, possibly empty, must be first */ - if (*options != ':') { - endword = strchr(options, ':'); - if (!endword) - endword = options + strlen(options); /* GNU strchrnul */ - - number = strtoul(options, &end, 0); - if (end == endword) { - dfuse_address = number; - } else { - errx(EX_IOERR, "Invalid dfuse address: %s", options); - } - options = endword; - } - - while (*options) { - if (*options == ':') { - options++; - continue; - } - endword = strchr(options, ':'); - if (!endword) - endword = options + strlen(options); - - if (!strncmp(options, "force", endword - options)) { - dfuse_force++; - options += 5; - continue; - } - if (!strncmp(options, "leave", endword - options)) { - dfuse_leave = 1; - options += 5; - continue; - } - if (!strncmp(options, "unprotect", endword - options)) { - dfuse_unprotect = 1; - options += 9; - continue; - } - if (!strncmp(options, "mass-erase", endword - options)) { - dfuse_mass_erase = 1; - options += 10; - continue; - } - - /* any valid number is interpreted as upload length */ - number = strtoul(options, &end, 0); - if (end == endword) { - dfuse_length = number; - } else { - errx(EX_IOERR, "Invalid dfuse modifier: %s", options); - } - options = endword; - } -} - -/* DFU_UPLOAD request for DfuSe 1.1a */ -int dfuse_upload(struct dfu_if *dif, const unsigned short length, - unsigned char *data, unsigned short transaction) -{ - int status; - - status = libusb_control_transfer(dif->dev_handle, - /* bmRequestType */ LIBUSB_ENDPOINT_IN | - LIBUSB_REQUEST_TYPE_CLASS | - LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_UPLOAD, - /* wValue */ transaction, - /* wIndex */ dif->interface, - /* Data */ data, - /* wLength */ length, - DFU_TIMEOUT); - if (status < 0) { - errx(EX_IOERR, "%s: libusb_control_msg returned %d", - __FUNCTION__, status); - } - return status; -} - -/* DFU_DNLOAD request for DfuSe 1.1a */ -int dfuse_download(struct dfu_if *dif, const unsigned short length, - unsigned char *data, unsigned short transaction) -{ - int status; - - status = libusb_control_transfer(dif->dev_handle, - /* bmRequestType */ LIBUSB_ENDPOINT_OUT | - LIBUSB_REQUEST_TYPE_CLASS | - LIBUSB_RECIPIENT_INTERFACE, - /* bRequest */ DFU_DNLOAD, - /* wValue */ transaction, - /* wIndex */ dif->interface, - /* Data */ data, - /* wLength */ length, - DFU_TIMEOUT); - if (status < 0) { - errx(EX_IOERR, "%s: libusb_control_transfer returned %d", - __FUNCTION__, status); - } - return status; -} - -/* DfuSe only commands */ -/* Leaves the device in dfuDNLOAD-IDLE state */ -int dfuse_special_command(struct dfu_if *dif, unsigned int address, - enum dfuse_command command) -{ - const char* dfuse_command_name[] = { "SET_ADDRESS" , "ERASE_PAGE", - "MASS_ERASE", "READ_UNPROTECT"}; - unsigned char buf[5]; - int length; - int ret; - struct dfu_status dst; - int firstpoll = 1; - - if (command == ERASE_PAGE) { - struct memsegment *segment; - int page_size; - - segment = find_segment(mem_layout, address); - if (!segment || !(segment->memtype & DFUSE_ERASABLE)) { - errx(EX_IOERR, "Page at 0x%08x can not be erased", - address); - } - page_size = segment->pagesize; - if (verbose > 1) - printf("Erasing page size %i at address 0x%08x, page " - "starting at 0x%08x\n", page_size, address, - address & ~(page_size - 1)); - buf[0] = 0x41; /* Erase command */ - length = 5; - last_erased_page = address & ~(page_size - 1); - } else if (command == SET_ADDRESS) { - if (verbose > 2) - printf(" Setting address pointer to 0x%08x\n", - address); - buf[0] = 0x21; /* Set Address Pointer command */ - length = 5; - } else if (command == MASS_ERASE) { - buf[0] = 0x41; /* Mass erase command when length = 1 */ - length = 1; - } else if (command == READ_UNPROTECT) { - buf[0] = 0x92; - length = 1; - } else { - errx(EX_IOERR, "Non-supported special command %d", command); - } - buf[1] = address & 0xff; - buf[2] = (address >> 8) & 0xff; - buf[3] = (address >> 16) & 0xff; - buf[4] = (address >> 24) & 0xff; - - ret = dfuse_download(dif, length, buf, 0); - if (ret < 0) { - errx(EX_IOERR, "Error during special command \"%s\" download", - dfuse_command_name[command]); - } - do { - ret = dfu_get_status(dif, &dst); - if (ret < 0) { - errx(EX_IOERR, "Error during special command \"%s\" get_status", - dfuse_command_name[command]); - } - if (firstpoll) { - firstpoll = 0; - if (dst.bState != DFU_STATE_dfuDNBUSY) { - printf("state(%u) = %s, status(%u) = %s\n", dst.bState, - dfu_state_to_string(dst.bState), dst.bStatus, - dfu_status_to_string(dst.bStatus)); - errx(EX_IOERR, "Wrong state after command \"%s\" download", - dfuse_command_name[command]); - } - } - /* wait while command is executed */ - if (verbose) - printf(" Poll timeout %i ms\n", dst.bwPollTimeout); - milli_sleep(dst.bwPollTimeout); - if (command == READ_UNPROTECT) - return ret; - } while (dst.bState == DFU_STATE_dfuDNBUSY); - - if (dst.bStatus != DFU_STATUS_OK) { - errx(EX_IOERR, "%s not correctly executed", - dfuse_command_name[command]); - } - return ret; -} - -int dfuse_dnload_chunk(struct dfu_if *dif, unsigned char *data, int size, - int transaction) -{ - int bytes_sent; - struct dfu_status dst; - int ret; - - ret = dfuse_download(dif, size, size ? data : NULL, transaction); - if (ret < 0) { - errx(EX_IOERR, "Error during download"); - return ret; - } - bytes_sent = ret; - - do { - ret = dfu_get_status(dif, &dst); - if (ret < 0) { - errx(EX_IOERR, "Error during download get_status"); - return ret; - } - milli_sleep(dst.bwPollTimeout); - } while (dst.bState != DFU_STATE_dfuDNLOAD_IDLE && - dst.bState != DFU_STATE_dfuERROR && - dst.bState != DFU_STATE_dfuMANIFEST); - - if (dst.bState == DFU_STATE_dfuMANIFEST) - printf("Transitioning to dfuMANIFEST state\n"); - - if (dst.bStatus != DFU_STATUS_OK) { - printf(" failed!\n"); - printf("state(%u) = %s, status(%u) = %s\n", dst.bState, - dfu_state_to_string(dst.bState), dst.bStatus, - dfu_status_to_string(dst.bStatus)); - return -1; - } - return bytes_sent; -} - -int dfuse_do_upload(struct dfu_if *dif, int xfer_size, int fd, - const char *dfuse_options) -{ - int total_bytes = 0; - int upload_limit = 0; - unsigned char *buf; - int transaction; - int ret; - - buf = dfu_malloc(xfer_size); - - if (dfuse_options) - dfuse_parse_options(dfuse_options); - if (dfuse_length) - upload_limit = dfuse_length; - if (dfuse_address) { - struct memsegment *segment; - - mem_layout = parse_memory_layout((char *)dif->alt_name); - if (!mem_layout) - errx(EX_IOERR, "Failed to parse memory layout"); - - segment = find_segment(mem_layout, dfuse_address); - if (!dfuse_force && - (!segment || !(segment->memtype & DFUSE_READABLE))) - errx(EX_IOERR, "Page at 0x%08x is not readable", - dfuse_address); - - if (!upload_limit) { - upload_limit = segment->end - dfuse_address + 1; - printf("Limiting upload to end of memory segment, " - "%i bytes\n", upload_limit); - } - dfuse_special_command(dif, dfuse_address, SET_ADDRESS); - dfu_abort_to_idle(dif); - } else { - /* Boot loader decides the start address, unknown to us */ - /* Use a short length to lower risk of running out of bounds */ - if (!upload_limit) - upload_limit = 0x4000; - printf("Limiting default upload to %i bytes\n", upload_limit); - } - - dfu_progress_bar("Upload", 0, 1); - - transaction = 2; - while (1) { - int rc; - - /* last chunk can be smaller than original xfer_size */ - if (upload_limit - total_bytes < xfer_size) - xfer_size = upload_limit - total_bytes; - rc = dfuse_upload(dif, xfer_size, buf, transaction++); - if (rc < 0) { - ret = rc; - goto out_free; - } - - dfu_file_write_crc(fd, 0, buf, rc); - total_bytes += rc; - - if (total_bytes < 0) - errx(EX_SOFTWARE, "Received too many bytes"); - - if (rc < xfer_size || total_bytes >= upload_limit) { - /* last block, return successfully */ - ret = total_bytes; - break; - } - dfu_progress_bar("Upload", total_bytes, upload_limit); - } - - dfu_progress_bar("Upload", total_bytes, total_bytes); - - dfu_abort_to_idle(dif); - if (dfuse_leave) { - dfuse_special_command(dif, dfuse_address, SET_ADDRESS); - dfuse_dnload_chunk(dif, NULL, 0, 2); /* Zero-size */ - } - - out_free: - free(buf); - - return ret; -} - -/* Writes an element of any size to the device, taking care of page erases */ -/* returns 0 on success, otherwise -EINVAL */ -int dfuse_dnload_element(struct dfu_if *dif, unsigned int dwElementAddress, - unsigned int dwElementSize, unsigned char *data, - int xfer_size) -{ - int p; - int ret; - struct memsegment *segment; - - /* Check at least that we can write to the last address */ - segment = - find_segment(mem_layout, dwElementAddress + dwElementSize - 1); - if (!segment || !(segment->memtype & DFUSE_WRITEABLE)) { - errx(EX_IOERR, "Last page at 0x%08x is not writeable", - dwElementAddress + dwElementSize - 1); - } - - dfu_progress_bar("Download", 0, 1); - - for (p = 0; p < (int)dwElementSize; p += xfer_size) { - int page_size; - unsigned int erase_address; - unsigned int address = dwElementAddress + p; - int chunk_size = xfer_size; - - segment = find_segment(mem_layout, address); - if (!segment || !(segment->memtype & DFUSE_WRITEABLE)) { - errx(EX_IOERR, "Page at 0x%08x is not writeable", - address); - } - page_size = segment->pagesize; - - /* check if this is the last chunk */ - if (p + chunk_size > (int)dwElementSize) - chunk_size = dwElementSize - p; - - /* Erase only for flash memory downloads */ - if ((segment->memtype & DFUSE_ERASABLE) && !dfuse_mass_erase) { - /* erase all involved pages */ - for (erase_address = address; - erase_address < address + chunk_size; - erase_address += page_size) - if ((erase_address & ~(page_size - 1)) != - last_erased_page) - dfuse_special_command(dif, - erase_address, - ERASE_PAGE); - - if (((address + chunk_size - 1) & ~(page_size - 1)) != - last_erased_page) { - if (verbose > 2) - printf(" Chunk extends into next page," - " erase it as well\n"); - dfuse_special_command(dif, - address + chunk_size - 1, - ERASE_PAGE); - } - } - - if (verbose) { - printf(" Download from image offset " - "%08x to memory %08x-%08x, size %i\n", - p, address, address + chunk_size - 1, - chunk_size); - } else { - dfu_progress_bar("Download", p, dwElementSize); - } - - dfuse_special_command(dif, address, SET_ADDRESS); - - /* transaction = 2 for no address offset */ - ret = dfuse_dnload_chunk(dif, data + p, chunk_size, 2); - if (ret != chunk_size) { - errx(EX_IOERR, "Failed to write whole chunk: " - "%i of %i bytes", ret, chunk_size); - return -EINVAL; - } - } - if (!verbose) - dfu_progress_bar("Download", dwElementSize, dwElementSize); - return 0; -} - -static void -dfuse_memcpy(unsigned char *dst, unsigned char **src, int *rem, int size) -{ - if (size > *rem) { - errx(EX_IOERR, "Corrupt DfuSe file: " - "Cannot read %d bytes from %d bytes", size, *rem); - } - if (dst != NULL) - memcpy(dst, *src, size); - (*src) += size; - (*rem) -= size; -} - -/* Download raw binary file to DfuSe device */ -int dfuse_do_bin_dnload(struct dfu_if *dif, int xfer_size, - struct dfu_file *file, unsigned int start_address) -{ - unsigned int dwElementAddress; - unsigned int dwElementSize; - unsigned char *data; - int ret; - - dwElementAddress = start_address; - dwElementSize = file->size.total - - file->size.suffix - file->size.prefix; - - printf("Downloading to address = 0x%08x, size = %i\n", - dwElementAddress, dwElementSize); - - data = file->firmware + file->size.prefix; - - ret = dfuse_dnload_element(dif, dwElementAddress, dwElementSize, data, - xfer_size); - if (ret != 0) - goto out_free; - - printf("File downloaded successfully\n"); - ret = dwElementSize; - - out_free: - return ret; -} - -/* Parse a DfuSe file and download contents to device */ -int dfuse_do_dfuse_dnload(struct dfu_if *dif, int xfer_size, - struct dfu_file *file) -{ - uint8_t dfuprefix[11]; - uint8_t targetprefix[274]; - uint8_t elementheader[8]; - int image; - int element; - int bTargets; - int bAlternateSetting; - int dwNbElements; - unsigned int dwElementAddress; - unsigned int dwElementSize; - uint8_t *data; - int ret; - int rem; - int bFirstAddressSaved = 0; - - rem = file->size.total - file->size.prefix - file->size.suffix; - data = file->firmware + file->size.prefix; - - /* Must be larger than a minimal DfuSe header and suffix */ - if (rem < (int)(sizeof(dfuprefix) + - sizeof(targetprefix) + sizeof(elementheader))) { - errx(EX_SOFTWARE, "File too small for a DfuSe file"); - } - - dfuse_memcpy(dfuprefix, &data, &rem, sizeof(dfuprefix)); - - if (strncmp((char *)dfuprefix, "DfuSe", 5)) { - errx(EX_IOERR, "No valid DfuSe signature"); - return -EINVAL; - } - if (dfuprefix[5] != 0x01) { - errx(EX_IOERR, "DFU format revision %i not supported", - dfuprefix[5]); - return -EINVAL; - } - bTargets = dfuprefix[10]; - printf("file contains %i DFU images\n", bTargets); - - for (image = 1; image <= bTargets; image++) { - printf("parsing DFU image %i\n", image); - dfuse_memcpy(targetprefix, &data, &rem, sizeof(targetprefix)); - if (strncmp((char *)targetprefix, "Target", 6)) { - errx(EX_IOERR, "No valid target signature"); - return -EINVAL; - } - bAlternateSetting = targetprefix[6]; - dwNbElements = quad2uint((unsigned char *)targetprefix + 270); - printf("image for alternate setting %i, ", bAlternateSetting); - printf("(%i elements, ", dwNbElements); - printf("total size = %i)\n", - quad2uint((unsigned char *)targetprefix + 266)); - if (bAlternateSetting != dif->altsetting) - printf("Warning: Image does not match current alternate" - " setting.\n" - "Please rerun with the correct -a option setting" - " to download this image!\n"); - for (element = 1; element <= dwNbElements; element++) { - printf("parsing element %i, ", element); - dfuse_memcpy(elementheader, &data, &rem, sizeof(elementheader)); - dwElementAddress = - quad2uint((unsigned char *)elementheader); - dwElementSize = - quad2uint((unsigned char *)elementheader + 4); - printf("address = 0x%08x, ", dwElementAddress); - printf("size = %i\n", dwElementSize); - - if (!bFirstAddressSaved) { - bFirstAddressSaved = 1; - dfuse_address = dwElementAddress; - } - /* sanity check */ - if ((int)dwElementSize > rem) - errx(EX_SOFTWARE, "File too small for element size"); - - if (bAlternateSetting == dif->altsetting) { - ret = dfuse_dnload_element(dif, dwElementAddress, - dwElementSize, data, xfer_size); - } else { - ret = 0; - } - - /* advance read pointer */ - dfuse_memcpy(NULL, &data, &rem, dwElementSize); - - if (ret != 0) - return ret; - } - } - - if (rem != 0) - warnx("%d bytes leftover", rem); - - printf("done parsing DfuSe file\n"); - - return 0; -} - -int dfuse_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file, - const char *dfuse_options) -{ - int ret; - - if (dfuse_options) - dfuse_parse_options(dfuse_options); - mem_layout = parse_memory_layout((char *)dif->alt_name); - if (!mem_layout) { - errx(EX_IOERR, "Failed to parse memory layout"); - } - if (dfuse_unprotect) { - if (!dfuse_force) { - errx(EX_IOERR, "The read unprotect command " - "will erase the flash memory" - "and can only be used with force\n"); - } - dfuse_special_command(dif, 0, READ_UNPROTECT); - printf("Device disconnects, erases flash and resets now\n"); - exit(0); - } - if (dfuse_mass_erase) { - if (!dfuse_force) { - errx(EX_IOERR, "The mass erase command " - "can only be used with force"); - } - printf("Performing mass erase, this can take a moment\n"); - dfuse_special_command(dif, 0, MASS_ERASE); - } - if (dfuse_address) { - if (file->bcdDFU == 0x11a) { - errx(EX_IOERR, "This is a DfuSe file, not " - "meant for raw download"); - } - ret = dfuse_do_bin_dnload(dif, xfer_size, file, dfuse_address); - } else { - if (file->bcdDFU != 0x11a) { - warnx("Only DfuSe file version 1.1a is supported"); - errx(EX_IOERR, "(for raw binary download, use the " - "--dfuse-address option)"); - } - ret = dfuse_do_dfuse_dnload(dif, xfer_size, file); - } - free_segment_list(mem_layout); - - dfu_abort_to_idle(dif); - - if (dfuse_leave) { - dfuse_special_command(dif, dfuse_address, SET_ADDRESS); - dfuse_dnload_chunk(dif, NULL, 0, 2); /* Zero-size */ - } - return ret; -} diff --git a/macosx/src/dfu-util/src/dfuse.h b/macosx/src/dfu-util/src/dfuse.h deleted file mode 100644 index ed1108cfc..000000000 --- a/macosx/src/dfu-util/src/dfuse.h +++ /dev/null @@ -1,35 +0,0 @@ -/* This implements the ST Microsystems DFU extensions (DfuSe) - * as per the DfuSe 1.1a specification (Document UM0391) - * - * (C) 2010-2012 Tormod Volden - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef DFUSE_H -#define DFUSE_H - -#include "dfu.h" - -enum dfuse_command { SET_ADDRESS, ERASE_PAGE, MASS_ERASE, READ_UNPROTECT }; - -int dfuse_special_command(struct dfu_if *dif, unsigned int address, - enum dfuse_command command); -int dfuse_do_upload(struct dfu_if *dif, int xfer_size, int fd, - const char *dfuse_options); -int dfuse_do_dnload(struct dfu_if *dif, int xfer_size, struct dfu_file *file, - const char *dfuse_options); - -#endif /* DFUSE_H */ diff --git a/macosx/src/dfu-util/src/dfuse_mem.c b/macosx/src/dfu-util/src/dfuse_mem.c deleted file mode 100644 index a91aacf5f..000000000 --- a/macosx/src/dfu-util/src/dfuse_mem.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Helper functions for reading the memory map of a device - * following the ST DfuSe 1.1a specification. - * - * Copyright 2011-2014 Tormod Volden - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#include "portable.h" -#include "dfu_file.h" -#include "dfuse_mem.h" - -int add_segment(struct memsegment **segment_list, struct memsegment segment) -{ - struct memsegment *new_element; - - new_element = dfu_malloc(sizeof(struct memsegment)); - *new_element = segment; - new_element->next = NULL; - - if (*segment_list == NULL) - /* list can be empty on first call */ - *segment_list = new_element; - else { - struct memsegment *next_element; - - /* find last element in list */ - next_element = *segment_list; - while (next_element->next != NULL) - next_element = next_element->next; - next_element->next = new_element; - } - return 0; -} - -struct memsegment *find_segment(struct memsegment *segment_list, - unsigned int address) -{ - while (segment_list != NULL) { - if (segment_list->start <= address && - segment_list->end >= address) - return segment_list; - segment_list = segment_list->next; - } - return NULL; -} - -void free_segment_list(struct memsegment *segment_list) -{ - struct memsegment *next_element; - - while (segment_list->next != NULL) { - next_element = segment_list->next; - free(segment_list); - segment_list = next_element; - } - free(segment_list); -} - -/* Parse memory map from interface descriptor string - * encoded as per ST document UM0424 section 4.3.2. - */ -struct memsegment *parse_memory_layout(char *intf_desc) -{ - - char multiplier, memtype; - unsigned int address; - int sectors, size; - char *name, *typestring; - int ret; - int count = 0; - char separator; - int scanned; - struct memsegment *segment_list = NULL; - struct memsegment segment; - - name = dfu_malloc(strlen(intf_desc)); - - ret = sscanf(intf_desc, "@%[^/]%n", name, &scanned); - if (ret < 1) { - free(name); - warnx("Could not read name, sscanf returned %d", ret); - return NULL; - } - printf("DfuSe interface name: \"%s\"\n", name); - - intf_desc += scanned; - typestring = dfu_malloc(strlen(intf_desc)); - - while (ret = sscanf(intf_desc, "/0x%x/%n", &address, &scanned), - ret > 0) { - - intf_desc += scanned; - while (ret = sscanf(intf_desc, "%d*%d%c%[^,/]%n", - §ors, &size, &multiplier, typestring, - &scanned), ret > 2) { - intf_desc += scanned; - - count++; - memtype = 0; - if (ret == 4) { - if (strlen(typestring) == 1 - && typestring[0] != '/') - memtype = typestring[0]; - else { - warnx("Parsing type identifier '%s' " - "failed for segment %i", - typestring, count); - continue; - } - } - - /* Quirk for STM32F4 devices */ - if (strcmp(name, "Device Feature") == 0) - memtype = 'e'; - - switch (multiplier) { - case 'B': - break; - case 'K': - size *= 1024; - break; - case 'M': - size *= 1024 * 1024; - break; - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - case 'g': - if (!memtype) { - warnx("Non-valid multiplier '%c', " - "interpreted as type " - "identifier instead", - multiplier); - memtype = multiplier; - break; - } - /* fallthrough if memtype was already set */ - default: - warnx("Non-valid multiplier '%c', " - "assuming bytes", multiplier); - } - - if (!memtype) { - warnx("No valid type for segment %d\n", count); - continue; - } - - segment.start = address; - segment.end = address + sectors * size - 1; - segment.pagesize = size; - segment.memtype = memtype & 7; - add_segment(&segment_list, segment); - - if (verbose) - printf("Memory segment at 0x%08x %3d x %4d = " - "%5d (%s%s%s)\n", - address, sectors, size, sectors * size, - memtype & DFUSE_READABLE ? "r" : "", - memtype & DFUSE_ERASABLE ? "e" : "", - memtype & DFUSE_WRITEABLE ? "w" : ""); - - address += sectors * size; - - separator = *intf_desc; - if (separator == ',') - intf_desc += 1; - else - break; - } /* while per segment */ - - } /* while per address */ - free(name); - free(typestring); - - return segment_list; -} diff --git a/macosx/src/dfu-util/src/dfuse_mem.h b/macosx/src/dfu-util/src/dfuse_mem.h deleted file mode 100644 index 0181f0c16..000000000 --- a/macosx/src/dfu-util/src/dfuse_mem.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Helper functions for reading the memory map in a device - * following the ST DfuSe 1.1a specification. - * - * (C) 2011 Tormod Volden - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef DFUSE_MEM_H -#define DFUSE_MEM_H - -#define DFUSE_READABLE 1 -#define DFUSE_ERASABLE 2 -#define DFUSE_WRITEABLE 4 - -struct memsegment { - unsigned int start; - unsigned int end; - int pagesize; - int memtype; - struct memsegment *next; -}; - -int add_segment(struct memsegment **list, struct memsegment new_element); - -struct memsegment *find_segment(struct memsegment *list, unsigned int address); - -void free_segment_list(struct memsegment *list); - -struct memsegment *parse_memory_layout(char *intf_desc_str); - -#endif /* DFUSE_MEM_H */ diff --git a/macosx/src/dfu-util/src/main.c b/macosx/src/dfu-util/src/main.c deleted file mode 100644 index acaed2f08..000000000 --- a/macosx/src/dfu-util/src/main.c +++ /dev/null @@ -1,699 +0,0 @@ -/* - * dfu-util - * - * Copyright 2007-2008 by OpenMoko, Inc. - * Copyright 2013-2014 Hans Petter Selasky - * - * Written by Harald Welte - * - * Based on existing code of dfu-programmer-0.4 - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "portable.h" -#include "dfu.h" -#include "usb_dfu.h" -#include "dfu_file.h" -#include "dfu_load.h" -#include "dfu_util.h" -#include "dfuse.h" -#include "quirks.h" - -#ifdef HAVE_USBPATH_H -#include -#endif - -int verbose = 0; - -struct dfu_if *dfu_root = NULL; - -int match_bus = -1; -int match_device = -1; -int match_vendor = -1; -int match_product = -1; -int match_vendor_dfu = -1; -int match_product_dfu = -1; -int match_config_index = -1; -int match_iface_index = -1; -int match_iface_alt_index = -1; -const char *match_iface_alt_name = NULL; -const char *match_serial = NULL; -const char *match_serial_dfu = NULL; - -static int parse_match_value(const char *str, int default_value) -{ - char *remainder; - int value; - - if (str == NULL) { - value = default_value; - } else if (*str == '*') { - value = -1; /* Match anything */ - } else if (*str == '-') { - value = 0x10000; /* Impossible vendor/product ID */ - } else { - value = strtoul(str, &remainder, 16); - if (remainder == str) { - value = default_value; - } - } - return value; -} - -static void parse_vendprod(const char *str) -{ - const char *comma; - const char *colon; - - /* Default to match any DFU device in runtime or DFU mode */ - match_vendor = -1; - match_product = -1; - match_vendor_dfu = -1; - match_product_dfu = -1; - - comma = strchr(str, ','); - if (comma == str) { - /* DFU mode vendor/product being specified without any runtime - * vendor/product specification, so don't match any runtime device */ - match_vendor = match_product = 0x10000; - } else { - colon = strchr(str, ':'); - if (colon != NULL) { - ++colon; - if ((comma != NULL) && (colon > comma)) { - colon = NULL; - } - } - match_vendor = parse_match_value(str, match_vendor); - match_product = parse_match_value(colon, match_product); - if (comma != NULL) { - /* Both runtime and DFU mode vendor/product specifications are - * available, so default DFU mode match components to the given - * runtime match components */ - match_vendor_dfu = match_vendor; - match_product_dfu = match_product; - } - } - if (comma != NULL) { - ++comma; - colon = strchr(comma, ':'); - if (colon != NULL) { - ++colon; - } - match_vendor_dfu = parse_match_value(comma, match_vendor_dfu); - match_product_dfu = parse_match_value(colon, match_product_dfu); - } -} - -static void parse_serial(char *str) -{ - char *comma; - - match_serial = str; - comma = strchr(str, ','); - if (comma == NULL) { - match_serial_dfu = match_serial; - } else { - *comma++ = 0; - match_serial_dfu = comma; - } - if (*match_serial == 0) match_serial = NULL; - if (*match_serial_dfu == 0) match_serial_dfu = NULL; -} - -#ifdef HAVE_USBPATH_H - -static int resolve_device_path(char *path) -{ - int res; - - res = usb_path2devnum(path); - if (res < 0) - return -EINVAL; - if (!res) - return 0; - - match_bus = atoi(path); - match_device = res; - - return 0; -} - -#else /* HAVE_USBPATH_H */ - -static int resolve_device_path(char *path) -{ - (void)path; /* Eliminate unused variable warning */ - errx(EX_SOFTWARE, "USB device paths are not supported by this dfu-util.\n"); -} - -#endif /* !HAVE_USBPATH_H */ - -static void help(void) -{ - fprintf(stderr, "Usage: dfu-util [options] ...\n" - " -h --help\t\t\tPrint this help message\n" - " -V --version\t\t\tPrint the version number\n" - " -v --verbose\t\t\tPrint verbose debug statements\n" - " -l --list\t\t\tList currently attached DFU capable devices\n"); - fprintf(stderr, " -e --detach\t\t\tDetach currently attached DFU capable devices\n" - " -E --detach-delay seconds\tTime to wait before reopening a device after detach\n" - " -d --device :[,:]\n" - "\t\t\t\tSpecify Vendor/Product ID(s) of DFU device\n" - " -p --path \tSpecify path to DFU device\n" - " -c --cfg \t\tSpecify the Configuration of DFU device\n" - " -i --intf \t\tSpecify the DFU Interface number\n" - " -S --serial [,]\n" - "\t\t\t\tSpecify Serial String of DFU device\n" - " -a --alt \t\tSpecify the Altsetting of the DFU Interface\n" - "\t\t\t\tby name or by number\n"); - fprintf(stderr, " -t --transfer-size \tSpecify the number of bytes per USB Transfer\n" - " -U --upload \t\tRead firmware from device into \n" - " -Z --upload-size \tSpecify the expected upload size in bytes\n" - " -D --download \t\tWrite firmware from into device\n" - " -R --reset\t\t\tIssue USB Reset signalling once we're finished\n" - " -s --dfuse-address
\tST DfuSe mode, specify target address for\n" - "\t\t\t\traw file download or upload. Not applicable for\n" - "\t\t\t\tDfuSe file (.dfu) downloads\n" - ); - exit(EX_USAGE); -} - -static void print_version(void) -{ - printf(PACKAGE_STRING "\n\n"); - printf("Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.\n" - "Copyright 2010-2014 Tormod Volden and Stefan Schmidt\n" - "This program is Free Software and has ABSOLUTELY NO WARRANTY\n" - "Please report bugs to " PACKAGE_BUGREPORT "\n\n"); -} - -static struct option opts[] = { - { "help", 0, 0, 'h' }, - { "version", 0, 0, 'V' }, - { "verbose", 0, 0, 'v' }, - { "list", 0, 0, 'l' }, - { "detach", 0, 0, 'e' }, - { "detach-delay", 1, 0, 'E' }, - { "device", 1, 0, 'd' }, - { "path", 1, 0, 'p' }, - { "configuration", 1, 0, 'c' }, - { "cfg", 1, 0, 'c' }, - { "interface", 1, 0, 'i' }, - { "intf", 1, 0, 'i' }, - { "altsetting", 1, 0, 'a' }, - { "alt", 1, 0, 'a' }, - { "serial", 1, 0, 'S' }, - { "transfer-size", 1, 0, 't' }, - { "upload", 1, 0, 'U' }, - { "upload-size", 1, 0, 'Z' }, - { "download", 1, 0, 'D' }, - { "reset", 0, 0, 'R' }, - { "dfuse-address", 1, 0, 's' }, - { 0, 0, 0, 0 } -}; - -int main(int argc, char **argv) -{ - int expected_size = 0; - unsigned int transfer_size = 0; - enum mode mode = MODE_NONE; - struct dfu_status status; - libusb_context *ctx; - struct dfu_file file; - char *end; - int final_reset = 0; - int ret; - int dfuse_device = 0; - int fd; - const char *dfuse_options = NULL; - int detach_delay = 5; - uint16_t runtime_vendor; - uint16_t runtime_product; - - memset(&file, 0, sizeof(file)); - - /* make sure all prints are flushed */ - setvbuf(stdout, NULL, _IONBF, 0); - - while (1) { - int c, option_index = 0; - c = getopt_long(argc, argv, "hVvleE:d:p:c:i:a:S:t:U:D:Rs:Z:", opts, - &option_index); - if (c == -1) - break; - - switch (c) { - case 'h': - help(); - break; - case 'V': - mode = MODE_VERSION; - break; - case 'v': - verbose++; - break; - case 'l': - mode = MODE_LIST; - break; - case 'e': - mode = MODE_DETACH; - match_iface_alt_index = 0; - match_iface_index = 0; - break; - case 'E': - detach_delay = atoi(optarg); - break; - case 'd': - parse_vendprod(optarg); - break; - case 'p': - /* Parse device path */ - ret = resolve_device_path(optarg); - if (ret < 0) - errx(EX_SOFTWARE, "Unable to parse '%s'", optarg); - if (!ret) - errx(EX_SOFTWARE, "Cannot find '%s'", optarg); - break; - case 'c': - /* Configuration */ - match_config_index = atoi(optarg); - break; - case 'i': - /* Interface */ - match_iface_index = atoi(optarg); - break; - case 'a': - /* Interface Alternate Setting */ - match_iface_alt_index = strtoul(optarg, &end, 0); - if (*end) { - match_iface_alt_name = optarg; - match_iface_alt_index = -1; - } - break; - case 'S': - parse_serial(optarg); - break; - case 't': - transfer_size = atoi(optarg); - break; - case 'U': - mode = MODE_UPLOAD; - file.name = optarg; - break; - case 'Z': - expected_size = atoi(optarg); - break; - case 'D': - mode = MODE_DOWNLOAD; - file.name = optarg; - break; - case 'R': - final_reset = 1; - break; - case 's': - dfuse_options = optarg; - break; - default: - help(); - break; - } - } - - print_version(); - if (mode == MODE_VERSION) { - exit(0); - } - - if (mode == MODE_NONE) { - fprintf(stderr, "You need to specify one of -D or -U\n"); - help(); - } - - if (match_config_index == 0) { - /* Handle "-c 0" (unconfigured device) as don't care */ - match_config_index = -1; - } - - if (mode == MODE_DOWNLOAD) { - dfu_load_file(&file, MAYBE_SUFFIX, MAYBE_PREFIX); - /* If the user didn't specify product and/or vendor IDs to match, - * use any IDs from the file suffix for device matching */ - if (match_vendor < 0 && file.idVendor != 0xffff) { - match_vendor = file.idVendor; - printf("Match vendor ID from file: %04x\n", match_vendor); - } - if (match_product < 0 && file.idProduct != 0xffff) { - match_product = file.idProduct; - printf("Match product ID from file: %04x\n", match_product); - } - } - - ret = libusb_init(&ctx); - if (ret) - errx(EX_IOERR, "unable to initialize libusb: %i", ret); - - if (verbose > 2) { - libusb_set_debug(ctx, 255); - } - - probe_devices(ctx); - - if (mode == MODE_LIST) { - list_dfu_interfaces(); - exit(0); - } - - if (dfu_root == NULL) { - errx(EX_IOERR, "No DFU capable USB device available"); - } else if (dfu_root->next != NULL) { - /* We cannot safely support more than one DFU capable device - * with same vendor/product ID, since during DFU we need to do - * a USB bus reset, after which the target device will get a - * new address */ - errx(EX_IOERR, "More than one DFU capable USB device found! " - "Try `--list' and specify the serial number " - "or disconnect all but one device\n"); - } - - /* We have exactly one device. Its libusb_device is now in dfu_root->dev */ - - printf("Opening DFU capable USB device...\n"); - ret = libusb_open(dfu_root->dev, &dfu_root->dev_handle); - if (ret || !dfu_root->dev_handle) - errx(EX_IOERR, "Cannot open device"); - - printf("ID %04x:%04x\n", dfu_root->vendor, dfu_root->product); - - printf("Run-time device DFU version %04x\n", - libusb_le16_to_cpu(dfu_root->func_dfu.bcdDFUVersion)); - - /* Transition from run-Time mode to DFU mode */ - if (!(dfu_root->flags & DFU_IFF_DFU)) { - int err; - /* In the 'first round' during runtime mode, there can only be one - * DFU Interface descriptor according to the DFU Spec. */ - - /* FIXME: check if the selected device really has only one */ - - runtime_vendor = dfu_root->vendor; - runtime_product = dfu_root->product; - - printf("Claiming USB DFU Runtime Interface...\n"); - if (libusb_claim_interface(dfu_root->dev_handle, dfu_root->interface) < 0) { - errx(EX_IOERR, "Cannot claim interface %d", - dfu_root->interface); - } - - if (libusb_set_interface_alt_setting(dfu_root->dev_handle, dfu_root->interface, 0) < 0) { - errx(EX_IOERR, "Cannot set alt interface zero"); - } - - printf("Determining device status: "); - - err = dfu_get_status(dfu_root, &status); - if (err == LIBUSB_ERROR_PIPE) { - printf("Device does not implement get_status, assuming appIDLE\n"); - status.bStatus = DFU_STATUS_OK; - status.bwPollTimeout = 0; - status.bState = DFU_STATE_appIDLE; - status.iString = 0; - } else if (err < 0) { - errx(EX_IOERR, "error get_status"); - } else { - printf("state = %s, status = %d\n", - dfu_state_to_string(status.bState), status.bStatus); - } - milli_sleep(status.bwPollTimeout); - - switch (status.bState) { - case DFU_STATE_appIDLE: - case DFU_STATE_appDETACH: - printf("Device really in Runtime Mode, send DFU " - "detach request...\n"); - if (dfu_detach(dfu_root->dev_handle, - dfu_root->interface, 1000) < 0) { - warnx("error detaching"); - } - if (dfu_root->func_dfu.bmAttributes & USB_DFU_WILL_DETACH) { - printf("Device will detach and reattach...\n"); - } else { - printf("Resetting USB...\n"); - ret = libusb_reset_device(dfu_root->dev_handle); - if (ret < 0 && ret != LIBUSB_ERROR_NOT_FOUND) - errx(EX_IOERR, "error resetting " - "after detach"); - } - break; - case DFU_STATE_dfuERROR: - printf("dfuERROR, clearing status\n"); - if (dfu_clear_status(dfu_root->dev_handle, - dfu_root->interface) < 0) { - errx(EX_IOERR, "error clear_status"); - } - /* fall through */ - default: - warnx("WARNING: Runtime device already in DFU state ?!?"); - libusb_release_interface(dfu_root->dev_handle, - dfu_root->interface); - goto dfustate; - } - libusb_release_interface(dfu_root->dev_handle, - dfu_root->interface); - libusb_close(dfu_root->dev_handle); - dfu_root->dev_handle = NULL; - - if (mode == MODE_DETACH) { - libusb_exit(ctx); - exit(0); - } - - /* keeping handles open might prevent re-enumeration */ - disconnect_devices(); - - milli_sleep(detach_delay * 1000); - - /* Change match vendor and product to impossible values to force - * only DFU mode matches in the following probe */ - match_vendor = match_product = 0x10000; - - probe_devices(ctx); - - if (dfu_root == NULL) { - errx(EX_IOERR, "Lost device after RESET?"); - } else if (dfu_root->next != NULL) { - errx(EX_IOERR, "More than one DFU capable USB device found! " - "Try `--list' and specify the serial number " - "or disconnect all but one device"); - } - - /* Check for DFU mode device */ - if (!(dfu_root->flags | DFU_IFF_DFU)) - errx(EX_SOFTWARE, "Device is not in DFU mode"); - - printf("Opening DFU USB Device...\n"); - ret = libusb_open(dfu_root->dev, &dfu_root->dev_handle); - if (ret || !dfu_root->dev_handle) { - errx(EX_IOERR, "Cannot open device"); - } - } else { - /* we're already in DFU mode, so we can skip the detach/reset - * procedure */ - /* If a match vendor/product was specified, use that as the runtime - * vendor/product, otherwise use the DFU mode vendor/product */ - runtime_vendor = match_vendor < 0 ? dfu_root->vendor : match_vendor; - runtime_product = match_product < 0 ? dfu_root->product : match_product; - } - -dfustate: -#if 0 - printf("Setting Configuration %u...\n", dfu_root->configuration); - if (libusb_set_configuration(dfu_root->dev_handle, dfu_root->configuration) < 0) { - errx(EX_IOERR, "Cannot set configuration"); - } -#endif - printf("Claiming USB DFU Interface...\n"); - if (libusb_claim_interface(dfu_root->dev_handle, dfu_root->interface) < 0) { - errx(EX_IOERR, "Cannot claim interface"); - } - - printf("Setting Alternate Setting #%d ...\n", dfu_root->altsetting); - if (libusb_set_interface_alt_setting(dfu_root->dev_handle, dfu_root->interface, dfu_root->altsetting) < 0) { - errx(EX_IOERR, "Cannot set alternate interface"); - } - -status_again: - printf("Determining device status: "); - if (dfu_get_status(dfu_root, &status ) < 0) { - errx(EX_IOERR, "error get_status"); - } - printf("state = %s, status = %d\n", - dfu_state_to_string(status.bState), status.bStatus); - - milli_sleep(status.bwPollTimeout); - - switch (status.bState) { - case DFU_STATE_appIDLE: - case DFU_STATE_appDETACH: - errx(EX_IOERR, "Device still in Runtime Mode!"); - break; - case DFU_STATE_dfuERROR: - printf("dfuERROR, clearing status\n"); - if (dfu_clear_status(dfu_root->dev_handle, dfu_root->interface) < 0) { - errx(EX_IOERR, "error clear_status"); - } - goto status_again; - break; - case DFU_STATE_dfuDNLOAD_IDLE: - case DFU_STATE_dfuUPLOAD_IDLE: - printf("aborting previous incomplete transfer\n"); - if (dfu_abort(dfu_root->dev_handle, dfu_root->interface) < 0) { - errx(EX_IOERR, "can't send DFU_ABORT"); - } - goto status_again; - break; - case DFU_STATE_dfuIDLE: - printf("dfuIDLE, continuing\n"); - break; - default: - break; - } - - if (DFU_STATUS_OK != status.bStatus ) { - printf("WARNING: DFU Status: '%s'\n", - dfu_status_to_string(status.bStatus)); - /* Clear our status & try again. */ - if (dfu_clear_status(dfu_root->dev_handle, dfu_root->interface) < 0) - errx(EX_IOERR, "USB communication error"); - if (dfu_get_status(dfu_root, &status) < 0) - errx(EX_IOERR, "USB communication error"); - if (DFU_STATUS_OK != status.bStatus) - errx(EX_SOFTWARE, "Status is not OK: %d", status.bStatus); - - milli_sleep(status.bwPollTimeout); - } - - printf("DFU mode device DFU version %04x\n", - libusb_le16_to_cpu(dfu_root->func_dfu.bcdDFUVersion)); - - if (dfu_root->func_dfu.bcdDFUVersion == libusb_cpu_to_le16(0x11a)) - dfuse_device = 1; - - /* If not overridden by the user */ - if (!transfer_size) { - transfer_size = libusb_le16_to_cpu( - dfu_root->func_dfu.wTransferSize); - if (transfer_size) { - printf("Device returned transfer size %i\n", - transfer_size); - } else { - errx(EX_IOERR, "Transfer size must be specified"); - } - } - -#ifdef HAVE_GETPAGESIZE -/* autotools lie when cross-compiling for Windows using mingw32/64 */ -#ifndef __MINGW32__ - /* limitation of Linux usbdevio */ - if ((int)transfer_size > getpagesize()) { - transfer_size = getpagesize(); - printf("Limited transfer size to %i\n", transfer_size); - } -#endif /* __MINGW32__ */ -#endif /* HAVE_GETPAGESIZE */ - - if (transfer_size < dfu_root->bMaxPacketSize0) { - transfer_size = dfu_root->bMaxPacketSize0; - printf("Adjusted transfer size to %i\n", transfer_size); - } - - switch (mode) { - case MODE_UPLOAD: - /* open for "exclusive" writing */ - fd = open(file.name, O_WRONLY | O_BINARY | O_CREAT | O_EXCL | O_TRUNC, 0666); - if (fd < 0) - err(EX_IOERR, "Cannot open file %s for writing", file.name); - - if (dfuse_device || dfuse_options) { - if (dfuse_do_upload(dfu_root, transfer_size, fd, - dfuse_options) < 0) - exit(1); - } else { - if (dfuload_do_upload(dfu_root, transfer_size, - expected_size, fd) < 0) { - exit(1); - } - } - close(fd); - break; - - case MODE_DOWNLOAD: - if (((file.idVendor != 0xffff && file.idVendor != runtime_vendor) || - (file.idProduct != 0xffff && file.idProduct != runtime_product)) && - ((file.idVendor != 0xffff && file.idVendor != dfu_root->vendor) || - (file.idProduct != 0xffff && file.idProduct != dfu_root->product))) { - errx(EX_IOERR, "Error: File ID %04x:%04x does " - "not match device (%04x:%04x or %04x:%04x)", - file.idVendor, file.idProduct, - runtime_vendor, runtime_product, - dfu_root->vendor, dfu_root->product); - } - if (dfuse_device || dfuse_options || file.bcdDFU == 0x11a) { - if (dfuse_do_dnload(dfu_root, transfer_size, &file, - dfuse_options) < 0) - exit(1); - } else { - if (dfuload_do_dnload(dfu_root, transfer_size, &file) < 0) - exit(1); - } - break; - case MODE_DETACH: - if (dfu_detach(dfu_root->dev_handle, dfu_root->interface, 1000) < 0) { - warnx("can't detach"); - } - break; - default: - errx(EX_IOERR, "Unsupported mode: %u", mode); - break; - } - - if (final_reset) { - if (dfu_detach(dfu_root->dev_handle, dfu_root->interface, 1000) < 0) { - /* Even if detach failed, just carry on to leave the - device in a known state */ - warnx("can't detach"); - } - printf("Resetting USB to switch back to runtime mode\n"); - ret = libusb_reset_device(dfu_root->dev_handle); - if (ret < 0 && ret != LIBUSB_ERROR_NOT_FOUND) { - errx(EX_IOERR, "error resetting after download"); - } - } - - libusb_close(dfu_root->dev_handle); - dfu_root->dev_handle = NULL; - libusb_exit(ctx); - - return (0); -} diff --git a/macosx/src/dfu-util/src/portable.h b/macosx/src/dfu-util/src/portable.h deleted file mode 100644 index cf8d5df38..000000000 --- a/macosx/src/dfu-util/src/portable.h +++ /dev/null @@ -1,72 +0,0 @@ - -#ifndef PORTABLE_H -#define PORTABLE_H - -#ifdef HAVE_CONFIG_H -# include "config.h" -#else -# define PACKAGE "dfu-util" -# define PACKAGE_VERSION "0.8-msvc" -# define PACKAGE_STRING "dfu-util 0.8-msvc" -# define PACKAGE_BUGREPORT "dfu-util@lists.gnumonks.org" -#endif /* HAVE_CONFIG_H */ - -#ifdef HAVE_FTRUNCATE -# include -#else -# include -#endif /* HAVE_FTRUNCATE */ - -#ifdef HAVE_NANOSLEEP -# include -# define milli_sleep(msec) do {\ - if (msec) {\ - struct timespec nanosleepDelay = { (msec) / 1000, ((msec) % 1000) * 1000000 };\ - nanosleep(&nanosleepDelay, NULL);\ - } } while (0) -#elif defined HAVE_WINDOWS_H -# define milli_sleep(msec) do {\ - if (msec) {\ - Sleep(msec);\ - } } while (0) -#else -# error "Can't get no sleep! Please report" -#endif /* HAVE_NANOSLEEP */ - -#ifdef HAVE_ERR -# include -#else -# include -# include -# define warnx(...) do {\ - fprintf(stderr, __VA_ARGS__);\ - fprintf(stderr, "\n"); } while (0) -# define errx(eval, ...) do {\ - warnx(__VA_ARGS__);\ - exit(eval); } while (0) -# define warn(...) do {\ - fprintf(stderr, "%s: ", strerror(errno));\ - warnx(__VA_ARGS__); } while (0) -# define err(eval, ...) do {\ - warn(__VA_ARGS__);\ - exit(eval); } while (0) -#endif /* HAVE_ERR */ - -#ifdef HAVE_SYSEXITS_H -# include -#else -# define EX_OK 0 /* successful termination */ -# define EX_USAGE 64 /* command line usage error */ -# define EX_SOFTWARE 70 /* internal software error */ -# define EX_IOERR 74 /* input/output error */ -#endif /* HAVE_SYSEXITS_H */ - -#ifndef O_BINARY -# define O_BINARY 0 -#endif - -#ifndef off_t -# define off_t long int -#endif - -#endif /* PORTABLE_H */ diff --git a/macosx/src/dfu-util/src/prefix.c b/macosx/src/dfu-util/src/prefix.c deleted file mode 100644 index be8e3faf3..000000000 --- a/macosx/src/dfu-util/src/prefix.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * dfu-prefix - * - * Copyright 2011-2012 Stefan Schmidt - * Copyright 2013 Hans Petter Selasky - * Copyright 2014 Uwe Bonnes - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#include "portable.h" -#include "dfu_file.h" - -enum mode { - MODE_NONE, - MODE_ADD, - MODE_DEL, - MODE_CHECK -}; - -int verbose; - -static void help(void) -{ - fprintf(stderr, "Usage: dfu-prefix [options] ...\n" - " -h --help\t\t\tPrint this help message\n" - " -V --version\t\t\tPrint the version number\n" - " -c --check \t\tCheck DFU prefix of \n" - " -D --delete \t\tDelete DFU prefix from \n" - " -a --add \t\tAdd DFU prefix to \n" - "In combination with -a:\n" - ); - fprintf(stderr, " -s --stellaris-address
Add TI Stellaris address prefix to \n" - "In combination with -D or -c:\n" - " -T --stellaris\t\tAct on TI Stellaris address prefix of \n" - "In combination with -a or -D or -c:\n" - " -L --lpc-prefix\t\tUse NXP LPC DFU prefix format\n" - ); - exit(EX_USAGE); -} - -static void print_version(void) -{ - printf("dfu-prefix (%s) %s\n\n", PACKAGE, PACKAGE_VERSION); - printf("Copyright 2011-2012 Stefan Schmidt, 2014 Uwe Bonnes\n" - "This program is Free Software and has ABSOLUTELY NO WARRANTY\n" - "Please report bugs to %s\n\n", PACKAGE_BUGREPORT); - -} - -static struct option opts[] = { - { "help", 0, 0, 'h' }, - { "version", 0, 0, 'V' }, - { "check", 1, 0, 'c' }, - { "add", 1, 0, 'a' }, - { "delete", 1, 0, 'D' }, - { "stellaris-address", 1, 0, 's' }, - { "stellaris", 0, 0, 'T' }, - { "LPC", 0, 0, 'L' }, -}; -int main(int argc, char **argv) -{ - struct dfu_file file; - enum mode mode = MODE_NONE; - enum prefix_type type = ZERO_PREFIX; - uint32_t lmdfu_flash_address = 0; - char *end; - - /* make sure all prints are flushed */ - setvbuf(stdout, NULL, _IONBF, 0); - - print_version(); - - memset(&file, 0, sizeof(file)); - - while (1) { - int c, option_index = 0; - c = getopt_long(argc, argv, "hVc:a:D:p:v:d:s:TL", opts, - &option_index); - if (c == -1) - break; - - switch (c) { - case 'h': - help(); - break; - case 'V': - exit(0); - break; - case 'D': - file.name = optarg; - mode = MODE_DEL; - break; - case 'c': - file.name = optarg; - mode = MODE_CHECK; - break; - case 'a': - file.name = optarg; - mode = MODE_ADD; - break; - case 's': - lmdfu_flash_address = strtoul(optarg, &end, 0); - if (*end) { - errx(EX_IOERR, "Invalid lmdfu " - "address: %s", optarg); - } - /* fall-through */ - case 'T': - type = LMDFU_PREFIX; - break; - case 'L': - type = LPCDFU_UNENCRYPTED_PREFIX; - break; - default: - help(); - break; - } - } - - if (!file.name) { - fprintf(stderr, "You need to specify a filename\n"); - help(); - } - - switch(mode) { - case MODE_ADD: - if (type == ZERO_PREFIX) - errx(EX_IOERR, "Prefix type must be specified"); - dfu_load_file(&file, MAYBE_SUFFIX, NO_PREFIX); - file.lmdfu_address = lmdfu_flash_address; - file.prefix_type = type; - printf("Adding prefix to file\n"); - dfu_store_file(&file, file.size.suffix != 0, 1); - break; - - case MODE_CHECK: - dfu_load_file(&file, MAYBE_SUFFIX, MAYBE_PREFIX); - show_suffix_and_prefix(&file); - if (type > ZERO_PREFIX && file.prefix_type != type) - errx(EX_IOERR, "No prefix of requested type"); - break; - - case MODE_DEL: - dfu_load_file(&file, MAYBE_SUFFIX, NEEDS_PREFIX); - if (type > ZERO_PREFIX && file.prefix_type != type) - errx(EX_IOERR, "No prefix of requested type"); - printf("Removing prefix from file\n"); - /* if there was a suffix, rewrite it */ - dfu_store_file(&file, file.size.suffix != 0, 0); - break; - - default: - help(); - break; - } - return (0); -} diff --git a/macosx/src/dfu-util/src/quirks.c b/macosx/src/dfu-util/src/quirks.c deleted file mode 100644 index de394a615..000000000 --- a/macosx/src/dfu-util/src/quirks.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Simple quirk system for dfu-util - * - * Copyright 2010-2014 Tormod Volden - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include "quirks.h" - -uint16_t get_quirks(uint16_t vendor, uint16_t product, uint16_t bcdDevice) -{ - uint16_t quirks = 0; - - /* Device returns bogus bwPollTimeout values */ - if ((vendor == VENDOR_OPENMOKO || vendor == VENDOR_FIC) && - product >= PRODUCT_FREERUNNER_FIRST && - product <= PRODUCT_FREERUNNER_LAST) - quirks |= QUIRK_POLLTIMEOUT; - - if (vendor == VENDOR_VOTI && - product == PRODUCT_OPENPCD) - quirks |= QUIRK_POLLTIMEOUT; - - /* Reports wrong DFU version in DFU descriptor */ - if (vendor == VENDOR_LEAFLABS && - product == PRODUCT_MAPLE3 && - bcdDevice == 0x0200) - quirks |= QUIRK_FORCE_DFU11; - - /* old devices(bcdDevice == 0) return bogus bwPollTimeout values */ - if (vendor == VENDOR_SIEMENS && - (product == PRODUCT_PXM40 || product == PRODUCT_PXM50) && - bcdDevice == 0) - quirks |= QUIRK_POLLTIMEOUT; - - /* M-Audio Transit returns bogus bwPollTimeout values */ - if (vendor == VENDOR_MIDIMAN && - product == PRODUCT_TRANSIT) - quirks |= QUIRK_POLLTIMEOUT; - - return (quirks); -} diff --git a/macosx/src/dfu-util/src/quirks.h b/macosx/src/dfu-util/src/quirks.h deleted file mode 100644 index 0e4b3ec58..000000000 --- a/macosx/src/dfu-util/src/quirks.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef DFU_QUIRKS_H -#define DFU_QUIRKS_H - -#define VENDOR_OPENMOKO 0x1d50 /* Openmoko Freerunner / GTA02 */ -#define VENDOR_FIC 0x1457 /* Openmoko Freerunner / GTA02 */ -#define VENDOR_VOTI 0x16c0 /* OpenPCD Reader */ -#define VENDOR_LEAFLABS 0x1eaf /* Maple */ -#define VENDOR_SIEMENS 0x0908 /* Siemens AG */ -#define VENDOR_MIDIMAN 0x0763 /* Midiman */ - -#define PRODUCT_FREERUNNER_FIRST 0x5117 -#define PRODUCT_FREERUNNER_LAST 0x5126 -#define PRODUCT_OPENPCD 0x076b -#define PRODUCT_MAPLE3 0x0003 /* rev 3 and 5 */ -#define PRODUCT_PXM40 0x02c4 /* Siemens AG, PXM 40 */ -#define PRODUCT_PXM50 0x02c5 /* Siemens AG, PXM 50 */ -#define PRODUCT_TRANSIT 0x2806 /* M-Audio Transit (Midiman) */ - -#define QUIRK_POLLTIMEOUT (1<<0) -#define QUIRK_FORCE_DFU11 (1<<1) - -/* Fallback value, works for OpenMoko */ -#define DEFAULT_POLLTIMEOUT 5 - -uint16_t get_quirks(uint16_t vendor, uint16_t product, uint16_t bcdDevice); - -#endif /* DFU_QUIRKS_H */ diff --git a/macosx/src/dfu-util/src/suffix.c b/macosx/src/dfu-util/src/suffix.c deleted file mode 100644 index 0df248f51..000000000 --- a/macosx/src/dfu-util/src/suffix.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * dfu-suffix - * - * Copyright 2011-2012 Stefan Schmidt - * Copyright 2013 Hans Petter Selasky - * Copyright 2014 Tormod Volden - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include - -#include "portable.h" -#include "dfu_file.h" - -enum mode { - MODE_NONE, - MODE_ADD, - MODE_DEL, - MODE_CHECK -}; - -int verbose; - -static void help(void) -{ - fprintf(stderr, "Usage: dfu-suffix [options] ...\n" - " -h --help\t\t\tPrint this help message\n" - " -V --version\t\t\tPrint the version number\n" - " -c --check \t\tCheck DFU suffix of \n" - " -a --add \t\tAdd DFU suffix to \n" - " -D --delete \t\tDelete DFU suffix from \n" - " -p --pid \t\tAdd product ID into DFU suffix in \n" - " -v --vid \t\tAdd vendor ID into DFU suffix in \n" - " -d --did \t\tAdd device ID into DFU suffix in \n" - " -S --spec \t\tAdd DFU specification ID into DFU suffix in \n" - ); - exit(EX_USAGE); -} - -static void print_version(void) -{ - printf("dfu-suffix (%s) %s\n\n", PACKAGE, PACKAGE_VERSION); - printf("Copyright 2011-2012 Stefan Schmidt, 2013-2014 Tormod Volden\n" - "This program is Free Software and has ABSOLUTELY NO WARRANTY\n" - "Please report bugs to %s\n\n", PACKAGE_BUGREPORT); - -} - -static struct option opts[] = { - { "help", 0, 0, 'h' }, - { "version", 0, 0, 'V' }, - { "check", 1, 0, 'c' }, - { "add", 1, 0, 'a' }, - { "delete", 1, 0, 'D' }, - { "pid", 1, 0, 'p' }, - { "vid", 1, 0, 'v' }, - { "did", 1, 0, 'd' }, - { "spec", 1, 0, 'S' }, -}; - -int main(int argc, char **argv) -{ - struct dfu_file file; - int pid, vid, did, spec; - enum mode mode = MODE_NONE; - - /* make sure all prints are flushed */ - setvbuf(stdout, NULL, _IONBF, 0); - - print_version(); - - pid = vid = did = 0xffff; - spec = 0x0100; /* Default to bcdDFU version 1.0 */ - memset(&file, 0, sizeof(file)); - - while (1) { - int c, option_index = 0; - c = getopt_long(argc, argv, "hVc:a:D:p:v:d:S:s:T", opts, - &option_index); - if (c == -1) - break; - - switch (c) { - case 'h': - help(); - break; - case 'V': - exit(0); - break; - case 'D': - file.name = optarg; - mode = MODE_DEL; - break; - case 'p': - pid = strtol(optarg, NULL, 16); - break; - case 'v': - vid = strtol(optarg, NULL, 16); - break; - case 'd': - did = strtol(optarg, NULL, 16); - break; - case 'S': - spec = strtol(optarg, NULL, 16); - break; - case 'c': - file.name = optarg; - mode = MODE_CHECK; - break; - case 'a': - file.name = optarg; - mode = MODE_ADD; - break; - default: - help(); - break; - } - } - - if (!file.name) { - fprintf(stderr, "You need to specify a filename\n"); - help(); - } - - if (spec != 0x0100 && spec != 0x011a) { - fprintf(stderr, "Only DFU specification 0x0100 and 0x011a supported\n"); - help(); - } - - switch(mode) { - case MODE_ADD: - dfu_load_file(&file, NO_SUFFIX, MAYBE_PREFIX); - file.idVendor = vid; - file.idProduct = pid; - file.bcdDevice = did; - file.bcdDFU = spec; - /* always write suffix, rewrite prefix if there was one */ - dfu_store_file(&file, 1, file.size.prefix != 0); - printf("Suffix successfully added to file\n"); - break; - - case MODE_CHECK: - dfu_load_file(&file, NEEDS_SUFFIX, MAYBE_PREFIX); - show_suffix_and_prefix(&file); - break; - - case MODE_DEL: - dfu_load_file(&file, NEEDS_SUFFIX, MAYBE_PREFIX); - dfu_store_file(&file, 0, file.size.prefix != 0); - if (file.size.suffix) /* had a suffix */ - printf("Suffix successfully removed from file\n"); - break; - - default: - help(); - break; - } - return (0); -} diff --git a/macosx/src/dfu-util/src/usb_dfu.h b/macosx/src/dfu-util/src/usb_dfu.h deleted file mode 100644 index 660bedcbf..000000000 --- a/macosx/src/dfu-util/src/usb_dfu.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef USB_DFU_H -#define USB_DFU_H -/* USB Device Firmware Update Implementation for OpenPCD - * (C) 2006 by Harald Welte - * - * Protocol definitions for USB DFU - * - * This ought to be compliant to the USB DFU Spec 1.0 as available from - * http://www.usb.org/developers/devclass_docs/usbdfu10.pdf - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include - -#define USB_DT_DFU 0x21 - -#ifdef _MSC_VER -# pragma pack(push) -# pragma pack(1) -#endif /* _MSC_VER */ -struct usb_dfu_func_descriptor { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bmAttributes; -#define USB_DFU_CAN_DOWNLOAD (1 << 0) -#define USB_DFU_CAN_UPLOAD (1 << 1) -#define USB_DFU_MANIFEST_TOL (1 << 2) -#define USB_DFU_WILL_DETACH (1 << 3) - uint16_t wDetachTimeOut; - uint16_t wTransferSize; - uint16_t bcdDFUVersion; -#ifdef _MSC_VER -}; -# pragma pack(pop) -#elif defined __GNUC__ -} __attribute__ ((packed)); -#else - #warning "No way to pack struct on this compiler? This will break!" -#endif /* _MSC_VER */ - -#define USB_DT_DFU_SIZE 9 - -#define USB_TYPE_DFU (LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE) - -/* DFU class-specific requests (Section 3, DFU Rev 1.1) */ -#define USB_REQ_DFU_DETACH 0x00 -#define USB_REQ_DFU_DNLOAD 0x01 -#define USB_REQ_DFU_UPLOAD 0x02 -#define USB_REQ_DFU_GETSTATUS 0x03 -#define USB_REQ_DFU_CLRSTATUS 0x04 -#define USB_REQ_DFU_GETSTATE 0x05 -#define USB_REQ_DFU_ABORT 0x06 - -/* DFU_GETSTATUS bStatus values (Section 6.1.2, DFU Rev 1.1) */ -#define DFU_STATUS_OK 0x00 -#define DFU_STATUS_errTARGET 0x01 -#define DFU_STATUS_errFILE 0x02 -#define DFU_STATUS_errWRITE 0x03 -#define DFU_STATUS_errERASE 0x04 -#define DFU_STATUS_errCHECK_ERASED 0x05 -#define DFU_STATUS_errPROG 0x06 -#define DFU_STATUS_errVERIFY 0x07 -#define DFU_STATUS_errADDRESS 0x08 -#define DFU_STATUS_errNOTDONE 0x09 -#define DFU_STATUS_errFIRMWARE 0x0a -#define DFU_STATUS_errVENDOR 0x0b -#define DFU_STATUS_errUSBR 0x0c -#define DFU_STATUS_errPOR 0x0d -#define DFU_STATUS_errUNKNOWN 0x0e -#define DFU_STATUS_errSTALLEDPKT 0x0f - -enum dfu_state { - DFU_STATE_appIDLE = 0, - DFU_STATE_appDETACH = 1, - DFU_STATE_dfuIDLE = 2, - DFU_STATE_dfuDNLOAD_SYNC = 3, - DFU_STATE_dfuDNBUSY = 4, - DFU_STATE_dfuDNLOAD_IDLE = 5, - DFU_STATE_dfuMANIFEST_SYNC = 6, - DFU_STATE_dfuMANIFEST = 7, - DFU_STATE_dfuMANIFEST_WAIT_RST = 8, - DFU_STATE_dfuUPLOAD_IDLE = 9, - DFU_STATE_dfuERROR = 10 -}; - -#endif /* USB_DFU_H */ diff --git a/macosx/src/dfu-util/www/build.html b/macosx/src/dfu-util/www/build.html deleted file mode 100644 index f3036e40c..000000000 --- a/macosx/src/dfu-util/www/build.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - Building dfu-util from source - - - - - - - - - -
-

How to build dfu-util from source

- -

Prerequisites for building from git

-

Mac OS X

-

-First install MacPorts (and if you are on 10.6 or older, the Java Developer Package) and then run: -

-
-	sudo port install libusb-devel git-core
-
- -

FreeBSD

-
-	sudo pkg_add -r git pkgconf
-
- -

Ubuntu and Debian and derivatives

-
-	sudo apt-get build-dep dfu-util
-	sudo apt-get install libusb-1.0-0-dev
-
- -

Get the source code and build it

-

-The first time you will have to clone the git repository: -

-
-	git clone git://gitorious.org/dfu-util/dfu-util.git
-	cd dfu-util
-
-

-If you later want to update to latest git version, just run this: -

-
-	make maintainer-clean
-	git pull
-
-

-To build the source: -

-
-	./autogen.sh
-	./configure  # on most systems
-	make
-
- -

-If you are building on Mac OS X, replace the ./configure command with: -

-
-	./configure --libdir=/opt/local/lib --includedir=/opt/local/include  # on MacOSX only
-
- -

-Your dfu-util binary will be inside the src folder. Use it from there, or install it to /usr/local/bin by running "sudo make install". -

- -

Cross-building for Windows

- -

-Windows binaries can be built in a MinGW -environment, on a Windows computer or cross-hosted in another OS. -To build it on a Debian or Ubuntu host, first install build dependencies: -

-
-	sudo apt-get build-dep libusb-1.0-0 dfu-util
-	sudo apt-get install mingw32
-
- -

-The below example builds dfu-util 0.8 and libusb 1.0.19 from unpacked release -tarballs. If you instead build from git, you will have to run "./autogen.sh" -before running the "./configure" steps. -

- -
-mkdir -p build
-cd libusb-1.0.19
-PKG_CONFIG_PATH=$PWD/../build/lib/pkgconfig ./configure \
-    --host=i586-mingw32msvc --prefix=$PWD/../build
-# WINVER workaround needed for 1.0.19 only
-make CFLAGS="-DWINVER=0x0501"
-make install
-cd ..
-
-cd dfu-util-0.8
-PKG_CONFIG_PATH=$PWD/../build/lib/pkgconfig ./configure \
-    --host=i586-mingw32msvc --prefix=$PWD/../build
-make
-make install
-cd ..
-
-The build files will now be in build/bin. -

- -

Building on Windows using MinGW

-This assumes using release tarballs or having run ./autogen.sh on -the git sources. -
-cd libusb-1.0.19
-./configure --prefix=$HOME
-# WINVER workaround needed for 1.0.19 only
-# MKDIR_P setting should not really be needed...
-make CFLAGS="-DWINVER=0x0501" MKDIR_P="mkdir -p"
-make install
-cd ..
-
-cd dfu-util-0.8
-./configure USB_CFLAGS="-I$HOME/include/libusb-1.0" \
-            USB_LIBS="-L $HOME/lib -lusb-1.0" PKG_CONFIG=true
-make
-make install
-cd ..
-
-To link libusb statically into dfu-util.exe use instead of "make": -
-make LDFLAGS=-static
-
-The built executables (and DLL) will now be under $HOME/bin. - -

-[Back to dfu-util main page] -

- -
- - diff --git a/macosx/src/dfu-util/www/dfu-util.1.html b/macosx/src/dfu-util/www/dfu-util.1.html deleted file mode 100644 index 62ca40b5d..000000000 --- a/macosx/src/dfu-util/www/dfu-util.1.html +++ /dev/null @@ -1,411 +0,0 @@ - - -Man page of DFU-UTIL - - -

DFU-UTIL(1)

- -  -

NAME

- -dfu-util - Device firmware update (DFU) USB programmer -  -

SYNOPSIS

- - -
-
-dfu-util - --l - -[-v] - -[-d - -vid:pid[,vid:pid]] - -[-p - -path] - -[-c - -configuration] - -[-i - -interface] - -[-a - -alt-intf] - -[-S - -serial[,serial]] - - -
-dfu-util - -[-v] - -[-d - -vid:pid[,vid:pid]] - -[-p - -path] - -[-c - -configuration] - -[-i - -interface] - -[-a - -alt-intf] - -[-S - -serial[,serial]] - -[-t - -size] - -[-Z - -size] - -[-s - -address] - -[-R] - -[-D|-U - -file] - - -
-dfu-util - -[-hV] - -
-  -

DESCRIPTION

- -dfu-util - -is a program that implements the host (computer) side of the USB DFU -(Universal Serial Bus Device Firmware Upgrade) protocol. -

-dfu-util communicates with devices that implement the device side of the -USB DFU protocol, and is often used to upgrade the firmware of such -devices. -  -

OPTIONS

- -
-
-l, --list - -
-List the currently attached DFU capable USB devices. -
-d, --device [Run-Time VENDOR]:[Run-Time PRODUCT][,[DFU Mode VENDOR]:[DFU Mode PRODUCT]] - -
-
-Specify run-time and/or DFU mode vendor and/or product IDs of the DFU device -to work with. VENDOR and PRODUCT are hexadecimal numbers (no prefix -needed), "*" (match any), or "-" (match nothing). By default, any DFU capable -device in either run-time or DFU mode will be considered. -

-If you only have one standards-compliant DFU device attached to your computer, -this parameter is optional. However, as soon as you have multiple DFU devices -connected, dfu-util will detect this and abort, asking you to specify which -device to use. -

-If only run-time IDs are specified (e.g. "--device 1457:51ab"), then in -addition to the specified run-time IDs, any DFU mode devices will also be -considered. This is beneficial to allow a DFU capable device to be found -again after a switch to DFU mode, since the vendor and/or product ID of a -device usually changes in DFU mode. -

-If only DFU mode IDs are specified (e.g. "--device ,951:26"), then all -run-time devices will be ignored, making it easy to target a specific device in -DFU mode. -

-If both run-time and DFU mode IDs are specified (e.g. "--device -1457:51ab,:2bc"), then unspecified DFU mode components will use the run-time -value specified. -

-Examples: -

-
--device 1457:51ab,951:26 - -
-
- -Work with a device in run-time mode with -vendor ID 0x1457 and product ID 0x51ab, or in DFU mode with vendor ID 0x0951 -and product ID 0x0026 -

-

--device 1457:51ab,:2bc - -
-
- -Work with a device in run-time mode with vendor ID 0x1457 and product ID -0x51ab, or in DFU mode with vendor ID 0x1457 and product ID 0x02bc -

-

--device 1457:51ab - -
-
- -Work with a device in run-time mode with vendor ID 0x1457 and product ID -0x51ab, or in DFU mode with any vendor and product ID -

-

--device ,951:26 - -
-
- -Work with a device in DFU mode with vendor ID 0x0951 and product ID 0x0026 -

-

--device *,- - -
-
- -Work with any device in run-time mode, and ignore any device in DFU mode -

-

--device , - -
-
- -Ignore any device in run-time mode, and Work with any device in DFU mode -
-
- -
-p, --path BUS-PORT. ... .PORT - -
-Specify the path to the DFU device. -
-c, --cfg CONFIG-NR - -
-Specify the configuration of the DFU device. Note that this is only used for matching, the configuration is not set by dfu-util. -
-i, --intf INTF-NR - -
-Specify the DFU interface number. -
-a, --alt ALT - -
-Specify the altsetting of the DFU interface by name or by number. -
-S, --serial [Run-Time SERIAL][,[DFU Mode SERIAL]] - -
-Specify the run-time and DFU mode serial numbers used to further restrict -device matches. If multiple, identical DFU devices are simultaneously -connected to a system then vendor and product ID will be insufficient for -targeting a single device. In this situation, it may be possible to use this -parameter to specify a serial number which also must match. -

-If only a single serial number is specified, then the same serial number is -used in both run-time and DFU mode. An empty serial number will match any -serial number in the corresponding mode. -

-t, --transfer-size SIZE - -
-Specify the number of bytes per USB transfer. The optimal value is -usually determined automatically so this option is rarely useful. If -you need to use this option for a device, please report it as a bug. -
-Z, --upload-size SIZE - -
-Specify the expected upload size, in bytes. -
-U, --upload FILE - -
-Read firmware from device into -FILE. - -
-D, --download FILE - -
-Write firmware from -FILE - -into device. -
-R, --reset - -
-Issue USB reset signalling after upload or download has finished. -
-s, --dfuse-address address - -
-Specify target address for raw binary download/upload on DfuSe devices. Do -not - -use this for downloading DfuSe (.dfu) files. Modifiers can be added -to the address, separated by a colon, to perform special DfuSE commands such -as "leave" DFU mode, "unprotect" and "mass-erase" flash memory. -
-v, --verbose - -
-Print more information about dfu-util's operation. A second --v - -will turn on verbose logging of USB requests. Repeat this option to further -increase verbosity. -
-h, --help - -
-Show a help text and exit. -
-V, --version - -
-Show version information and exit. -
-  -

EXAMPLES

- -  -

Using dfu-util in the OpenMoko project

- -(with the Neo1973 hardware) -

- -Flashing the rootfs: -
- - $ dfu-util -a rootfs -R -D /path/to/openmoko-devel-image.jffs2 - -

- -Flashing the kernel: -
- - $ dfu-util -a kernel -R -D /path/to/uImage - -

- -Flashing the bootloader: -
- - $ dfu-util -a u-boot -R -D /path/to/u-boot.bin - -

- -Copying a kernel into RAM: -
- - $ dfu-util -a 0 -R -D /path/to/uImage - -

-Once this has finished, the kernel will be available at the default load -address of 0x32000000 in Neo1973 RAM. -Note: - -You cannot transfer more than 2MB of data into RAM using this method. -

-  -

Using dfu-util with a DfuSe device

- -

- -Flashing a -.dfu - -(special DfuSe format) file to the device: -
- - $ dfu-util -a 0 -D /path/to/dfuse-image.dfu - -

- -Reading out 1 KB of flash starting at address 0x8000000: -
- - $ dfu-util -a 0 -s 0x08000000:1024 -U newfile.bin - -

- -Flashing a binary file to address 0x8004000 of device memory and -ask the device to leave DFU mode: -
- - $ dfu-util -a 0 -s 0x08004000:leave -D /path/to/image.bin - - -  -

BUGS

- -Please report any bugs to the dfu-util mailing list at -dfu-util@lists.gnumonks.org. - -Please use the ---verbose option (repeated as necessary) to provide more - -information in your bug report. -  -

SEE ALSO

- -The dfu-util home page is -http://dfu-util.gnumonks.org - -  -

HISTORY

- -dfu-util was originally written for the OpenMoko project by -Weston Schmidt <weston_schmidt@yahoo.com> and -Harald Welte <hwelte@hmw-consulting.de>. Over time, nearly complete -support of DFU 1.0, DFU 1.1 and DfuSe ("1.1a") has been added. -  -

LICENCE

- -dfu-util - -is covered by the GNU General Public License (GPL), version 2 or later. -  -

COPYRIGHT

- -This manual page was originally written by Uwe Hermann <uwe@hermann-uwe.de>, -and is now part of the dfu-util project. -

- -


- 

Index

-
-
NAME
-
SYNOPSIS
-
DESCRIPTION
-
OPTIONS
-
EXAMPLES
-
-
Using dfu-util in the OpenMoko project
-
Using dfu-util with a DfuSe device
-
-
BUGS
-
SEE ALSO
-
HISTORY
-
LICENCE
-
COPYRIGHT
-
-
-This document was created by man2html, -using the doc/dfu-util.1 manual page from dfu-util 0.8.
-Time: 14:40:57 GMT, September 13, 2014 - - diff --git a/macosx/src/dfu-util/www/dfuse.html b/macosx/src/dfu-util/www/dfuse.html deleted file mode 100644 index 35e4ffa9f..000000000 --- a/macosx/src/dfu-util/www/dfuse.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - DfuSe and dfu-util - - - - - - - - - -
-

Using dfu-util with DfuSe devices

-

DfuSe

-

- DfuSe (DFU with ST Microsystems extensions) is a protocol based on - DFU 1.1. However, in expanding the functionality of the DFU protocol, - ST Microsystems broke all compatibility with the DFU 1.1 standard. - DfuSe devices report the DFU version as "1.1a". -

-

- DfuSe can be used to download firmware and other data - from a host computer to a conforming device (or upload in the - opposite direction) over USB similar to standard DFU. -

-

- The main difference from standard DFU is that the target address in - the device (flash) memory is specified by the host, so that a - download can be performed to parts of the device memory. The host - program is also responsible for erasing flash pages before they - are written to. -

-

.dfu files

-

- A special file format is defined by ST Microsystems to carry firmware - for DfuSe devices. The file contains target information such as address - and alternate interface information in addition to the binary data. - Several blocks of binary data can be combined in one .dfu file. -

-

Alternate interfaces

-

- Different memory locations of the device may have different - characteristics that the host program (dfu-util) has to take - into considerations, such as flash memory page size, read-only - versus read-write segments, the need to erase, and so on. - These parameters are reported by the device in the string - descriptors meant for describing the USB interfaces. - The host program decodes these strings to build a memory map of - the device. Different memory units or address spaces are listed - in separate alternate interface settings that must be selected - according to the memory unit to access. -

-

- Note that dfu-util leaves it to the user to select alternate - interface. When parsing a .dfu file it will skip file segments - not matching the selected alternate interface. Also, some - DfuSe device firmware implementations ignore the setting of - alternate interface and deduct the memory unit from the - address, since they have no address space overlap. -

-

DfuSe special commands

-

- DfuSe special commands are used by the host program during normal - downloads or uploads, such as SET_ADDRESS and ERASE_PAGE. Also - the normal DFU_DNLOAD and DFU_UPLOAD commands have special - implementations in DfuSe. - Many DfuSe devices also support commands to leave DFU mode, - read unprotect the flash memory or mass erase the flash memory. - dfu-util (from version 0.7) - supports adding "leave", "unprotect", or "mass-erase" - to the -s option argument to send such requests in combination - with a download request. These modifiers are separated with a colon. -

-

- Some DfuSe devices have their DfuSe bootloader running from flash - memory. Erasing the whole flash memory would therefore destroy - the DfuSe bootloader itself and practically brick the device - for most users. Any use of modifiers such as "unprotect" - and "mass-erase" therefore needs to be combined with the "force" - modifer. This is not included in the examples, to not encourage - ignorant users to copy and paste such instructions and shoot - themselves in the foot. -

-

- Devices based on for instance STM32F103 all run the bootloader - from flash, since there is no USB bootloader in ROM. -

-

- For instance STM32F107, STM32F2xx and STM32F4xx devices have a - DfuSe bootloader in ROM, so the flash can be erased while - keeping the device available for USB DFU transfers as long - as the device designers use this built-in bootloader and have - not implemented another DfuSe bootloader in flash that the user is - dependent upon. -

-

- Well-written bootloaders running from flash will report their - own memory region as read-only and not eraseable, but this does - not prevent dfu-util from sending a "unprotect" or "mass-erase" - request which overrides this, if the user insists. -

-

Example usage

-

- Flashing a .dfu (special DfuSe format) file to the device: -

-
-         $ dfu-util -a 0 -D /path/to/dfuse-image.dfu
-	
-

- Reading out 1 KB of flash starting at address 0x8000000: -

-
-         $ dfu-util -a 0 -s 0x08000000:1024 -U newfile.bin
-	
-

- Flashing a binary file to address 0x8004000 of device memory and ask - the device to leave DFU mode: -

-
-         $ dfu-util -a 0 -s 0x08004000:leave -D /path/to/image.bin
-	
-

- [Back to dfu-util main page] -

- -
- - diff --git a/macosx/src/dfu-util/www/index.html b/macosx/src/dfu-util/www/index.html deleted file mode 100644 index 108ddaf66..000000000 --- a/macosx/src/dfu-util/www/index.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - dfu-util Homepage - - - - - - - - - -
-

dfu-util - Device Firmware Upgrade Utilities

-

Description

-

- dfu-util is a host side implementation of the DFU 1.0 and DFU 1.1 specifications of the USB forum. - - DFU is intended to download and upload firmware to/from devices connected - over USB. It ranges from small devices like micro-controller boards - to mobile phones. Using dfu-util you can download firmware to your - DFU-enabled device or upload firmware from it. dfu-util has been - tested with the Openmoko Neo1973 and Freerunner and many other devices. -

-

- See the manual page for examples of use. -

-

Supported Devices

- -

Releases

-

- Releases of the dfu-util software can be found in the - releases folder. - The current release is 0.8. -

-

- We offer binaries for Microsoft Windows and some other platforms. - dfu-util uses libusb 1.0 to access your device, so - on Windows you have to register the device with the WinUSB driver - (alternatively libusb-win32 or libusbK), please see the libusbx wiki - for more details. -

-

- Mac OS X users can also get dfu-util from Homebrew with "brew install dfu-util" or from MacPorts. -

-

- Most Linux distributions ship dfu-util in binary packages for those - who do not want to compile dfu-util from source. - On Debian, Ubuntu, Fedora and Gentoo you can install it through the - normal software package tools. For other distributions -(namely OpenSuSe, Mandriva, and CentOS) Holger Freyther was kind enough to -provide binary packages through the Open Build Service. -

-

Development

-

- Development happens in a GIT repository. Browse it via the web -interface or clone it with: -

-
-	git clone git://gitorious.org/dfu-util/dfu-util.git
-	
-

- See our build instructions for how to - build the source on different platforms. -

-

License

-

- This software is licensed under the GPL version 2. -

-

Contact

-

- If you have questions about the development or use of dfu-util please - send an e-mail to our dedicated -mailing list for dfu-util. -

-

People

-

- dfu-util was originally written by - Harald Welte partially based on code from - dfu-programmer 0.4 and is currently maintained by Stefan Schmidt and - Tormod Volden. -

- -
- - diff --git a/macosx/src/dfu-util/www/simple.css b/macosx/src/dfu-util/www/simple.css deleted file mode 100644 index 98100bc5c..000000000 --- a/macosx/src/dfu-util/www/simple.css +++ /dev/null @@ -1,56 +0,0 @@ -body { - margin: 10px; - font-size: 0.82em; - background-color: #EEE; -} - -h1 { - clear: both; - padding: 0 0 12px 0; - margin: 0; - font-size: 2em; - font-weight: bold; -} - -h2 { - clear: both; - margin: 0; - font-size: 1.5em; - font-weight: normal; -} - -h3 { - clear: both; - margin: 15px 0 0 0; - font-size: 1.0em; - font-weight: bold; -} - -p { - line-height: 20px; - padding: 8px 0 8px 0; - margin: 0; - font-size: 1.1em; -} - -pre { - white-space: pre-wrap; - background-color: #CCC; - padding: 3px; -} - -a:hover { - background-color: #DDD; -} - -#middlebox { - width: 600px; - margin: 0px auto; - text-align: left; -} - -#footer { - height: 100px; - padding: 28px 3px 0 0; - margin: 20px 0 20px 0; -} diff --git a/macosx/src/upload-reset/upload-reset.c b/macosx/src/upload-reset/upload-reset.c deleted file mode 100644 index 1d03bff51..000000000 --- a/macosx/src/upload-reset/upload-reset.c +++ /dev/null @@ -1,161 +0,0 @@ -/* Copyright (C) 2015 Roger Clark - * - * 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. - * - * - * Utility to send the reset sequence on RTS and DTR and chars - * which resets the libmaple and causes the bootloader to be run - * - * - * - * Terminal control code by Heiko Noordhof (see copyright below) - */ - - - -/* Copyright (C) 2003 Heiko Noordhof - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Function prototypes (belong in a seperate header file) */ -int openserial(char *devicename); -void closeserial(void); -int setDTR(unsigned short level); -int setRTS(unsigned short level); - - -/* Two globals for use by this module only */ -static int fd; -static struct termios oldterminfo; - - -void closeserial(void) -{ - tcsetattr(fd, TCSANOW, &oldterminfo); - close(fd); -} - - -int openserial(char *devicename) -{ - struct termios attr; - - if ((fd = open(devicename, O_RDWR)) == -1) return 0; /* Error */ - atexit(closeserial); - - if (tcgetattr(fd, &oldterminfo) == -1) return 0; /* Error */ - attr = oldterminfo; - attr.c_cflag |= CRTSCTS | CLOCAL; - attr.c_oflag = 0; - if (tcflush(fd, TCIOFLUSH) == -1) return 0; /* Error */ - if (tcsetattr(fd, TCSANOW, &attr) == -1) return 0; /* Error */ - - /* Set the lines to a known state, and */ - /* finally return non-zero is successful. */ - return setRTS(0) && setDTR(0); -} - - -/* For the two functions below: - * level=0 to set line to LOW - * level=1 to set line to HIGH - */ - -int setRTS(unsigned short level) -{ - int status; - - if (ioctl(fd, TIOCMGET, &status) == -1) { - perror("setRTS(): TIOCMGET"); - return 0; - } - if (level) status |= TIOCM_RTS; - else status &= ~TIOCM_RTS; - if (ioctl(fd, TIOCMSET, &status) == -1) { - perror("setRTS(): TIOCMSET"); - return 0; - } - return 1; -} - - -int setDTR(unsigned short level) -{ - int status; - - if (ioctl(fd, TIOCMGET, &status) == -1) { - perror("setDTR(): TIOCMGET"); - return 0; - } - if (level) status |= TIOCM_DTR; - else status &= ~TIOCM_DTR; - if (ioctl(fd, TIOCMSET, &status) == -1) { - perror("setDTR: TIOCMSET"); - return 0; - } - return 1; -} - -/* This portion of code was written by Roger Clark - * It was informed by various other pieces of code written by Leaflabs to reset their - * Maple and Maple mini boards - */ - -main(int argc, char *argv[]) -{ - - if (argc<2 || argc >3) - { - printf("Usage upload-reset \n\r"); - return; - } - - if (openserial(argv[1])) - { - // Send magic sequence of DTR and RTS followed by the magic word "1EAF" - setRTS(false); - setDTR(false); - setDTR(true); - - usleep(50000L); - - setDTR(false); - setRTS(true); - setDTR(true); - - usleep(50000L); - - setDTR(false); - - usleep(50000L); - - write(fd,"1EAF",4); - - closeserial(); - if (argc==3) - { - usleep(atol(argv[2])*1000L); - } - } - else - { - printf("Failed to open serial device.\n\r"); - } -} diff --git a/macosx/upload-reset b/macosx/upload_reset similarity index 100% rename from macosx/upload-reset rename to macosx/upload_reset diff --git a/maple_upload.sh b/maple_upload.sh new file mode 100755 index 000000000..2b10603a9 --- /dev/null +++ b/maple_upload.sh @@ -0,0 +1,102 @@ +#!/bin/sh - + +set -e + +if [ $# -lt 4 ]; then + echo "Usage: $0 " >&2 + exit 1 +fi +altID="$2" +usbID="$3" +binfile="$4" +EXT="" + +UNAME_OS="$(uname -s)" +case "${UNAME_OS}" in + Linux*) + dummy_port_fullpath="/dev/$1" + OS_DIR="linux" + ;; + Darwin*) + dummy_port_fullpath="/dev/$1" + OS_DIR="macosx" + ;; + Windows*) + dummy_port_fullpath="$1" + OS_DIR="win" + EXT=".exe" + ;; + *) + echo "Unknown host OS: ${UNAME_OS}." + exit 1 + ;; +esac + +# Get the directory where the script is running. +DIR=$(cd "$(dirname "$0")" && pwd) + +# ----------------- IMPORTANT ----------------- +# The 2nd parameter to upload_reset is the delay after resetting +# before it exits. This value is in milliseonds. +# You may need to tune this to your system +# 750ms to 1500ms seems to work on my Mac +# This is less critical now that we automatically retry dfu-util + +if ! "${DIR}/${OS_DIR}/upload_reset${EXT}" "${dummy_port_fullpath}" 750; then + echo "****************************************" >&2 + echo "* Could not automatically reset device *" >&2 + echo "* Please manually reset device! *" >&2 + echo "****************************************" >&2 + sleep 2 # Wait for user to see message. +fi + +COUNTER=5 +while + if [ $# -eq 5 ]; then + "${DIR}/dfu-util.sh" -d "${usbID}" -a "${altID}" -D "${binfile}" "--dfuse-address $5" -R + else + "${DIR}/dfu-util.sh" -d "${usbID}" -a "${altID}" -D "${binfile}" -R + fi + ret=$? +do + if [ $ret -eq 0 ]; then + break + else + COUNTER=$((COUNTER - 1)) + if [ $ret -eq 74 ] && [ $COUNTER -gt 0 ]; then + # I/O error, probably because no DFU device was found + echo "Trying ${COUNTER} more time(s)" >&2 + sleep 1 + else + exit $ret + fi + fi +done + +printf "Waiting for %s serial..." "${dummy_port_fullpath}" >&2 +COUNTER=40 +if [ ${OS_DIR} = "win" ]; then + while [ $COUNTER -gt 0 ]; do + if ! "${DIR}/${OS_DIR}/check_port${EXT}" "${dummy_port_fullpath}"; then + COUNTER=$((COUNTER - 1)) + printf "." >&2 + sleep 0.1 + else + break + fi + done + +else + while [ ! -r "${dummy_port_fullpath}" ] && [ $COUNTER -gt 0 ]; do + COUNTER=$((COUNTER - 1)) + printf "." >&2 + sleep 0.1 + done +fi + +if [ $COUNTER -eq -0 ]; then + echo " Timed out." >&2 + exit 1 +else + echo " Done." >&2 +fi diff --git a/src/check_port/Makefile b/src/check_port/Makefile new file mode 100644 index 000000000..16a48cdfc --- /dev/null +++ b/src/check_port/Makefile @@ -0,0 +1,22 @@ +CC = gcc +SRC = $(wildcard *.c) +LIBSRC = $(wildcard ../libserialport/*.c) +OBJ = $(SRC:.c=.o) $(LIBSRC:.c=.o) +CFLAGS = -DLIBSERIALPORT_MSBUILD -Wall -I../libserialport +LDFLAGS = -lsetupapi +DEST = ../../win +BIN = $(SRC:.c=) + +.PHONY: all clean + +all: $(BIN) install + +$(BIN): $(OBJ) + $(CC) -o $@ $^ $(LDFLAGS) + +install: $(BIN) + @echo "$@ $^..." + @mv $(BIN) $(DEST)/ + +clean: + rm -f $(OBJ) $(DEST)/$(BIN) diff --git a/src/check_port/check_port.c b/src/check_port/check_port.c new file mode 100644 index 000000000..4dd9bb7fb --- /dev/null +++ b/src/check_port/check_port.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +/* Example of how to get a list of serial ports on the system. + * + * This example file is released to the public domain. */ + +int main(int argc, char **argv) +{ + /* A pointer to a null-terminated array of pointers to + * struct sp_port, which will contain the ports found.*/ + struct sp_port **port_list; + char *search_name = NULL; + bool found = false; + bool search = false; + if (argc>2) + { + printf("Usage %s \n", argv[0]); + return -1; + } + if (argc == 2) { + search_name = argv[1]; + search = true; + } + if (!search) { + printf("Getting port list.\n"); + } + /* Call sp_list_ports() to get the ports. The port_list + * pointer will be updated to refer to the array created. */ + enum sp_return result = sp_list_ports(&port_list); + + if (result != SP_OK) { + printf("sp_list_ports() failed!\n"); + return -1; + } + + /* Iterate through the ports. When port_list[i] is NULL + * this indicates the end of the list. */ + int i; + for (i = 0; port_list[i] != NULL; i++) { + struct sp_port *port = port_list[i]; + + /* Get the name of the port. */ + char *port_name = sp_get_port_name(port); + if (!search) { + printf("Found port: %s\n", port_name); + } else { + if (strcmp( search_name, port_name ) == 0) { + found = true; + break; + } + } + } + if (!search){ + printf("Found %d ports.\n", i); + printf("Freeing port list.\n"); + } + + /* Free the array created by sp_list_ports(). */ + sp_free_port_list(port_list); + + /* Note that this will also free all the sp_port structures + * it points to. If you want to keep one of them (e.g. to + * use that port in the rest of your program), take a copy + * of it first using sp_copy_port(). */ + + return (search) ? !found : 0; +} diff --git a/win/src/build_dfu-util.sh b/src/dfu-util/build_dfu-util.sh similarity index 96% rename from win/src/build_dfu-util.sh rename to src/dfu-util/build_dfu-util.sh index 3563f576c..eb4895f1e 100644 --- a/win/src/build_dfu-util.sh +++ b/src/dfu-util/build_dfu-util.sh @@ -5,7 +5,6 @@ sudo apt-get install build-essentials sudo apt-get install libusb-1.0-0-dev sudo apt-get install autoconf automake autotools-dev -cd dfu-util ./autogen.sh ./configure make diff --git a/src/libserialport/AUTHORS b/src/libserialport/AUTHORS new file mode 100644 index 000000000..6975761c5 --- /dev/null +++ b/src/libserialport/AUTHORS @@ -0,0 +1,27 @@ +------------------------------------------------------------------------------- +AUTHORS +------------------------------------------------------------------------------- + +Martin Ling conceived the idea for the library, designed the API and wrote much +of the implementation and documentation. + +The initial codebase was adapted from serial code in libsigrok, written by Bert +Vermeulen and Uwe Hermann, who gave permission for it to be relicensed under +the LGPL3+ for inclusion in libserialport. + +The package is maintained by Uwe Hermann, with input from Martin Ling. + +Aurelien Jacobs made several contributions, including the USB metadata API, +improvements to the port enumeration code, and eliminating the previous +dependence on libudev for enumeration on Linux. + +Uffe Jakobsen contributed the FreeBSD support. + +Matthias Heidbrink contributed support for non-standard baudrates on Mac OS X. + +Bug fixes have been contributed by Bert Vermeulen, silverbuddy, Marcus +Comstedt, Antti Nykanen, Michael B. Trausch and Janne Huttunen. + +For a full history of contributions, see the git history. + +Others have helped the project by contributing bug reports and discussion. diff --git a/src/libserialport/COPYING b/src/libserialport/COPYING new file mode 100644 index 000000000..65c5ca88a --- /dev/null +++ b/src/libserialport/COPYING @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/src/libserialport/NEWS b/src/libserialport/NEWS new file mode 100644 index 000000000..7afa688cb --- /dev/null +++ b/src/libserialport/NEWS @@ -0,0 +1,81 @@ +0.1.1 (2016-01-27) +------------------ + +Note: This release does NOT change the libserialport API or ABI in + backwards-incompatible ways. Programs using libserialport should + continue to work fine without recompiling or relinking. + + * New API calls: + - sp_get_port_description(): Obtain a user friendly port description. + - sp_get_port_transport(): Obtain the underlying transport type. + - sp_get_port_usb_bus_address(): Obtain the USB bus number & device address. + - sp_get_port_usb_vid_pid(): Obtain the USB VID and PID. + - sp_get_port_usb_manufacturer(): Obtain the USB manufacturer string. + - sp_get_port_usb_product(): Obtain the USB product string. + - sp_get_port_usb_serial(): Obtain the USB serial number string. + - sp_get_port_bluetooth_address(): Obtain the Bluetooth MAC address. + - sp_blocking_read_next(): Read bytes from the specified serial port, + returning as soon as any data is available. + * API related additions: + - enum sp_mode: Add SP_MODE_READ_WRITE. + - Add enum sp_transport with the following enum entries: + SP_TRANSPORT_NATIVE, SP_TRANSPORT_USB, SP_TRANSPORT_BLUETOOTH. + * Fix the build on platforms where port enumeration and/or port + metadata is not available or implemented. + * Build system: + - Don't set/override "user variables" such as CFLAGS or LDFLAGS, since + those are meant to be controlled by the "user" (bug #577). + - Modernize and cleanup autotools setup. + * Remove trailing commas in libserialport.h enum definitions to allow + the code to build with the -pedantic compiler option. + * Fix various issues to allow successful builds with -std=c99. + * Fix various (non-fatal) compiler warnings. + * Fix various memory leaks (bug #419, among others). + * Fix a potential overflow of the timeout parameter of poll(). + * Fix ReadFile() ERROR_IO_PENDING in sp_nonblocking_read() (bug #707). + * Fix a glibc >= 2.20 compiler warning for deprecated _BSD_SOURCE (bug #716). + * Rename a 'signals' parameter to 'signal_mask' to avoid a conflict with Qt. + * Fix two potential segfaults in sp_get_port_handle() and sp_get_config_*() + (which only occurred if the user incorrectly passed in a NULL argument). + * sp_list_ports(): Actually set list_ptr NULL as documented. + * Use "Port not open" debug message when a closed port is used (bug #710). + * Linux: + - The libudev requirement has been dropped (/sys is now used directly). + - Fix a build issue in the get_termios_get_ioctl() call (bug #396). + - Fix sp_flush() so that it only flushes the requested buffers. + - Fix a build error if BOTHER is not available (bug #363). + - If present, add the USB "description" for better port identification. + - Handle the case when /sys/class/tty/ entries are not symlinks. + * Windows: + - MinGW-w64 (mingw-w64.sf.net) is now required for building, and MinGW + (mingw.org) is no longer supported (bug #393). + - Fix a build issue due to a missing #include. + - Fix a build issue due to the missing -lsetupapi linker argument. + - Use libtool's -no-undefined option to allow shared (DLL) builds. + - Fix a compile error due to multiply or not defined GUIDs (bug #416). + - Fix a build issue related to the SP_PRIV/SP_API macros (bug #553). + - Fix a bug where an uninitialized pointer was free()'d (bug #512). + - Fix a bug wrt the SetupDiOpenDevRegKey() return code (bug #499). + - Fix a bug wrt restart of RX/error wait operations after read (bug #421). + - Fix a bug wrt WaitCommEvents() and/or fAbortOnError handling (bug #341). + - Fix USB iSerial queries on USB composite devices. + - Strip CR/LF from end of system error messages (bug #585). + - Avoid unnecessary calls to the SetCommTimeouts() function (bug #586). + - Fix a bug in the Windows implementation of sp_blocking_read_next(). + - Fix an ERROR_SEM_TIMEOUT related issue in sp_blocking_write(). + * FreeBSD: + - Implement serial port enumeration for FreeBSD systems. + * Android: + - Fix a portability issue wrt the unavailable 'serial_struct' (bug #376). + - Fix a portability issue wrt a readlinkat() call (bug #377). + * Mac OS X: + - Fix port listing on Mac OS X 10.11 (El Capitan). + * README: Various documentation updates and fixes. + * AUTHORS: Add/update list of contributors. + * Doxygen API docs: Various documentation updates and fixes. + +0.1.0 (2014-05-06) +------------------ + + * Initial release. + diff --git a/src/libserialport/README b/src/libserialport/README new file mode 100644 index 000000000..817dff743 --- /dev/null +++ b/src/libserialport/README @@ -0,0 +1,92 @@ +------------------------------------------------------------------------------- +libserialport: cross-platform library for accessing serial ports +------------------------------------------------------------------------------- + +libserialport is a minimal library written in C that is intended to take care +of the OS-specific details when writing software that uses serial ports. + +By writing your serial code to use libserialport, you enable it to work +transparently on any platform supported by the library. + +The operations that are supported are: + +- Port enumeration (obtaining a list of serial ports on the system). +- Obtaining port metadata (USB device information, Bluetooth address, etc). +- Opening and closing ports. +- Setting port parameters (baud rate, parity, etc). +- Reading, writing and flushing data. +- Obtaining error information. + +libserialport is an open source project released under the LGPL3+ license. + +Status +====== + +The library should build and work on any Windows or Unix-based system. If it +does not, please submit a bug. + +Enumeration is currently implemented on Windows, Mac OS X, FreeBSD and Linux. +On other systems enumeration is not supported, but ports can still be opened +by name and then used. + +If you know how to enumerate available ports on another OS, please submit a bug +with this information, or better still a patch implementing it. + +Dependencies +============ + +No other libraries are required. + +Building +======== + +On Windows, libserialport can be built with Visual Studio 2019 or with +the standalone MSBuild tool, using the solution and project files provided. + +For other environments, the package uses a GNU style build based on autotools. + +Run "./autogen.sh" to generate the build system, "./configure" to setup, then +"make" to build the library and "make install" to install it. + +Windows builds can also be created using the autotools build system, using the +MinGW-w64 toolchain from http://mingw-w64.sourceforge.net/ - either natively +in Windows with the MSYS2 environment, or cross-compiling from another system. + +To build from MSYS2, the following packages must be installed: autoconf, +automake-wrapper, libtool, make, and either mingw-w64-i686-gcc (for 32-bit) +or mingw-w64-x86_64-gcc (for 64-bit). Open either the "MSYS2 MinGW 32-bit" or +"MSYS2 MinGW 64-bit" command window from the Start menu and use this when +configuring and building the package. Using the "MSYS2 MSYS" shell will build +against the Cygwin compatibility layer; this works, but port enumeration and +metadata will not be available, and binaries will depend on Cygwin. The builds +produced by MinGW-w64 are normal Windows DLLs without additional dependencies. + +API +=== + +Doxygen API documentation is included. + +It can also be viewed online at: + + http://sigrok.org/api/libserialport/unstable/ + +Bug reports +=========== + +You can report bugs for libserialport at https://sigrok.org/bugzilla. + +Mailing list +============ + + https://lists.sourceforge.net/lists/listinfo/sigrok-devel + +IRC +=== + +You can find the developers in the #sigrok IRC channel on Libera.Chat. + +Website +======= + +http://sigrok.org/wiki/Libserialport + diff --git a/src/libserialport/config.h b/src/libserialport/config.h new file mode 100644 index 000000000..17391764b --- /dev/null +++ b/src/libserialport/config.h @@ -0,0 +1,111 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* clock_gettime is available. */ +#define HAVE_CLOCK_GETTIME 1 + +/* Define to 1 if you have the declaration of `BOTHER', and to 0 if you don't. + */ +#define HAVE_DECL_BOTHER 0 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DLFCN_H */ + +/* flock is available. */ +/* #undef HAVE_FLOCK */ + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* realpath is available. */ +/* #undef HAVE_REALPATH */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if the system has the type `struct serial_struct'. */ +/* #undef HAVE_STRUCT_SERIAL_STRUCT */ + +/* Define to 1 if the system has the type `struct termios2'. */ +/* #undef HAVE_STRUCT_TERMIOS2 */ + +/* Define to 1 if `c_ispeed' is a member of `struct termios2'. */ +/* #undef HAVE_STRUCT_TERMIOS2_C_ISPEED */ + +/* Define to 1 if `c_ospeed' is a member of `struct termios2'. */ +/* #undef HAVE_STRUCT_TERMIOS2_C_OSPEED */ + +/* Define to 1 if `c_ispeed' is a member of `struct termios'. */ +/* #undef HAVE_STRUCT_TERMIOS_C_ISPEED */ + +/* Define to 1 if `c_ospeed' is a member of `struct termios'. */ +/* #undef HAVE_STRUCT_TERMIOS_C_OSPEED */ + +/* sys/file.h is available. */ +#define HAVE_SYS_FILE_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Enumeration is unsupported. */ +/* #undef NO_ENUMERATION */ + +/* Port metadata is unavailable. */ +/* #undef NO_PORT_METADATA */ + +/* Macro preceding public API functions */ +#define SP_API + +/* . */ +#define SP_LIB_VERSION_AGE 1 + +/* . */ +#define SP_LIB_VERSION_CURRENT 1 + +/* . */ +#define SP_LIB_VERSION_REVISION 0 + +/* . */ +#define SP_LIB_VERSION_STRING "1:0:1" + +/* Macro preceding private functions */ +#define SP_PRIV + +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ +#define STDC_HEADERS 1 + +/* Number of bits in a file offset, on hosts where this is settable. */ +#define _FILE_OFFSET_BITS 64 + +/* Define for large files, on AIX-style hosts. */ +/* #undef _LARGE_FILES */ + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +#if HAVE_STRUCT_TERMIOS_C_ISPEED && HAVE_STRUCT_TERMIOS_C_OSPEED +# define HAVE_TERMIOS_SPEED 1 +#endif +#if HAVE_STRUCT_TERMIOS2_C_ISPEED && HAVE_STRUCT_TERMIOS2_C_OSPEED +# define HAVE_TERMIOS2_SPEED 1 +#endif diff --git a/src/libserialport/libserialport.h b/src/libserialport/libserialport.h new file mode 100644 index 000000000..7467f7438 --- /dev/null +++ b/src/libserialport/libserialport.h @@ -0,0 +1,1827 @@ +/* + * This file is part of the libserialport project. + * + * Copyright (C) 2013, 2015 Martin Ling + * Copyright (C) 2014 Uwe Hermann + * Copyright (C) 2014 Aurelien Jacobs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser General Public License + * along with this program. If not, see . + */ + +/** + * @mainpage libserialport API + * + * Introduction + * ============ + * + * libserialport is a minimal library written in C that is intended to take + * care of the OS-specific details when writing software that uses serial ports. + * + * By writing your serial code to use libserialport, you enable it to work + * transparently on any platform supported by the library. + * + * libserialport is an open source project released under the LGPL3+ license. + * + * The library is maintained by the [sigrok](http://sigrok.org/) project. See + * the [libserialport homepage](http://sigrok.org/wiki/Libserialport) for the + * latest information. + * + * Source code is maintained in git at + * [git://sigrok.org/libserialport](http://sigrok.org/gitweb/?p=libserialport.git). + * + * Bugs are tracked at http://sigrok.org/bugzilla/. + * + * The library was conceived and designed by Martin Ling, is maintained by + * Uwe Hermann, and has received contributions from several other developers. + * See the git history for full credits. + * + * API information + * =============== + * + * The API has been designed from scratch. It does not exactly resemble the + * serial API of any particular operating system. Instead it aims to provide + * a set of functions that can reliably be implemented across all operating + * systems. These form a sufficient basis for higher level behaviour to + * be implemented in a platform independent manner. + * + * If you are porting code written for a particular OS, you may find you need + * to restructure things somewhat, or do without some specialised features. + * For particular notes on porting existing code, see @ref Porting. + * + * Examples + * -------- + * + * Some simple example programs using libserialport are included in the + * @c examples directory in the source package: + * + * - @ref list_ports.c - Getting a list of ports present on the system. + * - @ref port_info.c - Getting information on a particular serial port. + * - @ref port_config.c - Accessing configuration settings of a port. + * - @ref send_receive.c - Sending and receiving data. + * - @ref await_events.c - Awaiting events on multiple ports. + * - @ref handle_errors.c - Handling errors returned from the library. + * + * These examples are linked with the API documentation. Each function + * in the API reference includes links to where it is used in an example + * program, and each appearance of a function in the examples links + * to that function's entry in the API reference. + * + * Headers + * ------- + * + * To use libserialport functions in your code, you should include the + * libserialport.h header, i.e. + * @code + * #include + * @endcode + * + * Namespace + * --------- + * + * All identifiers defined by the public libserialport headers use the prefix + * @c sp_ (for functions and data types) or @c SP_ (for macros and constants). + * + * Functions + * --------- + * + * The functions provided by the library are documented in detail in + * the following sections: + * + * - @ref Enumeration (obtaining a list of serial ports on the system) + * - @ref Ports (opening, closing and getting information about ports) + * - @ref Configuration (baud rate, parity, etc.) + * - @ref Signals (modem control lines, breaks, etc.) + * - @ref Data (reading and writing data, and buffer management) + * - @ref Waiting (waiting for ports to be ready, integrating with event loops) + * - @ref Errors (getting error and debugging information) + * + * Data structures + * --------------- + * + * The library defines three data structures: + * + * - @ref sp_port, which represents a serial port. + * See @ref Enumeration. + * - @ref sp_port_config, which represents a port configuration. + * See @ref Configuration. + * - @ref sp_event_set, which represents a set of events. + * See @ref Waiting. + * + * All these structures are allocated and freed by library functions. It is + * the caller's responsibility to ensure that the correct calls are made to + * free allocated structures after use. + * + * Return codes and error handling + * ------------------------------- + * + * Most functions have return type @ref sp_return and can return only four + * possible error values: + * + * - @ref SP_ERR_ARG means that a function was called with invalid + * arguments. This implies a bug in the caller. The arguments passed would + * be invalid regardless of the underlying OS or serial device involved. + * + * - @ref SP_ERR_FAIL means that the OS reported a failure. The error code or + * message provided by the OS can be obtained by calling sp_last_error_code() + * or sp_last_error_message(). + * + * - @ref SP_ERR_SUPP indicates that there is no support for the requested + * operation in the current OS, driver or device. No error message is + * available from the OS in this case. There is either no way to request + * the operation in the first place, or libserialport does not know how to + * do so in the current version. + * + * - @ref SP_ERR_MEM indicates that a memory allocation failed. + * + * All of these error values are negative. + * + * Calls that succeed return @ref SP_OK, which is equal to zero. Some functions + * declared @ref sp_return can also return a positive value for a successful + * numeric result, e.g. sp_blocking_read() or sp_blocking_write(). + * + * An error message is only available via sp_last_error_message() in the case + * where @ref SP_ERR_FAIL was returned by the previous function call. The error + * message returned is that provided by the OS, using the current language + * settings. It is an error to call sp_last_error_code() or + * sp_last_error_message() except after a previous function call returned + * @ref SP_ERR_FAIL. The library does not define its own error codes or + * messages to accompany other return codes. + * + * Thread safety + * ------------- + * + * Certain combinations of calls can be made concurrently, as follows. + * + * - Calls using different ports may always be made concurrently, i.e. + * it is safe for separate threads to handle their own ports. + * + * - Calls using the same port may be made concurrently when one call + * is a read operation and one call is a write operation, i.e. it is safe + * to use separate "reader" and "writer" threads for the same port. See + * below for which operations meet these definitions. + * + * Read operations: + * + * - sp_blocking_read() + * - sp_blocking_read_next() + * - sp_nonblocking_read() + * - sp_input_waiting() + * - sp_flush() with @ref SP_BUF_INPUT only. + * - sp_wait() with @ref SP_EVENT_RX_READY only. + * + * Write operations: + * + * - sp_blocking_write() + * - sp_nonblocking_write() + * - sp_output_waiting() + * - sp_drain() + * - sp_flush() with @ref SP_BUF_OUTPUT only. + * - sp_wait() with @ref SP_EVENT_TX_READY only. + * + * If two calls, on the same port, do not fit into one of these categories + * each, then they may not be made concurrently. + * + * Debugging + * --------- + * + * The library can output extensive tracing and debugging information. The + * simplest way to use this is to set the environment variable + * @c LIBSERIALPORT_DEBUG to any value; messages will then be output to the + * standard error stream. + * + * This behaviour is implemented by a default debug message handling + * callback. An alternative callback can be set using sp_set_debug_handler(), + * in order to e.g. redirect the output elsewhere or filter it. + * + * No guarantees are made about the content of the debug output; it is chosen + * to suit the needs of the developers and may change between releases. + * + * @anchor Porting + * Porting + * ------- + * + * The following guidelines may help when porting existing OS-specific code + * to use libserialport. + * + * ### Porting from Unix-like systems ### + * + * There are two main differences to note when porting code written for Unix. + * + * The first is that Unix traditionally provides a wide range of functionality + * for dealing with serial devices at the OS level; this is exposed through the + * termios API and dates to the days when serial terminals were common. If your + * code relies on many of these facilities you will need to adapt it, because + * libserialport provides only a raw binary channel with no special handling. + * + * The second relates to blocking versus non-blocking I/O behaviour. In + * Unix-like systems this is normally specified by setting the @c O_NONBLOCK + * flag on the file descriptor, affecting the semantics of subsequent @c read() + * and @c write() calls. + * + * In libserialport, blocking and nonblocking operations are both available at + * any time. If your existing code ѕets @c O_NONBLOCK, you should use + * sp_nonblocking_read() and sp_nonblocking_write() to get the same behaviour + * as your existing @c read() and @c write() calls. If it does not, you should + * use sp_blocking_read() and sp_blocking_write() instead. You may also find + * sp_blocking_read_next() useful, which reproduces the semantics of a blocking + * read() with @c VTIME=0 and @c VMIN=1 set in termios. + * + * Finally, you should take care if your program uses custom signal handlers. + * The blocking calls provided by libserialport will restart system calls that + * return with @c EINTR, so you will need to make your own arrangements if you + * need to interrupt blocking operations when your signal handlers are called. + * This is not an issue if you only use the default handlers. + * + * ### Porting from Windows ### + * + * The main consideration when porting from Windows is that there is no + * direct equivalent for overlapped I/O operations. + * + * If your program does not use overlapped I/O, you can simply use + * sp_blocking_read() and sp_blocking_write() as direct equivalents for + * @c ReadFile() and @c WriteFile(). You may also find sp_blocking_read_next() + * useful, which reproduces the special semantics of @c ReadFile() with + * @c ReadIntervalTimeout and @c ReadTotalTimeoutMultiplier set to @c MAXDWORD + * and @c ReadTotalTimeoutConstant set to between @c 1 and @c MAXDWORD-1 . + * + * If your program makes use of overlapped I/O to continue work while a serial + * operation is in progress, then you can achieve the same results using + * sp_nonblocking_read() and sp_nonblocking_write(). + * + * Generally, overlapped I/O is combined with either waiting for completion + * once there is no more background work to do (using @c WaitForSingleObject() + * or @c WaitForMultipleObjects()), or periodically checking for completion + * with @c GetOverlappedResult(). If the aim is to start a new operation for + * further data once the previous one has completed, you can instead simply + * call the nonblocking functions again with the next data. If you need to + * wait for completion, use sp_wait() to determine when the port is ready to + * send or receive further data. + */ + +#ifndef LIBSERIALPORT_LIBSERIALPORT_H +#define LIBSERIALPORT_LIBSERIALPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** @cond */ +#ifdef _MSC_VER +/* Microsoft Visual C/C++ compiler in use */ +#ifdef LIBSERIALPORT_MSBUILD +/* Building the library - need to export DLL symbols */ +#define SP_API __declspec(dllexport) +#else +/* Using the library - need to import DLL symbols */ +#define SP_API __declspec(dllimport) +#endif +#else +/* Some other compiler in use */ +#ifndef LIBSERIALPORT_ATBUILD +/* Not building the library itself - don't need any special prefixes. */ +#define SP_API +#endif +#endif +/** @endcond */ + +/** Return values. */ +enum sp_return { + /** Operation completed successfully. */ + SP_OK = 0, + /** Invalid arguments were passed to the function. */ + SP_ERR_ARG = -1, + /** A system error occurred while executing the operation. */ + SP_ERR_FAIL = -2, + /** A memory allocation failed while executing the operation. */ + SP_ERR_MEM = -3, + /** The requested operation is not supported by this system or device. */ + SP_ERR_SUPP = -4 +}; + +/** Port access modes. */ +enum sp_mode { + /** Open port for read access. */ + SP_MODE_READ = 1, + /** Open port for write access. */ + SP_MODE_WRITE = 2, + /** Open port for read and write access. @since 0.1.1 */ + SP_MODE_READ_WRITE = 3 +}; + +/** Port events. */ +enum sp_event { + /** Data received and ready to read. */ + SP_EVENT_RX_READY = 1, + /** Ready to transmit new data. */ + SP_EVENT_TX_READY = 2, + /** Error occurred. */ + SP_EVENT_ERROR = 4 +}; + +/** Buffer selection. */ +enum sp_buffer { + /** Input buffer. */ + SP_BUF_INPUT = 1, + /** Output buffer. */ + SP_BUF_OUTPUT = 2, + /** Both buffers. */ + SP_BUF_BOTH = 3 +}; + +/** Parity settings. */ +enum sp_parity { + /** Special value to indicate setting should be left alone. */ + SP_PARITY_INVALID = -1, + /** No parity. */ + SP_PARITY_NONE = 0, + /** Odd parity. */ + SP_PARITY_ODD = 1, + /** Even parity. */ + SP_PARITY_EVEN = 2, + /** Mark parity. */ + SP_PARITY_MARK = 3, + /** Space parity. */ + SP_PARITY_SPACE = 4 +}; + +/** RTS pin behaviour. */ +enum sp_rts { + /** Special value to indicate setting should be left alone. */ + SP_RTS_INVALID = -1, + /** RTS off. */ + SP_RTS_OFF = 0, + /** RTS on. */ + SP_RTS_ON = 1, + /** RTS used for flow control. */ + SP_RTS_FLOW_CONTROL = 2 +}; + +/** CTS pin behaviour. */ +enum sp_cts { + /** Special value to indicate setting should be left alone. */ + SP_CTS_INVALID = -1, + /** CTS ignored. */ + SP_CTS_IGNORE = 0, + /** CTS used for flow control. */ + SP_CTS_FLOW_CONTROL = 1 +}; + +/** DTR pin behaviour. */ +enum sp_dtr { + /** Special value to indicate setting should be left alone. */ + SP_DTR_INVALID = -1, + /** DTR off. */ + SP_DTR_OFF = 0, + /** DTR on. */ + SP_DTR_ON = 1, + /** DTR used for flow control. */ + SP_DTR_FLOW_CONTROL = 2 +}; + +/** DSR pin behaviour. */ +enum sp_dsr { + /** Special value to indicate setting should be left alone. */ + SP_DSR_INVALID = -1, + /** DSR ignored. */ + SP_DSR_IGNORE = 0, + /** DSR used for flow control. */ + SP_DSR_FLOW_CONTROL = 1 +}; + +/** XON/XOFF flow control behaviour. */ +enum sp_xonxoff { + /** Special value to indicate setting should be left alone. */ + SP_XONXOFF_INVALID = -1, + /** XON/XOFF disabled. */ + SP_XONXOFF_DISABLED = 0, + /** XON/XOFF enabled for input only. */ + SP_XONXOFF_IN = 1, + /** XON/XOFF enabled for output only. */ + SP_XONXOFF_OUT = 2, + /** XON/XOFF enabled for input and output. */ + SP_XONXOFF_INOUT = 3 +}; + +/** Standard flow control combinations. */ +enum sp_flowcontrol { + /** No flow control. */ + SP_FLOWCONTROL_NONE = 0, + /** Software flow control using XON/XOFF characters. */ + SP_FLOWCONTROL_XONXOFF = 1, + /** Hardware flow control using RTS/CTS signals. */ + SP_FLOWCONTROL_RTSCTS = 2, + /** Hardware flow control using DTR/DSR signals. */ + SP_FLOWCONTROL_DTRDSR = 3 +}; + +/** Input signals. */ +enum sp_signal { + /** Clear to send. */ + SP_SIG_CTS = 1, + /** Data set ready. */ + SP_SIG_DSR = 2, + /** Data carrier detect. */ + SP_SIG_DCD = 4, + /** Ring indicator. */ + SP_SIG_RI = 8 +}; + +/** + * Transport types. + * + * @since 0.1.1 + */ +enum sp_transport { + /** Native platform serial port. @since 0.1.1 */ + SP_TRANSPORT_NATIVE, + /** USB serial port adapter. @since 0.1.1 */ + SP_TRANSPORT_USB, + /** Bluetooth serial port adapter. @since 0.1.1 */ + SP_TRANSPORT_BLUETOOTH +}; + +/** + * @struct sp_port + * An opaque structure representing a serial port. + */ +struct sp_port; + +/** + * @struct sp_port_config + * An opaque structure representing the configuration for a serial port. + */ +struct sp_port_config; + +/** + * @struct sp_event_set + * A set of handles to wait on for events. + */ +struct sp_event_set { + /** Array of OS-specific handles. */ + void *handles; + /** Array of bitmasks indicating which events apply for each handle. */ + enum sp_event *masks; + /** Number of handles. */ + unsigned int count; +}; + +/** + * @defgroup Enumeration Port enumeration + * + * Enumerating the serial ports of a system. + * + * See @ref list_ports.c for a working example of port enumeration. + * + * @{ + */ + +/** + * Obtain a pointer to a new sp_port structure representing the named port. + * + * The user should allocate a variable of type "struct sp_port *" and pass a + * pointer to this to receive the result. + * + * The result should be freed after use by calling sp_free_port(). + * + * @param[in] portname The OS-specific name of a serial port. Must not be NULL. + * @param[out] port_ptr If any error is returned, the variable pointed to by + * port_ptr will be set to NULL. Otherwise, it will be set + * to point to the newly allocated port. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_get_port_by_name(const char *portname, struct sp_port **port_ptr); + +/** + * Free a port structure obtained from sp_get_port_by_name() or sp_copy_port(). + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * + * @since 0.1.0 + */ +SP_API void sp_free_port(struct sp_port *port); + +/** + * List the serial ports available on the system. + * + * The result obtained is an array of pointers to sp_port structures, + * terminated by a NULL. The user should allocate a variable of type + * "struct sp_port **" and pass a pointer to this to receive the result. + * + * The result should be freed after use by calling sp_free_port_list(). + * If a port from the list is to be used after freeing the list, it must be + * copied first using sp_copy_port(). + * + * @param[out] list_ptr If any error is returned, the variable pointed to by + * list_ptr will be set to NULL. Otherwise, it will be set + * to point to the newly allocated array. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_list_ports(struct sp_port ***list_ptr); + +/** + * Make a new copy of an sp_port structure. + * + * The user should allocate a variable of type "struct sp_port *" and pass a + * pointer to this to receive the result. + * + * The copy should be freed after use by calling sp_free_port(). + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[out] copy_ptr If any error is returned, the variable pointed to by + * copy_ptr will be set to NULL. Otherwise, it will be set + * to point to the newly allocated copy. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_copy_port(const struct sp_port *port, struct sp_port **copy_ptr); + +/** + * Free a port list obtained from sp_list_ports(). + * + * This will also free all the sp_port structures referred to from the list; + * any that are to be retained must be copied first using sp_copy_port(). + * + * @param[in] ports Pointer to a list of port structures. Must not be NULL. + * + * @since 0.1.0 + */ +SP_API void sp_free_port_list(struct sp_port **ports); + +/** + * @} + * @defgroup Ports Port handling + * + * Opening, closing and querying ports. + * + * See @ref port_info.c for a working example of getting port information. + * + * @{ + */ + +/** + * Open the specified serial port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[in] flags Flags to use when opening the serial port. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_open(struct sp_port *port, enum sp_mode flags); + +/** + * Close the specified serial port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_close(struct sp_port *port); + +/** + * Get the name of a port. + * + * The name returned is whatever is normally used to refer to a port on the + * current operating system; e.g. for Windows it will usually be a "COMn" + * device name, and for Unix it will be a device path beginning with "/dev/". + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * + * @return The port name, or NULL if an invalid port is passed. The name + * string is part of the port structure and may not be used after + * the port structure has been freed. + * + * @since 0.1.0 + */ +SP_API char *sp_get_port_name(const struct sp_port *port); + +/** + * Get a description for a port, to present to end user. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * + * @return The port description, or NULL if an invalid port is passed. + * The description string is part of the port structure and may not + * be used after the port structure has been freed. + * + * @since 0.1.1 + */ +SP_API char *sp_get_port_description(const struct sp_port *port); + +/** + * Get the transport type used by a port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * + * @return The port transport type. + * + * @since 0.1.1 + */ +SP_API enum sp_transport sp_get_port_transport(const struct sp_port *port); + +/** + * Get the USB bus number and address on bus of a USB serial adapter port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[out] usb_bus Pointer to a variable to store the USB bus. + * Can be NULL (in that case it will be ignored). + * @param[out] usb_address Pointer to a variable to store the USB address. + * Can be NULL (in that case it will be ignored). + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.1 + */ +SP_API enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port, + int *usb_bus, int *usb_address); + +/** + * Get the USB Vendor ID and Product ID of a USB serial adapter port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[out] usb_vid Pointer to a variable to store the USB VID. + * Can be NULL (in that case it will be ignored). + * @param[out] usb_pid Pointer to a variable to store the USB PID. + * Can be NULL (in that case it will be ignored). + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.1 + */ +SP_API enum sp_return sp_get_port_usb_vid_pid(const struct sp_port *port, int *usb_vid, int *usb_pid); + +/** + * Get the USB manufacturer string of a USB serial adapter port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * + * @return The port manufacturer string, or NULL if an invalid port is passed. + * The manufacturer string is part of the port structure and may not + * be used after the port structure has been freed. + * + * @since 0.1.1 + */ +SP_API char *sp_get_port_usb_manufacturer(const struct sp_port *port); + +/** + * Get the USB product string of a USB serial adapter port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * + * @return The port product string, or NULL if an invalid port is passed. + * The product string is part of the port structure and may not be + * used after the port structure has been freed. + * + * @since 0.1.1 + */ +SP_API char *sp_get_port_usb_product(const struct sp_port *port); + +/** + * Get the USB serial number string of a USB serial adapter port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * + * @return The port serial number, or NULL if an invalid port is passed. + * The serial number string is part of the port structure and may + * not be used after the port structure has been freed. + * + * @since 0.1.1 + */ +SP_API char *sp_get_port_usb_serial(const struct sp_port *port); + +/** + * Get the MAC address of a Bluetooth serial adapter port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * + * @return The port MAC address, or NULL if an invalid port is passed. + * The MAC address string is part of the port structure and may not + * be used after the port structure has been freed. + * + * @since 0.1.1 + */ +SP_API char *sp_get_port_bluetooth_address(const struct sp_port *port); + +/** + * Get the operating system handle for a port. + * + * The type of the handle depends on the operating system. On Unix based + * systems, the handle is a file descriptor of type "int". On Windows, the + * handle is of type "HANDLE". The user should allocate a variable of the + * appropriate type and pass a pointer to this to receive the result. + * + * To obtain a valid handle, the port must first be opened by calling + * sp_open() using the same port structure. + * + * After the port is closed or the port structure freed, the handle may + * no longer be valid. + * + * @warning This feature is provided so that programs may make use of + * OS-specific functionality where desired. Doing so obviously + * comes at a cost in portability. It also cannot be guaranteed + * that direct usage of the OS handle will not conflict with the + * library's own usage of the port. Be careful. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[out] result_ptr If any error is returned, the variable pointed to by + * result_ptr will have unknown contents and should not + * be used. Otherwise, it will be set to point to the + * OS handle. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_get_port_handle(const struct sp_port *port, void *result_ptr); + +/** + * @} + * + * @defgroup Configuration Configuration + * + * Setting and querying serial port parameters. + * + * See @ref port_config.c for a working example of port configuration. + * + * You should always configure all settings before using a port. + * There are no default settings applied by libserialport. + * When you open a port it may have default settings from the OS or + * driver, or the settings left over by the last program to use it. + * + * You should always set baud rate, data bits, parity and stop bits. + * + * You should normally also set one of the preset @ref sp_flowcontrol + * flow control modes, which will set up the RTS, CTS, DTR and DSR pin + * behaviours and enable or disable XON/XOFF. If you need an unusual + * configuration not covered by the preset flow control modes, you + * will need to configure these settings individually, and avoid + * calling sp_set_flowcontrol() or sp_set_config_flowcontrol() which + * will overwrite these settings. + * + * A port must be opened before you can change its settings. + * + * There are two ways of accessing port settings: + * + * Configuration structures + * ------------------------ + * + * You can read and write a whole configuration (all settings at once) + * using sp_get_config() and sp_set_config(). This is handy if you want + * to change between some preset combinations, or save and restore an + * existing configuration. It also ensures the changes are made + * together, via an efficient set of calls into the OS - in some cases + * a single system call can be used. + * + * Use accessor functions like sp_get_config_baudrate() and + * sp_set_config_baudrate() to get and set individual settings + * from a configuration. + * + * For each setting in a port configuration, a special value of -1 can + * be used, which will cause that setting to be left alone when the + * configuration is applied by sp_set_config(). + * + * This value is also be used by sp_get_config() for any settings + * which are unconfigured at the OS level, or in a state that is + * not representable within the libserialport API. + * + * Configurations are allocated using sp_new_config() and freed + * with sp_free_config(). You need to manage them yourself. When + * a new configuration is allocated by sp_new_config(), all of + * its settings are initially set to the special -1 value. + * + * Direct functions for changing port settings + * ------------------------------------------- + * + * As a shortcut, you can set individual settings on a port directly + * by calling functions like sp_set_baudrate() and sp_set_parity(). + * This saves you the work of allocating a temporary config, setting it + * up, applying it to a port and then freeing it. + * + * @{ + */ + +/** + * Allocate a port configuration structure. + * + * The user should allocate a variable of type "struct sp_port_config *" and + * pass a pointer to this to receive the result. The variable will be updated + * to point to the new configuration structure. The structure is opaque and + * must be accessed via the functions provided. + * + * All parameters in the structure will be initialised to special values which + * are ignored by sp_set_config(). + * + * The structure should be freed after use by calling sp_free_config(). + * + * @param[out] config_ptr If any error is returned, the variable pointed to by + * config_ptr will be set to NULL. Otherwise, it will + * be set to point to the allocated config structure. + * Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_new_config(struct sp_port_config **config_ptr); + +/** + * Free a port configuration structure. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * + * @since 0.1.0 + */ +SP_API void sp_free_config(struct sp_port_config *config); + +/** + * Get the current configuration of the specified serial port. + * + * The user should allocate a configuration structure using sp_new_config() + * and pass this as the config parameter. The configuration structure will + * be updated with the port configuration. + * + * Any parameters that are configured with settings not recognised or + * supported by libserialport, will be set to special values that are + * ignored by sp_set_config(). + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[out] config Pointer to a configuration structure that will hold + * the result. Upon errors the contents of the config + * struct will not be changed. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config); + +/** + * Set the configuration for the specified serial port. + * + * For each parameter in the configuration, there is a special value (usually + * -1, but see the documentation for each field). These values will be ignored + * and the corresponding setting left unchanged on the port. + * + * Upon errors, the configuration of the serial port is unknown since + * partial/incomplete config updates may have happened. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_config(struct sp_port *port, const struct sp_port_config *config); + +/** + * Set the baud rate for the specified serial port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[in] baudrate Baud rate in bits per second. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_baudrate(struct sp_port *port, int baudrate); + +/** + * Get the baud rate from a port configuration. + * + * The user should allocate a variable of type int and + * pass a pointer to this to receive the result. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[out] baudrate_ptr Pointer to a variable to store the result. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_get_config_baudrate(const struct sp_port_config *config, int *baudrate_ptr); + +/** + * Set the baud rate in a port configuration. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[in] baudrate Baud rate in bits per second, or -1 to retain the current setting. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_config_baudrate(struct sp_port_config *config, int baudrate); + +/** + * Set the data bits for the specified serial port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[in] bits Number of data bits. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_bits(struct sp_port *port, int bits); + +/** + * Get the data bits from a port configuration. + * + * The user should allocate a variable of type int and + * pass a pointer to this to receive the result. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[out] bits_ptr Pointer to a variable to store the result. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_get_config_bits(const struct sp_port_config *config, int *bits_ptr); + +/** + * Set the data bits in a port configuration. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[in] bits Number of data bits, or -1 to retain the current setting. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_config_bits(struct sp_port_config *config, int bits); + +/** + * Set the parity setting for the specified serial port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[in] parity Parity setting. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_parity(struct sp_port *port, enum sp_parity parity); + +/** + * Get the parity setting from a port configuration. + * + * The user should allocate a variable of type enum sp_parity and + * pass a pointer to this to receive the result. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[out] parity_ptr Pointer to a variable to store the result. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_get_config_parity(const struct sp_port_config *config, enum sp_parity *parity_ptr); + +/** + * Set the parity setting in a port configuration. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[in] parity Parity setting, or -1 to retain the current setting. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_config_parity(struct sp_port_config *config, enum sp_parity parity); + +/** + * Set the stop bits for the specified serial port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[in] stopbits Number of stop bits. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_stopbits(struct sp_port *port, int stopbits); + +/** + * Get the stop bits from a port configuration. + * + * The user should allocate a variable of type int and + * pass a pointer to this to receive the result. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[out] stopbits_ptr Pointer to a variable to store the result. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_get_config_stopbits(const struct sp_port_config *config, int *stopbits_ptr); + +/** + * Set the stop bits in a port configuration. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[in] stopbits Number of stop bits, or -1 to retain the current setting. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_config_stopbits(struct sp_port_config *config, int stopbits); + +/** + * Set the RTS pin behaviour for the specified serial port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[in] rts RTS pin mode. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_rts(struct sp_port *port, enum sp_rts rts); + +/** + * Get the RTS pin behaviour from a port configuration. + * + * The user should allocate a variable of type enum sp_rts and + * pass a pointer to this to receive the result. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[out] rts_ptr Pointer to a variable to store the result. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_get_config_rts(const struct sp_port_config *config, enum sp_rts *rts_ptr); + +/** + * Set the RTS pin behaviour in a port configuration. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[in] rts RTS pin mode, or -1 to retain the current setting. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_config_rts(struct sp_port_config *config, enum sp_rts rts); + +/** + * Set the CTS pin behaviour for the specified serial port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[in] cts CTS pin mode. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_cts(struct sp_port *port, enum sp_cts cts); + +/** + * Get the CTS pin behaviour from a port configuration. + * + * The user should allocate a variable of type enum sp_cts and + * pass a pointer to this to receive the result. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[out] cts_ptr Pointer to a variable to store the result. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_get_config_cts(const struct sp_port_config *config, enum sp_cts *cts_ptr); + +/** + * Set the CTS pin behaviour in a port configuration. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[in] cts CTS pin mode, or -1 to retain the current setting. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_config_cts(struct sp_port_config *config, enum sp_cts cts); + +/** + * Set the DTR pin behaviour for the specified serial port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[in] dtr DTR pin mode. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_dtr(struct sp_port *port, enum sp_dtr dtr); + +/** + * Get the DTR pin behaviour from a port configuration. + * + * The user should allocate a variable of type enum sp_dtr and + * pass a pointer to this to receive the result. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[out] dtr_ptr Pointer to a variable to store the result. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_get_config_dtr(const struct sp_port_config *config, enum sp_dtr *dtr_ptr); + +/** + * Set the DTR pin behaviour in a port configuration. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[in] dtr DTR pin mode, or -1 to retain the current setting. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_config_dtr(struct sp_port_config *config, enum sp_dtr dtr); + +/** + * Set the DSR pin behaviour for the specified serial port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[in] dsr DSR pin mode. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_dsr(struct sp_port *port, enum sp_dsr dsr); + +/** + * Get the DSR pin behaviour from a port configuration. + * + * The user should allocate a variable of type enum sp_dsr and + * pass a pointer to this to receive the result. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[out] dsr_ptr Pointer to a variable to store the result. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_get_config_dsr(const struct sp_port_config *config, enum sp_dsr *dsr_ptr); + +/** + * Set the DSR pin behaviour in a port configuration. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[in] dsr DSR pin mode, or -1 to retain the current setting. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_config_dsr(struct sp_port_config *config, enum sp_dsr dsr); + +/** + * Set the XON/XOFF configuration for the specified serial port. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[in] xon_xoff XON/XOFF mode. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_xon_xoff(struct sp_port *port, enum sp_xonxoff xon_xoff); + +/** + * Get the XON/XOFF configuration from a port configuration. + * + * The user should allocate a variable of type enum sp_xonxoff and + * pass a pointer to this to receive the result. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[out] xon_xoff_ptr Pointer to a variable to store the result. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_get_config_xon_xoff(const struct sp_port_config *config, enum sp_xonxoff *xon_xoff_ptr); + +/** + * Set the XON/XOFF configuration in a port configuration. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[in] xon_xoff XON/XOFF mode, or -1 to retain the current setting. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_config_xon_xoff(struct sp_port_config *config, enum sp_xonxoff xon_xoff); + +/** + * Set the flow control type in a port configuration. + * + * This function is a wrapper that sets the RTS, CTS, DTR, DSR and + * XON/XOFF settings as necessary for the specified flow control + * type. For more fine-grained control of these settings, use their + * individual configuration functions. + * + * @param[in] config Pointer to a configuration structure. Must not be NULL. + * @param[in] flowcontrol Flow control setting to use. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, enum sp_flowcontrol flowcontrol); + +/** + * Set the flow control type for the specified serial port. + * + * This function is a wrapper that sets the RTS, CTS, DTR, DSR and + * XON/XOFF settings as necessary for the specified flow control + * type. For more fine-grained control of these settings, use their + * individual configuration functions. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[in] flowcontrol Flow control setting to use. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flowcontrol); + +/** + * @} + * + * @defgroup Data Data handling + * + * Reading, writing, and flushing data. + * + * See @ref send_receive.c for an example of sending and receiving data. + * + * @{ + */ + +/** + * Read bytes from the specified serial port, blocking until complete. + * + * @warning If your program runs on Unix, defines its own signal handlers, and + * needs to abort blocking reads when these are called, then you + * should not use this function. It repeats system calls that return + * with EINTR. To be able to abort a read from a signal handler, you + * should implement your own blocking read using sp_nonblocking_read() + * together with a blocking method that makes sense for your program. + * E.g. you can obtain the file descriptor for an open port using + * sp_get_port_handle() and use this to call select() or pselect(), + * with appropriate arrangements to return if a signal is received. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[out] buf Buffer in which to store the bytes read. Must not be NULL. + * @param[in] count Requested number of bytes to read. + * @param[in] timeout_ms Timeout in milliseconds, or zero to wait indefinitely. + * + * @return The number of bytes read on success, or a negative error code. If + * the number of bytes returned is less than that requested, the + * timeout was reached before the requested number of bytes was + * available. If timeout is zero, the function will always return + * either the requested number of bytes or a negative error code. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_blocking_read(struct sp_port *port, void *buf, size_t count, unsigned int timeout_ms); + +/** + * Read bytes from the specified serial port, returning as soon as any data is + * available. + * + * @warning If your program runs on Unix, defines its own signal handlers, and + * needs to abort blocking reads when these are called, then you + * should not use this function. It repeats system calls that return + * with EINTR. To be able to abort a read from a signal handler, you + * should implement your own blocking read using sp_nonblocking_read() + * together with a blocking method that makes sense for your program. + * E.g. you can obtain the file descriptor for an open port using + * sp_get_port_handle() and use this to call select() or pselect(), + * with appropriate arrangements to return if a signal is received. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[out] buf Buffer in which to store the bytes read. Must not be NULL. + * @param[in] count Maximum number of bytes to read. Must not be zero. + * @param[in] timeout_ms Timeout in milliseconds, or zero to wait indefinitely. + * + * @return The number of bytes read on success, or a negative error code. If + * the result is zero, the timeout was reached before any bytes were + * available. If timeout_ms is zero, the function will always return + * either at least one byte, or a negative error code. + * + * @since 0.1.1 + */ +SP_API enum sp_return sp_blocking_read_next(struct sp_port *port, void *buf, size_t count, unsigned int timeout_ms); + +/** + * Read bytes from the specified serial port, without blocking. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[out] buf Buffer in which to store the bytes read. Must not be NULL. + * @param[in] count Maximum number of bytes to read. + * + * @return The number of bytes read on success, or a negative error code. The + * number of bytes returned may be any number from zero to the maximum + * that was requested. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf, size_t count); + +/** + * Write bytes to the specified serial port, blocking until complete. + * + * Note that this function only ensures that the accepted bytes have been + * written to the OS; they may be held in driver or hardware buffers and not + * yet physically transmitted. To check whether all written bytes have actually + * been transmitted, use the sp_output_waiting() function. To wait until all + * written bytes have actually been transmitted, use the sp_drain() function. + * + * @warning If your program runs on Unix, defines its own signal handlers, and + * needs to abort blocking writes when these are called, then you + * should not use this function. It repeats system calls that return + * with EINTR. To be able to abort a write from a signal handler, you + * should implement your own blocking write using sp_nonblocking_write() + * together with a blocking method that makes sense for your program. + * E.g. you can obtain the file descriptor for an open port using + * sp_get_port_handle() and use this to call select() or pselect(), + * with appropriate arrangements to return if a signal is received. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[in] buf Buffer containing the bytes to write. Must not be NULL. + * @param[in] count Requested number of bytes to write. + * @param[in] timeout_ms Timeout in milliseconds, or zero to wait indefinitely. + * + * @return The number of bytes written on success, or a negative error code. + * If the number of bytes returned is less than that requested, the + * timeout was reached before the requested number of bytes was + * written. If timeout is zero, the function will always return + * either the requested number of bytes or a negative error code. In + * the event of an error there is no way to determine how many bytes + * were sent before the error occurred. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, size_t count, unsigned int timeout_ms); + +/** + * Write bytes to the specified serial port, without blocking. + * + * Note that this function only ensures that the accepted bytes have been + * written to the OS; they may be held in driver or hardware buffers and not + * yet physically transmitted. To check whether all written bytes have actually + * been transmitted, use the sp_output_waiting() function. To wait until all + * written bytes have actually been transmitted, use the sp_drain() function. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[in] buf Buffer containing the bytes to write. Must not be NULL. + * @param[in] count Maximum number of bytes to write. + * + * @return The number of bytes written on success, or a negative error code. + * The number of bytes returned may be any number from zero to the + * maximum that was requested. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_nonblocking_write(struct sp_port *port, const void *buf, size_t count); + +/** + * Gets the number of bytes waiting in the input buffer. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * + * @return Number of bytes waiting on success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_input_waiting(struct sp_port *port); + +/** + * Gets the number of bytes waiting in the output buffer. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * + * @return Number of bytes waiting on success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_output_waiting(struct sp_port *port); + +/** + * Flush serial port buffers. Data in the selected buffer(s) is discarded. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[in] buffers Which buffer(s) to flush. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers); + +/** + * Wait for buffered data to be transmitted. + * + * @warning If your program runs on Unix, defines its own signal handlers, and + * needs to abort draining the output buffer when when these are + * called, then you should not use this function. It repeats system + * calls that return with EINTR. To be able to abort a drain from a + * signal handler, you would need to implement your own blocking + * drain by polling the result of sp_output_waiting(). + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_drain(struct sp_port *port); + +/** + * @} + * + * @defgroup Waiting Waiting + * + * Waiting for events and timeout handling. + * + * See @ref await_events.c for an example of awaiting events on multiple ports. + * + * @{ + */ + +/** + * Allocate storage for a set of events. + * + * The user should allocate a variable of type struct sp_event_set *, + * then pass a pointer to this variable to receive the result. + * + * The result should be freed after use by calling sp_free_event_set(). + * + * @param[out] result_ptr If any error is returned, the variable pointed to by + * result_ptr will be set to NULL. Otherwise, it will + * be set to point to the event set. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_new_event_set(struct sp_event_set **result_ptr); + +/** + * Add events to a struct sp_event_set for a given port. + * + * The port must first be opened by calling sp_open() using the same port + * structure. + * + * After the port is closed or the port structure freed, the results may + * no longer be valid. + * + * @param[in,out] event_set Event set to update. Must not be NULL. + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[in] mask Bitmask of events to be waited for. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_add_port_events(struct sp_event_set *event_set, + const struct sp_port *port, enum sp_event mask); + +/** + * Wait for any of a set of events to occur. + * + * @param[in] event_set Event set to wait on. Must not be NULL. + * @param[in] timeout_ms Timeout in milliseconds, or zero to wait indefinitely. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_wait(struct sp_event_set *event_set, unsigned int timeout_ms); + +/** + * Free a structure allocated by sp_new_event_set(). + * + * @param[in] event_set Event set to free. Must not be NULL. + * + * @since 0.1.0 + */ +SP_API void sp_free_event_set(struct sp_event_set *event_set); + +/** + * @} + * + * @defgroup Signals Signals + * + * Port signalling operations. + * + * @{ + */ + +/** + * Gets the status of the control signals for the specified port. + * + * The user should allocate a variable of type "enum sp_signal" and pass a + * pointer to this variable to receive the result. The result is a bitmask + * in which individual signals can be checked by bitwise OR with values of + * the sp_signal enum. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[out] signal_mask Pointer to a variable to receive the result. + * Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_get_signals(struct sp_port *port, enum sp_signal *signal_mask); + +/** + * Put the port transmit line into the break state. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_start_break(struct sp_port *port); + +/** + * Take the port transmit line out of the break state. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * + * @return SP_OK upon success, a negative error code otherwise. + * + * @since 0.1.0 + */ +SP_API enum sp_return sp_end_break(struct sp_port *port); + +/** + * @} + * + * @defgroup Errors Errors + * + * Obtaining error information. + * + * See @ref handle_errors.c for an example of error handling. + * + * @{ + */ + +/** + * Get the error code for a failed operation. + * + * In order to obtain the correct result, this function should be called + * straight after the failure, before executing any other system operations. + * The result is thread-specific, and only valid when called immediately + * after a previous call returning SP_ERR_FAIL. + * + * @return The system's numeric code for the error that caused the last + * operation to fail. + * + * @since 0.1.0 + */ +SP_API int sp_last_error_code(void); + +/** + * Get the error message for a failed operation. + * + * In order to obtain the correct result, this function should be called + * straight after the failure, before executing other system operations. + * The result is thread-specific, and only valid when called immediately + * after a previous call returning SP_ERR_FAIL. + * + * @return The system's message for the error that caused the last + * operation to fail. This string may be allocated by the function, + * and should be freed after use by calling sp_free_error_message(). + * + * @since 0.1.0 + */ +SP_API char *sp_last_error_message(void); + +/** + * Free an error message returned by sp_last_error_message(). + * + * @param[in] message The error message string to free. Must not be NULL. + * + * @since 0.1.0 + */ +SP_API void sp_free_error_message(char *message); + +/** + * Set the handler function for library debugging messages. + * + * Debugging messages are generated by the library during each operation, + * to help in diagnosing problems. The handler will be called for each + * message. The handler can be set to NULL to ignore all debug messages. + * + * The handler function should accept a format string and variable length + * argument list, in the same manner as e.g. printf(). + * + * The default handler is sp_default_debug_handler(). + * + * @param[in] handler The handler function to use. Can be NULL (in that case + * all debug messages will be ignored). + * + * @since 0.1.0 + */ +SP_API void sp_set_debug_handler(void (*handler)(const char *format, ...)); + +/** + * Default handler function for library debugging messages. + * + * This function prints debug messages to the standard error stream if the + * environment variable LIBSERIALPORT_DEBUG is set. Otherwise, they are + * ignored. + * + * @param[in] format The format string to use. Must not be NULL. + * @param[in] ... The variable length argument list to use. + * + * @since 0.1.0 + */ +SP_API void sp_default_debug_handler(const char *format, ...); + +/** @} */ + +/** + * @defgroup Versions Versions + * + * Version number querying functions, definitions, and macros. + * + * This set of API calls returns two different version numbers related + * to libserialport. The "package version" is the release version number of the + * libserialport tarball in the usual "major.minor.micro" format, e.g. "0.1.0". + * + * The "library version" is independent of that; it is the libtool version + * number in the "current:revision:age" format, e.g. "2:0:0". + * See http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning for details. + * + * Both version numbers (and/or individual components of them) can be + * retrieved via the API calls at runtime, and/or they can be checked at + * compile/preprocessor time using the respective macros. + * + * @{ + */ + +/* + * Package version macros (can be used for conditional compilation). + */ + +/** The libserialport package 'major' version number. */ +#define SP_PACKAGE_VERSION_MAJOR 0 + +/** The libserialport package 'minor' version number. */ +#define SP_PACKAGE_VERSION_MINOR 1 + +/** The libserialport package 'micro' version number. */ +#define SP_PACKAGE_VERSION_MICRO 1 + +/** The libserialport package version ("major.minor.micro") as string. */ +#define SP_PACKAGE_VERSION_STRING "0.1.1" + +/* + * Library/libtool version macros (can be used for conditional compilation). + */ + +/** The libserialport libtool 'current' version number. */ +#define SP_LIB_VERSION_CURRENT 1 + +/** The libserialport libtool 'revision' version number. */ +#define SP_LIB_VERSION_REVISION 0 + +/** The libserialport libtool 'age' version number. */ +#define SP_LIB_VERSION_AGE 1 + +/** The libserialport libtool version ("current:revision:age") as string. */ +#define SP_LIB_VERSION_STRING "1:0:1" + +/** + * Get the major libserialport package version number. + * + * @return The major package version number. + * + * @since 0.1.0 + */ +SP_API int sp_get_major_package_version(void); + +/** + * Get the minor libserialport package version number. + * + * @return The minor package version number. + * + * @since 0.1.0 + */ +SP_API int sp_get_minor_package_version(void); + +/** + * Get the micro libserialport package version number. + * + * @return The micro package version number. + * + * @since 0.1.0 + */ +SP_API int sp_get_micro_package_version(void); + +/** + * Get the libserialport package version number as a string. + * + * @return The package version number string. The returned string is + * static and thus should NOT be free'd by the caller. + * + * @since 0.1.0 + */ +SP_API const char *sp_get_package_version_string(void); + +/** + * Get the "current" part of the libserialport library version number. + * + * @return The "current" library version number. + * + * @since 0.1.0 + */ +SP_API int sp_get_current_lib_version(void); + +/** + * Get the "revision" part of the libserialport library version number. + * + * @return The "revision" library version number. + * + * @since 0.1.0 + */ +SP_API int sp_get_revision_lib_version(void); + +/** + * Get the "age" part of the libserialport library version number. + * + * @return The "age" library version number. + * + * @since 0.1.0 + */ +SP_API int sp_get_age_lib_version(void); + +/** + * Get the libserialport library version number as a string. + * + * @return The library version number string. The returned string is + * static and thus should NOT be free'd by the caller. + * + * @since 0.1.0 + */ +SP_API const char *sp_get_lib_version_string(void); + +/** @} */ + +/** + * @example list_ports.c Getting a list of ports present on the system. + * @example port_info.c Getting information on a particular serial port. + * @example port_config.c Accessing configuration settings of a port. + * @example send_receive.c Sending and receiving data. + * @example await_events.c Awaiting events on multiple ports. + * @example handle_errors.c Handling errors returned from the library. +*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libserialport/libserialport_internal.h b/src/libserialport/libserialport_internal.h new file mode 100644 index 000000000..ecf8fe95f --- /dev/null +++ b/src/libserialport/libserialport_internal.h @@ -0,0 +1,311 @@ +/* + * This file is part of the libserialport project. + * + * Copyright (C) 2014 Martin Ling + * Copyright (C) 2014 Aurelien Jacobs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef LIBSERIALPORT_LIBSERIALPORT_INTERNAL_H +#define LIBSERIALPORT_LIBSERIALPORT_INTERNAL_H + +/* These MSVC-specific defines must appear before other headers.*/ +#ifdef _MSC_VER +#define _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_SECURE_NO_WARNINGS +#endif + +/* These feature test macros must appear before other headers.*/ +#if defined(__linux__) || defined(__CYGWIN__) +/* For timeradd, timersub, timercmp, realpath. */ +#define _BSD_SOURCE 1 /* for glibc < 2.19 */ +#define _DEFAULT_SOURCE 1 /* for glibc >= 2.20 */ +/* For clock_gettime and associated types. */ +#define _POSIX_C_SOURCE 199309L +#endif + +#ifdef LIBSERIALPORT_ATBUILD +/* If building with autoconf, include the generated config.h. */ +#include +#endif + +#ifdef LIBSERIALPORT_MSBUILD +/* If building with MS tools, define necessary things that + would otherwise appear in config.h. */ +#define SP_PRIV +#endif + +#include "libserialport.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#include +#include +#include +#undef DEFINE_GUID +#define DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + static const GUID name = { l,w1,w2,{ b1,b2,b3,b4,b5,b6,b7,b8 } } +#include +#include +/* The largest size that can be passed to WriteFile() safely + * on any architecture. This arises from the expression: + * PAGE_SIZE * (65535 - sizeof(MDL)) / sizeof(ULONG_PTR) + * and this worst-case value is found on x64. */ +#define WRITEFILE_MAX_SIZE 33525760 +#else +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_FILE_H +#include +#endif +#endif +#ifdef __APPLE__ +#include +#include +#include +#include +#include +#include +#endif +#ifdef __linux__ +#include +/* Android only has linux/serial.h from platform 21 onwards. */ +#if !(defined(__ANDROID__) && (__ANDROID_API__ < 21)) +#include +#endif +#include "linux_termios.h" + +/* TCGETX/TCSETX is not available everywhere. */ +#if defined(TCGETX) && defined(TCSETX) && defined(HAVE_STRUCT_TERMIOX) +#define USE_TERMIOX +#endif +#endif + +/* TIOCINQ/TIOCOUTQ is not available everywhere. */ +#if !defined(TIOCINQ) && defined(FIONREAD) +#define TIOCINQ FIONREAD +#endif +#if !defined(TIOCOUTQ) && defined(FIONWRITE) +#define TIOCOUTQ FIONWRITE +#endif + +/* + * O_CLOEXEC is not available everywhere, fallback to not setting the + * flag on those systems. + */ +#ifndef _WIN32 +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#endif +#endif + +/* Non-standard baudrates are not available everywhere. */ +#if (defined(HAVE_TERMIOS_SPEED) || defined(HAVE_TERMIOS2_SPEED)) && HAVE_DECL_BOTHER +#define USE_TERMIOS_SPEED +#endif + +struct sp_port { + char *name; + char *description; + enum sp_transport transport; + int usb_bus; + int usb_address; + int usb_vid; + int usb_pid; + char *usb_manufacturer; + char *usb_product; + char *usb_serial; + char *bluetooth_address; +#ifdef _WIN32 + char *usb_path; + HANDLE hdl; + COMMTIMEOUTS timeouts; + OVERLAPPED write_ovl; + OVERLAPPED read_ovl; + OVERLAPPED wait_ovl; + DWORD events; + BYTE *write_buf; + DWORD write_buf_size; + BOOL writing; + BOOL wait_running; +#else + int fd; +#endif +}; + +struct sp_port_config { + int baudrate; + int bits; + enum sp_parity parity; + int stopbits; + enum sp_rts rts; + enum sp_cts cts; + enum sp_dtr dtr; + enum sp_dsr dsr; + enum sp_xonxoff xon_xoff; +}; + +struct port_data { +#ifdef _WIN32 + DCB dcb; +#else + struct termios term; + int controlbits; + int termiox_supported; + int rts_flow; + int cts_flow; + int dtr_flow; + int dsr_flow; +#endif +}; + +#ifdef _WIN32 +typedef HANDLE event_handle; +#else +typedef int event_handle; +#endif + +/* Standard baud rates. */ +#ifdef _WIN32 +#define BAUD_TYPE DWORD +#define BAUD(n) {CBR_##n, n} +#else +#define BAUD_TYPE speed_t +#define BAUD(n) {B##n, n} +#endif + +struct std_baudrate { + BAUD_TYPE index; + int value; +}; + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + +extern void (*sp_debug_handler)(const char *format, ...); + +/* Debug output macros. */ +#define DEBUG_FMT(fmt, ...) do { \ + if (sp_debug_handler) \ + sp_debug_handler(fmt ".\n", __VA_ARGS__); \ +} while (0) +#define DEBUG(msg) DEBUG_FMT(msg, NULL) +#define DEBUG_ERROR(err, msg) DEBUG_FMT("%s returning " #err ": " msg, __func__) +#define DEBUG_FAIL(msg) do { \ + char *errmsg = sp_last_error_message(); \ + DEBUG_FMT("%s returning SP_ERR_FAIL: " msg ": %s", __func__, errmsg); \ + sp_free_error_message(errmsg); \ +} while (0); +#define RETURN() do { \ + DEBUG_FMT("%s returning", __func__); \ + return; \ +} while (0) +#define RETURN_CODE(x) do { \ + DEBUG_FMT("%s returning " #x, __func__); \ + return x; \ +} while (0) +#define RETURN_CODEVAL(x) do { \ + switch (x) { \ + case SP_OK: RETURN_CODE(SP_OK); \ + case SP_ERR_ARG: RETURN_CODE(SP_ERR_ARG); \ + case SP_ERR_FAIL: RETURN_CODE(SP_ERR_FAIL); \ + case SP_ERR_MEM: RETURN_CODE(SP_ERR_MEM); \ + case SP_ERR_SUPP: RETURN_CODE(SP_ERR_SUPP); \ + default: RETURN_CODE(SP_ERR_FAIL); \ + } \ +} while (0) +#define RETURN_OK() RETURN_CODE(SP_OK); +#define RETURN_ERROR(err, msg) do { \ + DEBUG_ERROR(err, msg); \ + return err; \ +} while (0) +#define RETURN_FAIL(msg) do { \ + DEBUG_FAIL(msg); \ + return SP_ERR_FAIL; \ +} while (0) +#define RETURN_INT(x) do { \ + int _x = x; \ + DEBUG_FMT("%s returning %d", __func__, _x); \ + return _x; \ +} while (0) +#define RETURN_STRING(x) do { \ + char *_x = x; \ + DEBUG_FMT("%s returning %s", __func__, _x); \ + return _x; \ +} while (0) +#define RETURN_POINTER(x) do { \ + void *_x = x; \ + DEBUG_FMT("%s returning %p", __func__, _x); \ + return _x; \ +} while (0) +#define SET_ERROR(val, err, msg) do { DEBUG_ERROR(err, msg); val = err; } while (0) +#define SET_FAIL(val, msg) do { DEBUG_FAIL(msg); val = SP_ERR_FAIL; } while (0) +#define TRACE(fmt, ...) DEBUG_FMT("%s(" fmt ") called", __func__, __VA_ARGS__) +#define TRACE_VOID() DEBUG_FMT("%s() called", __func__) + +#define TRY(x) do { int retval = x; if (retval != SP_OK) RETURN_CODEVAL(retval); } while (0) + +SP_PRIV struct sp_port **list_append(struct sp_port **list, const char *portname); + +/* OS-specific Helper functions. */ +SP_PRIV enum sp_return get_port_details(struct sp_port *port); +SP_PRIV enum sp_return list_ports(struct sp_port ***list); + +/* Timing abstraction */ + +struct time { +#ifdef _WIN32 + int64_t ticks; +#else + struct timeval tv; +#endif +}; + +struct timeout { + unsigned int ms, limit_ms; + struct time start, now, end, delta, delta_max; + struct timeval delta_tv; + bool calls_started, overflow; +}; + +SP_PRIV void time_get(struct time *time); +SP_PRIV void time_set_ms(struct time *time, unsigned int ms); +SP_PRIV void time_add(const struct time *a, const struct time *b, struct time *result); +SP_PRIV void time_sub(const struct time *a, const struct time *b, struct time *result); +SP_PRIV bool time_greater(const struct time *a, const struct time *b); +SP_PRIV void time_as_timeval(const struct time *time, struct timeval *tv); +SP_PRIV unsigned int time_as_ms(const struct time *time); +SP_PRIV void timeout_start(struct timeout *timeout, unsigned int timeout_ms); +SP_PRIV void timeout_limit(struct timeout *timeout, unsigned int limit_ms); +SP_PRIV bool timeout_check(struct timeout *timeout); +SP_PRIV void timeout_update(struct timeout *timeout); +SP_PRIV struct timeval *timeout_timeval(struct timeout *timeout); +SP_PRIV unsigned int timeout_remaining_ms(struct timeout *timeout); + +#endif diff --git a/src/libserialport/serialport.c b/src/libserialport/serialport.c new file mode 100644 index 000000000..e6097eeda --- /dev/null +++ b/src/libserialport/serialport.c @@ -0,0 +1,2624 @@ +/* + * This file is part of the libserialport project. + * + * Copyright (C) 2010-2012 Bert Vermeulen + * Copyright (C) 2010-2015 Uwe Hermann + * Copyright (C) 2013-2015 Martin Ling + * Copyright (C) 2013 Matthias Heidbrink + * Copyright (C) 2014 Aurelien Jacobs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser General Public License + * along with this program. If not, see . + */ + +#include "libserialport_internal.h" + +static const struct std_baudrate std_baudrates[] = { +#ifdef _WIN32 + /* + * The baudrates 50/75/134/150/200/1800/230400/460800 do not seem to + * have documented CBR_* macros. + */ + BAUD(110), BAUD(300), BAUD(600), BAUD(1200), BAUD(2400), BAUD(4800), + BAUD(9600), BAUD(14400), BAUD(19200), BAUD(38400), BAUD(57600), + BAUD(115200), BAUD(128000), BAUD(256000), +#else + BAUD(50), BAUD(75), BAUD(110), BAUD(134), BAUD(150), BAUD(200), + BAUD(300), BAUD(600), BAUD(1200), BAUD(1800), BAUD(2400), BAUD(4800), + BAUD(9600), BAUD(19200), BAUD(38400), BAUD(57600), BAUD(115200), + BAUD(230400), +#if !defined(__APPLE__) && !defined(__OpenBSD__) + BAUD(460800), +#endif +#endif +}; + +#define NUM_STD_BAUDRATES ARRAY_SIZE(std_baudrates) + +void (*sp_debug_handler)(const char *format, ...) = sp_default_debug_handler; + +static enum sp_return get_config(struct sp_port *port, struct port_data *data, + struct sp_port_config *config); + +static enum sp_return set_config(struct sp_port *port, struct port_data *data, + const struct sp_port_config *config); + +SP_API enum sp_return sp_get_port_by_name(const char *portname, struct sp_port **port_ptr) +{ + struct sp_port *port; +#ifndef NO_PORT_METADATA + enum sp_return ret; +#endif + size_t len; + + TRACE("%s, %p", portname, port_ptr); + + if (!port_ptr) + RETURN_ERROR(SP_ERR_ARG, "Null result pointer"); + + *port_ptr = NULL; + + if (!portname) + RETURN_ERROR(SP_ERR_ARG, "Null port name"); + + DEBUG_FMT("Building structure for port %s", portname); + +#if !defined(_WIN32) && defined(HAVE_REALPATH) + /* + * get_port_details() below tries to be too smart and figure out + * some transport properties from the port name which breaks with + * symlinks. Therefore we canonicalize the portname first. + */ + char pathbuf[PATH_MAX + 1]; + char *res = realpath(portname, pathbuf); + if (!res) + RETURN_ERROR(SP_ERR_ARG, "Could not retrieve realpath behind port name"); + + portname = pathbuf; +#endif + + if (!(port = malloc(sizeof(struct sp_port)))) + RETURN_ERROR(SP_ERR_MEM, "Port structure malloc failed"); + + len = strlen(portname) + 1; + + if (!(port->name = malloc(len))) { + free(port); + RETURN_ERROR(SP_ERR_MEM, "Port name malloc failed"); + } + + memcpy(port->name, portname, len); + +#ifdef _WIN32 + port->usb_path = NULL; + port->hdl = INVALID_HANDLE_VALUE; + port->write_buf = NULL; + port->write_buf_size = 0; +#else + port->fd = -1; +#endif + + port->description = NULL; + port->transport = SP_TRANSPORT_NATIVE; + port->usb_bus = -1; + port->usb_address = -1; + port->usb_vid = -1; + port->usb_pid = -1; + port->usb_manufacturer = NULL; + port->usb_product = NULL; + port->usb_serial = NULL; + port->bluetooth_address = NULL; + +#ifndef NO_PORT_METADATA + if ((ret = get_port_details(port)) != SP_OK) { + sp_free_port(port); + return ret; + } +#endif + + *port_ptr = port; + + RETURN_OK(); +} + +SP_API char *sp_get_port_name(const struct sp_port *port) +{ + TRACE("%p", port); + + if (!port) + return NULL; + + RETURN_STRING(port->name); +} + +SP_API char *sp_get_port_description(const struct sp_port *port) +{ + TRACE("%p", port); + + if (!port || !port->description) + return NULL; + + RETURN_STRING(port->description); +} + +SP_API enum sp_transport sp_get_port_transport(const struct sp_port *port) +{ + TRACE("%p", port); + + RETURN_INT(port ? port->transport : SP_TRANSPORT_NATIVE); +} + +SP_API enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port, + int *usb_bus,int *usb_address) +{ + TRACE("%p", port); + + if (!port) + RETURN_ERROR(SP_ERR_ARG, "Null port"); + if (port->transport != SP_TRANSPORT_USB) + RETURN_ERROR(SP_ERR_ARG, "Port does not use USB transport"); + if (port->usb_bus < 0 || port->usb_address < 0) + RETURN_ERROR(SP_ERR_SUPP, "Bus and address values are not available"); + + if (usb_bus) + *usb_bus = port->usb_bus; + if (usb_address) + *usb_address = port->usb_address; + + RETURN_OK(); +} + +SP_API enum sp_return sp_get_port_usb_vid_pid(const struct sp_port *port, + int *usb_vid, int *usb_pid) +{ + TRACE("%p", port); + + if (!port) + RETURN_ERROR(SP_ERR_ARG, "Null port"); + if (port->transport != SP_TRANSPORT_USB) + RETURN_ERROR(SP_ERR_ARG, "Port does not use USB transport"); + if (port->usb_vid < 0 || port->usb_pid < 0) + RETURN_ERROR(SP_ERR_SUPP, "VID:PID values are not available"); + + if (usb_vid) + *usb_vid = port->usb_vid; + if (usb_pid) + *usb_pid = port->usb_pid; + + RETURN_OK(); +} + +SP_API char *sp_get_port_usb_manufacturer(const struct sp_port *port) +{ + TRACE("%p", port); + + if (!port || port->transport != SP_TRANSPORT_USB || !port->usb_manufacturer) + return NULL; + + RETURN_STRING(port->usb_manufacturer); +} + +SP_API char *sp_get_port_usb_product(const struct sp_port *port) +{ + TRACE("%p", port); + + if (!port || port->transport != SP_TRANSPORT_USB || !port->usb_product) + return NULL; + + RETURN_STRING(port->usb_product); +} + +SP_API char *sp_get_port_usb_serial(const struct sp_port *port) +{ + TRACE("%p", port); + + if (!port || port->transport != SP_TRANSPORT_USB || !port->usb_serial) + return NULL; + + RETURN_STRING(port->usb_serial); +} + +SP_API char *sp_get_port_bluetooth_address(const struct sp_port *port) +{ + TRACE("%p", port); + + if (!port || port->transport != SP_TRANSPORT_BLUETOOTH + || !port->bluetooth_address) + return NULL; + + RETURN_STRING(port->bluetooth_address); +} + +SP_API enum sp_return sp_get_port_handle(const struct sp_port *port, + void *result_ptr) +{ + TRACE("%p, %p", port, result_ptr); + + if (!port) + RETURN_ERROR(SP_ERR_ARG, "Null port"); + if (!result_ptr) + RETURN_ERROR(SP_ERR_ARG, "Null result pointer"); + +#ifdef _WIN32 + HANDLE *handle_ptr = result_ptr; + *handle_ptr = port->hdl; +#else + int *fd_ptr = result_ptr; + *fd_ptr = port->fd; +#endif + + RETURN_OK(); +} + +SP_API enum sp_return sp_copy_port(const struct sp_port *port, + struct sp_port **copy_ptr) +{ + TRACE("%p, %p", port, copy_ptr); + + if (!copy_ptr) + RETURN_ERROR(SP_ERR_ARG, "Null result pointer"); + + *copy_ptr = NULL; + + if (!port) + RETURN_ERROR(SP_ERR_ARG, "Null port"); + + if (!port->name) + RETURN_ERROR(SP_ERR_ARG, "Null port name"); + + DEBUG("Copying port structure"); + + RETURN_INT(sp_get_port_by_name(port->name, copy_ptr)); +} + +SP_API void sp_free_port(struct sp_port *port) +{ + TRACE("%p", port); + + if (!port) { + DEBUG("Null port"); + RETURN(); + } + + DEBUG("Freeing port structure"); + + if (port->name) + free(port->name); + if (port->description) + free(port->description); + if (port->usb_manufacturer) + free(port->usb_manufacturer); + if (port->usb_product) + free(port->usb_product); + if (port->usb_serial) + free(port->usb_serial); + if (port->bluetooth_address) + free(port->bluetooth_address); +#ifdef _WIN32 + if (port->usb_path) + free(port->usb_path); + if (port->write_buf) + free(port->write_buf); +#endif + + free(port); + + RETURN(); +} + +SP_PRIV struct sp_port **list_append(struct sp_port **list, + const char *portname) +{ + void *tmp; + size_t count; + + for (count = 0; list[count]; count++) + ; + if (!(tmp = realloc(list, sizeof(struct sp_port *) * (count + 2)))) + goto fail; + list = tmp; + if (sp_get_port_by_name(portname, &list[count]) != SP_OK) + goto fail; + list[count + 1] = NULL; + return list; + +fail: + sp_free_port_list(list); + return NULL; +} + +SP_API enum sp_return sp_list_ports(struct sp_port ***list_ptr) +{ +#ifndef NO_ENUMERATION + struct sp_port **list; + int ret; +#endif + + TRACE("%p", list_ptr); + + if (!list_ptr) + RETURN_ERROR(SP_ERR_ARG, "Null result pointer"); + + *list_ptr = NULL; + +#ifdef NO_ENUMERATION + RETURN_ERROR(SP_ERR_SUPP, "Enumeration not supported on this platform"); +#else + DEBUG("Enumerating ports"); + + if (!(list = malloc(sizeof(struct sp_port *)))) + RETURN_ERROR(SP_ERR_MEM, "Port list malloc failed"); + + list[0] = NULL; + + ret = list_ports(&list); + + if (ret == SP_OK) { + *list_ptr = list; + } else { + sp_free_port_list(list); + *list_ptr = NULL; + } + + RETURN_CODEVAL(ret); +#endif +} + +SP_API void sp_free_port_list(struct sp_port **list) +{ + unsigned int i; + + TRACE("%p", list); + + if (!list) { + DEBUG("Null list"); + RETURN(); + } + + DEBUG("Freeing port list"); + + for (i = 0; list[i]; i++) + sp_free_port(list[i]); + free(list); + + RETURN(); +} + +#define CHECK_PORT() do { \ + if (!port) \ + RETURN_ERROR(SP_ERR_ARG, "Null port"); \ + if (!port->name) \ + RETURN_ERROR(SP_ERR_ARG, "Null port name"); \ +} while (0) +#ifdef _WIN32 +#define CHECK_PORT_HANDLE() do { \ + if (port->hdl == INVALID_HANDLE_VALUE) \ + RETURN_ERROR(SP_ERR_ARG, "Port not open"); \ +} while (0) +#else +#define CHECK_PORT_HANDLE() do { \ + if (port->fd < 0) \ + RETURN_ERROR(SP_ERR_ARG, "Port not open"); \ +} while (0) +#endif +#define CHECK_OPEN_PORT() do { \ + CHECK_PORT(); \ + CHECK_PORT_HANDLE(); \ +} while (0) + +#ifdef WIN32 +/** To be called after port receive buffer is emptied. */ +static enum sp_return restart_wait(struct sp_port *port) +{ + DWORD wait_result; + + if (port->wait_running) { + /* Check status of running wait operation. */ + if (GetOverlappedResult(port->hdl, &port->wait_ovl, + &wait_result, FALSE)) { + DEBUG("Previous wait completed"); + port->wait_running = FALSE; + } else if (GetLastError() == ERROR_IO_INCOMPLETE) { + DEBUG("Previous wait still running"); + RETURN_OK(); + } else { + RETURN_FAIL("GetOverlappedResult() failed"); + } + } + + if (!port->wait_running) { + /* Start new wait operation. */ + if (WaitCommEvent(port->hdl, &port->events, + &port->wait_ovl)) { + DEBUG("New wait returned, events already pending"); + } else if (GetLastError() == ERROR_IO_PENDING) { + DEBUG("New wait running in background"); + port->wait_running = TRUE; + } else { + RETURN_FAIL("WaitCommEvent() failed"); + } + } + + RETURN_OK(); +} +#endif + +SP_API enum sp_return sp_open(struct sp_port *port, enum sp_mode flags) +{ + struct port_data data; + struct sp_port_config config; + enum sp_return ret; + + TRACE("%p, 0x%x", port, flags); + + CHECK_PORT(); + + if (flags > SP_MODE_READ_WRITE) + RETURN_ERROR(SP_ERR_ARG, "Invalid flags"); + + DEBUG_FMT("Opening port %s", port->name); + +#ifdef _WIN32 + DWORD desired_access = 0, flags_and_attributes = 0, errors; + char *escaped_port_name; + COMSTAT status; + + /* Prefix port name with '\\.\' to work with ports above COM9. */ + if (!(escaped_port_name = malloc(strlen(port->name) + 5))) + RETURN_ERROR(SP_ERR_MEM, "Escaped port name malloc failed"); + sprintf(escaped_port_name, "\\\\.\\%s", port->name); + + /* Map 'flags' to the OS-specific settings. */ + flags_and_attributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED; + if (flags & SP_MODE_READ) + desired_access |= GENERIC_READ; + if (flags & SP_MODE_WRITE) + desired_access |= GENERIC_WRITE; + + port->hdl = CreateFileA(escaped_port_name, desired_access, 0, 0, + OPEN_EXISTING, flags_and_attributes, 0); + + free(escaped_port_name); + + if (port->hdl == INVALID_HANDLE_VALUE) + RETURN_FAIL("Port CreateFile() failed"); + + /* All timeouts initially disabled. */ + port->timeouts.ReadIntervalTimeout = 0; + port->timeouts.ReadTotalTimeoutMultiplier = 0; + port->timeouts.ReadTotalTimeoutConstant = 0; + port->timeouts.WriteTotalTimeoutMultiplier = 0; + port->timeouts.WriteTotalTimeoutConstant = 0; + + if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) { + sp_close(port); + RETURN_FAIL("SetCommTimeouts() failed"); + } + + /* Prepare OVERLAPPED structures. */ +#define INIT_OVERLAPPED(ovl) do { \ + memset(&port->ovl, 0, sizeof(port->ovl)); \ + port->ovl.hEvent = INVALID_HANDLE_VALUE; \ + if ((port->ovl.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL)) \ + == INVALID_HANDLE_VALUE) { \ + sp_close(port); \ + RETURN_FAIL(#ovl "CreateEvent() failed"); \ + } \ +} while (0) + + INIT_OVERLAPPED(read_ovl); + INIT_OVERLAPPED(write_ovl); + INIT_OVERLAPPED(wait_ovl); + + /* Set event mask for RX and error events. */ + if (SetCommMask(port->hdl, EV_RXCHAR | EV_ERR) == 0) { + sp_close(port); + RETURN_FAIL("SetCommMask() failed"); + } + + port->writing = FALSE; + port->wait_running = FALSE; + + ret = restart_wait(port); + + if (ret < 0) { + sp_close(port); + RETURN_CODEVAL(ret); + } +#else + int flags_local = O_NONBLOCK | O_NOCTTY | O_CLOEXEC; + + /* Map 'flags' to the OS-specific settings. */ + if ((flags & SP_MODE_READ_WRITE) == SP_MODE_READ_WRITE) + flags_local |= O_RDWR; + else if (flags & SP_MODE_READ) + flags_local |= O_RDONLY; + else if (flags & SP_MODE_WRITE) + flags_local |= O_WRONLY; + + if ((port->fd = open(port->name, flags_local)) < 0) + RETURN_FAIL("open() failed"); + + /* + * On POSIX in the default case the file descriptor of a serial port + * is not opened exclusively. Therefore the settings of a port are + * overwritten if the serial port is opened a second time. Windows + * opens all serial ports exclusively. + * So the idea is to open the serial ports alike in the exclusive mode. + * + * ioctl(*, TIOCEXCL) defines the file descriptor as exclusive. So all + * further open calls on the serial port will fail. + * + * There is a race condition if two processes open the same serial + * port. None of the processes will notice the exclusive ownership of + * the other process because ioctl() doesn't return an error code if + * the file descriptor is already marked as exclusive. + * This can be solved with flock(). It returns an error if the file + * descriptor is already locked by another process. + */ +#ifdef HAVE_FLOCK + if (flock(port->fd, LOCK_EX | LOCK_NB) < 0) + RETURN_FAIL("flock() failed"); +#endif + +#ifdef TIOCEXCL + /* + * Before Linux 3.8 ioctl(*, TIOCEXCL) was not implemented and could + * lead to EINVAL or ENOTTY. + * These errors aren't fatal and can be ignored. + */ + if (ioctl(port->fd, TIOCEXCL) < 0 && errno != EINVAL && errno != ENOTTY) + RETURN_FAIL("ioctl() failed"); +#endif + +#endif + + ret = get_config(port, &data, &config); + + if (ret < 0) { + sp_close(port); + RETURN_CODEVAL(ret); + } + + /* + * Assume a default baudrate if the OS does not provide one. + * Cannot assign -1 here since Windows holds the baudrate in + * the DCB and does not configure the rate individually. + */ + if (config.baudrate == 0) { + config.baudrate = 9600; + } + + /* Set sane port settings. */ +#ifdef _WIN32 + data.dcb.fBinary = TRUE; + data.dcb.fDsrSensitivity = FALSE; + data.dcb.fErrorChar = FALSE; + data.dcb.fNull = FALSE; + data.dcb.fAbortOnError = FALSE; +#else + /* Turn off all fancy termios tricks, give us a raw channel. */ + data.term.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IMAXBEL); +#ifdef IUCLC + data.term.c_iflag &= ~IUCLC; +#endif + data.term.c_oflag &= ~(OPOST | ONLCR | OCRNL | ONOCR | ONLRET); +#ifdef OLCUC + data.term.c_oflag &= ~OLCUC; +#endif +#ifdef NLDLY + data.term.c_oflag &= ~NLDLY; +#endif +#ifdef CRDLY + data.term.c_oflag &= ~CRDLY; +#endif +#ifdef TABDLY + data.term.c_oflag &= ~TABDLY; +#endif +#ifdef BSDLY + data.term.c_oflag &= ~BSDLY; +#endif +#ifdef VTDLY + data.term.c_oflag &= ~VTDLY; +#endif +#ifdef FFDLY + data.term.c_oflag &= ~FFDLY; +#endif +#ifdef OFILL + data.term.c_oflag &= ~OFILL; +#endif + data.term.c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN); + data.term.c_cc[VMIN] = 0; + data.term.c_cc[VTIME] = 0; + + /* Ignore modem status lines; enable receiver; leave control lines alone on close. */ + data.term.c_cflag |= (CLOCAL | CREAD); + data.term.c_cflag &= ~(HUPCL); +#endif + +#ifdef _WIN32 + if (ClearCommError(port->hdl, &errors, &status) == 0) + RETURN_FAIL("ClearCommError() failed"); +#endif + + ret = set_config(port, &data, &config); + + if (ret < 0) { + sp_close(port); + RETURN_CODEVAL(ret); + } + + RETURN_OK(); +} + +SP_API enum sp_return sp_close(struct sp_port *port) +{ + TRACE("%p", port); + + CHECK_OPEN_PORT(); + + DEBUG_FMT("Closing port %s", port->name); + +#ifdef _WIN32 + /* Returns non-zero upon success, 0 upon failure. */ + if (CloseHandle(port->hdl) == 0) + RETURN_FAIL("Port CloseHandle() failed"); + port->hdl = INVALID_HANDLE_VALUE; + + /* Close event handles for overlapped structures. */ +#define CLOSE_OVERLAPPED(ovl) do { \ + if (port->ovl.hEvent != INVALID_HANDLE_VALUE && \ + CloseHandle(port->ovl.hEvent) == 0) \ + RETURN_FAIL(# ovl "event CloseHandle() failed"); \ +} while (0) + CLOSE_OVERLAPPED(read_ovl); + CLOSE_OVERLAPPED(write_ovl); + CLOSE_OVERLAPPED(wait_ovl); + + if (port->write_buf) { + free(port->write_buf); + port->write_buf = NULL; + } +#else + /* Returns 0 upon success, -1 upon failure. */ + if (close(port->fd) == -1) + RETURN_FAIL("close() failed"); + port->fd = -1; +#endif + + RETURN_OK(); +} + +SP_API enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers) +{ + TRACE("%p, 0x%x", port, buffers); + + CHECK_OPEN_PORT(); + + if (buffers > SP_BUF_BOTH) + RETURN_ERROR(SP_ERR_ARG, "Invalid buffer selection"); + + const char *buffer_names[] = {"no", "input", "output", "both"}; + + DEBUG_FMT("Flushing %s buffers on port %s", + buffer_names[buffers], port->name); + +#ifdef _WIN32 + DWORD flags = 0; + if (buffers & SP_BUF_INPUT) + flags |= PURGE_RXCLEAR; + if (buffers & SP_BUF_OUTPUT) + flags |= PURGE_TXCLEAR; + + /* Returns non-zero upon success, 0 upon failure. */ + if (PurgeComm(port->hdl, flags) == 0) + RETURN_FAIL("PurgeComm() failed"); + + if (buffers & SP_BUF_INPUT) + TRY(restart_wait(port)); +#else + int flags = 0; + if (buffers == SP_BUF_BOTH) + flags = TCIOFLUSH; + else if (buffers == SP_BUF_INPUT) + flags = TCIFLUSH; + else if (buffers == SP_BUF_OUTPUT) + flags = TCOFLUSH; + + /* Returns 0 upon success, -1 upon failure. */ + if (tcflush(port->fd, flags) < 0) + RETURN_FAIL("tcflush() failed"); +#endif + RETURN_OK(); +} + +SP_API enum sp_return sp_drain(struct sp_port *port) +{ + TRACE("%p", port); + + CHECK_OPEN_PORT(); + + DEBUG_FMT("Draining port %s", port->name); + +#ifdef _WIN32 + /* Returns non-zero upon success, 0 upon failure. */ + if (FlushFileBuffers(port->hdl) == 0) + RETURN_FAIL("FlushFileBuffers() failed"); + RETURN_OK(); +#else + int result; + while (1) { +#if defined(__ANDROID__) && (__ANDROID_API__ < 21) + /* Android only has tcdrain from platform 21 onwards. + * On previous API versions, use the ioctl directly. */ + int arg = 1; + result = ioctl(port->fd, TCSBRK, &arg); +#else + result = tcdrain(port->fd); +#endif + if (result < 0) { + if (errno == EINTR) { + DEBUG("tcdrain() was interrupted"); + continue; + } else { + RETURN_FAIL("tcdrain() failed"); + } + } else { + RETURN_OK(); + } + } +#endif +} + +#ifdef _WIN32 +static enum sp_return await_write_completion(struct sp_port *port) +{ + TRACE("%p", port); + DWORD bytes_written; + BOOL result; + + /* Wait for previous non-blocking write to complete, if any. */ + if (port->writing) { + DEBUG("Waiting for previous write to complete"); + result = GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE); + port->writing = 0; + if (!result) + RETURN_FAIL("Previous write failed to complete"); + DEBUG("Previous write completed"); + } + + RETURN_OK(); +} +#endif + +SP_API enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, + size_t count, unsigned int timeout_ms) +{ + TRACE("%p, %p, %d, %d", port, buf, count, timeout_ms); + + CHECK_OPEN_PORT(); + + if (!buf) + RETURN_ERROR(SP_ERR_ARG, "Null buffer"); + + if (timeout_ms) + DEBUG_FMT("Writing %d bytes to port %s, timeout %d ms", + count, port->name, timeout_ms); + else + DEBUG_FMT("Writing %d bytes to port %s, no timeout", + count, port->name); + + if (count == 0) + RETURN_INT(0); + +#ifdef _WIN32 + DWORD remaining_ms, write_size, bytes_written; + size_t remaining_bytes, total_bytes_written = 0; + const uint8_t *write_ptr = (uint8_t *) buf; + bool result; + struct timeout timeout; + + timeout_start(&timeout, timeout_ms); + + TRY(await_write_completion(port)); + + while (total_bytes_written < count) { + + if (timeout_check(&timeout)) + break; + + remaining_ms = timeout_remaining_ms(&timeout); + + if (port->timeouts.WriteTotalTimeoutConstant != remaining_ms) { + port->timeouts.WriteTotalTimeoutConstant = remaining_ms; + if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) + RETURN_FAIL("SetCommTimeouts() failed"); + } + + /* Reduce write size if it exceeds the WriteFile limit. */ + remaining_bytes = count - total_bytes_written; + if (remaining_bytes > WRITEFILE_MAX_SIZE) + write_size = WRITEFILE_MAX_SIZE; + else + write_size = (DWORD) remaining_bytes; + + /* Start write. */ + + result = WriteFile(port->hdl, write_ptr, write_size, NULL, &port->write_ovl); + + timeout_update(&timeout); + + if (result) { + DEBUG("Write completed immediately"); + bytes_written = write_size; + } else if (GetLastError() == ERROR_IO_PENDING) { + DEBUG("Waiting for write to complete"); + if (GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE) == 0) { + if (GetLastError() == ERROR_SEM_TIMEOUT) { + DEBUG("Write timed out"); + break; + } else { + RETURN_FAIL("GetOverlappedResult() failed"); + } + } + DEBUG_FMT("Write completed, %d/%d bytes written", bytes_written, write_size); + } else { + RETURN_FAIL("WriteFile() failed"); + } + + write_ptr += bytes_written; + total_bytes_written += bytes_written; + } + + RETURN_INT((int) total_bytes_written); +#else + size_t bytes_written = 0; + unsigned char *ptr = (unsigned char *) buf; + struct timeout timeout; + fd_set fds; + int result; + + timeout_start(&timeout, timeout_ms); + + FD_ZERO(&fds); + FD_SET(port->fd, &fds); + + /* Loop until we have written the requested number of bytes. */ + while (bytes_written < count) { + + if (timeout_check(&timeout)) + break; + + result = select(port->fd + 1, NULL, &fds, NULL, timeout_timeval(&timeout)); + + timeout_update(&timeout); + + if (result < 0) { + if (errno == EINTR) { + DEBUG("select() call was interrupted, repeating"); + continue; + } else { + RETURN_FAIL("select() failed"); + } + } else if (result == 0) { + /* Timeout has expired. */ + break; + } + + /* Do write. */ + result = write(port->fd, ptr, count - bytes_written); + + if (result < 0) { + if (errno == EAGAIN) + /* This shouldn't happen because we did a select() first, but handle anyway. */ + continue; + else + /* This is an actual failure. */ + RETURN_FAIL("write() failed"); + } + + bytes_written += result; + ptr += result; + } + + if (bytes_written < count) + DEBUG("Write timed out"); + + RETURN_INT(bytes_written); +#endif +} + +SP_API enum sp_return sp_nonblocking_write(struct sp_port *port, + const void *buf, size_t count) +{ + TRACE("%p, %p, %d", port, buf, count); + + CHECK_OPEN_PORT(); + + if (!buf) + RETURN_ERROR(SP_ERR_ARG, "Null buffer"); + + DEBUG_FMT("Writing up to %d bytes to port %s", count, port->name); + + if (count == 0) + RETURN_INT(0); + +#ifdef _WIN32 + size_t buf_bytes; + + /* Check whether previous write is complete. */ + if (port->writing) { + if (HasOverlappedIoCompleted(&port->write_ovl)) { + DEBUG("Previous write completed"); + port->writing = 0; + } else { + DEBUG("Previous write not complete"); + /* Can't take a new write until the previous one finishes. */ + RETURN_INT(0); + } + } + + /* Set timeout. */ + if (port->timeouts.WriteTotalTimeoutConstant != 0) { + port->timeouts.WriteTotalTimeoutConstant = 0; + if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) + RETURN_FAIL("SetCommTimeouts() failed"); + } + + /* Reduce count if it exceeds the WriteFile limit. */ + if (count > WRITEFILE_MAX_SIZE) + count = WRITEFILE_MAX_SIZE; + + /* Copy data to our write buffer. */ + buf_bytes = min(port->write_buf_size, count); + memcpy(port->write_buf, buf, buf_bytes); + + /* Start asynchronous write. */ + if (WriteFile(port->hdl, port->write_buf, (DWORD) buf_bytes, NULL, &port->write_ovl) == 0) { + if (GetLastError() == ERROR_IO_PENDING) { + if ((port->writing = !HasOverlappedIoCompleted(&port->write_ovl))) + DEBUG("Asynchronous write completed immediately"); + else + DEBUG("Asynchronous write running"); + } else { + /* Actual failure of some kind. */ + RETURN_FAIL("WriteFile() failed"); + } + } + + DEBUG("All bytes written immediately"); + + RETURN_INT((int) buf_bytes); +#else + /* Returns the number of bytes written, or -1 upon failure. */ + ssize_t written = write(port->fd, buf, count); + + if (written < 0) { + if (errno == EAGAIN) + // Buffer is full, no bytes written. + RETURN_INT(0); + else + RETURN_FAIL("write() failed"); + } else { + RETURN_INT(written); + } +#endif +} + +#ifdef _WIN32 +/* Restart wait operation if buffer was emptied. */ +static enum sp_return restart_wait_if_needed(struct sp_port *port, unsigned int bytes_read) +{ + DWORD errors; + COMSTAT comstat; + + if (bytes_read == 0) + RETURN_OK(); + + if (ClearCommError(port->hdl, &errors, &comstat) == 0) + RETURN_FAIL("ClearCommError() failed"); + + if (comstat.cbInQue == 0) + TRY(restart_wait(port)); + + RETURN_OK(); +} +#endif + +SP_API enum sp_return sp_blocking_read(struct sp_port *port, void *buf, + size_t count, unsigned int timeout_ms) +{ + TRACE("%p, %p, %d, %d", port, buf, count, timeout_ms); + + CHECK_OPEN_PORT(); + + if (!buf) + RETURN_ERROR(SP_ERR_ARG, "Null buffer"); + + if (timeout_ms) + DEBUG_FMT("Reading %d bytes from port %s, timeout %d ms", + count, port->name, timeout_ms); + else + DEBUG_FMT("Reading %d bytes from port %s, no timeout", + count, port->name); + + if (count == 0) + RETURN_INT(0); + +#ifdef _WIN32 + DWORD bytes_read; + + /* Set timeout. */ + if (port->timeouts.ReadIntervalTimeout != 0 || + port->timeouts.ReadTotalTimeoutMultiplier != 0 || + port->timeouts.ReadTotalTimeoutConstant != timeout_ms) { + port->timeouts.ReadIntervalTimeout = 0; + port->timeouts.ReadTotalTimeoutMultiplier = 0; + port->timeouts.ReadTotalTimeoutConstant = timeout_ms; + if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) + RETURN_FAIL("SetCommTimeouts() failed"); + } + + /* Start read. */ + if (ReadFile(port->hdl, buf, (DWORD) count, NULL, &port->read_ovl)) { + DEBUG("Read completed immediately"); + bytes_read = (DWORD) count; + } else if (GetLastError() == ERROR_IO_PENDING) { + DEBUG("Waiting for read to complete"); + if (GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE) == 0) + RETURN_FAIL("GetOverlappedResult() failed"); + DEBUG_FMT("Read completed, %d/%d bytes read", bytes_read, count); + } else { + RETURN_FAIL("ReadFile() failed"); + } + + TRY(restart_wait_if_needed(port, bytes_read)); + + RETURN_INT((int) bytes_read); + +#else + size_t bytes_read = 0; + unsigned char *ptr = (unsigned char *) buf; + struct timeout timeout; + fd_set fds; + int result; + + timeout_start(&timeout, timeout_ms); + + FD_ZERO(&fds); + FD_SET(port->fd, &fds); + + /* Loop until we have the requested number of bytes. */ + while (bytes_read < count) { + + if (timeout_check(&timeout)) + /* Timeout has expired. */ + break; + + result = select(port->fd + 1, &fds, NULL, NULL, timeout_timeval(&timeout)); + + timeout_update(&timeout); + + if (result < 0) { + if (errno == EINTR) { + DEBUG("select() call was interrupted, repeating"); + continue; + } else { + RETURN_FAIL("select() failed"); + } + } else if (result == 0) { + /* Timeout has expired. */ + break; + } + + /* Do read. */ + result = read(port->fd, ptr, count - bytes_read); + + if (result < 0) { + if (errno == EAGAIN) + /* + * This shouldn't happen because we did a + * select() first, but handle anyway. + */ + continue; + else + /* This is an actual failure. */ + RETURN_FAIL("read() failed"); + } + + bytes_read += result; + ptr += result; + } + + if (bytes_read < count) + DEBUG("Read timed out"); + + RETURN_INT(bytes_read); +#endif +} + +SP_API enum sp_return sp_blocking_read_next(struct sp_port *port, void *buf, + size_t count, unsigned int timeout_ms) +{ + TRACE("%p, %p, %d, %d", port, buf, count, timeout_ms); + + CHECK_OPEN_PORT(); + + if (!buf) + RETURN_ERROR(SP_ERR_ARG, "Null buffer"); + + if (count == 0) + RETURN_ERROR(SP_ERR_ARG, "Zero count"); + + if (timeout_ms) + DEBUG_FMT("Reading next max %d bytes from port %s, timeout %d ms", + count, port->name, timeout_ms); + else + DEBUG_FMT("Reading next max %d bytes from port %s, no timeout", + count, port->name); + +#ifdef _WIN32 + DWORD bytes_read = 0; + + /* If timeout_ms == 0, set maximum timeout. */ + DWORD timeout_val = (timeout_ms == 0 ? MAXDWORD - 1 : timeout_ms); + + /* Set timeout. */ + if (port->timeouts.ReadIntervalTimeout != MAXDWORD || + port->timeouts.ReadTotalTimeoutMultiplier != MAXDWORD || + port->timeouts.ReadTotalTimeoutConstant != timeout_val) { + port->timeouts.ReadIntervalTimeout = MAXDWORD; + port->timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; + port->timeouts.ReadTotalTimeoutConstant = timeout_val; + if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) + RETURN_FAIL("SetCommTimeouts() failed"); + } + + /* Loop until we have at least one byte, or timeout is reached. */ + while (bytes_read == 0) { + /* Start read. */ + if (ReadFile(port->hdl, buf, (DWORD) count, &bytes_read, &port->read_ovl)) { + DEBUG("Read completed immediately"); + } else if (GetLastError() == ERROR_IO_PENDING) { + DEBUG("Waiting for read to complete"); + if (GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE) == 0) + RETURN_FAIL("GetOverlappedResult() failed"); + if (bytes_read > 0) { + DEBUG("Read completed"); + } else if (timeout_ms > 0) { + DEBUG("Read timed out"); + break; + } else { + DEBUG("Restarting read"); + } + } else { + RETURN_FAIL("ReadFile() failed"); + } + } + + TRY(restart_wait_if_needed(port, bytes_read)); + + RETURN_INT(bytes_read); + +#else + size_t bytes_read = 0; + struct timeout timeout; + fd_set fds; + int result; + + timeout_start(&timeout, timeout_ms); + + FD_ZERO(&fds); + FD_SET(port->fd, &fds); + + /* Loop until we have at least one byte, or timeout is reached. */ + while (bytes_read == 0) { + + if (timeout_check(&timeout)) + /* Timeout has expired. */ + break; + + result = select(port->fd + 1, &fds, NULL, NULL, timeout_timeval(&timeout)); + + timeout_update(&timeout); + + if (result < 0) { + if (errno == EINTR) { + DEBUG("select() call was interrupted, repeating"); + continue; + } else { + RETURN_FAIL("select() failed"); + } + } else if (result == 0) { + /* Timeout has expired. */ + break; + } + + /* Do read. */ + result = read(port->fd, buf, count); + + if (result < 0) { + if (errno == EAGAIN) + /* This shouldn't happen because we did a select() first, but handle anyway. */ + continue; + else + /* This is an actual failure. */ + RETURN_FAIL("read() failed"); + } + + bytes_read = result; + } + + if (bytes_read == 0) + DEBUG("Read timed out"); + + RETURN_INT(bytes_read); +#endif +} + +SP_API enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf, + size_t count) +{ + TRACE("%p, %p, %d", port, buf, count); + + CHECK_OPEN_PORT(); + + if (!buf) + RETURN_ERROR(SP_ERR_ARG, "Null buffer"); + + DEBUG_FMT("Reading up to %d bytes from port %s", count, port->name); + +#ifdef _WIN32 + DWORD bytes_read; + + /* Set timeout. */ + if (port->timeouts.ReadIntervalTimeout != MAXDWORD || + port->timeouts.ReadTotalTimeoutMultiplier != 0 || + port->timeouts.ReadTotalTimeoutConstant != 0) { + port->timeouts.ReadIntervalTimeout = MAXDWORD; + port->timeouts.ReadTotalTimeoutMultiplier = 0; + port->timeouts.ReadTotalTimeoutConstant = 0; + if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) + RETURN_FAIL("SetCommTimeouts() failed"); + } + + /* Do read. */ + if (ReadFile(port->hdl, buf, (DWORD) count, NULL, &port->read_ovl) == 0) + if (GetLastError() != ERROR_IO_PENDING) + RETURN_FAIL("ReadFile() failed"); + + /* Get number of bytes read. */ + if (GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, FALSE) == 0) + RETURN_FAIL("GetOverlappedResult() failed"); + + TRY(restart_wait_if_needed(port, bytes_read)); + + RETURN_INT(bytes_read); +#else + ssize_t bytes_read; + + /* Returns the number of bytes read, or -1 upon failure. */ + if ((bytes_read = read(port->fd, buf, count)) < 0) { + if (errno == EAGAIN) + /* No bytes available. */ + bytes_read = 0; + else + /* This is an actual failure. */ + RETURN_FAIL("read() failed"); + } + RETURN_INT(bytes_read); +#endif +} + +SP_API enum sp_return sp_input_waiting(struct sp_port *port) +{ + TRACE("%p", port); + + CHECK_OPEN_PORT(); + + DEBUG_FMT("Checking input bytes waiting on port %s", port->name); + +#ifdef _WIN32 + DWORD errors; + COMSTAT comstat; + + if (ClearCommError(port->hdl, &errors, &comstat) == 0) + RETURN_FAIL("ClearCommError() failed"); + RETURN_INT(comstat.cbInQue); +#else + int bytes_waiting; + if (ioctl(port->fd, TIOCINQ, &bytes_waiting) < 0) + RETURN_FAIL("TIOCINQ ioctl failed"); + RETURN_INT(bytes_waiting); +#endif +} + +SP_API enum sp_return sp_output_waiting(struct sp_port *port) +{ + TRACE("%p", port); + +#ifdef __CYGWIN__ + /* TIOCOUTQ is not defined in Cygwin headers */ + RETURN_ERROR(SP_ERR_SUPP, + "Getting output bytes waiting is not supported on Cygwin"); +#else + CHECK_OPEN_PORT(); + + DEBUG_FMT("Checking output bytes waiting on port %s", port->name); + +#ifdef _WIN32 + DWORD errors; + COMSTAT comstat; + + if (ClearCommError(port->hdl, &errors, &comstat) == 0) + RETURN_FAIL("ClearCommError() failed"); + RETURN_INT(comstat.cbOutQue); +#else + int bytes_waiting; + if (ioctl(port->fd, TIOCOUTQ, &bytes_waiting) < 0) + RETURN_FAIL("TIOCOUTQ ioctl failed"); + RETURN_INT(bytes_waiting); +#endif +#endif +} + +SP_API enum sp_return sp_new_event_set(struct sp_event_set **result_ptr) +{ + struct sp_event_set *result; + + TRACE("%p", result_ptr); + + if (!result_ptr) + RETURN_ERROR(SP_ERR_ARG, "Null result"); + + *result_ptr = NULL; + + if (!(result = malloc(sizeof(struct sp_event_set)))) + RETURN_ERROR(SP_ERR_MEM, "sp_event_set malloc() failed"); + + memset(result, 0, sizeof(struct sp_event_set)); + + *result_ptr = result; + + RETURN_OK(); +} + +static enum sp_return add_handle(struct sp_event_set *event_set, + event_handle handle, enum sp_event mask) +{ + void *new_handles; + enum sp_event *new_masks; + + TRACE("%p, %d, %d", event_set, handle, mask); + + if (!(new_handles = realloc(event_set->handles, + sizeof(event_handle) * (event_set->count + 1)))) + RETURN_ERROR(SP_ERR_MEM, "Handle array realloc() failed"); + + event_set->handles = new_handles; + + if (!(new_masks = realloc(event_set->masks, + sizeof(enum sp_event) * (event_set->count + 1)))) + RETURN_ERROR(SP_ERR_MEM, "Mask array realloc() failed"); + + event_set->masks = new_masks; + + ((event_handle *) event_set->handles)[event_set->count] = handle; + event_set->masks[event_set->count] = mask; + + event_set->count++; + + RETURN_OK(); +} + +SP_API enum sp_return sp_add_port_events(struct sp_event_set *event_set, + const struct sp_port *port, enum sp_event mask) +{ + TRACE("%p, %p, %d", event_set, port, mask); + + if (!event_set) + RETURN_ERROR(SP_ERR_ARG, "Null event set"); + + if (!port) + RETURN_ERROR(SP_ERR_ARG, "Null port"); + + if (mask > (SP_EVENT_RX_READY | SP_EVENT_TX_READY | SP_EVENT_ERROR)) + RETURN_ERROR(SP_ERR_ARG, "Invalid event mask"); + + if (!mask) + RETURN_OK(); + +#ifdef _WIN32 + enum sp_event handle_mask; + if ((handle_mask = mask & SP_EVENT_TX_READY)) + TRY(add_handle(event_set, port->write_ovl.hEvent, handle_mask)); + if ((handle_mask = mask & (SP_EVENT_RX_READY | SP_EVENT_ERROR))) + TRY(add_handle(event_set, port->wait_ovl.hEvent, handle_mask)); +#else + TRY(add_handle(event_set, port->fd, mask)); +#endif + + RETURN_OK(); +} + +SP_API void sp_free_event_set(struct sp_event_set *event_set) +{ + TRACE("%p", event_set); + + if (!event_set) { + DEBUG("Null event set"); + RETURN(); + } + + DEBUG("Freeing event set"); + + if (event_set->handles) + free(event_set->handles); + if (event_set->masks) + free(event_set->masks); + + free(event_set); + + RETURN(); +} + +SP_API enum sp_return sp_wait(struct sp_event_set *event_set, + unsigned int timeout_ms) +{ + TRACE("%p, %d", event_set, timeout_ms); + + if (!event_set) + RETURN_ERROR(SP_ERR_ARG, "Null event set"); + +#ifdef _WIN32 + if (WaitForMultipleObjects(event_set->count, event_set->handles, FALSE, + timeout_ms ? timeout_ms : INFINITE) == WAIT_FAILED) + RETURN_FAIL("WaitForMultipleObjects() failed"); + + RETURN_OK(); +#else + struct timeout timeout; + int poll_timeout; + int result; + struct pollfd *pollfds; + unsigned int i; + + if (!(pollfds = malloc(sizeof(struct pollfd) * event_set->count))) + RETURN_ERROR(SP_ERR_MEM, "pollfds malloc() failed"); + + for (i = 0; i < event_set->count; i++) { + pollfds[i].fd = ((int *)event_set->handles)[i]; + pollfds[i].events = 0; + pollfds[i].revents = 0; + if (event_set->masks[i] & SP_EVENT_RX_READY) + pollfds[i].events |= POLLIN; + if (event_set->masks[i] & SP_EVENT_TX_READY) + pollfds[i].events |= POLLOUT; + if (event_set->masks[i] & SP_EVENT_ERROR) + pollfds[i].events |= POLLERR; + } + + timeout_start(&timeout, timeout_ms); + timeout_limit(&timeout, INT_MAX); + + /* Loop until an event occurs. */ + while (1) { + + if (timeout_check(&timeout)) { + DEBUG("Wait timed out"); + break; + } + + poll_timeout = (int) timeout_remaining_ms(&timeout); + if (poll_timeout == 0) + poll_timeout = -1; + + result = poll(pollfds, event_set->count, poll_timeout); + + timeout_update(&timeout); + + if (result < 0) { + if (errno == EINTR) { + DEBUG("poll() call was interrupted, repeating"); + continue; + } else { + free(pollfds); + RETURN_FAIL("poll() failed"); + } + } else if (result == 0) { + DEBUG("poll() timed out"); + if (!timeout.overflow) + break; + } else { + DEBUG("poll() completed"); + break; + } + } + + free(pollfds); + RETURN_OK(); +#endif +} + +#ifdef USE_TERMIOS_SPEED +static enum sp_return get_baudrate(int fd, int *baudrate) +{ + void *data; + + TRACE("%d, %p", fd, baudrate); + + DEBUG("Getting baud rate"); + + if (!(data = malloc(get_termios_size()))) + RETURN_ERROR(SP_ERR_MEM, "termios malloc failed"); + + if (ioctl(fd, get_termios_get_ioctl(), data) < 0) { + free(data); + RETURN_FAIL("Getting termios failed"); + } + + *baudrate = get_termios_speed(data); + + free(data); + + RETURN_OK(); +} + +static enum sp_return set_baudrate(int fd, int baudrate) +{ + void *data; + + TRACE("%d, %d", fd, baudrate); + + DEBUG("Getting baud rate"); + + if (!(data = malloc(get_termios_size()))) + RETURN_ERROR(SP_ERR_MEM, "termios malloc failed"); + + if (ioctl(fd, get_termios_get_ioctl(), data) < 0) { + free(data); + RETURN_FAIL("Getting termios failed"); + } + + DEBUG("Setting baud rate"); + + set_termios_speed(data, baudrate); + + if (ioctl(fd, get_termios_set_ioctl(), data) < 0) { + free(data); + RETURN_FAIL("Setting termios failed"); + } + + free(data); + + RETURN_OK(); +} +#endif /* USE_TERMIOS_SPEED */ + +#ifdef USE_TERMIOX +static enum sp_return get_flow(int fd, struct port_data *data) +{ + void *termx; + + TRACE("%d, %p", fd, data); + + DEBUG("Getting advanced flow control"); + + if (!(termx = malloc(get_termiox_size()))) + RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed"); + + if (ioctl(fd, TCGETX, termx) < 0) { + free(termx); + RETURN_FAIL("Getting termiox failed"); + } + + get_termiox_flow(termx, &data->rts_flow, &data->cts_flow, + &data->dtr_flow, &data->dsr_flow); + + free(termx); + + RETURN_OK(); +} + +static enum sp_return set_flow(int fd, struct port_data *data) +{ + void *termx; + + TRACE("%d, %p", fd, data); + + DEBUG("Getting advanced flow control"); + + if (!(termx = malloc(get_termiox_size()))) + RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed"); + + if (ioctl(fd, TCGETX, termx) < 0) { + free(termx); + RETURN_FAIL("Getting termiox failed"); + } + + DEBUG("Setting advanced flow control"); + + set_termiox_flow(termx, data->rts_flow, data->cts_flow, + data->dtr_flow, data->dsr_flow); + + if (ioctl(fd, TCSETX, termx) < 0) { + free(termx); + RETURN_FAIL("Setting termiox failed"); + } + + free(termx); + + RETURN_OK(); +} +#endif /* USE_TERMIOX */ + +static enum sp_return get_config(struct sp_port *port, struct port_data *data, + struct sp_port_config *config) +{ + unsigned int i; + + TRACE("%p, %p, %p", port, data, config); + + DEBUG_FMT("Getting configuration for port %s", port->name); + +#ifdef _WIN32 + if (!GetCommState(port->hdl, &data->dcb)) + RETURN_FAIL("GetCommState() failed"); + + for (i = 0; i < NUM_STD_BAUDRATES; i++) { + if (data->dcb.BaudRate == std_baudrates[i].index) { + config->baudrate = std_baudrates[i].value; + break; + } + } + + if (i == NUM_STD_BAUDRATES) + /* BaudRate field can be either an index or a custom baud rate. */ + config->baudrate = data->dcb.BaudRate; + + config->bits = data->dcb.ByteSize; + + switch (data->dcb.Parity) { + case NOPARITY: + config->parity = SP_PARITY_NONE; + break; + case ODDPARITY: + config->parity = SP_PARITY_ODD; + break; + case EVENPARITY: + config->parity = SP_PARITY_EVEN; + break; + case MARKPARITY: + config->parity = SP_PARITY_MARK; + break; + case SPACEPARITY: + config->parity = SP_PARITY_SPACE; + break; + default: + config->parity = -1; + } + + switch (data->dcb.StopBits) { + case ONESTOPBIT: + config->stopbits = 1; + break; + case TWOSTOPBITS: + config->stopbits = 2; + break; + default: + config->stopbits = -1; + } + + switch (data->dcb.fRtsControl) { + case RTS_CONTROL_DISABLE: + config->rts = SP_RTS_OFF; + break; + case RTS_CONTROL_ENABLE: + config->rts = SP_RTS_ON; + break; + case RTS_CONTROL_HANDSHAKE: + config->rts = SP_RTS_FLOW_CONTROL; + break; + default: + config->rts = -1; + } + + config->cts = data->dcb.fOutxCtsFlow ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE; + + switch (data->dcb.fDtrControl) { + case DTR_CONTROL_DISABLE: + config->dtr = SP_DTR_OFF; + break; + case DTR_CONTROL_ENABLE: + config->dtr = SP_DTR_ON; + break; + case DTR_CONTROL_HANDSHAKE: + config->dtr = SP_DTR_FLOW_CONTROL; + break; + default: + config->dtr = -1; + } + + config->dsr = data->dcb.fOutxDsrFlow ? SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE; + + if (data->dcb.fInX) { + if (data->dcb.fOutX) + config->xon_xoff = SP_XONXOFF_INOUT; + else + config->xon_xoff = SP_XONXOFF_IN; + } else { + if (data->dcb.fOutX) + config->xon_xoff = SP_XONXOFF_OUT; + else + config->xon_xoff = SP_XONXOFF_DISABLED; + } + +#else // !_WIN32 + + if (tcgetattr(port->fd, &data->term) < 0) + RETURN_FAIL("tcgetattr() failed"); + + if (ioctl(port->fd, TIOCMGET, &data->controlbits) < 0) + RETURN_FAIL("TIOCMGET ioctl failed"); + +#ifdef USE_TERMIOX + int ret = get_flow(port->fd, data); + + if (ret == SP_ERR_FAIL && errno == EINVAL) + data->termiox_supported = 0; + else if (ret < 0) + RETURN_CODEVAL(ret); + else + data->termiox_supported = 1; +#else + data->termiox_supported = 0; +#endif + + for (i = 0; i < NUM_STD_BAUDRATES; i++) { + if (cfgetispeed(&data->term) == std_baudrates[i].index) { + config->baudrate = std_baudrates[i].value; + break; + } + } + + if (i == NUM_STD_BAUDRATES) { +#ifdef __APPLE__ + config->baudrate = (int)data->term.c_ispeed; +#elif defined(USE_TERMIOS_SPEED) + TRY(get_baudrate(port->fd, &config->baudrate)); +#else + config->baudrate = -1; +#endif + } + + switch (data->term.c_cflag & CSIZE) { + case CS8: + config->bits = 8; + break; + case CS7: + config->bits = 7; + break; + case CS6: + config->bits = 6; + break; + case CS5: + config->bits = 5; + break; + default: + config->bits = -1; + } + + if (!(data->term.c_cflag & PARENB) && (data->term.c_iflag & IGNPAR)) + config->parity = SP_PARITY_NONE; + else if (!(data->term.c_cflag & PARENB) || (data->term.c_iflag & IGNPAR)) + config->parity = -1; +#ifdef CMSPAR + else if (data->term.c_cflag & CMSPAR) + config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_MARK : SP_PARITY_SPACE; +#endif + else + config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_ODD : SP_PARITY_EVEN; + + config->stopbits = (data->term.c_cflag & CSTOPB) ? 2 : 1; + + if (data->term.c_cflag & CRTSCTS) { + config->rts = SP_RTS_FLOW_CONTROL; + config->cts = SP_CTS_FLOW_CONTROL; + } else { + if (data->termiox_supported && data->rts_flow) + config->rts = SP_RTS_FLOW_CONTROL; + else + config->rts = (data->controlbits & TIOCM_RTS) ? SP_RTS_ON : SP_RTS_OFF; + + config->cts = (data->termiox_supported && data->cts_flow) ? + SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE; + } + + if (data->termiox_supported && data->dtr_flow) + config->dtr = SP_DTR_FLOW_CONTROL; + else + config->dtr = (data->controlbits & TIOCM_DTR) ? SP_DTR_ON : SP_DTR_OFF; + + config->dsr = (data->termiox_supported && data->dsr_flow) ? + SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE; + + if (data->term.c_iflag & IXOFF) { + if (data->term.c_iflag & IXON) + config->xon_xoff = SP_XONXOFF_INOUT; + else + config->xon_xoff = SP_XONXOFF_IN; + } else { + if (data->term.c_iflag & IXON) + config->xon_xoff = SP_XONXOFF_OUT; + else + config->xon_xoff = SP_XONXOFF_DISABLED; + } +#endif + + RETURN_OK(); +} + +static enum sp_return set_config(struct sp_port *port, struct port_data *data, + const struct sp_port_config *config) +{ + unsigned int i; +#ifdef __APPLE__ + BAUD_TYPE baud_nonstd; + + baud_nonstd = B0; +#endif +#ifdef USE_TERMIOS_SPEED + int baud_nonstd = 0; +#endif + + TRACE("%p, %p, %p", port, data, config); + + DEBUG_FMT("Setting configuration for port %s", port->name); + +#ifdef _WIN32 + BYTE* new_buf; + + TRY(await_write_completion(port)); + + if (config->baudrate >= 0) { + for (i = 0; i < NUM_STD_BAUDRATES; i++) { + if (config->baudrate == std_baudrates[i].value) { + data->dcb.BaudRate = std_baudrates[i].index; + break; + } + } + + if (i == NUM_STD_BAUDRATES) + data->dcb.BaudRate = config->baudrate; + + /* Allocate write buffer for 50ms of data at baud rate. */ + port->write_buf_size = max(config->baudrate / (8 * 20), 1); + new_buf = realloc(port->write_buf, port->write_buf_size); + if (!new_buf) + RETURN_ERROR(SP_ERR_MEM, "Allocating write buffer failed"); + port->write_buf = new_buf; + } + + if (config->bits >= 0) + data->dcb.ByteSize = config->bits; + + if (config->parity >= 0) { + switch (config->parity) { + case SP_PARITY_NONE: + data->dcb.Parity = NOPARITY; + break; + case SP_PARITY_ODD: + data->dcb.Parity = ODDPARITY; + break; + case SP_PARITY_EVEN: + data->dcb.Parity = EVENPARITY; + break; + case SP_PARITY_MARK: + data->dcb.Parity = MARKPARITY; + break; + case SP_PARITY_SPACE: + data->dcb.Parity = SPACEPARITY; + break; + default: + RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting"); + } + } + + if (config->stopbits >= 0) { + switch (config->stopbits) { + /* Note: There's also ONE5STOPBITS == 1.5 (unneeded so far). */ + case 1: + data->dcb.StopBits = ONESTOPBIT; + break; + case 2: + data->dcb.StopBits = TWOSTOPBITS; + break; + default: + RETURN_ERROR(SP_ERR_ARG, "Invalid stop bit setting"); + } + } + + if (config->rts >= 0) { + switch (config->rts) { + case SP_RTS_OFF: + data->dcb.fRtsControl = RTS_CONTROL_DISABLE; + break; + case SP_RTS_ON: + data->dcb.fRtsControl = RTS_CONTROL_ENABLE; + break; + case SP_RTS_FLOW_CONTROL: + data->dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; + break; + default: + RETURN_ERROR(SP_ERR_ARG, "Invalid RTS setting"); + } + } + + if (config->cts >= 0) { + switch (config->cts) { + case SP_CTS_IGNORE: + data->dcb.fOutxCtsFlow = FALSE; + break; + case SP_CTS_FLOW_CONTROL: + data->dcb.fOutxCtsFlow = TRUE; + break; + default: + RETURN_ERROR(SP_ERR_ARG, "Invalid CTS setting"); + } + } + + if (config->dtr >= 0) { + switch (config->dtr) { + case SP_DTR_OFF: + data->dcb.fDtrControl = DTR_CONTROL_DISABLE; + break; + case SP_DTR_ON: + data->dcb.fDtrControl = DTR_CONTROL_ENABLE; + break; + case SP_DTR_FLOW_CONTROL: + data->dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; + break; + default: + RETURN_ERROR(SP_ERR_ARG, "Invalid DTR setting"); + } + } + + if (config->dsr >= 0) { + switch (config->dsr) { + case SP_DSR_IGNORE: + data->dcb.fOutxDsrFlow = FALSE; + break; + case SP_DSR_FLOW_CONTROL: + data->dcb.fOutxDsrFlow = TRUE; + break; + default: + RETURN_ERROR(SP_ERR_ARG, "Invalid DSR setting"); + } + } + + if (config->xon_xoff >= 0) { + switch (config->xon_xoff) { + case SP_XONXOFF_DISABLED: + data->dcb.fInX = FALSE; + data->dcb.fOutX = FALSE; + break; + case SP_XONXOFF_IN: + data->dcb.fInX = TRUE; + data->dcb.fOutX = FALSE; + break; + case SP_XONXOFF_OUT: + data->dcb.fInX = FALSE; + data->dcb.fOutX = TRUE; + break; + case SP_XONXOFF_INOUT: + data->dcb.fInX = TRUE; + data->dcb.fOutX = TRUE; + break; + default: + RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting"); + } + } + + if (!SetCommState(port->hdl, &data->dcb)) + RETURN_FAIL("SetCommState() failed"); + +#else /* !_WIN32 */ + + int controlbits; + + if (config->baudrate >= 0) { + for (i = 0; i < NUM_STD_BAUDRATES; i++) { + if (config->baudrate == std_baudrates[i].value) { + if (cfsetospeed(&data->term, std_baudrates[i].index) < 0) + RETURN_FAIL("cfsetospeed() failed"); + + if (cfsetispeed(&data->term, std_baudrates[i].index) < 0) + RETURN_FAIL("cfsetispeed() failed"); + break; + } + } + + /* Non-standard baud rate */ + if (i == NUM_STD_BAUDRATES) { +#ifdef __APPLE__ + /* Set "dummy" baud rate. */ + if (cfsetspeed(&data->term, B9600) < 0) + RETURN_FAIL("cfsetspeed() failed"); + baud_nonstd = config->baudrate; +#elif defined(USE_TERMIOS_SPEED) + baud_nonstd = 1; +#else + RETURN_ERROR(SP_ERR_SUPP, "Non-standard baudrate not supported"); +#endif + } + } + + if (config->bits >= 0) { + data->term.c_cflag &= ~CSIZE; + switch (config->bits) { + case 8: + data->term.c_cflag |= CS8; + break; + case 7: + data->term.c_cflag |= CS7; + break; + case 6: + data->term.c_cflag |= CS6; + break; + case 5: + data->term.c_cflag |= CS5; + break; + default: + RETURN_ERROR(SP_ERR_ARG, "Invalid data bits setting"); + } + } + + if (config->parity >= 0) { + data->term.c_iflag &= ~IGNPAR; + data->term.c_cflag &= ~(PARENB | PARODD); +#ifdef CMSPAR + data->term.c_cflag &= ~CMSPAR; +#endif + switch (config->parity) { + case SP_PARITY_NONE: + data->term.c_iflag |= IGNPAR; + break; + case SP_PARITY_EVEN: + data->term.c_cflag |= PARENB; + break; + case SP_PARITY_ODD: + data->term.c_cflag |= PARENB | PARODD; + break; +#ifdef CMSPAR + case SP_PARITY_MARK: + data->term.c_cflag |= PARENB | PARODD; + data->term.c_cflag |= CMSPAR; + break; + case SP_PARITY_SPACE: + data->term.c_cflag |= PARENB; + data->term.c_cflag |= CMSPAR; + break; +#else + case SP_PARITY_MARK: + case SP_PARITY_SPACE: + RETURN_ERROR(SP_ERR_SUPP, "Mark/space parity not supported"); +#endif + default: + RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting"); + } + } + + if (config->stopbits >= 0) { + data->term.c_cflag &= ~CSTOPB; + switch (config->stopbits) { + case 1: + data->term.c_cflag &= ~CSTOPB; + break; + case 2: + data->term.c_cflag |= CSTOPB; + break; + default: + RETURN_ERROR(SP_ERR_ARG, "Invalid stop bits setting"); + } + } + + if (config->rts >= 0 || config->cts >= 0) { + if (data->termiox_supported) { + data->rts_flow = data->cts_flow = 0; + switch (config->rts) { + case SP_RTS_OFF: + case SP_RTS_ON: + controlbits = TIOCM_RTS; + if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0) + RETURN_FAIL("Setting RTS signal level failed"); + break; + case SP_RTS_FLOW_CONTROL: + data->rts_flow = 1; + break; + default: + break; + } + if (config->cts == SP_CTS_FLOW_CONTROL) + data->cts_flow = 1; + + if (data->rts_flow && data->cts_flow) + data->term.c_iflag |= CRTSCTS; + else + data->term.c_iflag &= ~CRTSCTS; + } else { + /* Asymmetric use of RTS/CTS not supported. */ + if (data->term.c_iflag & CRTSCTS) { + /* Flow control can only be disabled for both RTS & CTS together. */ + if (config->rts >= 0 && config->rts != SP_RTS_FLOW_CONTROL) { + if (config->cts != SP_CTS_IGNORE) + RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together"); + } + if (config->cts >= 0 && config->cts != SP_CTS_FLOW_CONTROL) { + if (config->rts <= 0 || config->rts == SP_RTS_FLOW_CONTROL) + RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together"); + } + } else { + /* Flow control can only be enabled for both RTS & CTS together. */ + if (((config->rts == SP_RTS_FLOW_CONTROL) && (config->cts != SP_CTS_FLOW_CONTROL)) || + ((config->cts == SP_CTS_FLOW_CONTROL) && (config->rts != SP_RTS_FLOW_CONTROL))) + RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be enabled together"); + } + + if (config->rts >= 0) { + if (config->rts == SP_RTS_FLOW_CONTROL) { + data->term.c_iflag |= CRTSCTS; + } else { + controlbits = TIOCM_RTS; + if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC, + &controlbits) < 0) + RETURN_FAIL("Setting RTS signal level failed"); + } + } + } + } + + if (config->dtr >= 0 || config->dsr >= 0) { + if (data->termiox_supported) { + data->dtr_flow = data->dsr_flow = 0; + switch (config->dtr) { + case SP_DTR_OFF: + case SP_DTR_ON: + controlbits = TIOCM_DTR; + if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0) + RETURN_FAIL("Setting DTR signal level failed"); + break; + case SP_DTR_FLOW_CONTROL: + data->dtr_flow = 1; + break; + default: + break; + } + if (config->dsr == SP_DSR_FLOW_CONTROL) + data->dsr_flow = 1; + } else { + /* DTR/DSR flow control not supported. */ + if (config->dtr == SP_DTR_FLOW_CONTROL || config->dsr == SP_DSR_FLOW_CONTROL) + RETURN_ERROR(SP_ERR_SUPP, "DTR/DSR flow control not supported"); + + if (config->dtr >= 0) { + controlbits = TIOCM_DTR; + if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC, + &controlbits) < 0) + RETURN_FAIL("Setting DTR signal level failed"); + } + } + } + + if (config->xon_xoff >= 0) { + data->term.c_iflag &= ~(IXON | IXOFF | IXANY); + switch (config->xon_xoff) { + case SP_XONXOFF_DISABLED: + break; + case SP_XONXOFF_IN: + data->term.c_iflag |= IXOFF; + break; + case SP_XONXOFF_OUT: + data->term.c_iflag |= IXON | IXANY; + break; + case SP_XONXOFF_INOUT: + data->term.c_iflag |= IXON | IXOFF | IXANY; + break; + default: + RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting"); + } + } + + if (tcsetattr(port->fd, TCSANOW, &data->term) < 0) + RETURN_FAIL("tcsetattr() failed"); + +#ifdef __APPLE__ + if (baud_nonstd != B0) { + if (ioctl(port->fd, IOSSIOSPEED, &baud_nonstd) == -1) + RETURN_FAIL("IOSSIOSPEED ioctl failed"); + /* + * Set baud rates in data->term to correct, but incompatible + * with tcsetattr() value, same as delivered by tcgetattr(). + */ + if (cfsetspeed(&data->term, baud_nonstd) < 0) + RETURN_FAIL("cfsetspeed() failed"); + } +#elif defined(__linux__) +#ifdef USE_TERMIOS_SPEED + if (baud_nonstd) + TRY(set_baudrate(port->fd, config->baudrate)); +#endif +#ifdef USE_TERMIOX + if (data->termiox_supported) + TRY(set_flow(port->fd, data)); +#endif +#endif + +#endif /* !_WIN32 */ + + RETURN_OK(); +} + +SP_API enum sp_return sp_new_config(struct sp_port_config **config_ptr) +{ + struct sp_port_config *config; + + TRACE("%p", config_ptr); + + if (!config_ptr) + RETURN_ERROR(SP_ERR_ARG, "Null result pointer"); + + *config_ptr = NULL; + + if (!(config = malloc(sizeof(struct sp_port_config)))) + RETURN_ERROR(SP_ERR_MEM, "Config malloc failed"); + + config->baudrate = -1; + config->bits = -1; + config->parity = -1; + config->stopbits = -1; + config->rts = -1; + config->cts = -1; + config->dtr = -1; + config->dsr = -1; + + *config_ptr = config; + + RETURN_OK(); +} + +SP_API void sp_free_config(struct sp_port_config *config) +{ + TRACE("%p", config); + + if (!config) + DEBUG("Null config"); + else + free(config); + + RETURN(); +} + +SP_API enum sp_return sp_get_config(struct sp_port *port, + struct sp_port_config *config) +{ + struct port_data data; + + TRACE("%p, %p", port, config); + + CHECK_OPEN_PORT(); + + if (!config) + RETURN_ERROR(SP_ERR_ARG, "Null config"); + + TRY(get_config(port, &data, config)); + + RETURN_OK(); +} + +SP_API enum sp_return sp_set_config(struct sp_port *port, + const struct sp_port_config *config) +{ + struct port_data data; + struct sp_port_config prev_config; + + TRACE("%p, %p", port, config); + + CHECK_OPEN_PORT(); + + if (!config) + RETURN_ERROR(SP_ERR_ARG, "Null config"); + + TRY(get_config(port, &data, &prev_config)); + TRY(set_config(port, &data, config)); + + RETURN_OK(); +} + +#define CREATE_ACCESSORS(x, type) \ +SP_API enum sp_return sp_set_##x(struct sp_port *port, type x) { \ + struct port_data data; \ + struct sp_port_config config; \ + TRACE("%p, %d", port, x); \ + CHECK_OPEN_PORT(); \ + TRY(get_config(port, &data, &config)); \ + config.x = x; \ + TRY(set_config(port, &data, &config)); \ + RETURN_OK(); \ +} \ +SP_API enum sp_return sp_get_config_##x(const struct sp_port_config *config, \ + type *x) { \ + TRACE("%p, %p", config, x); \ + if (!x) \ + RETURN_ERROR(SP_ERR_ARG, "Null result pointer"); \ + if (!config) \ + RETURN_ERROR(SP_ERR_ARG, "Null config"); \ + *x = config->x; \ + RETURN_OK(); \ +} \ +SP_API enum sp_return sp_set_config_##x(struct sp_port_config *config, \ + type x) { \ + TRACE("%p, %d", config, x); \ + if (!config) \ + RETURN_ERROR(SP_ERR_ARG, "Null config"); \ + config->x = x; \ + RETURN_OK(); \ +} + +CREATE_ACCESSORS(baudrate, int) +CREATE_ACCESSORS(bits, int) +CREATE_ACCESSORS(parity, enum sp_parity) +CREATE_ACCESSORS(stopbits, int) +CREATE_ACCESSORS(rts, enum sp_rts) +CREATE_ACCESSORS(cts, enum sp_cts) +CREATE_ACCESSORS(dtr, enum sp_dtr) +CREATE_ACCESSORS(dsr, enum sp_dsr) +CREATE_ACCESSORS(xon_xoff, enum sp_xonxoff) + +SP_API enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, + enum sp_flowcontrol flowcontrol) +{ + if (!config) + RETURN_ERROR(SP_ERR_ARG, "Null configuration"); + + if (flowcontrol > SP_FLOWCONTROL_DTRDSR) + RETURN_ERROR(SP_ERR_ARG, "Invalid flow control setting"); + + if (flowcontrol == SP_FLOWCONTROL_XONXOFF) + config->xon_xoff = SP_XONXOFF_INOUT; + else + config->xon_xoff = SP_XONXOFF_DISABLED; + + if (flowcontrol == SP_FLOWCONTROL_RTSCTS) { + config->rts = SP_RTS_FLOW_CONTROL; + config->cts = SP_CTS_FLOW_CONTROL; + } else { + if (config->rts == SP_RTS_FLOW_CONTROL) + config->rts = SP_RTS_ON; + config->cts = SP_CTS_IGNORE; + } + + if (flowcontrol == SP_FLOWCONTROL_DTRDSR) { + config->dtr = SP_DTR_FLOW_CONTROL; + config->dsr = SP_DSR_FLOW_CONTROL; + } else { + if (config->dtr == SP_DTR_FLOW_CONTROL) + config->dtr = SP_DTR_ON; + config->dsr = SP_DSR_IGNORE; + } + + RETURN_OK(); +} + +SP_API enum sp_return sp_set_flowcontrol(struct sp_port *port, + enum sp_flowcontrol flowcontrol) +{ + struct port_data data; + struct sp_port_config config; + + TRACE("%p, %d", port, flowcontrol); + + CHECK_OPEN_PORT(); + + TRY(get_config(port, &data, &config)); + + TRY(sp_set_config_flowcontrol(&config, flowcontrol)); + + TRY(set_config(port, &data, &config)); + + RETURN_OK(); +} + +SP_API enum sp_return sp_get_signals(struct sp_port *port, + enum sp_signal *signals) +{ + TRACE("%p, %p", port, signals); + + CHECK_OPEN_PORT(); + + if (!signals) + RETURN_ERROR(SP_ERR_ARG, "Null result pointer"); + + DEBUG_FMT("Getting control signals for port %s", port->name); + + *signals = 0; +#ifdef _WIN32 + DWORD bits; + if (GetCommModemStatus(port->hdl, &bits) == 0) + RETURN_FAIL("GetCommModemStatus() failed"); + if (bits & MS_CTS_ON) + *signals |= SP_SIG_CTS; + if (bits & MS_DSR_ON) + *signals |= SP_SIG_DSR; + if (bits & MS_RLSD_ON) + *signals |= SP_SIG_DCD; + if (bits & MS_RING_ON) + *signals |= SP_SIG_RI; +#else + int bits; + if (ioctl(port->fd, TIOCMGET, &bits) < 0) + RETURN_FAIL("TIOCMGET ioctl failed"); + if (bits & TIOCM_CTS) + *signals |= SP_SIG_CTS; + if (bits & TIOCM_DSR) + *signals |= SP_SIG_DSR; + if (bits & TIOCM_CAR) + *signals |= SP_SIG_DCD; + if (bits & TIOCM_RNG) + *signals |= SP_SIG_RI; +#endif + RETURN_OK(); +} + +SP_API enum sp_return sp_start_break(struct sp_port *port) +{ + TRACE("%p", port); + + CHECK_OPEN_PORT(); +#ifdef _WIN32 + if (SetCommBreak(port->hdl) == 0) + RETURN_FAIL("SetCommBreak() failed"); +#else + if (ioctl(port->fd, TIOCSBRK, 1) < 0) + RETURN_FAIL("TIOCSBRK ioctl failed"); +#endif + + RETURN_OK(); +} + +SP_API enum sp_return sp_end_break(struct sp_port *port) +{ + TRACE("%p", port); + + CHECK_OPEN_PORT(); +#ifdef _WIN32 + if (ClearCommBreak(port->hdl) == 0) + RETURN_FAIL("ClearCommBreak() failed"); +#else + if (ioctl(port->fd, TIOCCBRK, 1) < 0) + RETURN_FAIL("TIOCCBRK ioctl failed"); +#endif + + RETURN_OK(); +} + +SP_API int sp_last_error_code(void) +{ + TRACE_VOID(); +#ifdef _WIN32 + RETURN_INT(GetLastError()); +#else + RETURN_INT(errno); +#endif +} + +SP_API char *sp_last_error_message(void) +{ + TRACE_VOID(); + +#ifdef _WIN32 + char *message; + DWORD error = GetLastError(); + + DWORD length = FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR) &message, + 0, NULL ); + + if (length >= 2 && message[length - 2] == '\r') + message[length - 2] = '\0'; + + RETURN_STRING(message); +#else + RETURN_STRING(strerror(errno)); +#endif +} + +SP_API void sp_free_error_message(char *message) +{ + TRACE("%s", message); + +#ifdef _WIN32 + LocalFree(message); +#else + (void)message; +#endif + + RETURN(); +} + +SP_API void sp_set_debug_handler(void (*handler)(const char *format, ...)) +{ + TRACE("%p", handler); + + sp_debug_handler = handler; + + RETURN(); +} + +SP_API void sp_default_debug_handler(const char *format, ...) +{ + va_list args; + va_start(args, format); + if (getenv("LIBSERIALPORT_DEBUG")) { + fputs("sp: ", stderr); + vfprintf(stderr, format, args); + } + va_end(args); +} + +SP_API int sp_get_major_package_version(void) +{ + return SP_PACKAGE_VERSION_MAJOR; +} + +SP_API int sp_get_minor_package_version(void) +{ + return SP_PACKAGE_VERSION_MINOR; +} + +SP_API int sp_get_micro_package_version(void) +{ + return SP_PACKAGE_VERSION_MICRO; +} + +SP_API const char *sp_get_package_version_string(void) +{ + return SP_PACKAGE_VERSION_STRING; +} + +SP_API int sp_get_current_lib_version(void) +{ + return SP_LIB_VERSION_CURRENT; +} + +SP_API int sp_get_revision_lib_version(void) +{ + return SP_LIB_VERSION_REVISION; +} + +SP_API int sp_get_age_lib_version(void) +{ + return SP_LIB_VERSION_AGE; +} + +SP_API const char *sp_get_lib_version_string(void) +{ + return SP_LIB_VERSION_STRING; +} + +/** @} */ diff --git a/src/libserialport/timing.c b/src/libserialport/timing.c new file mode 100644 index 000000000..25876d622 --- /dev/null +++ b/src/libserialport/timing.c @@ -0,0 +1,174 @@ +/* + * This file is part of the libserialport project. + * + * Copyright (C) 2019 Martin Ling + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser General Public License + * along with this program. If not, see . + */ + +#include "libserialport_internal.h" + +SP_PRIV void time_get(struct time *time) +{ +#ifdef _WIN32 + LARGE_INTEGER count; + QueryPerformanceCounter(&count); + time->ticks = count.QuadPart; +#elif defined(HAVE_CLOCK_GETTIME) + struct timespec ts; + if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) + clock_gettime(CLOCK_REALTIME, &ts); + time->tv.tv_sec = ts.tv_sec; + time->tv.tv_usec = ts.tv_nsec / 1000; +#elif defined(__APPLE__) + mach_timebase_info_data_t info; + mach_timebase_info(&info); + uint64_t ticks = mach_absolute_time(); + uint64_t ns = (ticks * info.numer) / info.denom; + time->tv.tv_sec = ns / 1000000000; + time->tv.tv_usec = (ns % 1000000000) / 1000; +#else + gettimeofday(&time->tv, NULL); +#endif +} + +SP_PRIV void time_set_ms(struct time *time, unsigned int ms) +{ +#ifdef _WIN32 + LARGE_INTEGER frequency; + QueryPerformanceFrequency(&frequency); + time->ticks = ms * (frequency.QuadPart / 1000); +#else + time->tv.tv_sec = ms / 1000; + time->tv.tv_usec = (ms % 1000) * 1000; +#endif +} + +SP_PRIV void time_add(const struct time *a, + const struct time *b, struct time *result) +{ +#ifdef _WIN32 + result->ticks = a->ticks + b->ticks; +#else + timeradd(&a->tv, &b->tv, &result->tv); +#endif +} + +SP_PRIV void time_sub(const struct time *a, + const struct time *b, struct time *result) +{ +#ifdef _WIN32 + result->ticks = a->ticks - b->ticks; +#else + timersub(&a->tv, &b->tv, &result->tv); +#endif +} + +SP_PRIV bool time_greater(const struct time *a, const struct time *b) +{ +#ifdef _WIN32 + return (a->ticks > b->ticks); +#else + return timercmp(&a->tv, &b->tv, >); +#endif +} + +SP_PRIV void time_as_timeval(const struct time *time, struct timeval *tv) +{ +#ifdef _WIN32 + LARGE_INTEGER frequency; + QueryPerformanceFrequency(&frequency); + tv->tv_sec = (long) (time->ticks / frequency.QuadPart); + tv->tv_usec = (long) ((time->ticks % frequency.QuadPart) / + (frequency.QuadPart / 1000000)); +#else + *tv = time->tv; +#endif +} + +SP_PRIV unsigned int time_as_ms(const struct time *time) +{ +#ifdef _WIN32 + LARGE_INTEGER frequency; + QueryPerformanceFrequency(&frequency); + return (unsigned int) (time->ticks / (frequency.QuadPart / 1000)); +#else + return time->tv.tv_sec * 1000 + time->tv.tv_usec / 1000; +#endif +} + +SP_PRIV void timeout_start(struct timeout *timeout, unsigned int timeout_ms) +{ + timeout->ms = timeout_ms; + + /* Get time at start of operation. */ + time_get(&timeout->start); + /* Define duration of timeout. */ + time_set_ms(&timeout->delta, timeout_ms); + /* Calculate time at which we should give up. */ + time_add(&timeout->start, &timeout->delta, &timeout->end); + /* Disable limit unless timeout_limit() called. */ + timeout->limit_ms = 0; + /* First blocking call has not yet been made. */ + timeout->calls_started = false; +} + +SP_PRIV void timeout_limit(struct timeout *timeout, unsigned int limit_ms) +{ + timeout->limit_ms = limit_ms; + timeout->overflow = (timeout->ms > timeout->limit_ms); + time_set_ms(&timeout->delta_max, timeout->limit_ms); +} + +SP_PRIV bool timeout_check(struct timeout *timeout) +{ + if (!timeout->calls_started) + return false; + + if (timeout->ms == 0) + return false; + + time_get(&timeout->now); + time_sub(&timeout->end, &timeout->now, &timeout->delta); + if (timeout->limit_ms) + if ((timeout->overflow = time_greater(&timeout->delta, &timeout->delta_max))) + timeout->delta = timeout->delta_max; + + return time_greater(&timeout->now, &timeout->end); +} + +SP_PRIV void timeout_update(struct timeout *timeout) +{ + timeout->calls_started = true; +} + +#ifndef _WIN32 +SP_PRIV struct timeval *timeout_timeval(struct timeout *timeout) +{ + if (timeout->ms == 0) + return NULL; + + time_as_timeval(&timeout->delta, &timeout->delta_tv); + + return &timeout->delta_tv; +} +#endif + +SP_PRIV unsigned int timeout_remaining_ms(struct timeout *timeout) +{ + if (timeout->limit_ms && timeout->overflow) + return timeout->limit_ms; + else + return time_as_ms(&timeout->delta); +} diff --git a/src/libserialport/windows.c b/src/libserialport/windows.c new file mode 100644 index 000000000..2825a9208 --- /dev/null +++ b/src/libserialport/windows.c @@ -0,0 +1,569 @@ +/* + * This file is part of the libserialport project. + * + * Copyright (C) 2013-2014 Martin Ling + * Copyright (C) 2014 Aurelien Jacobs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser General Public License + * along with this program. If not, see . + */ + +#include "libserialport_internal.h" + +/* USB path is a string of at most 8 decimal numbers < 128 separated by dots. */ +#define MAX_USB_PATH ((8 * 3) + (7 * 1) + 1) + +static void enumerate_hub(struct sp_port *port, const char *hub_name, + const char *parent_path, DEVINST dev_inst); + +static char *wc_to_utf8(PWCHAR wc_buffer, ULONG wc_bytes) +{ + ULONG wc_length = wc_bytes / sizeof(WCHAR); + ULONG utf8_bytes; + WCHAR *wc_str = NULL; + char *utf8_str = NULL; + + /* Allocate aligned wide char buffer */ + if (!(wc_str = malloc((wc_length + 1) * sizeof(WCHAR)))) + goto wc_to_utf8_end; + + /* Zero-terminate the wide char string. */ + memcpy(wc_str, wc_buffer, wc_bytes); + wc_str[wc_length] = 0; + + /* Compute the size of the UTF-8 converted string. */ + if (!(utf8_bytes = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wc_str, -1, + NULL, 0, NULL, NULL))) + goto wc_to_utf8_end; + + /* Allocate UTF-8 output buffer. */ + if (!(utf8_str = malloc(utf8_bytes))) + goto wc_to_utf8_end; + + /* Actually converted to UTF-8. */ + if (!WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wc_str, -1, + utf8_str, utf8_bytes, NULL, NULL)) { + free(utf8_str); + utf8_str = NULL; + goto wc_to_utf8_end; + } + +wc_to_utf8_end: + if (wc_str) + free(wc_str); + + return utf8_str; +} + +static char *get_root_hub_name(HANDLE host_controller) +{ + USB_ROOT_HUB_NAME root_hub_name; + PUSB_ROOT_HUB_NAME root_hub_name_wc; + char *root_hub_name_utf8; + ULONG size = 0; + + /* Compute the size of the root hub name string. */ + if (!DeviceIoControl(host_controller, IOCTL_USB_GET_ROOT_HUB_NAME, 0, 0, + &root_hub_name, sizeof(root_hub_name), &size, NULL)) + return NULL; + + /* Allocate wide char root hub name string. */ + size = root_hub_name.ActualLength; + if (!(root_hub_name_wc = malloc(size))) + return NULL; + + /* Actually get the root hub name string. */ + if (!DeviceIoControl(host_controller, IOCTL_USB_GET_ROOT_HUB_NAME, + NULL, 0, root_hub_name_wc, size, &size, NULL)) { + free(root_hub_name_wc); + return NULL; + } + + /* Convert the root hub name string to UTF-8. */ + root_hub_name_utf8 = wc_to_utf8(root_hub_name_wc->RootHubName, size - offsetof(USB_ROOT_HUB_NAME, RootHubName)); + free(root_hub_name_wc); + return root_hub_name_utf8; +} + +static char *get_external_hub_name(HANDLE hub, ULONG connection_index) +{ + USB_NODE_CONNECTION_NAME ext_hub_name; + PUSB_NODE_CONNECTION_NAME ext_hub_name_wc; + char *ext_hub_name_utf8; + ULONG size; + + /* Compute the size of the external hub name string. */ + ext_hub_name.ConnectionIndex = connection_index; + if (!DeviceIoControl(hub, IOCTL_USB_GET_NODE_CONNECTION_NAME, + &ext_hub_name, sizeof(ext_hub_name), + &ext_hub_name, sizeof(ext_hub_name), &size, NULL)) + return NULL; + + /* Allocate wide char external hub name string. */ + size = ext_hub_name.ActualLength; + if (size <= sizeof(ext_hub_name) + || !(ext_hub_name_wc = malloc(size))) + return NULL; + + /* Get the name of the external hub attached to the specified port. */ + ext_hub_name_wc->ConnectionIndex = connection_index; + if (!DeviceIoControl(hub, IOCTL_USB_GET_NODE_CONNECTION_NAME, + ext_hub_name_wc, size, + ext_hub_name_wc, size, &size, NULL)) { + free(ext_hub_name_wc); + return NULL; + } + + /* Convert the external hub name string to UTF-8. */ + ext_hub_name_utf8 = wc_to_utf8(ext_hub_name_wc->NodeName, size - offsetof(USB_NODE_CONNECTION_NAME, NodeName)); + free(ext_hub_name_wc); + return ext_hub_name_utf8; +} + +static char *get_string_descriptor(HANDLE hub_device, ULONG connection_index, + UCHAR descriptor_index) +{ + char desc_req_buf[sizeof(USB_DESCRIPTOR_REQUEST) + + MAXIMUM_USB_STRING_LENGTH] = { 0 }; + PUSB_DESCRIPTOR_REQUEST desc_req = (void *)desc_req_buf; + PUSB_STRING_DESCRIPTOR desc = (void *)(desc_req + 1); + ULONG size = sizeof(desc_req_buf); + + desc_req->ConnectionIndex = connection_index; + desc_req->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE << 8) + | descriptor_index; + desc_req->SetupPacket.wIndex = 0; + desc_req->SetupPacket.wLength = (USHORT) (size - sizeof(*desc_req)); + + if (!DeviceIoControl(hub_device, + IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, + desc_req, size, desc_req, size, &size, NULL) + || size < 2 + || desc->bDescriptorType != USB_STRING_DESCRIPTOR_TYPE + || desc->bLength != size - sizeof(*desc_req) + || desc->bLength % 2) + return NULL; + + return wc_to_utf8(desc->bString, desc->bLength - offsetof(USB_STRING_DESCRIPTOR, bString)); +} + +static void enumerate_hub_ports(struct sp_port *port, HANDLE hub_device, + ULONG nb_ports, const char *parent_path, DEVINST dev_inst) +{ + char path[MAX_USB_PATH]; + ULONG index = 0; + + for (index = 1; index <= nb_ports; index++) { + PUSB_NODE_CONNECTION_INFORMATION_EX connection_info_ex; + ULONG size = sizeof(*connection_info_ex) + (30 * sizeof(USB_PIPE_INFO)); + + if (!(connection_info_ex = malloc(size))) + break; + + connection_info_ex->ConnectionIndex = index; + if (!DeviceIoControl(hub_device, + IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, + connection_info_ex, size, + connection_info_ex, size, &size, NULL)) { + /* + * Try to get CONNECTION_INFORMATION if + * CONNECTION_INFORMATION_EX did not work. + */ + PUSB_NODE_CONNECTION_INFORMATION connection_info; + + size = sizeof(*connection_info) + (30 * sizeof(USB_PIPE_INFO)); + if (!(connection_info = malloc(size))) { + free(connection_info_ex); + continue; + } + connection_info->ConnectionIndex = index; + if (!DeviceIoControl(hub_device, + IOCTL_USB_GET_NODE_CONNECTION_INFORMATION, + connection_info, size, + connection_info, size, &size, NULL)) { + free(connection_info); + free(connection_info_ex); + continue; + } + + connection_info_ex->ConnectionIndex = connection_info->ConnectionIndex; + connection_info_ex->DeviceDescriptor = connection_info->DeviceDescriptor; + connection_info_ex->DeviceIsHub = connection_info->DeviceIsHub; + connection_info_ex->DeviceAddress = connection_info->DeviceAddress; + free(connection_info); + } + + if (connection_info_ex->DeviceIsHub) { + /* Recursively enumerate external hub. */ + PCHAR ext_hub_name; + if ((ext_hub_name = get_external_hub_name(hub_device, index))) { + snprintf(path, sizeof(path), "%s%ld.", + parent_path, connection_info_ex->ConnectionIndex); + enumerate_hub(port, ext_hub_name, path, dev_inst); + } + free(connection_info_ex); + } else { + snprintf(path, sizeof(path), "%s%ld", + parent_path, connection_info_ex->ConnectionIndex); + + /* Check if this device is the one we search for. */ + if (strcmp(path, port->usb_path)) { + free(connection_info_ex); + continue; + } + + /* Finally grab detailed information regarding the device. */ + port->usb_address = connection_info_ex->DeviceAddress + 1; + port->usb_vid = connection_info_ex->DeviceDescriptor.idVendor; + port->usb_pid = connection_info_ex->DeviceDescriptor.idProduct; + + if (connection_info_ex->DeviceDescriptor.iManufacturer) + port->usb_manufacturer = get_string_descriptor(hub_device, index, + connection_info_ex->DeviceDescriptor.iManufacturer); + if (connection_info_ex->DeviceDescriptor.iProduct) + port->usb_product = get_string_descriptor(hub_device, index, + connection_info_ex->DeviceDescriptor.iProduct); + if (connection_info_ex->DeviceDescriptor.iSerialNumber) { + port->usb_serial = get_string_descriptor(hub_device, index, + connection_info_ex->DeviceDescriptor.iSerialNumber); + if (port->usb_serial == NULL) { + //composite device, get the parent's serial number + char device_id[MAX_DEVICE_ID_LEN]; + if (CM_Get_Parent(&dev_inst, dev_inst, 0) == CR_SUCCESS) { + if (CM_Get_Device_IDA(dev_inst, device_id, sizeof(device_id), 0) == CR_SUCCESS) + port->usb_serial = strdup(strrchr(device_id, '\\')+1); + } + } + } + + free(connection_info_ex); + break; + } + } +} + +static void enumerate_hub(struct sp_port *port, const char *hub_name, + const char *parent_path, DEVINST dev_inst) +{ + USB_NODE_INFORMATION hub_info; + HANDLE hub_device; + ULONG size = sizeof(hub_info); + char *device_name; + + /* Open the hub with its full name. */ + if (!(device_name = malloc(strlen("\\\\.\\") + strlen(hub_name) + 1))) + return; + strcpy(device_name, "\\\\.\\"); + strcat(device_name, hub_name); + hub_device = CreateFileA(device_name, GENERIC_WRITE, FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, NULL); + free(device_name); + if (hub_device == INVALID_HANDLE_VALUE) + return; + + /* Get the number of ports of the hub. */ + if (DeviceIoControl(hub_device, IOCTL_USB_GET_NODE_INFORMATION, + &hub_info, size, &hub_info, size, &size, NULL)) + /* Enumerate the ports of the hub. */ + enumerate_hub_ports(port, hub_device, + hub_info.u.HubInformation.HubDescriptor.bNumberOfPorts, parent_path, dev_inst); + + CloseHandle(hub_device); +} + +static void enumerate_host_controller(struct sp_port *port, + HANDLE host_controller_device, + DEVINST dev_inst) +{ + char *root_hub_name; + + if ((root_hub_name = get_root_hub_name(host_controller_device))) { + enumerate_hub(port, root_hub_name, "", dev_inst); + free(root_hub_name); + } +} + +static void get_usb_details(struct sp_port *port, DEVINST dev_inst_match) +{ + HDEVINFO device_info; + SP_DEVINFO_DATA device_info_data; + ULONG i, size = 0; + + device_info = SetupDiGetClassDevs(&GUID_CLASS_USB_HOST_CONTROLLER, NULL, NULL, + DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + device_info_data.cbSize = sizeof(device_info_data); + + for (i = 0; SetupDiEnumDeviceInfo(device_info, i, &device_info_data); i++) { + SP_DEVICE_INTERFACE_DATA device_interface_data; + PSP_DEVICE_INTERFACE_DETAIL_DATA device_detail_data; + DEVINST dev_inst = dev_inst_match; + HANDLE host_controller_device; + + device_interface_data.cbSize = sizeof(device_interface_data); + if (!SetupDiEnumDeviceInterfaces(device_info, 0, + &GUID_CLASS_USB_HOST_CONTROLLER, + i, &device_interface_data)) + continue; + + if (!SetupDiGetDeviceInterfaceDetail(device_info,&device_interface_data, + NULL, 0, &size, NULL) + && GetLastError() != ERROR_INSUFFICIENT_BUFFER) + continue; + + if (!(device_detail_data = malloc(size))) + continue; + device_detail_data->cbSize = sizeof(*device_detail_data); + if (!SetupDiGetDeviceInterfaceDetail(device_info,&device_interface_data, + device_detail_data, size, &size, + NULL)) { + free(device_detail_data); + continue; + } + + while (CM_Get_Parent(&dev_inst, dev_inst, 0) == CR_SUCCESS + && dev_inst != device_info_data.DevInst) { } + if (dev_inst != device_info_data.DevInst) { + free(device_detail_data); + continue; + } + + port->usb_bus = i + 1; + + host_controller_device = CreateFile(device_detail_data->DevicePath, + GENERIC_WRITE, FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, NULL); + if (host_controller_device != INVALID_HANDLE_VALUE) { + enumerate_host_controller(port, host_controller_device, dev_inst_match); + CloseHandle(host_controller_device); + } + free(device_detail_data); + } + + SetupDiDestroyDeviceInfoList(device_info); + return; +} + +SP_PRIV enum sp_return get_port_details(struct sp_port *port) +{ + /* + * Description limited to 127 char, anything longer + * would not be user friendly anyway. + */ + char description[128]; + SP_DEVINFO_DATA device_info_data = { .cbSize = sizeof(device_info_data) }; + HDEVINFO device_info; + int i; + + device_info = SetupDiGetClassDevs(NULL, 0, 0, + DIGCF_PRESENT | DIGCF_ALLCLASSES); + if (device_info == INVALID_HANDLE_VALUE) + RETURN_FAIL("SetupDiGetClassDevs() failed"); + + for (i = 0; SetupDiEnumDeviceInfo(device_info, i, &device_info_data); i++) { + HKEY device_key; + DEVINST dev_inst; + char value[8], class[16]; + DWORD size, type; + CONFIGRET cr; + + /* Check if this is the device we are looking for. */ + device_key = SetupDiOpenDevRegKey(device_info, &device_info_data, + DICS_FLAG_GLOBAL, 0, + DIREG_DEV, KEY_QUERY_VALUE); + if (device_key == INVALID_HANDLE_VALUE) + continue; + size = sizeof(value); + if (RegQueryValueExA(device_key, "PortName", NULL, &type, (LPBYTE)value, + &size) != ERROR_SUCCESS || type != REG_SZ) { + RegCloseKey(device_key); + continue; + } + RegCloseKey(device_key); + value[sizeof(value) - 1] = 0; + if (strcmp(value, port->name)) + continue; + + /* Check port transport type. */ + dev_inst = device_info_data.DevInst; + size = sizeof(class); + cr = CR_FAILURE; + while (CM_Get_Parent(&dev_inst, dev_inst, 0) == CR_SUCCESS && + (cr = CM_Get_DevNode_Registry_PropertyA(dev_inst, + CM_DRP_CLASS, 0, class, &size, 0)) != CR_SUCCESS) { } + if (cr == CR_SUCCESS) { + if (!strcmp(class, "USB")) + port->transport = SP_TRANSPORT_USB; + } + + /* Get port description (friendly name). */ + dev_inst = device_info_data.DevInst; + size = sizeof(description); + while ((cr = CM_Get_DevNode_Registry_PropertyA(dev_inst, + CM_DRP_FRIENDLYNAME, 0, description, &size, 0)) != CR_SUCCESS + && CM_Get_Parent(&dev_inst, dev_inst, 0) == CR_SUCCESS) { } + if (cr == CR_SUCCESS) + port->description = strdup(description); + + /* Get more informations for USB connected ports. */ + if (port->transport == SP_TRANSPORT_USB) { + char usb_path[MAX_USB_PATH] = "", tmp[MAX_USB_PATH]; + char device_id[MAX_DEVICE_ID_LEN]; + + /* Recurse over parents to build the USB device path. */ + dev_inst = device_info_data.DevInst; + do { + /* Verify that this layer of the tree is USB related. */ + if (CM_Get_Device_IDA(dev_inst, device_id, + sizeof(device_id), 0) != CR_SUCCESS + || strncmp(device_id, "USB\\", 4)) + continue; + + /* Discard one layer for composite devices. */ + char compat_ids[512], *p = compat_ids; + size = sizeof(compat_ids); + if (CM_Get_DevNode_Registry_PropertyA(dev_inst, + CM_DRP_COMPATIBLEIDS, 0, + &compat_ids, + &size, 0) == CR_SUCCESS) { + while (*p) { + if (!strncmp(p, "USB\\COMPOSITE", 13)) + break; + p += strlen(p) + 1; + } + if (*p) + continue; + } + + /* Stop the recursion when reaching the USB root. */ + if (!strncmp(device_id, "USB\\ROOT", 8)) + break; + + /* Prepend the address of current USB layer to the USB path. */ + DWORD address; + size = sizeof(address); + if (CM_Get_DevNode_Registry_PropertyA(dev_inst, CM_DRP_ADDRESS, + 0, &address, &size, 0) == CR_SUCCESS) { + strcpy(tmp, usb_path); + snprintf(usb_path, sizeof(usb_path), "%d%s%s", + (int)address, *tmp ? "." : "", tmp); + } + } while (CM_Get_Parent(&dev_inst, dev_inst, 0) == CR_SUCCESS); + + port->usb_path = strdup(usb_path); + + /* Wake up the USB device to be able to read string descriptor. */ + char *escaped_port_name; + HANDLE handle; + if (!(escaped_port_name = malloc(strlen(port->name) + 5))) + RETURN_ERROR(SP_ERR_MEM, "Escaped port name malloc failed"); + sprintf(escaped_port_name, "\\\\.\\%s", port->name); + handle = CreateFileA(escaped_port_name, GENERIC_READ, 0, 0, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, 0); + free(escaped_port_name); + CloseHandle(handle); + + /* Retrieve USB device details from the device descriptor. */ + get_usb_details(port, device_info_data.DevInst); + } + break; + } + + SetupDiDestroyDeviceInfoList(device_info); + + RETURN_OK(); +} + +SP_PRIV enum sp_return list_ports(struct sp_port ***list) +{ + HKEY key; + TCHAR *value, *data; + DWORD max_value_len, max_data_size, max_data_len; + DWORD value_len, data_size, data_len; + DWORD type, index = 0; + LSTATUS result; + char *name; + int name_len; + int ret = SP_OK; + + DEBUG("Opening registry key"); + if ((result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"), + 0, KEY_QUERY_VALUE, &key)) != ERROR_SUCCESS) { + /* It's possible for this key to not exist if there are no serial ports + * at all. In that case we're done. Return a failure for any other error. */ + if (result != ERROR_FILE_NOT_FOUND) { + SetLastError(result); + SET_FAIL(ret, "RegOpenKeyEx() failed"); + } + goto out_done; + } + DEBUG("Querying registry key value and data sizes"); + if ((result = RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &max_value_len, &max_data_size, NULL, NULL)) != ERROR_SUCCESS) { + SetLastError(result); + SET_FAIL(ret, "RegQueryInfoKey() failed"); + goto out_close; + } + max_data_len = max_data_size / sizeof(TCHAR); + if (!(value = malloc((max_value_len + 1) * sizeof(TCHAR)))) { + SET_ERROR(ret, SP_ERR_MEM, "Registry value malloc failed"); + goto out_close; + } + if (!(data = malloc((max_data_len + 1) * sizeof(TCHAR)))) { + SET_ERROR(ret, SP_ERR_MEM, "Registry data malloc failed"); + goto out_free_value; + } + DEBUG("Iterating over values"); + while ( + value_len = max_value_len + 1, + data_size = max_data_size, + RegEnumValue(key, index, value, &value_len, + NULL, &type, (LPBYTE)data, &data_size) == ERROR_SUCCESS) + { + if (type == REG_SZ) { + data_len = data_size / sizeof(TCHAR); + data[data_len] = '\0'; +#ifdef UNICODE + name_len = WideCharToMultiByte(CP_ACP, 0, data, -1, NULL, 0, NULL, NULL); +#else + name_len = data_len + 1; +#endif + if (!(name = malloc(name_len))) { + SET_ERROR(ret, SP_ERR_MEM, "Registry port name malloc failed"); + goto out; + } +#ifdef UNICODE + WideCharToMultiByte(CP_ACP, 0, data, -1, name, name_len, NULL, NULL); +#else + strcpy(name, data); +#endif + DEBUG_FMT("Found port %s", name); + if (!(*list = list_append(*list, name))) { + SET_ERROR(ret, SP_ERR_MEM, "List append failed"); + free(name); + goto out; + } + free(name); + } + index++; + } +out: + free(data); +out_free_value: + free(value); +out_close: + RegCloseKey(key); +out_done: + + return ret; +} diff --git a/src/maple_loader/README.md b/src/maple_loader/README.md deleted file mode 100644 index c6c937950..000000000 --- a/src/maple_loader/README.md +++ /dev/null @@ -1,5 +0,0 @@ -These files build the maple_loader.jar file used on Windows to reset the Sketch via USB Serial, so that the bootloader will run in dfu upload mode, ready for a new sketch to be uploaded - -The files were written by @bobC (github) and have been slightly modified by me (Roger Clark), so that dfu-util no longer attempts to reset the board after upload. -This change to dfu-util's reset command line argument, was required because dfu-util was showing errors on some Windows systems, because the bootloader had reset its self after upload, -before dfu-util had chance to tell it to reset. \ No newline at end of file diff --git a/src/maple_loader/build.xml b/src/maple_loader/build.xml deleted file mode 100644 index 80bdd6fdb..000000000 --- a/src/maple_loader/build.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - Builds, tests, and runs the project maple_loader. - - - diff --git a/src/maple_loader/build/built-jar.properties b/src/maple_loader/build/built-jar.properties deleted file mode 100644 index 10752d534..000000000 --- a/src/maple_loader/build/built-jar.properties +++ /dev/null @@ -1,4 +0,0 @@ -#Mon, 20 Jul 2015 11:21:26 +1000 - - -C\:\\Users\\rclark\\Desktop\\maple-asp-master\\installer\\maple_loader= diff --git a/src/maple_loader/build/classes/CliTemplate/CliMain.class b/src/maple_loader/build/classes/CliTemplate/CliMain.class deleted file mode 100644 index 37ee63000..000000000 Binary files a/src/maple_loader/build/classes/CliTemplate/CliMain.class and /dev/null differ diff --git a/src/maple_loader/build/classes/CliTemplate/DFUUploader.class b/src/maple_loader/build/classes/CliTemplate/DFUUploader.class deleted file mode 100644 index 77087b052..000000000 Binary files a/src/maple_loader/build/classes/CliTemplate/DFUUploader.class and /dev/null differ diff --git a/src/maple_loader/build/classes/CliTemplate/ExecCommand.class b/src/maple_loader/build/classes/CliTemplate/ExecCommand.class deleted file mode 100644 index ad95f7984..000000000 Binary files a/src/maple_loader/build/classes/CliTemplate/ExecCommand.class and /dev/null differ diff --git a/src/maple_loader/build/classes/processing/app/Base.class b/src/maple_loader/build/classes/processing/app/Base.class deleted file mode 100644 index 4aa0bde02..000000000 Binary files a/src/maple_loader/build/classes/processing/app/Base.class and /dev/null differ diff --git a/src/maple_loader/build/classes/processing/app/Preferences.class b/src/maple_loader/build/classes/processing/app/Preferences.class deleted file mode 100644 index 89cf01004..000000000 Binary files a/src/maple_loader/build/classes/processing/app/Preferences.class and /dev/null differ diff --git a/src/maple_loader/build/classes/processing/app/Serial.class b/src/maple_loader/build/classes/processing/app/Serial.class deleted file mode 100644 index cceccdd27..000000000 Binary files a/src/maple_loader/build/classes/processing/app/Serial.class and /dev/null differ diff --git a/src/maple_loader/build/classes/processing/app/SerialException.class b/src/maple_loader/build/classes/processing/app/SerialException.class deleted file mode 100644 index 71048dd3a..000000000 Binary files a/src/maple_loader/build/classes/processing/app/SerialException.class and /dev/null differ diff --git a/src/maple_loader/build/classes/processing/app/debug/MessageConsumer.class b/src/maple_loader/build/classes/processing/app/debug/MessageConsumer.class deleted file mode 100644 index 37250e770..000000000 Binary files a/src/maple_loader/build/classes/processing/app/debug/MessageConsumer.class and /dev/null differ diff --git a/src/maple_loader/build/classes/processing/app/debug/MessageSiphon.class b/src/maple_loader/build/classes/processing/app/debug/MessageSiphon.class deleted file mode 100644 index e22c8d499..000000000 Binary files a/src/maple_loader/build/classes/processing/app/debug/MessageSiphon.class and /dev/null differ diff --git a/src/maple_loader/build/classes/processing/app/debug/RunnerException.class b/src/maple_loader/build/classes/processing/app/debug/RunnerException.class deleted file mode 100644 index 710f79650..000000000 Binary files a/src/maple_loader/build/classes/processing/app/debug/RunnerException.class and /dev/null differ diff --git a/src/maple_loader/build/classes/processing/app/helpers/ProcessUtils.class b/src/maple_loader/build/classes/processing/app/helpers/ProcessUtils.class deleted file mode 100644 index 27eca6262..000000000 Binary files a/src/maple_loader/build/classes/processing/app/helpers/ProcessUtils.class and /dev/null differ diff --git a/src/maple_loader/dist/README.TXT b/src/maple_loader/dist/README.TXT deleted file mode 100644 index 255b89c68..000000000 --- a/src/maple_loader/dist/README.TXT +++ /dev/null @@ -1,32 +0,0 @@ -======================== -BUILD OUTPUT DESCRIPTION -======================== - -When you build an Java application project that has a main class, the IDE -automatically copies all of the JAR -files on the projects classpath to your projects dist/lib folder. The IDE -also adds each of the JAR files to the Class-Path element in the application -JAR files manifest file (MANIFEST.MF). - -To run the project from the command line, go to the dist folder and -type the following: - -java -jar "maple_loader.jar" - -To distribute this project, zip up the dist folder (including the lib folder) -and distribute the ZIP file. - -Notes: - -* If two JAR files on the project classpath have the same name, only the first -JAR file is copied to the lib folder. -* Only JAR files are copied to the lib folder. -If the classpath contains other types of files or folders, these files (folders) -are not copied. -* If a library on the projects classpath also has a Class-Path element -specified in the manifest,the content of the Class-Path element has to be on -the projects runtime path. -* To set a main class in a standard Java project, right-click the project node -in the Projects window and choose Properties. Then click Run and enter the -class name in the Main Class field. Alternatively, you can manually type the -class name in the manifest Main-Class element. diff --git a/src/maple_loader/dist/lib/jssc.jar b/src/maple_loader/dist/lib/jssc.jar deleted file mode 100644 index eb74f154a..000000000 Binary files a/src/maple_loader/dist/lib/jssc.jar and /dev/null differ diff --git a/src/maple_loader/dist/maple_loader.jar b/src/maple_loader/dist/maple_loader.jar deleted file mode 100644 index e1f9965c1..000000000 Binary files a/src/maple_loader/dist/maple_loader.jar and /dev/null differ diff --git a/src/maple_loader/jars/jssc.jar b/src/maple_loader/jars/jssc.jar deleted file mode 100644 index eb74f154a..000000000 Binary files a/src/maple_loader/jars/jssc.jar and /dev/null differ diff --git a/src/maple_loader/manifest.mf b/src/maple_loader/manifest.mf deleted file mode 100644 index 328e8e5bc..000000000 --- a/src/maple_loader/manifest.mf +++ /dev/null @@ -1,3 +0,0 @@ -Manifest-Version: 1.0 -X-COMMENT: Main-Class will be added automatically by build - diff --git a/src/maple_loader/nbproject/build-impl.xml b/src/maple_loader/nbproject/build-impl.xml deleted file mode 100644 index a66f34964..000000000 --- a/src/maple_loader/nbproject/build-impl.xml +++ /dev/null @@ -1,1413 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set src.dir - Must set test.src.dir - Must set build.dir - Must set dist.dir - Must set build.classes.dir - Must set dist.javadoc.dir - Must set build.test.classes.dir - Must set build.test.results.dir - Must set build.classes.excludes - Must set dist.jar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set javac.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - No tests executed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set JVM to use for profiling in profiler.info.jvm - Must set profiler agent JVM arguments in profiler.info.jvmargs.agent - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select some files in the IDE or set javac.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - java -jar "${dist.jar.resolved}" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set run.class - - - - Must select one file in the IDE or set run.class - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set debug.class - - - - - Must select one file in the IDE or set debug.class - - - - - Must set fix.includes - - - - - - - - - - This target only works when run from inside the NetBeans IDE. - - - - - - - - - Must select one file in the IDE or set profile.class - This target only works when run from inside the NetBeans IDE. - - - - - - - - - This target only works when run from inside the NetBeans IDE. - - - - - - - - - - - - - This target only works when run from inside the NetBeans IDE. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set run.class - - - - - - Must select some files in the IDE or set test.includes - - - - - Must select one file in the IDE or set run.class - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select some files in the IDE or set javac.includes - - - - - - - - - - - - - - - - - - - - Some tests failed; see details above. - - - - - - - - - Must select some files in the IDE or set test.includes - - - - Some tests failed; see details above. - - - - Must select some files in the IDE or set test.class - Must select some method in the IDE or set test.method - - - - Some tests failed; see details above. - - - - - Must select one file in the IDE or set test.class - - - - Must select one file in the IDE or set test.class - Must select some method in the IDE or set test.method - - - - - - - - - - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/maple_loader/nbproject/genfiles.properties b/src/maple_loader/nbproject/genfiles.properties deleted file mode 100644 index c13672132..000000000 --- a/src/maple_loader/nbproject/genfiles.properties +++ /dev/null @@ -1,8 +0,0 @@ -build.xml.data.CRC32=2e6a03ba -build.xml.script.CRC32=4676ee6b -build.xml.stylesheet.CRC32=8064a381@1.75.2.48 -# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. -# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=2e6a03ba -nbproject/build-impl.xml.script.CRC32=392b3f79 -nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.75.2.48 diff --git a/src/maple_loader/nbproject/private/config.properties b/src/maple_loader/nbproject/private/config.properties deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/maple_loader/nbproject/private/private.properties b/src/maple_loader/nbproject/private/private.properties deleted file mode 100644 index e5c9f10c4..000000000 --- a/src/maple_loader/nbproject/private/private.properties +++ /dev/null @@ -1,6 +0,0 @@ -compile.on.save=true -do.depend=false -do.jar=true -javac.debug=true -javadoc.preview=true -user.properties.file=C:\\Users\\rclark\\AppData\\Roaming\\NetBeans\\8.0.2\\build.properties diff --git a/src/maple_loader/nbproject/private/private.xml b/src/maple_loader/nbproject/private/private.xml deleted file mode 100644 index a1bbd60c9..000000000 --- a/src/maple_loader/nbproject/private/private.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - file:/C:/Users/rclark/Desktop/maple-asp-master/installer/maple_loader/src/CliTemplate/CliMain.java - file:/C:/Users/rclark/Desktop/maple-asp-master/installer/maple_loader/src/CliTemplate/DFUUploader.java - - - diff --git a/src/maple_loader/nbproject/project.properties b/src/maple_loader/nbproject/project.properties deleted file mode 100644 index 7f48d719f..000000000 --- a/src/maple_loader/nbproject/project.properties +++ /dev/null @@ -1,79 +0,0 @@ -annotation.processing.enabled=true -annotation.processing.enabled.in.editor=false -annotation.processing.processors.list= -annotation.processing.run.all.processors=true -annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output -application.title=maple_loader -application.vendor=bob -build.classes.dir=${build.dir}/classes -build.classes.excludes=**/*.java,**/*.form -# This directory is removed when the project is cleaned: -build.dir=build -build.generated.dir=${build.dir}/generated -build.generated.sources.dir=${build.dir}/generated-sources -# Only compile against the classpath explicitly listed here: -build.sysclasspath=ignore -build.test.classes.dir=${build.dir}/test/classes -build.test.results.dir=${build.dir}/test/results -# Uncomment to specify the preferred debugger connection transport: -#debug.transport=dt_socket -debug.classpath=\ - ${run.classpath} -debug.test.classpath=\ - ${run.test.classpath} -# Files in build.classes.dir which should be excluded from distribution jar -dist.archive.excludes= -# This directory is removed when the project is cleaned: -dist.dir=dist -dist.jar=${dist.dir}/maple_loader.jar -dist.javadoc.dir=${dist.dir}/javadoc -endorsed.classpath= -excludes= -file.reference.jssc.jar=dist/lib/jssc.jar -file.reference.jssc.jar-1=jars/jssc.jar -includes=** -jar.compress=false -javac.classpath=\ - ${file.reference.jssc.jar}:\ - ${file.reference.jssc.jar-1} -# Space-separated list of extra javac options -javac.compilerargs= -javac.deprecation=false -javac.processorpath=\ - ${javac.classpath} -javac.source=1.7 -javac.target=1.7 -javac.test.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -javac.test.processorpath=\ - ${javac.test.classpath} -javadoc.additionalparam= -javadoc.author=false -javadoc.encoding=${source.encoding} -javadoc.noindex=false -javadoc.nonavbar=false -javadoc.notree=false -javadoc.private=false -javadoc.splitindex=true -javadoc.use=true -javadoc.version=false -javadoc.windowtitle= -main.class=CliTemplate.CliMain -manifest.file=manifest.mf -meta.inf.dir=${src.dir}/META-INF -mkdist.disabled=false -platform.active=default_platform -run.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -# Space-separated list of JVM arguments used when running the project. -# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. -# To set system properties for unit tests define test-sys-prop.name=value: -run.jvmargs= -run.test.classpath=\ - ${javac.test.classpath}:\ - ${build.test.classes.dir} -source.encoding=UTF-8 -src.dir=src -test.src.dir=test diff --git a/src/maple_loader/nbproject/project.xml b/src/maple_loader/nbproject/project.xml deleted file mode 100644 index 92218a925..000000000 --- a/src/maple_loader/nbproject/project.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - org.netbeans.modules.java.j2seproject - - - maple_loader - - - - - - - - - diff --git a/src/maple_loader/src/CliTemplate/CliMain.java b/src/maple_loader/src/CliTemplate/CliMain.java deleted file mode 100644 index c7dc9f098..000000000 --- a/src/maple_loader/src/CliTemplate/CliMain.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package CliTemplate; - -import java.io.IOException; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import processing.app.Preferences; - -//import processing.app.I18n; -import processing.app.helpers.ProcessUtils; - -/** - * - * @author cousinr - */ -public class CliMain { - - - /** - * @param args the command line arguments - */ - public static void main(String[] args) { - - String comPort = args[0]; // - String altIf = args[1]; // - String usbID = args[2]; // "1EAF:0003"; - String binFile = args[3]; // bin file - - System.out.println("maple_loader v0.1"); - - Preferences.set ("serial.port",comPort); - Preferences.set ("serial.parity","N"); - Preferences.setInteger ("serial.databits", 8); - Preferences.setInteger ("serial.debug_rate",9600); - Preferences.setInteger ("serial.stopbits",1); - - Preferences.setInteger ("programDelay",1200); - - Preferences.set ("upload.usbID", usbID); - Preferences.set ("upload.altID", altIf); - Preferences.setBoolean ("upload.auto_reset", true); - Preferences.setBoolean ("upload.verbose", false); - - // - DFUUploader dfuUploader = new DFUUploader(); - try { - //dfuUploader.uploadViaDFU(binFile); - dfuUploader.uploadViaDFU(binFile); - } catch (Exception e) - { - System.err.print (MessageFormat.format("an error occurred! {0}\n", e.getMessage())); - } - } -} diff --git a/src/maple_loader/src/CliTemplate/DFUUploader.java b/src/maple_loader/src/CliTemplate/DFUUploader.java deleted file mode 100644 index 3dee0b4b7..000000000 --- a/src/maple_loader/src/CliTemplate/DFUUploader.java +++ /dev/null @@ -1,345 +0,0 @@ -/* - DFUUploader - uploader implementation using DFU - - Copyright (c) 2010 - Andrew Meyer - - 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, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ - -package CliTemplate; - -import java.io.BufferedReader; -import java.io.File; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import processing.app.Preferences; -import processing.app.Serial; -import processing.app.debug.MessageConsumer; -import processing.app.debug.MessageSiphon; -import processing.app.debug.RunnerException; - -/** - * - * @author bob - */ -public class DFUUploader implements MessageConsumer { - - boolean firstErrorFound; - boolean secondErrorFound; - // part of the PdeMessageConsumer interface - boolean notFoundError; - boolean verbose; - RunnerException exception; - - static final String SUPER_BADNESS = - "Compiler error!"; - - public boolean uploadUsingPreferences(String binPath, boolean verbose) - throws RunnerException { - - this.verbose = verbose; - - return uploadViaDFU(binPath); - } - - // works with old and new versions of dfu-util - private boolean found_device (String dfuData, String usbID) - { - return dfuData.contains(("Found DFU: [0x"+usbID.substring(0,4)).toUpperCase()) || - dfuData.contains(("Found DFU: ["+usbID.substring(0,4)).toUpperCase()); - } - - public boolean uploadViaDFU (String binPath) - throws RunnerException { - - this.verbose = Preferences.getBoolean ("upload.verbose"); - - /* todo, check for size overruns! */ - String fileType="bin"; - - if (fileType.equals("bin")) { - String usbID = Preferences.get("upload.usbID"); - if (usbID == null) { - /* fall back on default */ - /* this isnt great because is default Avrdude or dfu-util? */ - usbID = Preferences.get("upload.usbID"); - } - - /* if auto-reset, then emit the reset pulse on dtr/rts */ - if (Preferences.get("upload.auto_reset") != null) { - if (Preferences.get("upload.auto_reset").toLowerCase().equals("true")) { - System.out.println("Resetting to bootloader via DTR pulse"); - emitResetPulse(); - } - } else { - System.out.println("Resetting to bootloader via DTR pulse"); - emitResetPulse(); - } - - String dfuList = new String(); - List commandCheck = new ArrayList(); - commandCheck.add("dfu-util"); - commandCheck.add("-l"); - long startChecking = System.currentTimeMillis(); - System.out.println("Searching for DFU device [" + usbID + "]..."); - do { - try { - Thread.sleep(100); - } catch (InterruptedException e) {} - dfuList = executeCheckCommand(commandCheck); - //System.out.println(dfuList); - } - while ( !found_device (dfuList.toUpperCase(), usbID) && (System.currentTimeMillis() - startChecking < 7000)); - - if ( !found_device (dfuList.toUpperCase(), usbID) ) - { - System.out.println(dfuList); - System.err.println("Couldn't find the DFU device: [" + usbID + "]"); - return false; - } - System.out.println("Found it!"); - - /* todo, add handle to let user choose altIf at upload time! */ - String altIf = Preferences.get("upload.altID"); - - List commandDownloader = new ArrayList(); - commandDownloader.add("dfu-util"); - commandDownloader.add("-a "+altIf); - commandDownloader.add("-R"); - commandDownloader.add("-d "+usbID); - commandDownloader.add("-D"+ binPath); //"./thisbin.bin"); - - return executeUploadCommand(commandDownloader); - } - - System.err.println("Only .bin files are supported at this time"); - return false; - } - - /* we need to ensure both RTS and DTR are low to start, - then pulse DTR on its own. This is the reset signal - maple responds to - */ - private void emitResetPulse() throws RunnerException { - - /* wait a while for the device to reboot */ - int programDelay = Preferences.getInteger("programDelay"); - - try { - Serial serialPort = new Serial(); - - // try to toggle DTR/RTS (old scheme) - serialPort.setRTS(false); - serialPort.setDTR(false); - serialPort.setDTR(true); - try { - Thread.sleep(50); - } catch (InterruptedException e) {} - serialPort.setDTR(false); - - // try magic number - serialPort.setRTS(true); - serialPort.setDTR(true); - try { - Thread.sleep(50); - } catch (InterruptedException e) {} - serialPort.setDTR(false); - try { - Thread.sleep(50); - } catch (InterruptedException e) {} - serialPort.write("1EAF"); - try { - Thread.sleep(50); - } catch (InterruptedException e) {} - serialPort.dispose(); - - } catch(Exception e) { - System.err.println("Reset via USB Serial Failed! Did you select the right serial port?\nAssuming the board is in perpetual bootloader mode and continuing to attempt dfu programming...\n"); - } - } - - protected String executeCheckCommand(Collection commandDownloader) - throws RunnerException - { - firstErrorFound = false; // haven't found any errors yet - secondErrorFound = false; - notFoundError = false; - int result=0; // pre-initialized to quiet a bogus warning from jikes - - String userdir = System.getProperty("user.dir") + File.separator; - String returnStr = new String(); - - try { - String[] commandArray = new String[commandDownloader.size()]; - commandDownloader.toArray(commandArray); - - String armBasePath; - - //armBasePath = new String(Base.getHardwarePath() + "/tools/arm/bin/"); - armBasePath = ""; - - commandArray[0] = armBasePath + commandArray[0]; - - if (verbose || Preferences.getBoolean("upload.verbose")) { - for(int i = 0; i < commandArray.length; i++) { - System.out.print(commandArray[i] + " "); - } - System.out.println(); - } - - Process process = Runtime.getRuntime().exec(commandArray); - BufferedReader stdInput = new BufferedReader(new - InputStreamReader(process.getInputStream())); - BufferedReader stdError = new BufferedReader(new - InputStreamReader(process.getErrorStream())); - - // wait for the process to finish. if interrupted - // before waitFor returns, continue waiting - // - boolean busy = true; - while (busy) { - try { - result = process.waitFor(); - busy = false; - } catch (InterruptedException intExc) { - } - } - - String s; - while ((s = stdInput.readLine()) != null) { - returnStr += s + "\n"; - } - - process.destroy(); - - if(exception!=null) { - exception.hideStackTrace(); - throw exception; - } - if(result!=0) return "Error!"; - } catch (Exception e) { - e.printStackTrace(); - } - //System.out.println("result2 is "+result); - // if the result isn't a known, expected value it means that something - // is fairly wrong, one possibility is that jikes has crashed. - // - if (exception != null) throw exception; - - if ((result != 0) && (result != 1 )) { - exception = new RunnerException(SUPER_BADNESS); - } - - return returnStr; // ? true : false; - - } - - // Need to overload this from Uploader to use the system-wide dfu-util - protected boolean executeUploadCommand(Collection commandDownloader) - throws RunnerException - { - firstErrorFound = false; // haven't found any errors yet - secondErrorFound = false; - notFoundError = false; - int result=0; // pre-initialized to quiet a bogus warning from jikes - - String userdir = System.getProperty("user.dir") + File.separator; - - try { - String[] commandArray = new String[commandDownloader.size()]; - commandDownloader.toArray(commandArray); - - String armBasePath; - - //armBasePath = new String(Base.getHardwarePath() + "/tools/arm/bin/"); - armBasePath = ""; - - commandArray[0] = armBasePath + commandArray[0]; - - if (verbose || Preferences.getBoolean("upload.verbose")) { - for(int i = 0; i < commandArray.length; i++) { - System.out.print(commandArray[i] + " "); - } - System.out.println(); - } - - Process process = Runtime.getRuntime().exec(commandArray); - new MessageSiphon(process.getInputStream(), this); - new MessageSiphon(process.getErrorStream(), this); - - // wait for the process to finish. if interrupted - // before waitFor returns, continue waiting - // - boolean compiling = true; - while (compiling) { - try { - result = process.waitFor(); - compiling = false; - } catch (InterruptedException intExc) { - } - } - if(exception!=null) { - exception.hideStackTrace(); - throw exception; - } - if(result!=0) - return false; - } catch (Exception e) { - e.printStackTrace(); - } - //System.out.println("result2 is "+result); - // if the result isn't a known, expected value it means that something - // is fairly wrong, one possibility is that jikes has crashed. - // - if (exception != null) throw exception; - - if ((result != 0) && (result != 1 )) { - exception = new RunnerException(SUPER_BADNESS); - //editor.error(exception); - //PdeBase.openURL(BUGS_URL); - //throw new PdeException(SUPER_BADNESS); - } - - return (result == 0); // ? true : false; - - } - - // deal with messages from dfu-util... - public void message(String s) { - - if(s.indexOf("dfu-util - (C) ") != -1) { return; } - if(s.indexOf("This program is Free Software and has ABSOLUTELY NO WARRANTY") != -1) { return; } - - if(s.indexOf("No DFU capable USB device found") != -1) { - System.err.print(s); - exception = new RunnerException("Problem uploading via dfu-util: No Maple found"); - return; - } - - if(s.indexOf("Operation not perimitted") != -1) { - System.err.print(s); - exception = new RunnerException("Problem uploading via dfu-util: Insufficient privilages"); - return; - } - - // else just print everything... - System.out.print(s); - } - -} diff --git a/src/maple_loader/src/CliTemplate/ExecCommand.java b/src/maple_loader/src/CliTemplate/ExecCommand.java deleted file mode 100644 index 3d6c106b7..000000000 --- a/src/maple_loader/src/CliTemplate/ExecCommand.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package CliTemplate; - -import java.io.IOException; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.List; - -import processing.app.debug.MessageConsumer; -import processing.app.debug.MessageSiphon; -import processing.app.debug.RunnerException; -import processing.app.helpers.ProcessUtils; - -/** - * - * @author cousinr - */ -public class ExecCommand implements MessageConsumer { - - private boolean verbose = true; - private boolean firstErrorFound; - private boolean secondErrorFound; - private RunnerException exception; - - /** - * Either succeeds or throws a RunnerException fit for public consumption. - * - * @param command - * @throws RunnerException - */ - public void execAsynchronously(String[] command) throws RunnerException { - - // eliminate any empty array entries - List stringList = new ArrayList<>(); - for (String string : command) { - string = string.trim(); - if (string.length() != 0) - stringList.add(string); - } - command = stringList.toArray(new String[stringList.size()]); - if (command.length == 0) - return; - int result = 0; - - if (verbose) { - for (String c : command) - System.out.print(c + " "); - System.out.println(); - } - - firstErrorFound = false; // haven't found any errors yet - secondErrorFound = false; - - Process process; - try { - process = ProcessUtils.exec(command); - } catch (IOException e) { - RunnerException re = new RunnerException(e.getMessage()); - re.hideStackTrace(); - throw re; - } - - MessageSiphon in = new MessageSiphon(process.getInputStream(), this); - MessageSiphon err = new MessageSiphon(process.getErrorStream(), this); - - // wait for the process to finish. if interrupted - // before waitFor returns, continue waiting - boolean compiling = true; - while (compiling) { - try { - in.join(); - err.join(); - result = process.waitFor(); - //System.out.println("result is " + result); - compiling = false; - } catch (InterruptedException ignored) { } - } - - // an error was queued up by message(), barf this back to compile(), - // which will barf it back to Editor. if you're having trouble - // discerning the imagery, consider how cows regurgitate their food - // to digest it, and the fact that they have five stomaches. - // - //System.out.println("throwing up " + exception); - if (exception != null) - throw exception; - - if (result > 1) { - // a failure in the tool (e.g. unable to locate a sub-executable) - System.err.println(MessageFormat.format("{0} returned {1}", command[0], result)); - } - - if (result != 0) { - RunnerException re = new RunnerException(MessageFormat.format("exit code: {0}", result)); - re.hideStackTrace(); - throw re; - } - } - - /** - * Part of the MessageConsumer interface, this is called - * whenever a piece (usually a line) of error message is spewed - * out from the compiler. The errors are parsed for their contents - * and line number, which is then reported back to Editor. - * @param s - */ - @Override - public void message(String s) { - int i; - - - System.err.print(s); - } - -} diff --git a/src/maple_loader/src/processing/app/Base.java b/src/maple_loader/src/processing/app/Base.java deleted file mode 100644 index c3a174dcb..000000000 --- a/src/maple_loader/src/processing/app/Base.java +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2004-10 Ben Fry and Casey Reas - Copyright (c) 2001-04 Massachusetts Institute of Technology - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 - as published by the Free Software Foundation. - - 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, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -package processing.app; - - -/** - * The base class for the main processing application. - * Primary role of this class is for platform identification and - * general interaction with the system (launching URLs, loading - * files and images, etc) that comes from that. - */ -public class Base { - - /** - * returns true if running on windows. - */ - static public boolean isWindows() { - //return PApplet.platform == PConstants.WINDOWS; - return System.getProperty("os.name").indexOf("Windows") != -1; - } - - - /** - * true if running on linux. - */ - static public boolean isLinux() { - //return PApplet.platform == PConstants.LINUX; - return System.getProperty("os.name").indexOf("Linux") != -1; - } - - - -} diff --git a/src/maple_loader/src/processing/app/Preferences.java b/src/maple_loader/src/processing/app/Preferences.java deleted file mode 100644 index 6368e38af..000000000 --- a/src/maple_loader/src/processing/app/Preferences.java +++ /dev/null @@ -1,157 +0,0 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2004-09 Ben Fry and Casey Reas - Copyright (c) 2001-04 Massachusetts Institute of Technology - - 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, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -package processing.app; - -import java.io.*; -import java.util.*; - - -/** - * Storage class for user preferences and environment settings. - *

- * This class no longer uses the Properties class, since - * properties files are iso8859-1, which is highly likely to - * be a problem when trying to save sketch folders and locations. - *

- * The GUI portion in here is really ugly, as it uses exact layout. This was - * done in frustration one evening (and pre-Swing), but that's long since past, - * and it should all be moved to a proper swing layout like BoxLayout. - *

- * This is very poorly put together, that the preferences panel and the actual - * preferences i/o is part of the same code. But there hasn't yet been a - * compelling reason to bother with the separation aside from concern about - * being lectured by strangers who feel that it doesn't look like what they - * learned in CS class. - *

- * Would also be possible to change this to use the Java Preferences API. - * Some useful articles - * here and - * here. - * However, haven't implemented this yet for lack of time, but more - * importantly, because it would entail writing to the registry (on Windows), - * or an obscure file location (on Mac OS X) and make it far more difficult to - * find the preferences to tweak them by hand (no! stay out of regedit!) - * or to reset the preferences by simply deleting the preferences.txt file. - */ -public class Preferences { - - // what to call the feller - - static final String PREFS_FILE = "preferences.txt"; - - - // prompt text stuff - - static final String PROMPT_YES = "Yes"; - static final String PROMPT_NO = "No"; - static final String PROMPT_CANCEL = "Cancel"; - static final String PROMPT_OK = "OK"; - static final String PROMPT_BROWSE = "Browse"; - - /** - * Standardized width for buttons. Mac OS X 10.3 wants 70 as its default, - * Windows XP needs 66, and my Ubuntu machine needs 80+, so 80 seems proper. - */ - static public int BUTTON_WIDTH = 80; - - /** - * Standardized button height. Mac OS X 10.3 (Java 1.4) wants 29, - * presumably because it now includes the blue border, where it didn't - * in Java 1.3. Windows XP only wants 23 (not sure what default Linux - * would be). Because of the disparity, on Mac OS X, it will be set - * inside a static block. - */ - static public int BUTTON_HEIGHT = 24; - - // value for the size bars, buttons, etc - - static final int GRID_SIZE = 33; - - - // indents and spacing standards. these probably need to be modified - // per platform as well, since macosx is so huge, windows is smaller, - // and linux is all over the map - - static final int GUI_BIG = 13; - static final int GUI_BETWEEN = 10; - static final int GUI_SMALL = 6; - - - - // data model - - static Hashtable table = new Hashtable();; - static File preferencesFile; - - - static protected void init(String commandLinePrefs) { - - - } - - - public Preferences() { - - } - - // ................................................................. - - // ................................................................. - - // ................................................................. - - // ................................................................. - - - - static public String get(String attribute) { - return (String) table.get(attribute); - } - - static public void set(String attribute, String value) { - table.put(attribute, value); - } - - - static public boolean getBoolean(String attribute) { - String value = get(attribute); - return (new Boolean(value)).booleanValue(); - } - - - static public void setBoolean(String attribute, boolean value) { - set(attribute, value ? "true" : "false"); - } - - - static public int getInteger(String attribute) { - return Integer.parseInt(get(attribute)); - } - - - static public void setInteger(String key, int value) { - set(key, String.valueOf(value)); - } - -} diff --git a/src/maple_loader/src/processing/app/Serial.java b/src/maple_loader/src/processing/app/Serial.java deleted file mode 100644 index 04566a738..000000000 --- a/src/maple_loader/src/processing/app/Serial.java +++ /dev/null @@ -1,527 +0,0 @@ -/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - PSerial - class for serial port goodness - Part of the Processing project - http://processing.org - - Copyright (c) 2004 Ben Fry & Casey Reas - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ - -package processing.app; -//import processing.core.*; - - -import java.io.*; -import java.text.MessageFormat; -import java.util.*; -import jssc.SerialPort; -import jssc.SerialPortEvent; -import jssc.SerialPortEventListener; -import jssc.SerialPortException; -import jssc.SerialPortList; -import processing.app.debug.MessageConsumer; - - -public class Serial implements SerialPortEventListener { - - //PApplet parent; - - // properties can be passed in for default values - // otherwise defaults to 9600 N81 - - // these could be made static, which might be a solution - // for the classloading problem.. because if code ran again, - // the static class would have an object that could be closed - - SerialPort port; - - int rate; - int parity; - int databits; - int stopbits; - boolean monitor = false; - - // read buffer and streams - - InputStream input; - OutputStream output; - - byte buffer[] = new byte[32768]; - int bufferIndex; - int bufferLast; - - MessageConsumer consumer; - - public Serial(boolean monitor) throws SerialException { - this(Preferences.get("serial.port"), - Preferences.getInteger("serial.debug_rate"), - Preferences.get("serial.parity").charAt(0), - Preferences.getInteger("serial.databits"), - new Float(Preferences.get("serial.stopbits")).floatValue()); - this.monitor = monitor; - } - - public Serial() throws SerialException { - this(Preferences.get("serial.port"), - Preferences.getInteger("serial.debug_rate"), - Preferences.get("serial.parity").charAt(0), - Preferences.getInteger("serial.databits"), - new Float(Preferences.get("serial.stopbits")).floatValue()); - } - - public Serial(int irate) throws SerialException { - this(Preferences.get("serial.port"), irate, - Preferences.get("serial.parity").charAt(0), - Preferences.getInteger("serial.databits"), - new Float(Preferences.get("serial.stopbits")).floatValue()); - } - - public Serial(String iname, int irate) throws SerialException { - this(iname, irate, Preferences.get("serial.parity").charAt(0), - Preferences.getInteger("serial.databits"), - new Float(Preferences.get("serial.stopbits")).floatValue()); - } - - public Serial(String iname) throws SerialException { - this(iname, Preferences.getInteger("serial.debug_rate"), - Preferences.get("serial.parity").charAt(0), - Preferences.getInteger("serial.databits"), - new Float(Preferences.get("serial.stopbits")).floatValue()); - } - - public Serial(String iname, int irate, - char iparity, int idatabits, float istopbits) - throws SerialException { - //if (port != null) port.close(); - //this.parent = parent; - //parent.attach(this); - - this.rate = irate; - - parity = SerialPort.PARITY_NONE; - if (iparity == 'E') parity = SerialPort.PARITY_EVEN; - if (iparity == 'O') parity = SerialPort.PARITY_ODD; - - this.databits = idatabits; - - stopbits = SerialPort.STOPBITS_1; - if (istopbits == 1.5f) stopbits = SerialPort.STOPBITS_1_5; - if (istopbits == 2) stopbits = SerialPort.STOPBITS_2; - - try { - port = new SerialPort(iname); - port.openPort(); - port.setParams(rate, databits, stopbits, parity, true, true); - port.addEventListener(this); - } catch (Exception e) { - throw new SerialException(MessageFormat.format("Error opening serial port ''{0}''.", iname), e); - } - - if (port == null) { - throw new SerialException("Serial port '" + iname + "' not found. Did you select the right one from the Tools > Serial Port menu?"); - } - } - - - public void setup() { - //parent.registerCall(this, DISPOSE); - } - - public void dispose() throws IOException { - if (port != null) { - try { - if (port.isOpened()) { - port.closePort(); // close the port - } - } catch (SerialPortException e) { - throw new IOException(e); - } finally { - port = null; - } - } - } - - public void addListener(MessageConsumer consumer) { - this.consumer = consumer; - } - - public synchronized void serialEvent(SerialPortEvent serialEvent) { - if (serialEvent.isRXCHAR()) { - try { - byte[] buf = port.readBytes(serialEvent.getEventValue()); - if (buf.length > 0) { - if (bufferLast == buffer.length) { - byte temp[] = new byte[bufferLast << 1]; - System.arraycopy(buffer, 0, temp, 0, bufferLast); - buffer = temp; - } - if (monitor) { - System.out.print(new String(buf)); - } - if (this.consumer != null) { - this.consumer.message(new String(buf)); - } - } - } catch (SerialPortException e) { - errorMessage("serialEvent", e); - } - } - } - - - /** - * Returns the number of bytes that have been read from serial - * and are waiting to be dealt with by the user. - */ - public synchronized int available() { - return (bufferLast - bufferIndex); - } - - - /** - * Ignore all the bytes read so far and empty the buffer. - */ - public synchronized void clear() { - bufferLast = 0; - bufferIndex = 0; - } - - - /** - * Returns a number between 0 and 255 for the next byte that's - * waiting in the buffer. - * Returns -1 if there was no byte (although the user should - * first check available() to see if things are ready to avoid this) - */ - public synchronized int read() { - if (bufferIndex == bufferLast) return -1; - - int outgoing = buffer[bufferIndex++] & 0xff; - if (bufferIndex == bufferLast) { // rewind - bufferIndex = 0; - bufferLast = 0; - } - return outgoing; - } - - - /** - * Returns the next byte in the buffer as a char. - * Returns -1, or 0xffff, if nothing is there. - */ - public synchronized char readChar() { - if (bufferIndex == bufferLast) return (char)(-1); - return (char) read(); - } - - - /** - * Return a byte array of anything that's in the serial buffer. - * Not particularly memory/speed efficient, because it creates - * a byte array on each read, but it's easier to use than - * readBytes(byte b[]) (see below). - */ - public synchronized byte[] readBytes() { - if (bufferIndex == bufferLast) return null; - - int length = bufferLast - bufferIndex; - byte outgoing[] = new byte[length]; - System.arraycopy(buffer, bufferIndex, outgoing, 0, length); - - bufferIndex = 0; // rewind - bufferLast = 0; - return outgoing; - } - - - /** - * Grab whatever is in the serial buffer, and stuff it into a - * byte buffer passed in by the user. This is more memory/time - * efficient than readBytes() returning a byte[] array. - *

- * Returns an int for how many bytes were read. If more bytes - * are available than can fit into the byte array, only those - * that will fit are read. - */ - public synchronized int readBytes(byte outgoing[]) { - if (bufferIndex == bufferLast) return 0; - - int length = bufferLast - bufferIndex; - if (length > outgoing.length) length = outgoing.length; - System.arraycopy(buffer, bufferIndex, outgoing, 0, length); - - bufferIndex += length; - if (bufferIndex == bufferLast) { - bufferIndex = 0; // rewind - bufferLast = 0; - } - return length; - } - - - /** - * Reads from the serial port into a buffer of bytes up to and - * including a particular character. If the character isn't in - * the serial buffer, then 'null' is returned. - */ - public synchronized byte[] readBytesUntil(int interesting) { - if (bufferIndex == bufferLast) return null; - byte what = (byte)interesting; - - int found = -1; - for (int k = bufferIndex; k < bufferLast; k++) { - if (buffer[k] == what) { - found = k; - break; - } - } - if (found == -1) return null; - - int length = found - bufferIndex + 1; - byte outgoing[] = new byte[length]; - System.arraycopy(buffer, bufferIndex, outgoing, 0, length); - - bufferIndex = 0; // rewind - bufferLast = 0; - return outgoing; - } - - - /** - * Reads from the serial port into a buffer of bytes until a - * particular character. If the character isn't in the serial - * buffer, then 'null' is returned. - *

- * If outgoing[] is not big enough, then -1 is returned, - * and an error message is printed on the console. - * If nothing is in the buffer, zero is returned. - * If 'interesting' byte is not in the buffer, then 0 is returned. - */ - public synchronized int readBytesUntil(int interesting, byte outgoing[]) { - if (bufferIndex == bufferLast) return 0; - byte what = (byte)interesting; - - int found = -1; - for (int k = bufferIndex; k < bufferLast; k++) { - if (buffer[k] == what) { - found = k; - break; - } - } - if (found == -1) return 0; - - int length = found - bufferIndex + 1; - if (length > outgoing.length) { - System.err.println("readBytesUntil() byte buffer is" + - " too small for the " + length + - " bytes up to and including char " + interesting); - return -1; - } - //byte outgoing[] = new byte[length]; - System.arraycopy(buffer, bufferIndex, outgoing, 0, length); - - bufferIndex += length; - if (bufferIndex == bufferLast) { - bufferIndex = 0; // rewind - bufferLast = 0; - } - return length; - } - - - /** - * Return whatever has been read from the serial port so far - * as a String. It assumes that the incoming characters are ASCII. - *

- * If you want to move Unicode data, you can first convert the - * String to a byte stream in the representation of your choice - * (i.e. UTF8 or two-byte Unicode data), and send it as a byte array. - */ - public synchronized String readString() { - if (bufferIndex == bufferLast) return null; - return new String(readBytes()); - } - - - /** - * Combination of readBytesUntil and readString. See caveats in - * each function. Returns null if it still hasn't found what - * you're looking for. - *

- * If you want to move Unicode data, you can first convert the - * String to a byte stream in the representation of your choice - * (i.e. UTF8 or two-byte Unicode data), and send it as a byte array. - */ - public synchronized String readStringUntil(int interesting) { - byte b[] = readBytesUntil(interesting); - if (b == null) return null; - return new String(b); - } - - - /** - * This will handle both ints, bytes and chars transparently. - */ - public void write(int what) { // will also cover char - try { - port.writeInt(what & 0xff); - } catch (SerialPortException e) { - errorMessage("write", e); - } - } - - - public void write(byte bytes[]) { - try { - port.writeBytes(bytes); - } catch (SerialPortException e) { - errorMessage("write", e); - } - } - - - /** - * Write a String to the output. Note that this doesn't account - * for Unicode (two bytes per char), nor will it send UTF8 - * characters.. It assumes that you mean to send a byte buffer - * (most often the case for networking and serial i/o) and - * will only use the bottom 8 bits of each char in the string. - * (Meaning that internally it uses String.getBytes) - *

- * If you want to move Unicode data, you can first convert the - * String to a byte stream in the representation of your choice - * (i.e. UTF8 or two-byte Unicode data), and send it as a byte array. - */ - public void write(String what) { - write(what.getBytes()); - } - - public void setDTR(boolean state) { - try { - port.setDTR(state); - } catch (SerialPortException e) { - errorMessage("setDTR", e); - } - } - - public void setRTS(boolean state) { - try { - port.setRTS(state); - } catch (SerialPortException e) { - errorMessage("setRTS", e); - } - } - - static public List list() { - return Arrays.asList(SerialPortList.getPortNames()); - } - - - /** - * General error reporting, all corraled here just in case - * I think of something slightly more intelligent to do. - */ - static public void errorMessage(String where, Throwable e) { - System.err.println("Error inside Serial." + where + "()"); - e.printStackTrace(); - } -} - - - /* - class SerialMenuListener implements ItemListener { - //public SerialMenuListener() { } - - public void itemStateChanged(ItemEvent e) { - int count = serialMenu.getItemCount(); - for (int i = 0; i < count; i++) { - ((CheckboxMenuItem)serialMenu.getItem(i)).setState(false); - } - CheckboxMenuItem item = (CheckboxMenuItem)e.getSource(); - item.setState(true); - String name = item.getLabel(); - //System.out.println(item.getLabel()); - PdeBase.properties.put("serial.port", name); - //System.out.println("set to " + get("serial.port")); - } - } - */ - - - /* - protected Vector buildPortList() { - // get list of names for serial ports - // have the default port checked (if present) - Vector list = new Vector(); - - //SerialMenuListener listener = new SerialMenuListener(); - boolean problem = false; - - // if this is failing, it may be because - // lib/javax.comm.properties is missing. - // java is weird about how it searches for java.comm.properties - // so it tends to be very fragile. i.e. quotes in the CLASSPATH - // environment variable will hose things. - try { - //System.out.println("building port list"); - Enumeration portList = CommPortIdentifier.getPortIdentifiers(); - while (portList.hasMoreElements()) { - CommPortIdentifier portId = - (CommPortIdentifier) portList.nextElement(); - //System.out.println(portId); - - if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) { - //if (portId.getName().equals(port)) { - String name = portId.getName(); - //CheckboxMenuItem mi = - //new CheckboxMenuItem(name, name.equals(defaultName)); - - //mi.addItemListener(listener); - //serialMenu.add(mi); - list.addElement(name); - } - } - } catch (UnsatisfiedLinkError e) { - e.printStackTrace(); - problem = true; - - } catch (Exception e) { - System.out.println("exception building serial menu"); - e.printStackTrace(); - } - - //if (serialMenu.getItemCount() == 0) { - //System.out.println("dimming serial menu"); - //serialMenu.setEnabled(false); - //} - - // only warn them if this is the first time - if (problem && PdeBase.firstTime) { - JOptionPane.showMessageDialog(this, //frame, - "Serial port support not installed.\n" + - "Check the readme for instructions\n" + - "if you need to use the serial port. ", - "Serial Port Warning", - JOptionPane.WARNING_MESSAGE); - } - return list; - } - */ - - - diff --git a/src/maple_loader/src/processing/app/SerialException.java b/src/maple_loader/src/processing/app/SerialException.java deleted file mode 100644 index 525c24078..000000000 --- a/src/maple_loader/src/processing/app/SerialException.java +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - Copyright (c) 2007 David A. Mellis - - 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, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -package processing.app; - -public class SerialException extends Exception { - public SerialException() { - super(); - } - - public SerialException(String message) { - super(message); - } - - public SerialException(String message, Throwable cause) { - super(message, cause); - } - - public SerialException(Throwable cause) { - super(cause); - } -} diff --git a/src/maple_loader/src/processing/app/debug/MessageConsumer.java b/src/maple_loader/src/processing/app/debug/MessageConsumer.java deleted file mode 100644 index 5e2042943..000000000 --- a/src/maple_loader/src/processing/app/debug/MessageConsumer.java +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2004-06 Ben Fry and Casey Reas - Copyright (c) 2001-04 Massachusetts Institute of Technology - - 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, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -package processing.app.debug; - - -/** - * Interface for dealing with parser/compiler output. - *

- * Different instances of MessageStream need to do different things with - * messages. In particular, a stream instance used for parsing output from - * the compiler compiler has to interpret its messages differently than one - * parsing output from the runtime. - *

- * Classes which consume messages and do something with them - * should implement this interface. - */ -public interface MessageConsumer { - - public void message(String s); - -} diff --git a/src/maple_loader/src/processing/app/debug/MessageSiphon.java b/src/maple_loader/src/processing/app/debug/MessageSiphon.java deleted file mode 100644 index 26901c3f4..000000000 --- a/src/maple_loader/src/processing/app/debug/MessageSiphon.java +++ /dev/null @@ -1,104 +0,0 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2004-06 Ben Fry and Casey Reas - Copyright (c) 2001-04 Massachusetts Institute of Technology - - 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, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -package processing.app.debug; - -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.SocketException; - -/** - * Slurps up messages from compiler. - */ -public class MessageSiphon implements Runnable { - - private final BufferedReader streamReader; - private final MessageConsumer consumer; - - private Thread thread; - private boolean canRun; - - public MessageSiphon(InputStream stream, MessageConsumer consumer) { - this.streamReader = new BufferedReader(new InputStreamReader(stream)); - this.consumer = consumer; - this.canRun = true; - - thread = new Thread(this); - // don't set priority too low, otherwise exceptions won't - // bubble up in time (i.e. compile errors have a weird delay) - //thread.setPriority(Thread.MIN_PRIORITY); - thread.setPriority(Thread.MAX_PRIORITY - 1); - thread.start(); - } - - - public void run() { - try { - // process data until we hit EOF; this will happily block - // (effectively sleeping the thread) until new data comes in. - // when the program is finally done, null will come through. - // - String currentLine; - while (canRun && (currentLine = streamReader.readLine()) != null) { - // \n is added again because readLine() strips it out - //EditorConsole.systemOut.println("messaging in"); - consumer.message(currentLine + "\n"); - //EditorConsole.systemOut.println("messaging out"); - } - //EditorConsole.systemOut.println("messaging thread done"); - } catch (NullPointerException npe) { - // Fairly common exception during shutdown - } catch (SocketException e) { - // socket has been close while we were wainting for data. nothing to see here, move along - } catch (Exception e) { - // On Linux and sometimes on Mac OS X, a "bad file descriptor" - // message comes up when closing an applet that's run externally. - // That message just gets supressed here.. - String mess = e.getMessage(); - if ((mess != null) && - (mess.indexOf("Bad file descriptor") != -1)) { - //if (e.getMessage().indexOf("Bad file descriptor") == -1) { - //System.err.println("MessageSiphon err " + e); - //e.printStackTrace(); - } else { - e.printStackTrace(); - } - } finally { - thread = null; - } - } - - // Wait until the MessageSiphon thread is complete. - public void join() throws java.lang.InterruptedException { - // Grab a temp copy in case another thread nulls the "thread" - // member variable - Thread t = thread; - if (t != null) t.join(); - } - - public void stop() { - this.canRun = false; - } - -} diff --git a/src/maple_loader/src/processing/app/debug/RunnerException.java b/src/maple_loader/src/processing/app/debug/RunnerException.java deleted file mode 100644 index 0a67d1e80..000000000 --- a/src/maple_loader/src/processing/app/debug/RunnerException.java +++ /dev/null @@ -1,161 +0,0 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2004-08 Ben Fry and Casey Reas - Copyright (c) 2001-04 Massachusetts Institute of Technology - - 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, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -package processing.app.debug; - - -/** - * An exception with a line number attached that occurs - * during either compile time or run time. - */ -@SuppressWarnings("serial") -public class RunnerException extends Exception { - protected String message; - protected int codeIndex; - protected int codeLine; - protected int codeColumn; - protected boolean showStackTrace; - - - public RunnerException(String message) { - this(message, true); - } - - public RunnerException(String message, boolean showStackTrace) { - this(message, -1, -1, -1, showStackTrace); - } - - public RunnerException(String message, int file, int line) { - this(message, file, line, -1, true); - } - - - public RunnerException(String message, int file, int line, int column) { - this(message, file, line, column, true); - } - - - public RunnerException(String message, int file, int line, int column, - boolean showStackTrace) { - this.message = message; - this.codeIndex = file; - this.codeLine = line; - this.codeColumn = column; - this.showStackTrace = showStackTrace; - } - - - public RunnerException(Exception e) { - super(e); - this.showStackTrace = true; - } - - /** - * Override getMessage() in Throwable, so that I can set - * the message text outside the constructor. - */ - public String getMessage() { - return message; - } - - - public void setMessage(String message) { - this.message = message; - } - - - public int getCodeIndex() { - return codeIndex; - } - - - public void setCodeIndex(int index) { - codeIndex = index; - } - - - public boolean hasCodeIndex() { - return codeIndex != -1; - } - - - public int getCodeLine() { - return codeLine; - } - - - public void setCodeLine(int line) { - this.codeLine = line; - } - - - public boolean hasCodeLine() { - return codeLine != -1; - } - - - public void setCodeColumn(int column) { - this.codeColumn = column; - } - - - public int getCodeColumn() { - return codeColumn; - } - - - public void showStackTrace() { - showStackTrace = true; - } - - - public void hideStackTrace() { - showStackTrace = false; - } - - - /** - * Nix the java.lang crap out of an exception message - * because it scares the children. - *

- * This function must be static to be used with super() - * in each of the constructors above. - */ - /* - static public final String massage(String msg) { - if (msg.indexOf("java.lang.") == 0) { - //int dot = msg.lastIndexOf('.'); - msg = msg.substring("java.lang.".length()); - } - return msg; - //return (dot == -1) ? msg : msg.substring(dot+1); - } - */ - - - public void printStackTrace() { - if (showStackTrace) { - super.printStackTrace(); - } - } -} diff --git a/src/maple_loader/src/processing/app/helpers/ProcessUtils.java b/src/maple_loader/src/processing/app/helpers/ProcessUtils.java deleted file mode 100644 index c023f5810..000000000 --- a/src/maple_loader/src/processing/app/helpers/ProcessUtils.java +++ /dev/null @@ -1,32 +0,0 @@ -package processing.app.helpers; - -//import processing.app.Base; - -import java.io.IOException; -import java.util.Map; - -import processing.app.Base; - -public class ProcessUtils { - - public static Process exec(String[] command) throws IOException { - // No problems on linux and mac - if (!Base.isWindows()) { - return Runtime.getRuntime().exec(command); - } - - // Brutal hack to workaround windows command line parsing. - // http://stackoverflow.com/questions/5969724/java-runtime-exec-fails-to-escape-characters-properly - // http://msdn.microsoft.com/en-us/library/a1y7w461.aspx - // http://bugs.sun.com/view_bug.do?bug_id=6468220 - // http://bugs.sun.com/view_bug.do?bug_id=6518827 - String[] cmdLine = new String[command.length]; - for (int i = 0; i < command.length; i++) - cmdLine[i] = command[i].replace("\"", "\\\""); - - ProcessBuilder pb = new ProcessBuilder(cmdLine); - Map env = pb.environment(); - env.put("CYGWIN", "nodosfilewarning"); - return pb.start(); - } -} diff --git a/src/upload-reset/upload-reset.c b/src/upload-reset/upload-reset.c deleted file mode 100644 index 1d03bff51..000000000 --- a/src/upload-reset/upload-reset.c +++ /dev/null @@ -1,161 +0,0 @@ -/* Copyright (C) 2015 Roger Clark - * - * 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. - * - * - * Utility to send the reset sequence on RTS and DTR and chars - * which resets the libmaple and causes the bootloader to be run - * - * - * - * Terminal control code by Heiko Noordhof (see copyright below) - */ - - - -/* Copyright (C) 2003 Heiko Noordhof - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Function prototypes (belong in a seperate header file) */ -int openserial(char *devicename); -void closeserial(void); -int setDTR(unsigned short level); -int setRTS(unsigned short level); - - -/* Two globals for use by this module only */ -static int fd; -static struct termios oldterminfo; - - -void closeserial(void) -{ - tcsetattr(fd, TCSANOW, &oldterminfo); - close(fd); -} - - -int openserial(char *devicename) -{ - struct termios attr; - - if ((fd = open(devicename, O_RDWR)) == -1) return 0; /* Error */ - atexit(closeserial); - - if (tcgetattr(fd, &oldterminfo) == -1) return 0; /* Error */ - attr = oldterminfo; - attr.c_cflag |= CRTSCTS | CLOCAL; - attr.c_oflag = 0; - if (tcflush(fd, TCIOFLUSH) == -1) return 0; /* Error */ - if (tcsetattr(fd, TCSANOW, &attr) == -1) return 0; /* Error */ - - /* Set the lines to a known state, and */ - /* finally return non-zero is successful. */ - return setRTS(0) && setDTR(0); -} - - -/* For the two functions below: - * level=0 to set line to LOW - * level=1 to set line to HIGH - */ - -int setRTS(unsigned short level) -{ - int status; - - if (ioctl(fd, TIOCMGET, &status) == -1) { - perror("setRTS(): TIOCMGET"); - return 0; - } - if (level) status |= TIOCM_RTS; - else status &= ~TIOCM_RTS; - if (ioctl(fd, TIOCMSET, &status) == -1) { - perror("setRTS(): TIOCMSET"); - return 0; - } - return 1; -} - - -int setDTR(unsigned short level) -{ - int status; - - if (ioctl(fd, TIOCMGET, &status) == -1) { - perror("setDTR(): TIOCMGET"); - return 0; - } - if (level) status |= TIOCM_DTR; - else status &= ~TIOCM_DTR; - if (ioctl(fd, TIOCMSET, &status) == -1) { - perror("setDTR: TIOCMSET"); - return 0; - } - return 1; -} - -/* This portion of code was written by Roger Clark - * It was informed by various other pieces of code written by Leaflabs to reset their - * Maple and Maple mini boards - */ - -main(int argc, char *argv[]) -{ - - if (argc<2 || argc >3) - { - printf("Usage upload-reset \n\r"); - return; - } - - if (openserial(argv[1])) - { - // Send magic sequence of DTR and RTS followed by the magic word "1EAF" - setRTS(false); - setDTR(false); - setDTR(true); - - usleep(50000L); - - setDTR(false); - setRTS(true); - setDTR(true); - - usleep(50000L); - - setDTR(false); - - usleep(50000L); - - write(fd,"1EAF",4); - - closeserial(); - if (argc==3) - { - usleep(atol(argv[2])*1000L); - } - } - else - { - printf("Failed to open serial device.\n\r"); - } -} diff --git a/linux/src/upload-reset/upload-reset.c b/src/upload_reset/unix/upload_reset.c similarity index 95% rename from linux/src/upload-reset/upload-reset.c rename to src/upload_reset/unix/upload_reset.c index 1d03bff51..975ef258d 100644 --- a/linux/src/upload-reset/upload-reset.c +++ b/src/upload_reset/unix/upload_reset.c @@ -1,5 +1,5 @@ /* Copyright (C) 2015 Roger Clark - * + * * 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 @@ -17,7 +17,7 @@ /* Copyright (C) 2003 Heiko Noordhof - * + * * 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 @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -38,7 +38,7 @@ int openserial(char *devicename); void closeserial(void); int setDTR(unsigned short level); -int setRTS(unsigned short level); +int setRTS(unsigned short level); /* Two globals for use by this module only */ @@ -53,11 +53,11 @@ void closeserial(void) } -int openserial(char *devicename) +int openserial(char *devicename) { struct termios attr; - if ((fd = open(devicename, O_RDWR)) == -1) return 0; /* Error */ + if ((fd = open(devicename, O_RDWR)) == -1) return 0; /* Error */ atexit(closeserial); if (tcgetattr(fd, &oldterminfo) == -1) return 0; /* Error */ @@ -65,7 +65,7 @@ int openserial(char *devicename) attr.c_cflag |= CRTSCTS | CLOCAL; attr.c_oflag = 0; if (tcflush(fd, TCIOFLUSH) == -1) return 0; /* Error */ - if (tcsetattr(fd, TCSANOW, &attr) == -1) return 0; /* Error */ + if (tcsetattr(fd, TCSANOW, &attr) == -1) return 0; /* Error */ /* Set the lines to a known state, and */ /* finally return non-zero is successful. */ @@ -114,13 +114,13 @@ int setDTR(unsigned short level) } /* This portion of code was written by Roger Clark - * It was informed by various other pieces of code written by Leaflabs to reset their - * Maple and Maple mini boards + * It was informed by various other pieces of code written by Leaflabs to reset their + * Maple and Maple mini boards */ main(int argc, char *argv[]) { - + if (argc<2 || argc >3) { printf("Usage upload-reset \n\r"); @@ -147,7 +147,7 @@ main(int argc, char *argv[]) usleep(50000L); write(fd,"1EAF",4); - + closeserial(); if (argc==3) { diff --git a/src/upload_reset/win/Makefile b/src/upload_reset/win/Makefile new file mode 100644 index 000000000..4aac4846b --- /dev/null +++ b/src/upload_reset/win/Makefile @@ -0,0 +1,23 @@ +CC = gcc +SRC = $(wildcard *.c) +LIBSRC = $(wildcard ../../libserialport/*.c) +OBJ = $(SRC:.c=.o) $(LIBSRC:.c=.o) +CFLAGS = -DLIBSERIALPORT_MSBUILD -Wall -I../../libserialport +LDFLAGS = -lsetupapi +DEST = ../../../win +BIN = $(SRC:.c=) + +.PHONY: all clean + +all: $(BIN) install + +$(BIN): $(OBJ) + $(CC) -o $@ $^ $(LDFLAGS) + +install: $(BIN) + @echo "$@ $^..." + @mv $(BIN) $(DEST)/ + +clean: + rm -f $(OBJ) $(DEST)/$(BIN) + diff --git a/src/upload_reset/win/upload_reset.c b/src/upload_reset/win/upload_reset.c new file mode 100644 index 000000000..414e0c6a6 --- /dev/null +++ b/src/upload_reset/win/upload_reset.c @@ -0,0 +1,85 @@ +#include +#include +#include +/* + * Utility to send the reset sequence on RTS and DTR and chars + * which resets the libmaple and causes the bootloader to be run + */ + +/* Helper function for error handling. */ +int check(enum sp_return result) +{ + char *error_message; + + switch (result) { + case SP_ERR_ARG: + printf("Error: Invalid argument.\n"); + exit(SP_ERR_ARG); + case SP_ERR_FAIL: + error_message = sp_last_error_message(); + printf("Error: Failed: %s\n", error_message); + sp_free_error_message(error_message); + exit(SP_ERR_FAIL); + case SP_ERR_SUPP: + printf("Error: Not supported.\n"); + exit(SP_ERR_SUPP); + case SP_ERR_MEM: + printf("Error: Couldn't allocate memory.\n"); + exit(SP_ERR_MEM); + case SP_OK: + default: + return result; + } +} + +int main(int argc, char **argv) +{ + if (argc<2 || argc >3) + { + printf("Usage %s \n", argv[0]); + return -1; + } + + char *port_name = argv[1]; + /* A pointer to a struct sp_port, which will refer to + * the port found. */ + struct sp_port *port; + printf("Looking for port %s.\n", port_name); + /* Call sp_get_port_by_name() to find the port. The port + * pointer will be updated to refer to the port found. */ + check(sp_get_port_by_name(port_name, &port)); + + /* Display some basic information about the port. */ + printf("Port name: %s\n", sp_get_port_name(port)); + printf("Description: %s\n", sp_get_port_description(port)); + + /* The port must be open to access its configuration. */ + printf("Opening port.\n"); + check(sp_open(port, SP_MODE_READ_WRITE)); + check(sp_set_flowcontrol(port, SP_FLOWCONTROL_RTSCTS)); + check(sp_flush(port, SP_BUF_BOTH)); + // check(sp_set_rts(port, SP_RTS_OFF)); + // check(sp_set_dtr(port, SP_DTR_OFF)); + + // Send magic sequence of DTR and RTS followed by the magic word "1EAF" + check(sp_set_rts(port, SP_RTS_OFF)); + check(sp_set_dtr(port, SP_DTR_OFF)); + check(sp_set_dtr(port, SP_DTR_ON)); + Sleep(50); + check(sp_set_dtr(port, SP_DTR_OFF)); + check(sp_set_rts(port, SP_RTS_ON)); + check(sp_set_dtr(port, SP_DTR_ON)); + Sleep(50); + check(sp_set_dtr(port, SP_DTR_OFF)); + Sleep(50); + check(sp_blocking_write(port, "1EAF", 4, 1000)); + + /* Now clean up by closing the port and freeing structures. */ + check(sp_close(port)); + sp_free_port(port); + if (argc==3) + { + Sleep(atol(argv[2])); + } + return 0; +} diff --git a/win/check_port.exe b/win/check_port.exe new file mode 100644 index 000000000..be48c8537 Binary files /dev/null and b/win/check_port.exe differ diff --git a/win/lib/jssc.jar b/win/lib/jssc.jar deleted file mode 100644 index d2b5c070a..000000000 Binary files a/win/lib/jssc.jar and /dev/null differ diff --git a/win/maple_loader.jar b/win/maple_loader.jar deleted file mode 100644 index e64676cef..000000000 Binary files a/win/maple_loader.jar and /dev/null differ diff --git a/win/maple_upload.bat b/win/maple_upload.bat deleted file mode 100644 index 7d59bf53b..000000000 --- a/win/maple_upload.bat +++ /dev/null @@ -1,18 +0,0 @@ -@echo off -rem: Note %~dp0 get path of this batch file -rem: Need to change drive if My Documents is on a drive other than C: -set driverLetter=%~dp0 -set driverLetter=%driverLetter:~0,2% -%driverLetter% -cd %~dp0 -java -jar maple_loader.jar %1 %2 %3 %4 %5 %6 %7 %8 %9 - -for /l %%x in (1, 1, 40) do ( - ping -w 50 -n 1 192.0.2.1 > nul - mode %1 > nul - if ERRORLEVEL 0 goto comPortFound -) - -echo timeout waiting for %1 serial - -:comPortFound diff --git a/win/upload_reset.exe b/win/upload_reset.exe new file mode 100644 index 000000000..27cdc459b Binary files /dev/null and b/win/upload_reset.exe differ