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 pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy