diff --git a/build-fxload.sh b/build-fxload.sh new file mode 100755 index 0000000..5ce53a3 --- /dev/null +++ b/build-fxload.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +DIR=$(dirname "$0") + +cd $DIR/fxload + +cmake -B build -S . -DCMAKE_INSTALL_PREFIX=/usr +cmake --build ./build +sudo cmake --install ./build diff --git a/fxload/CMakeLists.txt b/fxload/CMakeLists.txt new file mode 100644 index 0000000..6c1e141 --- /dev/null +++ b/fxload/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.0) +PROJECT(fx3load C) + +set(DATA_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/usb/") +############# FX3 Load ############### +set(fx3load_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/main.c ${CMAKE_CURRENT_SOURCE_DIR}/ezusb.c) + +add_executable(fxload ${fx3load_SRCS}) + +install(TARGETS fxload RUNTIME DESTINATION sbin) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/a3load.hex DESTINATION ${DATA_INSTALL_DIR}) diff --git a/fxload/COPYING b/fxload/COPYING new file mode 100644 index 0000000..60549be --- /dev/null +++ b/fxload/COPYING @@ -0,0 +1,340 @@ + 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) 19yy + + 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) 19yy 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/fxload/README.txt b/fxload/README.txt new file mode 100644 index 0000000..01aba69 --- /dev/null +++ b/fxload/README.txt @@ -0,0 +1,35 @@ + +FXLOAD UTILITY + +This program is conveniently able to download firmware into FX, FX2, +and FX2LP EZ-USB devices, as well as the original AnchorChips EZ-USB. +It is intended to be invoked by hotplug scripts when the unprogrammed +device appears on the bus. + +Primarily as an aid for developers, this can also be used to update +firmware on devices which boot from I2C serial EEPROMs. For that +use, as well as downloading firmware to all other off-chip memory, +a second stage loader must first be downloaded. + +The distribution includes "a3load.hex", which is a simple second stage +loader that works with all the EZ-USB products listed above. If you +want to write to an EEPROM, you can use the appropriate version of the +"Vend_Ax" code provided with the Cypress developer kit. + + +UPDATES + +See the download page at http://linux-hotplug.sourceforge.net for the +latest release. The CVS repository there holds the most current version +of this software. The web site shows some ways to use "fxload" in +conjunction with USB hotplugging, to load device firmware. + +Post any bug reports to the linux-hotplug-devel or linux-usb-devel lists. + +If you modify the code, the GPL requires that you make your updates +generally available (under most circumstances). Providing them in the +form of patches against the current CVS ("cvs diff -u"), or the last +release ("diff -u old new") is most useful, since otherwise it's awkward +to integrate such changes into the standard distribution. + +$Id: README.txt,v 1.5 2008/10/13 21:23:23 dbrownell Exp $ diff --git a/fxload/a3load.hex b/fxload/a3load.hex new file mode 100644 index 0000000..90f3a52 --- /dev/null +++ b/fxload/a3load.hex @@ -0,0 +1,95 @@ +# +# $Id: a3load.hex,v 1.1 2002/04/12 00:23:28 dbrownell Exp $ +# +# This file contains "a3load" object code, as found in the Cypress +# EZ-USB developer kit. It implements a second stage firmware loader +# supporting the original EZ-USB parts and the newer FX and FX2 ones, +# using the 0xA3 vendor request convention. +# +# If you want a loader for development use, which can write to the I2C +# boot EEPROM using the 0xA2 request, see the "Vend_Ax" code provided +# with the developer kit for your microcontroller. +# +# +# Copyright (c) 2001-2002 by Cypress Semiconductor Corporation +# +# Cypress Semiconductor Corporation hereby grants a copyright license to +# use or redistribute this firmware image, in text or binary form as +# required, only in conjunction with devices using a Cypress USB +# microcontroller. Every copy in any form of the firmware shall include +# Cypress copyright legends. +# +# DISCLAIMERS. +# THIS FIRMWARE IS LICENSED "AS-IS." CYPRESS MAKES NO WARRANTIES AS TO +# PERFORMANCE, WHETHER EXPRESS, IMPLIED, OR STATUTORY, IN THIS LICENSE +# OR COMMUNICATION BETWEEN LICENSEE AND CYPRESS. CYPRESS SPECIFICALLY +# DISCLAIMS ALL WARRANTIES, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING +# BUT NOT LIMITED TO THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS +# OF THIS PROGRAM FOR A PARTICULAR PURPOSE, WITH RESPECT TO THE +# FIRMWARE, AND THE USE, OPERATION OR SUPPORT OF THE FIRMWARE. +# IN NO EVENT SHALL CYPRESS BE LIABLE FOR ANY CONSEQUENTIAL, INDIRECT, +# INCIDENTAL, PUNITIVE, OR SPECIAL DAMAGES WHATSOEVER, INCLUDING WITHOUT +# LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS +# INTERRUPTION, LOSS OF BUSINESS INFORMATION, AND THE LIKE, ARISING OUT +# OF OR RELATED TO THE FIRMWARE, EVEN IF CYPRESS HAS BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGES. +# +:1003570090E668E0FF74FFF0E0B40B04EFF0D322FF +:0603670090E668EFF0C310 +:01036D00226D +:1001B500907FE9E064A360030202C5A3E07508002F +:1001C500F509A3E0FEE4EE4208907FEEE0750A0033 +:1001D500F50BA3E0FEE4EE420A907FE8E064407090 +:1001E50064E50B450A70030202D6E4907FC5F090E2 +:1001F5007FB4E020E3F9907FC5E0750C00F50DE4D0 +:10020500FCFDC3ED950DEC950C501F74C02DF582CA +:10021500E4347EF583E0FFE5092DF582E5083CF53C +:1002250083EFF00DBD00010C80D8E50D2509F5091A +:10023500E50C3508F508C3E50B950DF50BE50A95B5 +:100245000CF50A809C907FE8E064C060030202D64A +:10025500E50B450A607BC3E50B9440E50A94005025 +:1002650008850A0C850B0D8006750C00750D40E49C +:10027500FCFDC3ED950DEC950C501FE5092DF582A0 +:10028500E5083CF583E0FF74002DF582E4347FF545 +:1002950083EFF00DBD00010C80D8907FB5E50DF022 +:1002A5002509F509E50C3508F508C3E50B950DF5A8 +:1002B5000BE50A950CF50A907FB4E030E29280F7E1 +:1002C500907FE9E0B4AC0AE4907F00F0907FB5043C +:0802D500F0907FB4E04402F058 +:0102DD0022FE +:1000800090E6B9E064A36003020198A3E07508005C +:10009000F509A3E0FEE4EE420890E6BEE0750A0032 +:1000A000F50BA3E0FEE4EE420A90E6B8E06440708F +:1000B00066E50B450A70030201ADE490E68AF0A301 +:1000C000F090E6A0E020E1F990E68BE0750C00F5F9 +:1000D0000DE4FCFDC3ED950DEC950C501F74402D07 +:1000E000F582E434E7F583E0FFE5092DF582E508C4 +:1000F0003CF583EFF00DBD00010C80D8E50D25091E +:10010000F509E50C3508F508C3E50B950DF50BE58C +:100110000A950CF50A809A90E6B8E064C060030284 +:1001200001ADE50B450A70030201ADC3E50B944038 +:10013000E50A94005008850A0C850B0D8006750CA5 +:1001400000750D40E4FCFDC3ED950DEC950C501FC2 +:10015000E5092DF582E5083CF583E0FF74402DF5B7 +:1001600082E434E7F583EFF00DBD00010C80D8E4A4 +:1001700090E68AF0A3E50DF02509F509E50C3508B0 +:10018000F508C3E50B950DF50BE50A950CF50A90FE +:10019000E6A0E030E18C80F790E6B9E0B4AC0E90D8 +:1001A000E7407401F0E490E68AF0A304F090E6A042 +:0401B000E04480F0B7 +:0101B4002228 +:1002DE00C2011203579200907F95E044C0F0D2E81D +:1002EE0030000890E6687408F08007907FAFE04415 +:1002FE0001F030000890E65C7401F08006907FAE4D +:10030E007401F0D2AF3001FD300005120080800381 +:07031E001201B5C20180EEDF +:03000300020325D0 +:10032500C0E0C083C082C085C084C086758600D207 +:10033500015391EF30000890E65D7401F08006905E +:100345007FAB7401F0D086D084D085D082D083D0A5 +:02035500E03294 +:03004300020400B4 +:0404000002032500CE +:0300000002036E8A +:0C036E00787FE4F6D8FD7581200202DEE5 +:00000001FF diff --git a/fxload/debian/changelog b/fxload/debian/changelog new file mode 100644 index 0000000..f5f7ad6 --- /dev/null +++ b/fxload/debian/changelog @@ -0,0 +1,5 @@ +fxload (1.0) bionic; urgency=medium + + * FX3 release. + + -- Jasem Mutlaq Thu, 07 Jul 2022 20:00:00 +0300 diff --git a/fxload/debian/compat b/fxload/debian/compat new file mode 100644 index 0000000..f599e28 --- /dev/null +++ b/fxload/debian/compat @@ -0,0 +1 @@ +10 diff --git a/fxload/debian/control b/fxload/debian/control new file mode 100644 index 0000000..f3005a7 --- /dev/null +++ b/fxload/debian/control @@ -0,0 +1,19 @@ +Source: fxload +Section: admin +Priority: optional +Maintainer: Ubuntu MOTU Developers +XSBC-Original-Maintainer: Jasem Mutlaq +Build-Depends: debhelper (>= 7), cdbs, cmake +Standards-Version: 3.8.4 + +Package: fxload +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Conflicts: hotplug-utils +Replaces: hotplug-utils +Provides: hotplug-utils +Enhances: hotplug +Description: Firmware download to EZ-USB devices + This program is conveniently able to download firmware into FX and FX2 + ez-usb devices. It is intended to be invoked by hotplug scripts when + the unprogrammed device appears on the bus. diff --git a/fxload/debian/copyright b/fxload/debian/copyright new file mode 100644 index 0000000..3ddbf6f --- /dev/null +++ b/fxload/debian/copyright @@ -0,0 +1,40 @@ +This package was debianized by Fumitoshi UKAI on +Tue, 30 Apr 2002 02:46:12 +0900. + +It was downloaded from http://linux-hotplug.sourceforge.net/ + +Upstream Authors: + Stephen Williams + David Brownell + Roger Williams + + Greg Kroah-Hartman + Matthew Dharm + Miles Lane + Randy Dunlap + +Copyright: + Copyright (c) 2001 Stephen Williams (steve@icarus.com) + Copyright (c) 2001-2002 David Brownell (dbrownell@users.sourceforge.net) + Copyright (c) 2008 Roger Williams (rawqux@users.sourceforge.net) + +License: GPL2+ + + This source code is free software; you can redistribute it + and/or modify it in source code form 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +On Debian systems, a copy of the GNU General Public License may be found in +/usr/share/common-licenses/GPL. + diff --git a/fxload/debian/rules b/fxload/debian/rules new file mode 100755 index 0000000..e236f91 --- /dev/null +++ b/fxload/debian/rules @@ -0,0 +1,6 @@ +#!/usr/bin/make -f + +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/class/cmake.mk + +DEB_DH_SHLIBDEPS_ARGS=-u--ignore-missing-info diff --git a/fxload/debian/source/format b/fxload/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/fxload/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/fxload/ezusb.c b/fxload/ezusb.c new file mode 100644 index 0000000..f58d37f --- /dev/null +++ b/fxload/ezusb.c @@ -0,0 +1,1039 @@ +/* + * Copyright (c) 2001 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2002 David Brownell (dbrownell@users.sourceforge.net) + * Copyright (c) 2008 Roger Williams (rawqux@users.sourceforge.net) + * Copyright (c) 2012 Steve Magnani (steve@digidescorp.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form 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 + */ +#ident "$Id: ezusb.c,v 1.12 2008/10/13 21:25:29 dbrownell Exp $" + +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include + +# include +# include +# include + +#ifndef _BSD_SOURCE +#define _BSD_SOURCE +#endif +#include + +# include "ezusb.h" + +extern void logerror(const char *format, ...) + __attribute__ ((format (printf, 1, 2))); + +/* + * This file contains functions for downloading firmware into Cypress + * EZ-USB microcontrollers. These chips use control endpoint 0 and vendor + * specific commands to support writing into the on-chip SRAM. They also + * support writing into the CPUCS register, which is how we reset the + * processor after loading firmware (including the reset vector). + * + * A second stage loader must be used when writing to off-chip memory, + * or when downloading firmare into the bootstrap I2C EEPROM which may + * be available in some hardware configurations. + * + * These Cypress devices are 8-bit 8051 based microcontrollers with + * special support for USB I/O. They come in several packages, and + * some can be set up with external memory when device costs allow. + * Note that the design was originally by AnchorChips, so you may find + * references to that vendor (which was later merged into Cypress). + * The Cypress FX parts are largely compatible with the Anchorhip ones. + */ + +int verbose; + +/* + * return true iff [addr,addr+len) includes external RAM + * for Anchorchips EZ-USB or Cypress EZ-USB FX + */ +static int fx_is_external (unsigned int addr, size_t len) +{ + /* with 8KB RAM, 0x0000-0x1b3f can be written + * we can't tell if it's a 4KB device here + */ + if (addr <= 0x1b3f) + return ((addr + len) > 0x1b40); + + /* there may be more RAM; unclear if we can write it. + * some bulk buffers may be unused, 0x1b3f-0x1f3f + * firmware can set ISODISAB for 2KB at 0x2000-0x27ff + */ + return 1; +} + +/* + * return true iff [addr,addr+len) includes external RAM + * for Cypress EZ-USB FX2 + */ +static int fx2_is_external (unsigned int addr, size_t len) +{ + /* 1st 8KB for data/code, 0x0000-0x1fff */ + if (addr <= 0x1fff) + return ((addr + len) > 0x2000); + + /* and 512 for data, 0xe000-0xe1ff */ + else if (addr >= 0xe000 && addr <= 0xe1ff) + return ((addr + len) > 0xe200); + + /* otherwise, it's certainly external */ + else + return 1; +} + +/* + * return true iff [addr,addr+len) includes external RAM + * for Cypress EZ-USB FX2LP + */ +static int fx2lp_is_external (unsigned int addr, size_t len) +{ + /* 1st 16KB for data/code, 0x0000-0x3fff */ + if (addr <= 0x3fff) + return ((addr + len) > 0x4000); + + /* and 512 for data, 0xe000-0xe1ff */ + else if (addr >= 0xe000 && addr <= 0xe1ff) + return ((addr + len) > 0xe200); + + /* otherwise, it's certainly external */ + else + return 1; +} + +/*****************************************************************************/ +/* + * Read num_bytes from fd into buf. + * Report any errors. + */ +int read_fd(int fd, void *buf, size_t num_bytes) +{ + ssize_t bytes_read = read(fd, buf, num_bytes); + + if (bytes_read != num_bytes) { + if (bytes_read < 0) + logerror("Error reading file: %s\n", strerror(errno)); + else + logerror("Truncated file\n"); + } + + return (bytes_read == num_bytes); +} + +/*****************************************************************************/ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,3) +/* + * in 2.5, "struct usbdevfs_ctrltransfer" fields were renamed + * to match the USB spec + */ +# define bRequestType requesttype +# define bRequest request +# define wValue value +# define wIndex index +# define wLength length +#endif + +/* + * Issue a control request to the specified device. + * This is O/S specific ... + */ +static inline int ctrl_msg ( + int device, + unsigned char requestType, + unsigned char request, + unsigned short value, + unsigned short index, + unsigned char *data, + size_t length +) { + struct usbdevfs_ctrltransfer ctrl; + + if (length > USHRT_MAX) { + logerror("length too big\n"); + return -EINVAL; + } + + /* 8 bytes SETUP */ + ctrl.bRequestType = requestType; + ctrl.bRequest = request; + ctrl.wValue = value; + ctrl.wLength = (unsigned short) length; + ctrl.wIndex = index; + + /* "length" bytes DATA */ + ctrl.data = data; + + ctrl.timeout = 10000; + + return ioctl (device, USBDEVFS_CONTROL, &ctrl); +} + + +/* + * These are the requests (bRequest) that the bootstrap loader is expected + * to recognize. The codes are reserved by Cypress, and these values match + * what EZ-USB hardware, or "Vend_Ax" firmware (2nd stage loader) uses. + * Cypress' "a3load" is nice because it supports both FX and FX2, although + * it doesn't have the EEPROM support (subset of "Vend_Ax"). + */ +#define RW_INTERNAL 0xA0 /* hardware implements this one */ +#define RW_EEPROM 0xA2 +#define RW_MEMORY 0xA3 +#define GET_EEPROM_SIZE 0xA5 + + +/* + * Issues the specified vendor-specific read request. + */ +static int ezusb_read ( + int device, + char *label, + unsigned char opcode, + unsigned short addr, + unsigned char *data, + size_t len +) { + int status; + + if (verbose) + logerror("%s, addr 0x%04x len %4zd (0x%04zx)\n", label, addr, len, len); + status = ctrl_msg (device, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, opcode, + addr, 0, + data, len); + if (status != len) { + if (status < 0) + logerror("%s: %s\n", label, strerror(errno)); + else + logerror("%s ==> %d\n", label, status); + } + return status; +} + +/* + * Issues the specified vendor-specific write request. + */ +static int ezusb_write ( + int device, + char *label, + unsigned char opcode, + unsigned int addr, + const unsigned char *data, + size_t len +) { + int status; + + if (verbose) + logerror("%s, addr 0x%05x len %4zd (0x%04zx)\n", label, addr, len, len); + status = ctrl_msg (device, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, opcode, + addr & 0xFFFF, addr >> 16, + (unsigned char *) data, len); + if (status != len) { + if (status < 0) + logerror("%s: %s\n", label, strerror(errno)); + else + logerror("%s ==> %d\n", label, status); + } + return status; +} + +/* + * Modifies the CPUCS register to stop or reset the CPU. + * Returns false on error. + */ +static int ezusb_cpucs ( + int device, + unsigned short addr, + int doRun +) { + int status; + unsigned char data = doRun ? 0 : 1; + + if (verbose) + logerror("%s\n", data ? "stop CPU" : "reset CPU"); + status = ctrl_msg (device, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + RW_INTERNAL, + addr, 0, + &data, 1); + if (status != 1) { + char *mesg = "can't modify CPUCS"; + if (status < 0) + logerror("%s: %s\n", mesg, strerror(errno)); + else + logerror("%s\n", mesg); + return 0; + } else + return 1; +} + +/* + * Returns the size of the EEPROM (assuming one is present). + * *data == 0 means it uses 8 bit addresses (or there is no EEPROM), + * *data == 1 means it uses 16 bit addresses + */ +static inline int ezusb_get_eeprom_type (int fd, unsigned char *data) +{ + return ezusb_read (fd, "get EEPROM size", GET_EEPROM_SIZE, 0, data, 1); +} + +/*****************************************************************************/ + +/* + * Parse an Intel HEX image file and invoke the poke() function on the + * various segments to implement policies such as writing to RAM (with + * a one or two stage loader setup, depending on the firmware) or to + * EEPROM (two stages required). + * + * image - the hex image file + * context - for use by poke() + * is_external - if non-null, used to check which segments go into + * external memory (writable only by software loader) + * poke - called with each memory segment; errors indicated + * by returning negative values. + * + * Caller is responsible for halting CPU as needed, such as when + * overwriting a second stage loader. + */ +int parse_ihex ( + FILE *image, + void *context, + int (*is_external)(unsigned int addr, size_t len), + int (*poke) (void *context, unsigned int addr, int external, + const unsigned char *data, size_t len) +) +{ + unsigned char data [1023]; + unsigned short data_addr = 0; + size_t data_len = 0; + int rc; + int first_line = 1; + int external = 0; + + /* Read the input file as an IHEX file, and report the memory segments + * as we go. Each line holds a max of 16 bytes, but downloading is + * faster (and EEPROM space smaller) if we merge those lines into larger + * chunks. Most hex files keep memory segments together, which makes + * such merging all but free. (But it may still be worth sorting the + * hex files to make up for undesirable behavior from tools.) + * + * Note that EEPROM segments max out at 1023 bytes; the download protocol + * allows segments of up to 64 KBytes (more than a loader could handle). + */ + for (;;) { + char buf [512], *cp; + char tmp, type; + size_t len; + unsigned idx, off; + + cp = fgets(buf, sizeof buf, image); + if (cp == 0) { + logerror("EOF without EOF record!\n"); + break; + } + + /* EXTENSION: "# comment-till-end-of-line", for copyrights etc */ + if (buf[0] == '#') + continue; + + if (buf[0] != ':') { + logerror("not an ihex record: %s", buf); + return -2; + } + + /* ignore any newline */ + cp = strchr (buf, '\n'); + if (cp) + *cp = 0; + + if (verbose >= 3) + logerror("** LINE: %s\n", buf); + + /* Read the length field (up to 16 bytes) */ + tmp = buf[3]; + buf[3] = 0; + len = strtoul(buf+1, 0, 16); + buf[3] = tmp; + + /* Read the target offset (address up to 64KB) */ + tmp = buf[7]; + buf[7] = 0; + off = strtoul(buf+3, 0, 16); + buf[7] = tmp; + + /* Initialize data_addr */ + if (first_line) { + data_addr = off; + first_line = 0; + } + + /* Read the record type */ + tmp = buf[9]; + buf[9] = 0; + type = strtoul(buf+7, 0, 16); + buf[9] = tmp; + + /* If this is an EOF record, then make it so. */ + if (type == 1) { + if (verbose >= 2) + logerror("EOF on hexfile\n"); + break; + } + + if (type != 0) { + logerror("unsupported record type: %u\n", type); + return -3; + } + + if ((len * 2) + 11 > strlen(buf)) { + logerror("record too short?\n"); + return -4; + } + + // FIXME check for _physically_ contiguous not just virtually + // e.g. on FX2 0x1f00-0x2100 includes both on-chip and external + // memory so it's not really contiguous + + /* flush the saved data if it's not contiguous, + * or when we've buffered as much as we can. + */ + if (data_len != 0 + && (off != (data_addr + data_len) + // || !merge + || (data_len + len) > sizeof data)) { + if (is_external) + external = is_external (data_addr, data_len); + rc = poke (context, data_addr, external, data, data_len); + if (rc < 0) + return -1; + data_addr = off; + data_len = 0; + } + + /* append to saved data, flush later */ + for (idx = 0, cp = buf+9 ; idx < len ; idx += 1, cp += 2) { + tmp = cp[2]; + cp[2] = 0; + data [data_len + idx] = strtoul(cp, 0, 16); + cp[2] = tmp; + } + data_len += len; + } + + + /* flush any data remaining */ + if (data_len != 0) { + if (is_external) + external = is_external (data_addr, data_len); + rc = poke (context, data_addr, external, data, data_len); + if (rc < 0) + return -1; + } + return 0; +} + +/* + * Parse a FX3 '.img' file and invoke the poke() function on the + * various segments to implement policies such as writing to RAM (with + * a one or two stage loader setup, depending on the firmware) or to + * EEPROM (two stages required). + * + * img_fd - the image file + * context - for use by poke() + * poke - called with each memory segment; errors indicated + * by returning negative values. + * + * Caller is responsible for halting CPU as needed, such as when + * overwriting a second stage loader. + */ +int parse_img ( + int img_fd, + void *context, + int (*poke) (void *context, unsigned int addr, int external, + const unsigned char *data, size_t len) +) +{ + unsigned char header[4]; + unsigned char data[4096]; + int rc = -1; + + /* Validate the header */ + if (!read_fd(img_fd, header, sizeof(header))) + return -1; + + if ((header[0] != 'C') || (header[1] != 'Y')) { + logerror("Invalid file: missing CYpress signature\n"); + return -1; + } + + if (header[3] != 0xB0) { + logerror("Invalid file: format 0x%02X, expected 0xB0\n", header[3]); + return -1; + } + + /* Now process data segments */ + do { + uint32_t segment_addr, cur_addr; + uint32_t segment_len, bytes_remaining, bytes_this_chunk; + + rc = -1; /* In case of error */ + if (!read_fd(img_fd, &segment_len, sizeof(segment_len))) + break; + + if (!read_fd(img_fd, &segment_addr, sizeof(segment_addr))) + break; + + segment_len = le32toh(segment_len) << 2; + segment_addr = le32toh(segment_addr); + + cur_addr = segment_addr; + bytes_remaining = segment_len; + + /* Make sure we poke() if segment_len == 0, + * as FX3 interprets this as a "run from address" command + */ + + do { + bytes_this_chunk = bytes_remaining; + if (bytes_this_chunk > sizeof(data)) + bytes_this_chunk = sizeof(data); + + if (bytes_this_chunk && !read_fd(img_fd, data, bytes_this_chunk)) { + rc = -1; + break; + } + + rc = poke (context, cur_addr, 0, data, bytes_this_chunk); + + cur_addr += bytes_this_chunk; + bytes_remaining -= bytes_this_chunk; + } while ((rc == 0) && (bytes_remaining > 0)); + + if (segment_len == 0) + break; + + } while (rc == 0); + + return rc; +} + +/*****************************************************************************/ + +/* + * For writing to RAM using a first (hardware) or second (software) + * stage loader and 0xA0 or 0xA3 vendor requests + */ +typedef enum { + _undef = 0, + internal_only, /* hardware first-stage loader */ + skip_internal, /* first phase, second-stage loader */ + skip_external /* second phase, second-stage loader */ +} ram_mode; + +struct ram_poke_context { + int device; + ram_mode mode; + unsigned total, count; +}; + +# define RETRY_LIMIT 5 + +static int ram_poke ( + void *context, + unsigned int addr, + int external, + const unsigned char *data, + size_t len +) { + struct ram_poke_context *ctx = context; + int rc; + unsigned retry = 0; + + switch (ctx->mode) { + case internal_only: /* CPU should be stopped */ + if (external) { + logerror("can't write %zd bytes external memory at 0x%05x\n", + len, addr); + return -EINVAL; + } + break; + case skip_internal: /* CPU must be running */ + if (!external) { + if (verbose >= 2) { + logerror("SKIP on-chip RAM, %zd bytes at 0x%05x\n", + len, addr); + } + return 0; + } + break; + case skip_external: /* CPU should be stopped */ + if (external) { + if (verbose >= 2) { + logerror("SKIP external RAM, %zd bytes at 0x%05x\n", + len, addr); + } + return 0; + } + break; + default: + logerror("bug\n"); + return -EDOM; + } + + ctx->total += len; + ctx->count++; + + /* Retry this till we get a real error. Control messages are not + * NAKed (just dropped) so time out means is a real problem. + */ + while ((rc = ezusb_write (ctx->device, + external ? "write external" : "write on-chip", + external ? RW_MEMORY : RW_INTERNAL, + addr, data, len)) < 0 + && retry < RETRY_LIMIT) { + if (errno != ETIMEDOUT) + break; + retry += 1; + } + return (rc < 0) ? -errno : 0; +} + +/* + * Load a FX3 'img' file into target RAM. The dev_fd is the open "usbfs" + * device, and the path is the name of the source file. Open the file, + * parse the bytes, and write them in one or two phases. + * + * This uses the first stage loader, built into FX3 hardware but limited + * to writing on-chip memory. Everything is written during one stage. + */ +static int fx3_load_ram (int dev_fd, const char *path, int stage) +{ + int image_fd; + struct ram_poke_context ctx; + int status; + + if (stage != 0) { + logerror("Two-stage load not yet supported for FX3\n"); + return -1; + } + + image_fd = open(path, O_RDONLY); + if (image_fd < 0) { + logerror("%s: unable to open for input.\n", path); + return -2; + } else if (verbose) + logerror("open RAM image %s\n", path); + + ctx.device = dev_fd; + ctx.total = 0; + ctx.count = 0; + ctx.mode = internal_only; + + status = parse_img(image_fd, &ctx, ram_poke); + if (status < 0) { + logerror("unable to download %s\n", path); + return status; + } + + if (verbose) { + logerror("... WROTE: %d bytes, %d segments, avg %d\n", + ctx.total, ctx.count, ctx.total / ctx.count); + } + + return 0; +} + +/* + * Load an Intel HEX file into target RAM. The fd is the open "usbfs" + * device, and the path is the name of the source file. Open the file, + * parse the bytes, and write them in one or two phases. + * + * If stage == 0, this uses the first stage loader, built into EZ-USB + * hardware but limited to writing on-chip memory or CPUCS. Everything + * is written during one stage, unless there's an error such as the image + * holding data that needs to be written to external memory. + * + * Otherwise, things are written in two stages. First the external + * memory is written, expecting a second stage loader to have already + * been loaded. Then file is re-parsed and on-chip memory is written. + */ +int ezusb_load_ram (int fd, const char *path, const char *type, int stage) +{ + FILE *image; + unsigned short cpucs_addr; + int (*is_external)(unsigned int off, size_t len); + struct ram_poke_context ctx; + int status; + + /* FX3 loading differs significantly from that of previous devices */ + if (strcmp(type, "fx3") == 0) + return fx3_load_ram (fd, path, stage); + + + image = fopen (path, "r"); + if (image == 0) { + logerror("%s: unable to open for input.\n", path); + return -2; + } else if (verbose) + logerror("open RAM hexfile image %s\n", path); + + /* EZ-USB original/FX and FX2 devices differ, apart from the 8051 core */ + if (strcmp(type, "fx2lp") == 0) { + cpucs_addr = 0xe600; + is_external = fx2lp_is_external; + } else if (strcmp(type, "fx2") == 0) { + cpucs_addr = 0xe600; + is_external = fx2_is_external; + } else { + cpucs_addr = 0x7f92; + is_external = fx_is_external; + } + + /* use only first stage loader? */ + if (!stage) { + ctx.mode = internal_only; + + /* don't let CPU run while we overwrite its code/data */ + if (!ezusb_cpucs (fd, cpucs_addr, 0)) + return -1; + + /* 2nd stage, first part? loader was already downloaded */ + } else { + ctx.mode = skip_internal; + + /* let CPU run; overwrite the 2nd stage loader later */ + if (verbose) + logerror("2nd stage: write external memory\n"); + } + + /* scan the image, first (maybe only) time */ + ctx.device = fd; + ctx.total = ctx.count = 0; + status = parse_ihex (image, &ctx, is_external, ram_poke); + if (status < 0) { + logerror("unable to download %s\n", path); + return status; + } + + /* second part of 2nd stage: rescan */ + if (stage) { + ctx.mode = skip_external; + + /* don't let CPU run while we overwrite the 1st stage loader */ + if (!ezusb_cpucs (fd, cpucs_addr, 0)) + return -1; + + /* at least write the interrupt vectors (at 0x0000) for reset! */ + rewind (image); + if (verbose) + logerror("2nd stage: write on-chip memory\n"); + status = parse_ihex (image, &ctx, is_external, ram_poke); + if (status < 0) { + logerror("unable to completely download %s\n", path); + return status; + } + } + + if (verbose) + logerror("... WROTE: %d bytes, %d segments, avg %d\n", + ctx.total, ctx.count, ctx.total / ctx.count); + + /* now reset the CPU so it runs what we just downloaded */ + if (!ezusb_cpucs (fd, cpucs_addr, 1)) + return -1; + + return 0; +} + +/*****************************************************************************/ + +/* + * For writing to EEPROM using a 2nd stage loader + */ +struct eeprom_poke_context { + int device; + unsigned short ee_addr; /* next free address */ + int last; +}; + +static int eeprom_poke ( + void *context, + unsigned int addr, + int external, + const unsigned char *data, + size_t len +) { + struct eeprom_poke_context *ctx = context; + int rc; + unsigned char header [4]; + + if (external) { + logerror( + "EEPROM can't init %zd bytes external memory at 0x%05x\n", + len, addr); + return -EINVAL; + } + + if (len > 1023) { + logerror("not fragmenting %zd bytes\n", len); + return -EDOM; + } + + /* NOTE: No retries here. They don't seem to be needed; + * could be added if that changes. + */ + + /* write header */ + header [0] = len >> 8; + header [1] = len; + header [2] = addr >> 8; + header [3] = addr; + if (ctx->last) + header [0] |= 0x80; + if ((rc = ezusb_write (ctx->device, "write EEPROM segment header", + RW_EEPROM, + ctx->ee_addr, header, 4)) < 0) + return rc; + + /* write code/data */ + if ((rc = ezusb_write (ctx->device, "write EEPROM segment", + RW_EEPROM, + ctx->ee_addr + 4, data, len)) < 0) + return rc; + + /* next shouldn't overwrite it */ + ctx->ee_addr += 4 + len; + + return 0; +} + +/* + * Load an Intel HEX file into target (large) EEPROM, set up to boot from + * that EEPROM using the specified microcontroller-specific config byte. + * (Defaults: FX2 0x08, FX 0x00, AN21xx n/a) + * + * Caller must have pre-loaded a second stage loader that knows how + * to handle the EEPROM write requests. + */ +int ezusb_load_eeprom (int dev, const char *path, const char *type, int config) +{ + FILE *image; + unsigned short cpucs_addr; + int (*is_external)(unsigned int off, size_t len); + struct eeprom_poke_context ctx; + int status; + unsigned char value, first_byte; + + if (strcmp ("fx3", type) == 0) { + logerror("FX3 EEPROM loading is not yet supported.\n"); + return -1; + } + + if (ezusb_get_eeprom_type (dev, &value) != 1 || value != 1) { + logerror("don't see a large enough EEPROM\n"); + return -1; + } + + image = fopen (path, "r"); + if (image == 0) { + logerror("%s: unable to open for input.\n", path); + return -2; + } else if (verbose) + logerror("open EEPROM hexfile image %s\n", path); + + if (verbose) + logerror("2nd stage: write boot EEPROM\n"); + + /* EZ-USB family devices differ, apart from the 8051 core */ + if (strcmp ("fx2", type) == 0) { + first_byte = 0xC2; + cpucs_addr = 0xe600; + is_external = fx2_is_external; + ctx.ee_addr = 8; + config &= 0x4f; + logerror( + "FX2: config = 0x%02x, %sconnected, I2C = %d KHz\n", + config, + (config & 0x40) ? "dis" : "", + // NOTE: old chiprevs let CPU clock speed be set + // or cycle inverted here. You shouldn't use those. + // (Silicon revs B, C? Rev E is nice!) + (config & 0x01) ? 400 : 100 + ); + + } else if (strcmp ("fx2lp", type) == 0) { + first_byte = 0xC2; + cpucs_addr = 0xe600; + is_external = fx2lp_is_external; + ctx.ee_addr = 8; + config &= 0x4f; + logerror ( + "FX2LP: config = 0x%02x, %sconnected, I2C = %d KHz\n", + config, + (config & 0x40) ? "dis" : "", + (config & 0x01) ? 400 : 100 + ); + } else if (strcmp ("fx", type) == 0) { + first_byte = 0xB6; + cpucs_addr = 0x7f92; + is_external = fx_is_external; + ctx.ee_addr = 9; + config &= 0x07; + logerror( + "FX: config = 0x%02x, %d MHz%s, I2C = %d KHz\n", + config, + ((config & 0x04) ? 48 : 24), + (config & 0x02) ? " inverted" : "", + (config & 0x01) ? 400 : 100 + ); + + } else if (strcmp ("an21", type) == 0) { + first_byte = 0xB2; + cpucs_addr = 0x7f92; + is_external = fx_is_external; + ctx.ee_addr = 7; + config = 0; + logerror("AN21xx: no EEPROM config byte\n"); + + } else { + logerror("?? Unrecognized microcontroller type %s ??\n", type); + return -1; + } + + /* make sure the EEPROM won't be used for booting, + * in case of problems writing it + */ + value = 0x00; + status = ezusb_write (dev, "mark EEPROM as unbootable", + RW_EEPROM, 0, &value, sizeof value); + if (status < 0) + return status; + + /* scan the image, write to EEPROM */ + ctx.device = dev; + ctx.last = 0; + status = parse_ihex (image, &ctx, is_external, eeprom_poke); + if (status < 0) { + logerror("unable to write EEPROM %s\n", path); + return status; + } + + /* append a reset command */ + value = 0; + ctx.last = 1; + status = eeprom_poke (&ctx, cpucs_addr, 0, &value, sizeof value); + if (status < 0) { + logerror("unable to append reset to EEPROM %s\n", path); + return status; + } + + /* write the config byte for FX, FX2 */ + if (strcmp ("an21", type) != 0) { + value = config; + status = ezusb_write (dev, "write config byte", + RW_EEPROM, 7, &value, sizeof value); + if (status < 0) + return status; + } + + /* EZ-USB FX has a reserved byte */ + if (strcmp ("fx", type) == 0) { + value = 0; + status = ezusb_write (dev, "write reserved byte", + RW_EEPROM, 8, &value, sizeof value); + if (status < 0) + return status; + } + + /* make the EEPROM say to boot from this EEPROM */ + status = ezusb_write (dev, "write EEPROM type byte", + RW_EEPROM, 0, &first_byte, sizeof first_byte); + if (status < 0) + return status; + + /* Note: VID/PID/version aren't written. They should be + * written if the EEPROM type is modified (to B4 or C0). + */ + + return 0; +} + +/* + * $Log: ezusb.c,v $ + * Revision 1.12 2008/10/13 21:25:29 dbrownell + * Whitespace fixes. + * + * Revision 1.11 2008/10/13 21:23:23 dbrownell + * From Roger Williams : FX2LP support + * + * Revision 1.10 2008/10/13 21:22:10 dbrownell + * Built against current kernel headers; remove various warnings. + * + * Revision 1.9 2005/01/11 03:58:02 dbrownell + * From Dirk Jagdmann : optionally output messages to + * syslog instead of stderr. + * + * Revision 1.8 2005/01/11 03:08:12 dbrownell + * Patch from Giovanni Mels, so the string is always null terminated + * rather than only with "verbose >= 3" ... and the length test is + * changed accordingly. + * + * Revision 1.7 2002/04/12 00:25:58 dbrownell + * - support older AnchorChips style EEPROMs too + * - minor bugfix for config byte mask in FX + * + * Revision 1.6 2002/04/02 08:34:16 dbrownell + * minor stuff: + * - don't assume last segment in file is always internal + * - tweak diagnostics for easier matchup to 8051 linker maps + * - minor comment/format updates + * + * Revision 1.5 2002/02/26 20:06:31 dbrownell + * - Rewrite for 2nd stage loader support, so this can write + * to external RAM and (given the right loader) EEPROM. + * - Handle usbfs API changes in Linux kernel 2.5. + * - A "more verbose" option. + * + * Revision 1.4 2002/01/17 14:47:44 dbrownell + * init first line, remove warnings + * + * Revision 1.3 2001/12/27 17:59:33 dbrownell + * merge adjacent hex records, and optionally show writes + * + * Revision 1.2 2001/12/14 11:24:04 dbrownell + * Add sanity check: reject requests to load off-chip memory, + * The EZ-USB devices just fail silently in these cases. + * + * Revision 1.1 2001/06/12 00:00:50 stevewilliams + * Added the fxload program. + * Rework root makefile and hotplug.spec to install in prefix + * location without need of spec file for install. + * + */ + diff --git a/fxload/ezusb.h b/fxload/ezusb.h new file mode 100644 index 0000000..89f7e0d --- /dev/null +++ b/fxload/ezusb.h @@ -0,0 +1,80 @@ +#ifndef __ezusb_H +#define __ezusb_H +/* + * Copyright (c) 2001 Stephen Williams (steve@icarus.com) + * Copyright (c) 2002 David Brownell (dbrownell@users.sourceforge.net) + * Copyright (c) 2012 Steve Magnani (steve@digidescorp.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form 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 + */ +#ident "$Id: ezusb.h,v 1.4 2008/10/13 21:25:29 dbrownell Exp $" + + +/* + * This function loads the firmware from the given file into RAM. + * The file is assumed to be in Intel HEX format unless type is fx3. + * If type is fx2 or fx2lp, appropriate reset commands are used. + * Stage == 0 means this is a single stage load (or the first of two stages). + * Otherwise it's the second of two stages; the caller preloaded the second + * stage loader. + * + * The target processor is reset at the end of this download. + */ +extern int ezusb_load_ram (int dev, const char *path, const char *type, + int stage); + + +/* + * This function stores the firmware from the given file into EEPROM. + * The file is assumed to be in Intel HEX format. This uses the right + * CPUCS address to terminate the EEPROM load with a reset command, + * where FX parts behave differently than FX2 ones. The configuration + * byte is as provided here (zero for an21xx parts) and the EEPROM + * type is set so that the microcontroller will boot from it. + * + * The caller must have preloaded a second stage loader that knows + * how to respond to the EEPROM write request. + */ +extern int ezusb_load_eeprom ( + int dev, /* usbfs device handle */ + const char *path, /* path to hexfile */ + const char *type, /* fx, fx2, an21 */ + int config /* config byte for fx/fx2; else zero */ + ); + + +/* boolean flag, says whether to write extra messages to stderr */ +extern int verbose; + + +/* + * $Log: ezusb.h,v $ + * Revision 1.4 2008/10/13 21:25:29 dbrownell + * Whitespace fixes. + * + * Revision 1.3 2002/04/12 00:28:21 dbrownell + * support "-t an21" to program EEPROMs for those microcontrollers + * + * Revision 1.2 2002/02/26 19:55:05 dbrownell + * 2nd stage loader support + * + * Revision 1.1 2001/06/12 00:00:50 stevewilliams + * Added the fxload program. + * Rework root makefile and hotplug.spec to install in prefix + * location without need of spec file for install. + * + */ +#endif diff --git a/fxload/fxload b/fxload/fxload new file mode 100644 index 0000000..e0a41ba Binary files /dev/null and b/fxload/fxload differ diff --git a/fxload/fxload.8 b/fxload/fxload.8 new file mode 100644 index 0000000..a0abaf5 --- /dev/null +++ b/fxload/fxload.8 @@ -0,0 +1,249 @@ +.\" fxload.8 +.\" Created: Fri Dec 28 2001 by David Brownell +.\" Copyright (c) 2001-2002 David Brownell +.\" Copyright (c) 2008 Roger Williams +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of this +.\" manual under the conditions for verbatim copying, provided that the +.\" entire resulting derived work is distributed under the terms of a +.\" permission notice identical to this one +.\" +.\" Since the Linux kernel and libraries are constantly changing, this +.\" manual page may be incorrect or out-of-date. The author(s) assume no +.\" responsibility for errors or omissions, or for damages resulting from +.\" the use of the information contained herein. The author(s) may not +.\" have taken the same level of care in the production of this manual, +.\" which is licensed free of charge, as they might when working +.\" professionally. +.\" +.\" Formatted or processed versions of this manual, if unaccompanied by +.\" the source, must acknowledge the copyright and authors of this work. +.\" +.TH FXLOAD 8 "April 2012" "" "Linux Programmer's Manual" +.SH "NAME" +fxload \- Firmware download to EZ-USB devices +.SH "SYNOPSIS" +.B fxload +.BI "[ \-v ]" +.BI "[ \-l ]" +.BI "[ \-D " devpath " ]" +.BI "[ \-I " firmware " ]" +.BI "[ \-t " type " ]" +.BI "[ \-c " config " ]" +.BI "[ \-s " loader " ]" +.br +.B fxload +.BI "[ \-D " devpath " ]" +.BI "[ \-L " link " ]" +.BI "[ \-m " mode " ]" +.br +.B fxload +.BI "[ \-V ]" +.SH "DESCRIPTION" +.B fxload +is a program which downloads firmware to USB devices based on +AnchorChips EZ-USB, Cypress EZ-USB FX, +or Cypress EZ-USB FX2/FX2LP/FX3 microcontrollers. +These have 8-bit 8051 cores with special extensions for USB I/O. +The FX2 supports high speed USB 2.0 transfers (480 Mbit/sec) +as well as full speed USB 1.1 transfers (12 Mbit/sec), +while the earlier parts support only full speed transfers. +The FX3 supports super speed USB 3.0 transfers and has a 32-bit +ARM core. +These controllers have several package options, +and can be set up with external memory (on-chip memory is +usually 8K or 16K; for FX3, it is 512K), EEPROMs, and ROMs when +device costs allow. +.PP +This uses "usbfs" (older name: "usbdevfs") to access +devices, and issues vendor specific control requests +to download and reset the EZ-USB devices. +Normally, firmware will then "renumerate" by disconnecting from +USB and then reconnecting as a new device. +It then appears with new device descriptors and functionality, +as provided by the firmware which has been downloaded. +.PP +To support some non-firmware applications, this can also set +up symbolic links for those usbfs names. +It can also change their access modes. +Both of these can help simplify software applications that +need to talk to USB devices using user mode drivers, +don't want to run with privileges or to examine all of the +existing USB devices, +and which don't need more kernel drivers. +.PP +See the +.I Linux-Hotplug +web site for information about how to use +.B fxload +to download device firmware when hotplugging USB devices, +using driver-specific scripts stored in the +.I /etc/hotplug/usb +directory. +.SH "FUNCTION LETTERS" +At least one of the following options must be specified. +Note that as usual with UNIX and Linux commands, +the order of command option flags does not matter. +You may use these in any order. +.TP +.BI "\-I " firmware +Downloads the specified firmware file. +For FX3 devices, the format is a Cypress-specific binary image. +For other devices, the file has standard Intel hexfile format. +(Common naming conventions include +.I *.hex +, +.I *.ihx +, and +.IR *.img ). +Depending on the device and firmware in use, the +.B \-s +option may also be necessary to specify a second stage loader. +Firmware is normally downloaded to RAM and executed, but there +is also an option for downloading into bootable I2C EEPROMs. +.TP +.BI "\-L " link +Creates the specified symbolic link to the usbfs device path. +This would typically be used to create a name in a directory +that would be searched by an application. +The symlink would be removed by some other component on device unplug. +.TP +.BI "\-m " mode +Changes permissions on the "usbfs" device node. +By default, those nodes are only accessible by privileged +users, which doesn't help when the user mode device driver +needs to run without root privileges. +Note that usbfs mount options like +.I devmode=0666 +are also available. +.TP +.B "\-V" +Identifies the version of fxload being invoked, and exits +without performing other actions. +.PP +Note that when downloading firmware that renumerates, +there's no point in changing the device permissions +or creating a symbolic link. +.SH "OPTIONS" +By default, +.B fxload +assumes the device uses an EZ-USB or EZ-USB FX. +It also assumes that the device in question has been specified +by USB kernel hotplugging conventions, using the +.I DEVICE +environment variable to name a "usbfs" +file that can be used to talk to the device. +.TP +.BI "\-c " config +Indicates the specified firmware should be downloaded to an +I2C boot EEPROM rather than to RAM. +The parameter is the EZ-USB FX or FX2 configuration byte, +and for AnchorChips devices the value should be zero. +This requires a second stage loader (e.g. vend_ax.hex) that knows +how to write to I2C EEPROMs specified using the +.B \-s +option, as well as a device that's provided with an EEPROM +large enough to store the boot firmware. +After downloading to a device's EEPROM, +you should retest it starting from power off. +.TP +.BI "\-s " loader +This identifies the file holding a second stage loader +(in the same file format as the firmware itself), +which is loaded into internal memory. +This loader understands additional vendor control requests, +beyond the one built into all EZ-USB hardware, +which are needed to write external RAM or EEPROM. +As a last step when loading firmware, +.B fxload +normally overwrites this second stage loader +with parts of the firmware residing on-chip. +.TP +.BI "\-t " type +Indicates which type of microcontroller is used in the device; +type may be one of +.I an21 +(the original AnchorChips devices), +.I fx +(Cypress' updated version, the EZ-USB FX), +.I fx2 +(the Cypress EZ-USB FX2, supporting high speed transfers), +.I fx2lp +(the Cypress EZ-USB FX2LP, with 16KB internal RAM), or +.I fx3 +(the Cypress EZ-USB FX3, supporting USB 3.0). +Except when writing to EEPROM, all that normally matters when +downloading firmware is whether or not the device uses an FX2 +or FX3. +.TP +.B "\-v" +Prints some diagnostics, such as download addresses and sizes, +to standard error. Repeat the flag +.RB ( -vv ", " -vvv ) +to get more diagnostics. +.TP +.B "\-l" +print error and verbose messages to syslog. +.TP +.BI "\-D " devpath +Specifies the "usbfs" path name for the device in question, +such as +.IR /proc/bus/usb/004/080 . +This takes precedence over any +.I DEVICE +environment variable that may be set. +.SH "NOTES" +.PP +This program implements one extension to the standard "hex file" format. +Lines beginning with a "#" character are ignored, and may be used to +hold copyright statements and other information. +Other tools may not handle hexfiles using this extension. +.PP +At this writing, "usbfs" is a kernel configuration option. +That means that device drivers relying on user mode firmware +downloading may need to depend on that kernel configuration option. +A less preferable alternative involves compiling the firmware +into the kernel and managing downloads and renumeration there. +This is less preferable in part because much device firmware is +provided with GPL-incompatible licensing, and in part because +storing such firmware firmware wastes kernel memory. +.PP +For EZ-USB family devices, the hardware's first stage loader +(supporting the 0xA0 vendor request) can't write into external memory. +Configurations that put firmware into external memory thus need a +second stage loader. +For typical "flat" memory architectures, a loader supporting the 0xA3 +vendor request is used to write into that memory. +Similarly, a second stage loader that supports the 0xA2 vendor request +is needed when writing boot firmware into an I2C EEPROM. +These 0xA2 and 0xA3 vendor commands are conventions defined by Cypress. +Devices that use bank switching or similar mechanisms to stretch the +64KByte address space may need different approaches to loading firmware. +.PP +Not all devices support EEPROM updates. +Some EZ-USB based devices don't have an I2C EEPROM; +many such EEPROMs are too small to store firmware; +and some firmware can't be placed in bootable I2C EEPROMs. +.SH "ENVIRONMENT VARIABLES" +.TP +.B DEVICE +normally names a "usbfs" file that will be used to talk to the device. +This is provided by the Linux kernel as part of USB hotplugging. +.SH "FILES" +.TP +.I /usr/share/usb/a3load.hex +Second stage loader that works with AnchorChips EZ-USB, +Cypress EZ-USB FX, and Cypress EZ-USB FX2. +Note that this only supports the 0xA3 vendor command, to +write external memory. +A loader that also supports the 0xA2 command, to write boot EEPROMs, +is included with Cypress developer kits. +.SH "SEE ALSO" +.BR hotplug "(8) " +.SH "AUTHORS" +Linux Hotplugging Project +.I http://linux-hotplug.sourceforge.net/ diff --git a/fxload/fxload.spec b/fxload/fxload.spec new file mode 100644 index 0000000..9a85759 --- /dev/null +++ b/fxload/fxload.spec @@ -0,0 +1,87 @@ +Summary: EZ-USB utility program +Name: fxload +Version: VERCODE +Release: 1 +Group: Applications/System +License: GPL +Url: http://linux-hotplug.sourceforge.net/ +Source0: %{name}-%{version}.tar.gz + +%description +This package contains utilities for downloading firmware to EZ-USB devices. +EZ-USB devices use 8051-based microcontrollers that have been enhanced with +registers, buffers, and other device-side support for USB transactions. + +It currently supports devices based on the Anchorchips EZ-USB, as well as the +Cypress EZ-USB FX (which is almost completely source compatible) and EZ-USB FX2 +(which is not). All of these support full speed (12 Mbit/sec) transfers. The +FX2 also supports high speed (480 Mbit/s) transfers, introduced in USB 2.0. + +This version of FXLOAD supports optional use of two-stage loading, where +special device firmware is used to support writing into off-chip memory such +as RAM (when firmware neeeds more than about 8 KBytes of code and data) or, +for firmware development, I2C serial EEPROM. + +%prep +%setup -q + +%build +# Build any compiled programs in the source tree. +make all CFLAGS="%optflags -DFXLOAD_VERSION=\\\"%version\\\"" + +%install +make prefix=%buildroot install + +# -- +# The utils package contains utility programs that certain devices +# might need along with the core hotplug in order to boot up the +# device in question. +%files +%defattr(-,root,root) +/sbin/fxload + + +%changelog +* Mon Apr 01 2002 David Brownell +- fixed/updated RPM build and Makefile +- Makefile automatically embeds version into specfile and binary +- fxload handles 2nd stage loader + +* Mon Jan 21 2002 David Brownell +- update fxload rpm description. also, manpage now installs. + +* Mon Jan 14 2002 Greg Kroah-Hartman +- split fxload specific stuff out of the base hotplug.spec file + to keep the hotplug core arch independant + +* Mon Jun 11 2001 Steve Williams +- The install process is now in the comon makefile, so that non- + rpm installs can work. This spec file thus invokes that install. + +* Fri Jun 8 2001 Steve Williams +- added the /var/run/usb directory to spec file + +* Tue Apr 24 2001 Greg Kroah-Hartman +- added the hotplug.8 manpage written by Fumitoshi UKAI + +* Fri Mar 2 2001 Greg Kroah-Hartman +- tweaked the post and preun sections to fix problem of hotplug + not starting automatically when the package is upgraded. + +* Wed Feb 28 2001 Greg Kroah-Hartman +- 2001_02_28 release + +* Wed Feb 14 2001 Greg Kroah-Hartman +- 2001_02_14 release + +* Wed Jan 17 2001 Greg Kroah-Hartman +- changed specfile based on Chmouel Boudjnah's comments. + +* Tue Jan 16 2001 Greg Kroah-Hartman +- tweaked the file locations due to the change in the tarball structure. +- 2001_01_16 release + +* Mon Jan 15 2001 Greg Kroah-Hartman +- First cut at a spec file for the hotplug scripts. +- added patch to usb.rc to allow chkconfig to install and remove it. + diff --git a/fxload/main.c b/fxload/main.c new file mode 100644 index 0000000..7ae3fe3 --- /dev/null +++ b/fxload/main.c @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2001 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2002 David Brownell (dbrownell@users.sourceforge.net) + * Copyright (c) 2008 Roger Williams (rawqux@users.sourceforge.net) + * Copyright (c) 2012 Steve Magnani (steve@digidescorp.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form 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 + */ +#ident "$Id: main.c,v 1.10 2008/10/13 21:25:29 dbrownell Exp $" + +/* + * This program supports loading firmware into a target USB device + * that is discovered and referenced by the hotplug usb agent. It can + * also do other useful things, like set the permissions of the device + * and create a symbolic link for the benefit of applications that are + * looking for the device. + * + * -I -- Download this firmware (intel hex) + * -t -- uController type: an21, fx, fx2, fx2lp, fx3 + * -s -- use this second stage loader + * -c -- Download to EEPROM, with this config byte + * + * -L -- Create a symbolic link to the device. + * -m -- Set the permissions on the device after download. + * -D -- Use this device, instead of $DEVICE + * + * -V -- Print version ID for program + * + * This program is intended to be started by hotplug scripts in + * response to a device appearing on the bus. It therefore also + * expects these environment variables which are passed by hotplug to + * its sub-scripts: + * + * DEVICE= + * This is the path to the device is /proc/bus/usb. It is the + * complete path to the device, that I can pass to open and + * manipulate as a USB device. + */ + +# include +# include +# include +# include + +# include +# include +# include +# include + +# include "ezusb.h" + +#ifndef FXLOAD_VERSION +# define FXLOAD_VERSION (__DATE__ " (development)") +#endif + +#include +#include +#include + + +static int dosyslog=0; + +void logerror(const char *format, ...) + __attribute__ ((format (__printf__, 1, 2))); + +void logerror(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + + if(dosyslog) + vsyslog(LOG_ERR, format, ap); + else + vfprintf(stderr, format, ap); + va_end(ap); +} + +int main(int argc, char*argv[]) +{ + const char *link_path = 0; + const char *ihex_path = 0; + const char *device_path = getenv("DEVICE"); + const char *type = 0; + const char *stage1 = 0; + mode_t mode = 0; + int opt; + int config = -1; + + while ((opt = getopt (argc, argv, "2vV?D:I:L:c:lm:s:t:")) != EOF) + switch (opt) { + + case '2': // original version of "-t fx2" + type = "fx2"; + break; + + case 'D': + device_path = optarg; + break; + + case 'I': + ihex_path = optarg; + break; + + case 'L': + link_path = optarg; + break; + + case 'V': + puts (FXLOAD_VERSION); + return 0; + + case 'c': + config = strtoul (optarg, 0, 0); + if (config < 0 || config > 255) { + logerror("illegal config byte: %s\n", optarg); + goto usage; + } + break; + + case 'l': + openlog(argv[0], LOG_CONS|LOG_NOWAIT|LOG_PERROR, LOG_USER); + dosyslog=1; + break; + + case 'm': + mode = strtoul(optarg,0,0); + mode &= 0777; + break; + + case 's': + stage1 = optarg; + break; + + case 't': + if (strcmp (optarg, "an21") // original AnchorChips parts + && strcmp (optarg, "fx") // updated Cypress versions + && strcmp (optarg, "fx2") // Cypress USB 2.0 versions + && strcmp (optarg, "fx2lp") // updated FX2 + && strcmp (optarg, "fx3") // Cypress USB 3.0 versions + ) { + logerror("illegal microcontroller type: %s\n", optarg); + goto usage; + } + type = optarg; + break; + + case 'v': + verbose++; + break; + + case '?': + default: + goto usage; + + } + + if (config >= 0) { + if (type == 0) { + logerror("must specify microcontroller type %s", + "to write EEPROM!\n"); + goto usage; + } + if (!stage1 || !ihex_path) { + logerror("need 2nd stage loader and firmware %s", + "to write EEPROM!\n"); + goto usage; + } + if (link_path || mode) { + logerror("links and modes not set up when writing EEPROM\n"); + goto usage; + } + } + + if (!device_path) { + logerror("no device specified!\n"); +usage: + fputs ("usage: ", stderr); + fputs (argv [0], stderr); + fputs (" [-vV] [-l] [-t type] [-D devpath]\n", stderr); + fputs ("\t\t[-I firmware_hexfile] ", stderr); + fputs ("[-s loader] [-c config_byte]\n", stderr); + fputs ("\t\t[-L link] [-m mode]\n", stderr); + fputs ("... [-D devpath] overrides DEVICE= in env\n", stderr); + fputs ("... device types: one of an21, fx, fx2, fx2lp, fx3\n", stderr); + fputs ("... at least one of -I, -L, -m is required\n", stderr); + return -1; + } + + if (ihex_path) { + int fd = open(device_path, O_RDWR); + int status; + + if (fd == -1) { + logerror("%s : %s\n", strerror(errno), device_path); + return -1; + } + + if (type == 0) { + type = "fx"; /* an21-compatible for most purposes */ + } + + if (verbose) + logerror("microcontroller type: %s\n", type); + + if (stage1) { + /* first stage: put loader into internal memory */ + if (verbose) + logerror("1st stage: load 2nd stage loader\n"); + status = ezusb_load_ram (fd, stage1, type, 0); + if (status != 0) + return status; + + /* second stage ... write either EEPROM, or RAM. */ + if (config >= 0) + status = ezusb_load_eeprom (fd, ihex_path, type, config); + else + status = ezusb_load_ram (fd, ihex_path, type, 1); + if (status != 0) + return status; + } else { + /* single stage, put into internal memory */ + if (verbose) + logerror("single stage: load on-chip memory\n"); + status = ezusb_load_ram (fd, ihex_path, type, 0); + if (status != 0) + return status; + } + + /* some firmware won't renumerate, but typically it will. + * link and chmod only make sense without renumeration... + */ + } + + if (link_path) { + int rc = unlink(link_path); + rc = symlink(device_path, link_path); + if (rc == -1) { + logerror("%s : %s\n", strerror(errno), link_path); + return -1; + } + } + + if (mode != 0) { + int rc = chmod(device_path, mode); + if (rc == -1) { + logerror("%s : %s\n", strerror(errno), link_path); + return -1; + } + } + + if (!ihex_path && !link_path && !mode) { + logerror("missing request! (firmware, link, or mode)\n"); + return -1; + } + + return 0; +} + + +/* + * $Log: main.c,v $ + * Revision 1.10 2008/10/13 21:25:29 dbrownell + * Whitespace fixes. + * + * Revision 1.9 2008/10/13 21:23:23 dbrownell + * From Roger Williams : FX2LP support + * + * Revision 1.8 2005/01/11 03:58:02 dbrownell + * From Dirk Jagdmann : optionally output messages to + * syslog instead of stderr. + * + * Revision 1.7 2002/04/12 00:28:22 dbrownell + * support "-t an21" to program EEPROMs for those microcontrollers + * + * Revision 1.6 2002/04/02 05:26:15 dbrownell + * version display now noiseless (-V); + * '-?' (usage info) convention now explicit + * + * Revision 1.5 2002/02/26 20:10:28 dbrownell + * - "-s loader" option for 2nd stage loader + * - "-c byte" option to write EEPROM with 2nd stage + * - "-V" option to dump version code + * + * Revision 1.4 2002/01/17 14:19:28 dbrownell + * fix warnings + * + * Revision 1.3 2001/12/27 17:54:04 dbrownell + * forgot an important character :) + * + * Revision 1.2 2001/12/27 17:43:29 dbrownell + * fail on firmware download errors; add "-v" flag + * + * Revision 1.1 2001/06/12 00:00:50 stevewilliams + * Added the fxload program. + * Rework root makefile and hotplug.spec to install in prefix + * location without need of spec file for install. + * + */