pax_global_header00006660000000000000000000000064133725563020014520gustar00rootroot0000000000000052 comment=44a26443600472c5ff121d5fe479e7675641d935 xc3sprog-0+svn795+dfsg/000077500000000000000000000000001337255630200147575ustar00rootroot00000000000000xc3sprog-0+svn795+dfsg/.gitignore000066400000000000000000000010451337255630200167470ustar00rootroot00000000000000*~ # / /*at90* /devlist /devlist.h /jedecparse /detectchain /bitparse /debug /xc3sprog /_impact* /a.out /build* /devices.h /cables.h /CMakeCache.txt /CMakeFiles /cmake_install.cmake /srecparse /Makefile CPackConfig.cmake CPackSourceConfig.cmake avrfuseparse javr/CMakeFiles/ javr/cmake_install.cmake libxc3sproglib.a packages/CMakeFiles/ packages/Makefile packages/cmake_install.cmake readdna xc2c_warp # /bscan_spi/ /bscan_spi/bscan_spi_isf_sp3adsp # /javr/ /javr/build /javr/build-win32 /javr/javr /javr/*.map /javr/*.exe /javr/*.o javr/Makefilexc3sprog-0+svn795+dfsg/CMakeLists.txt000066400000000000000000000141711337255630200175230ustar00rootroot00000000000000# Project project(xc3sprog) set(xc3sprog_VERSION_MAJOR 0) set(xc3sprog_VERSION_MINOR 0) SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}") set(CMAKE_CXX_FLAGS "-g -Wall") cmake_minimum_required(VERSION 2.6) find_package(PkgConfig REQUIRED) if(${WIN32}) set(USE_STATIC_FTDI ON) IF( ${CMAKE_COMPILER_IS_GNUCXX} ) # link libstdc++ and others statically add_definitions( -D__USE_MINGW_ANSI_STDIO ) SET (CMAKE_EXE_LINKER_FLAGS "-static-libstdc++ -static-libgcc") ENDIF( ${CMAKE_COMPILER_IS_GNUCXX} ) endif(${WIN32}) option(USE_FTD2XX "Use FTDI libFTD2XX instead of free libftdi" ON) pkg_check_modules(LIBFTDI REQUIRED libftdi1) include_directories(${LIBFTDI_INCLUDE_DIRS}) if(USE_FTD2XX) find_package(libFTD2XX) endif(USE_FTD2XX) if(LIBFTD2XX_FOUND) include_directories(${LIBFTD2XX_INCLUDE_DIR}) add_definitions( -DUSE_FTD2XX ) else(LIBFTD2XX_FOUND) set(LIBFTD2XX_LIBRARIES "") endif(LIBFTD2XX_FOUND) if(EXISTS ${PROJECT_SOURCE_DIR}/.git) set(VERSION_STRING "${xc3sprog_VERSION_MAJOR}.${xc3sprog_VERSION_MINOR}-git") else(EXISTS ${PROJECT_SOURCE_DIR}/.git) FIND_PACKAGE(Subversion) IF(Subversion_FOUND AND EXISTS ${PROJECT_SOURCE_DIR}/.svn) Subversion_WC_INFO(${PROJECT_SOURCE_DIR} Project) set(VERSION_STRING "${xc3sprog_VERSION_MAJOR}.${xc3sprog_VERSION_MINOR}-svn${Project_WC_REVISION}") ELSE(Subversion_FOUND AND EXISTS ${PROJECT_SOURCE_DIR}/.svn) set(VERSION_STRING "unknown") ENDIF(Subversion_FOUND AND EXISTS ${PROJECT_SOURCE_DIR}/.svn) endif(EXISTS ${PROJECT_SOURCE_DIR}/.git) # Create suffix to eventually install inlib64 IF(CMAKE_SIZEOF_VOID_P EQUAL 4) SET(LIB_SUFFIX "") SET(PACK_ARCH ".x86") ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) SET(LIB_SUFFIX 64) SET(PACK_ARCH .x86_64) endif(CMAKE_SIZEOF_VOID_P EQUAL 4) # Package information set(CPACK_PACKAGE_VERSION ${VERSION_STRING}) set(CPACK_PACKAGE_CONTACT "Uwe Bonnes ") set(CPACK_PACKAGE_DESCRIPTION "JTAG Progarmming tools") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${CPACK_PACKAGE_DESCRIPTION} ) # Package settings if(${UNIX}) set(CPACK_GENERATOR "DEB;RPM") set(CPACK_CMAKE_GENERATOR "Unix Makefiles") set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) set(CPACK_PACKAGE_FILE_NAME ${PROJECT_NAME}-${VERSION_STRING}${PACK_ARCH}) endif(${UNIX}) if(${WIN32}) set(CPACK_GENERATOR "NSIS") set(CPACK_CMAKE_GENERATOR "MinGW Makefiles") set(CPACK_PACKAGE_NAME "${PROJECT_NAME}") set(CPACK_PACKAGE_VENDOR "") set(CPACK_PACKAGE_INSTALL_DIRECTORY "libftdi") set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-win32") set(CPACK_NSIS_DISPLAY_NAME "libftdi") set(CPACK_NSIS_MODIFY_PATH "ON") endif(${WIN32}) set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE) set(CPACK_SOURCE_GENERATOR TGZ) set(CPACK_SOURCE_IGNORE_FILES "\\\\.svn" "build*") set(CPACK_SOURCE_PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME}) # Subdirectories if(${UNIX}) set(CPACK_SET_DESTDIR "ON") endif(${UNIX}) #link libusb dynamic at runtime on windows at at compile time else #this circumvents a problem with Debian set (CONDITIONAL_FILES) set (CONDITIONAL_LIBS) if("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") set (CONDITIONAL_FILES ${CONDITIONAL_FILES} "libusb_dyn.c") else("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") pkg_check_modules(LIBUSB_COMPAT REQUIRED libusb) include_directories(${LIBUSB_INCLUDE_DIRS}) set(CONDITIONAL_LIBS ${CONDITIONAL_LIBS} usb usb-1.0) endif("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") if(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") set (CONDITIONAL_FILES ${CONDITIONAL_FILES} "ioparport.cpp") endif(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") set (LIBUSRP_INCLUDE_DIR "fallback/") include_directories(${LIBUSRP_INCLUDE_DIR}) include_directories(${CMAKE_SOURCE_DIR}) #add_executable(debug debug.cpp iobase.cpp ioparport.cpp iodebug.cpp) add_executable(bitparse bitrev.cpp bitfile.cpp bitparse.cpp) add_executable(jedecparse jedecparse.cpp jedecfile.cpp) add_executable(srecparse srecparse.cpp srecfile.cpp) add_executable(avrfuseparse avrfuseparse.cpp avrfusefile.cpp) ADD_CUSTOM_COMMAND(OUTPUT devices.h COMMAND ${CMAKE_COMMAND} -DDEVLIST_DIR=${CMAKE_SOURCE_DIR} -P ${CMAKE_SOURCE_DIR}/devlist.cmk DEPENDS devlist.txt ) ADD_CUSTOM_COMMAND(OUTPUT cables.h COMMAND ${CMAKE_COMMAND} -DCABLELIST_DIR=${CMAKE_SOURCE_DIR} -P ${CMAKE_SOURCE_DIR}/cablelist.cmk DEPENDS cablelist.txt ) INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) add_library(xc3sproglib STATIC ioftdi.cpp iofx2.cpp devicedb.cpp jtag.cpp jedecfile.cpp bitfile.cpp iobase.cpp progalgxc95x.cpp utilities.cpp progalgxcf.cpp progalgxcfp.cpp progalgxc3s.cpp progalgavr.cpp progalgxc2c.cpp mapfile_xc2c.cpp ioxpc.cpp progalgspiflash.cpp bitrev.cpp cabledb.cpp pdioverjtag.cpp xmega_pdi_nvm.cpp ${CONDITIONAL_FILES} devices.h cables.h) add_executable(xc2c_warp xc2c_warp.cpp) target_link_libraries(xc2c_warp xc3sproglib ${CONDITIONAL_LIBS}) add_executable(detectchain detectchain.cpp cables.h devices.h) target_link_libraries(detectchain xc3sproglib ${LIBFTDI_LIBRARIES} ${LIBFTD2XX_LIBRARIES} ${CONDITIONAL_LIBS}) add_executable(xc3sprog xc3sprog.cpp javr.cpp srecfile.cpp progalgavr.cpp devices.h) target_link_libraries(xc3sprog xc3sproglib ${LIBFTDI_LIBRARIES} ${LIBFTD2XX_LIBRARIES} ${CONDITIONAL_LIBS} ) add_executable(readdna readdna.cpp devices.h) target_link_libraries(readdna xc3sproglib ${LIBFTDI_LIBRARIES} ${LIBFTD2XX_LIBRARIES} ${CONDITIONAL_LIBS} ) add_subdirectory(javr) install(TARGETS xc3sprog DESTINATION bin) install(TARGETS xc2c_warp DESTINATION bin) install(TARGETS readdna DESTINATION bin) install(TARGETS bitparse DESTINATION bin) install(TARGETS jedecparse DESTINATION bin) install(TARGETS srecparse DESTINATION bin) install(TARGETS detectchain DESTINATION bin) add_subdirectory(packages) include(CPack) SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${GENERATED_FILES}") xc3sprog-0+svn795+dfsg/COPYING000066400000000000000000000431311337255630200160140ustar00rootroot00000000000000 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. xc3sprog-0+svn795+dfsg/Contributors000066400000000000000000000001251337255630200173750ustar00rootroot00000000000000Contributions since July 2010: Joris van Rantwijk : XCFxxP handling xc3sprog-0+svn795+dfsg/FindlibFTD2XX.cmake000066400000000000000000000021161337255630200202300ustar00rootroot00000000000000# Copyright 2009 SoftPLC Corporation http://softplc.com # Dick Hollenbeck # License: GPL v2 # # - Try to find libftd2xx # Once done this will define # # LIBFTD2XX_FOUND - system has libftdi # LIBFTD2XX_INCLUDE_DIR - the libftdi include directory # LIBFTD2XX_LIBRARIES - Link these to use libftdi if (NOT LIBFTD2XX_FOUND) if(NOT WIN32) include(FindPkgConfig) pkg_check_modules(LIBFTD2XX_PKG libftd2xx) endif(NOT WIN32) find_path(LIBFTD2XX_INCLUDE_DIR NAMES ftd2xx.h HINTS ${LIBFTD2XX_PKG_INCLUDE_DIRS} PATHS /usr/include /usr/local/include ) find_library(LIBFTD2XX_LIBRARIES NAMES ftd2xx HINTS ${LIBFTD2XX_PKG_LIBRARY_DIRS} PATHS /usr/lib /usr/local/lib ) include(FindPackageHandleStandardArgs) # handle the QUIETLY AND REQUIRED arguments AND set LIBFTD2XX_FOUND to TRUE if # all listed variables are TRUE find_package_handle_standard_args(LIBFTD2XX DEFAULT_MSG LIBFTD2XX_LIBRARIES LIBFTD2XX_INCLUDE_DIR) #mark_as_advanced(LIBFTD2XX_INCLUDE_DIR LIBFTD2XX_LIBRARIES) endif(NOT LIBFTD2XX_FOUND) xc3sprog-0+svn795+dfsg/LICENSE000066400000000000000000000003101337255630200157560ustar00rootroot00000000000000The "xc3sprog" suite of programs is distributed under the GNU General Public License version 2. A copy of the GNU General Public License (LGPL) is included in this distribution, in the file COPYING. xc3sprog-0+svn795+dfsg/PERFORMANCE000066400000000000000000000006041337255630200164430ustar00rootroot00000000000000Here is a tabulation of the byte transfer counts for various FTDI sending options. These were recorded for a XC3S400 bitstream of 1699136 bits (212392 bytes). Byte-by-byte: 703719 (expected bitstream-only part 637197) 1350 ms Block transfers: 278887 (expected bitstream-only part 212427) 422 ms Just for comparison, loading the same bitstream through the parallel port takes 6809 ms. xc3sprog-0+svn795+dfsg/README000066400000000000000000000107051337255630200156420ustar00rootroot00000000000000Spartan3, XCF and CPLD JTAG programmer and other utilities Copyright (C) 2004 Andrew Rogers (C) 2005-2011 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de 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 Please also read the file "COPYING" which is a copy of the GNU General Public License Thanks to - nahitafu@nifty.com (naxjp, XC95X algorithm example), - zoltan_csizmadia at yahoo dot (xilprg) - Benedikt Heinz for the XC3SAN ISF - and many others This program should run without installation. For accessing USB cables, libusb0 is required as runtime dynamic linked libray. To compile, you need CMAKE, the static libftdi library and usb.h. $ mkdir build; cd build; cmake ..; make To crosscompile for Win32 with mingw: $ mkdir build-win32; cd build-win32; $ cmake -DCMAKE_TOOLCHAIN_FILE=../Toolchain-mingw32.cmake .. Get a description with $ ./xc3sprog -h This will also list the supported cables. Get a chain description: $ ./xcs3prog -j Device descrption is searched in the file pointed to by the XCDB environment variable, or when not found the built-in list is used Test the chain integrity $ ./xc3sprog -T -j Here "-j" stops xc3sprog from entering the program/verify/read the part. If things go wrong, an endless loop is entered to facilitate hardware degugging with the scope. Stop with ^C. The Platform Flash PROM of the Xilinx Spartan3 Starter Kit can be programmed by specifying it's location in the JTAG chain. Example command line below. $ ./xc3sprog -c pp -p 1 Program the flash of an XC3S50AN by loading the bscan_spi bitfile first. Aassume the XC3S50AN as single part in the jtag chain $ ./xc3sprog ../bscan_spi/xc3s50an.bit Now program the flash $ ./xc3sprog -I Verify the flash content against a file $ ./xc3sprog -I -C You can readout XCF/ISF flash and CPLD ISF flash probably mean Incircuit Serial Flash, as internal to XC3SAN or external connected to XC3SA/XC3SA or XC6S First load an appropriate bitfile. Some bitfiles are in bscan_spi. Otherwise use the appropriate HDL file from bscan_spi and a fitting UCF file to create a ISE Project and run the Xilinx tools to generate the bitfile. Load the bitfile, like $ ./xc3sprog bscan_spi/xc6s_cs324.ucf After loading the ISF Bitfile, you can now talk to the ISF Flash. When writing to the ISF, at the end the FPGA tries to reconfigure from flash and the ISF Bitfile is lost. $ ./xc3sprog -r (-I) xc3sprog handles XC3, XCF0x and XC95xxxXx. XC4 should work but is untested. There is also a utility program included that parses and prints the header of a Xilinx .bit file. $ ./bitparse echo_out.bit Jedecfiles for CPLD programming can be parsed with $ ./jedecparse When using a FT2232D|L programmer, speed is noticely enhance with a USB-2.0 Hub between the adapter and the PC. Some effort has been made to concatenate as many JTAG actions as possible. Example fallback multi boot setup on XC6S Load intermediate BSCAN_SPI bitfile $ ./xc3sprog -I Eventually erase (not really needed) $ ./xc3sprog -I -e Prepare the Multiboot header from the Template. Adapt GENERAL2 and GENERAL4 for your setup. Here a 32 MiBit Flash and a XC6SLX45 is used. The Bitstream length is about 1484404 = 0x16a674 bytes, so with placing the golden image at 0x10000 the golden image ends at 0x17a674 and with placing the normal image at 0x190000, there should be enough spacing between both. Double check that GENERAL2 and GENERAL4 match the offsets. Write the header $ ./xc3sprog -I Write golden image $ ./xc3sprog -I :w:0x10000 Write normal image $ ./xc3sprog -I :w:0x190000 Reboot $ ./xc3sprog -R All all in one $ ./xc3sprog -R -I :w:0x10000 \ :w:0x190000 xc3sprog-0+svn795+dfsg/README.Win32000066400000000000000000000026241337255630200165440ustar00rootroot00000000000000Building with mingw32 ===================== To (cross)build with recent mingw, following packages need to be installed: - mingw32-(cross-)gcc and it's dependancies - mingw32-(cross-)gcc-c++ - mingw32-(cross-)pkg-config - mingw32-libftdi1 mingw32-libftdi1-devel Tested as cross-compile on OpenSuse LEAP 42.2/42.3. Parallelport Access via the $VDMLPT device and the PARVDM service ================================================================ The get the desired access, check that - the BIOS is set to EPP(ECP/EPP) mode for the LPT device - the parvdm service is running "sc query parvdm" On different machines here, "sc start parvdm" refused to start the service with Error 1058. You can get information about the parvdm in the Device Manager with the display of hidden devices enables under the NON-PNP section. Sometimes deinstalling parvdm in the device manager and then reenabling it with regedit by setting "Start" to "2" in HKLM/SYSTEM/ControlSet001/Services/ParVdm got it working. Please report your findings! Lib-USB Access ============== For devices access to devices with already installed drivers, like the Xilinx Download cables or FTDI cables with default VID:PID, install the filter driver. Follow the instructions given in the download page of the sourceforge libusb-win32 project. Only if your device has no driver, create an inf file as explaind in the "Device driver Installation" on above page. xc3sprog-0+svn795+dfsg/Readme.Cmake000066400000000000000000000016531337255630200171230ustar00rootroot00000000000000At best, build in own directory, e.g.: mkdir build; cd build; "cmake .." oder "cmake -DCMAKE_BUILD_TYPE=Debug .." mkdir build-win32; cd build-win32; "cmake -DCMAKE_TOOLCHAIN_FILE=../Toolchain-mingw32.cmake .." Build import library pexports -h /opt/cross/i386-mingw32msvc/include/ftd2xx.h \ /opt/spare/bon/ftdi/ftd2xx/i386/ftd2xx.dll > /tmp/ftd2xx.def /opt/cross/i386-mingw32msvc/bin/dlltool -d /tmp/ftd2xx.def -l libftd2xx.a -k Needed packages (as on a clean osboxes Leap-42): Install gcc, gcc-c++, git, cmake, libftdi1-devel, libusb-compat-devel Crosscompile: Follow instructions on https://software.opensuse.org/download.html?project=windows%3Amingw%3Awin32&package=mingw32-cross-gcc zypper addrepo http://download.opensuse.org/repositories/windows:mingw:win32/openSUSE_Leap_42.3/windows:mingw:win32.repo zypper refresh zypper install mingw32-cross-gcc mingw32-cross-gcc-c++ mingw32-libftdi1-devel mingw32-cross-pkg-config xc3sprog-0+svn795+dfsg/Readme.DLC10000066400000000000000000000023541337255630200166450ustar00rootroot00000000000000090605: Tested with a DLC10 cable. The DLC9/10 cables need firmware to be uploaded. This firmware is installed with impact. On plugin, some mechanism is needed to upload this firmware. On windows, windows should care. On Linux udev should care. The firmware can also loaded with programs like "fxload". To use the cable, the cable must report an ID "03fd:0008", which indicates successfull loaded firmware. This VID:PID is the same for DLC9/DLC9 embedded and DLC10. The buffer size could be increased substantial against Koljas observations on the DLC9, resulting in great speed increase. Time to programm the 1 MByte "bscan_spi/sp3adsp-fg676.bit" file to a XC3SD1800A is about 6 seconds, versus 3 seconds in Impact. Probably impact selects a higher TCK speed. Didn't look for the appropriate message in deepth. Internal chain didn't work for the DLC9, neither in SVN-urjtag, nor in xc3sprog. For serial number readout: DLC10: First load /usr/share/xusb_xp2.hex (Version 2300) then /opt/Xilinx/11.1/ISE/data/xusb_xp2.hex (Version 2401) SP601: First load /usr/share/xusb_emb.hex (Version 1028) then /opt/Xilinx/11.1/ISE/data/xusb_emp.hex (Version 1303) Get firmware Version form HEX file like grep :0219B900 /opt/Xilinx/11.1/ISE/data/*hexxc3sprog-0+svn795+dfsg/Readme.Darwin000066400000000000000000000034731337255630200173310ustar00rootroot00000000000000This is a simplified readme covering MasOSX aspects of build and use xc3sprog. This is not a complete HOWTO, so don't hesitate to read other README's supplied in this project. 1. Compilation environment following installations require before proceeding to compile xc3sprog: - XCode SDK downloadable from here https://developer.apple.com/xcode/download/ - Homebrew downloadable from here http://brew.sh/ - SVN just type in the terminal brew install svn - CMake just type in the terminal brew install cmake - libusb just type in the terminal brew install libusb - libftdi just type in the terminal brew install libftdi 2. Build sequence following the original README - checkout source code using SVN: svn co https://xc3sprog.svn.sourceforge.net/svnroot/xc3sprog/trunk xc3sprog - change folder inside xc3sprog and create subfolder build cd xc3sprog mkdir build - change folder inside build and execute cmake (double dots after the 'cmake' is important) cd build cmake .. - once cmake discover all the components necessary for the build (require at least libusb and libftdi - proceed with the classical make) make - if the error happened (usually cmake coudn't find libftdi) it means file Findlibftdi.cmake hasn't been patched yet (the hint is simple, cmake is looking for ftdi yet it should look for the ftdi1 except for the header) 3. Execution environment - useful tool inside the project is detectchain to verify if FTDI actually has any chip connected to JTAG pins ./detectchain -c ftdi -d /dev/tty.usbserial-fd12 - resolving conflict with the original AppleUSBFTDI driver (aka KEXT:) at first trial to connect to the peripherals the error about unable to acquire port will show up unload original KEXT from the system and proceed again with the commands no more problems to happend sudo kextunload -b com.apple.driver.AppleUSBFTDI xc3sprog-0+svn795+dfsg/Readme.JTAG_Timing000066400000000000000000000003721337255630200201340ustar00rootroot00000000000000For JTAG Timing example, look e.g. at http://pdfserv.maxim-ic.com/en/ds/DS4550.pdf or http://www.xilinx.com/support/documentation/application_notes/xapp070.pdf This concludes to: - Change TDI with the negative edge - Sample TDO at the negative edgexc3sprog-0+svn795+dfsg/ToDo000066400000000000000000000014661337255630200155560ustar00rootroot00000000000000- Use Bitarrays and not One-Byte-for-a-Bit in javr - AT90CAN reads back the flash as Bytes. With USB transfers, this is damned slow. Provides some mechanism to queue read requests - Compress the XC3AN bit files and include into the binary - More cables - Cleanup C++ code - More devices (XC2C, XC95xx (without X)) - Other devices with published 1532 algorithm - Bitorder for Intel HEX format - Finer granularity for erasing XCFP - ... - Check Byte Order IHEX versus MCS - Document cable Database - Break possible infinite loops, like ProgAlgXC3S::array_program do jtag->shiftIR(CFG_IN, buf); while (! (buf[0] & 0x10)); /* wait until configuration cleared */ - Progress in indicator when writing large bitfiles in legacy mode. Perhaps have an indicator thread reading out variables when writing the JTAG bits xc3sprog-0+svn795+dfsg/Toolchain-FreeBSD.cmake000066400000000000000000000002011337255630200211020ustar00rootroot00000000000000set(CMAKE_SYSTEM_NAME FreeBSD) set(CMAKE_C_COMPILER cc -m32) set(CMAKE_CXX_COMPILER c++ -m32) set(CMAKE_FIND_ROOT_PATH /usr/lib) xc3sprog-0+svn795+dfsg/Toolchain-SUSE32.cmake000066400000000000000000000002771337255630200206310ustar00rootroot00000000000000set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_C_COMPILER gcc -m32) set(CMAKE_CXX_COMPILER g++ -m32) set(CMAKE_FIND_ROOT_PATH /usr/lib) set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS OFF) xc3sprog-0+svn795+dfsg/Toolchain-mingw32.cmake000066400000000000000000000013471337255630200211720ustar00rootroot00000000000000#from http://www.cmake.org/Wiki/CmakeMingw # the name of the target operating system SET(CMAKE_SYSTEM_NAME Windows) SET(MINGW_VER i686-w64-mingw32) # which compilers to use for C and C++ SET(CMAKE_C_COMPILER ${MINGW_VER}-gcc) SET(CMAKE_CXX_COMPILER ${MINGW_VER}-g++) SET(CMAKE_RC_COMPILER ${MINGW_VER}-windres) SET(PKG_CONFIG_EXECUTABLE ${MINGW_VER}-pkg-config) # here is the target environment located SET(CMAKE_FIND_ROOT_PATH /usr/${MINGW_VER} ) # adjust the default behaviour of the FIND_XXX() commands: # search headers and libraries in the target environment, search # programs in the host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) xc3sprog-0+svn795+dfsg/atxmega128a1_nvm_regs.h000066400000000000000000000074721337255630200211450ustar00rootroot00000000000000/** * \file * * \brief ATXmega128A1 NVM Register Definition * * Copyright (C) 2009 Atmel Corporation. All rights reserved. * * \page License * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. The name of Atmel may not be used to endorse or promote products derived * from this software without specific prior written permission. * * 4. This software may only be redistributed and used in connection with an * Atmel AVR product. * * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ #ifndef ATXMEGA128A1_NVM_REGS #define ATXMEGA128A1_NVM_REGS #define XNVM_FLASH_BASE 0x0800000 //!< Adress where the flash starts. #define XNVM_EEPROM_BASE 0x08C0000 //!< Address where eeprom starts. #define XNVM_FUSE_BASE 0x08F0020 //!< Address where fuses start. #define XNVM_DATA_BASE 0x1000000 //!< Address where data region starts. #define XNVM_APPL_BASE XNVM_FLASH_BASE //!< Addres where application section starts. #define XNVM_CALIBRATION_BASE 0x008E0200 //!< Address where calibration row starts. #define XNVM_SIGNATURE_BASE 0x008E0400 //!< Address where signature bytes start. #define XNVM_FLASH_PAGE_SIZE 512 // #define XNVM_CONTROLLER_BASE 0x01C0 //!< NVM Controller register base address. #define XNVM_CONTROLLER_CMD_REG_OFFSET 0x0A //!< NVM Controller Command Register offset. #define XNVM_CONTROLLER_STATUS_REG_OFFSET 0x0F //!< NVM Controller Status Register offset. #define XNVM_CONTROLLER_CTRLA_REG_OFFSET 0x0B //!< NVM Controller Control Register A offset. #define XNVM_CTRLA_CMDEX (1 << 0) //!< CMDEX bit offset. #define XNVM_NVMEN (1 << 1) //!< NVMEN bit offset. #define XNVM_NVM_BUSY (1 << 7) //!< NVMBUSY bit offset. #define XOCD_STATUS_REGISTER_ADDRESS 0x00 //!< PDI status register address. #define XOCD_RESET_REGISTER_ADDRESS 0x01 //!< PDI reset register address. #define XOCD_RESET_SIGNATURE 0x59 //!< PDI reset Signature. #define XOCD_FCMR_ADDRESS 0x05 #define NVM_PAGE_ORDER 9 //!< NVM Page Order of 2. #define NVM_PAGE_SIZE (1 << NVM_PAGE_ORDER) //!< NVM Page Size. #define NVM_EEPROM_PAGE_SIZE 32 //!< EEPROM Page Size. #define NVM_LOCKBIT_ADDR 7 //!< Lockbit address. #define NVM_MCU_CONTROL 0x90 //!< MCU Control base address. #define NVM_COMMAND_BUFFER_SIZE 20 //!< NVM Command buffer size. #define WAIT_RETRIES_NUM 1000 //!< Retry Number. #define DUMMY_BYTE 0x55 //!< Dummy byte for Dummy writing. #endif xc3sprog-0+svn795+dfsg/avrfusefile.cpp000066400000000000000000000375771337255630200200210ustar00rootroot00000000000000/* AVR ..fus file parser Copyright (C) Uwe Bonnes 2009 bon@elektron.ikp.physik.tu-darmstadt.de 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 Modifyied from fuse/parse * Copyright (C) <2001> * antone@sentechsa.com */ #include #include #include #include "avrfusefile.h" #include "javr.h" AvrFuseFile::AvrFuseFile(int deviceindex) { index = deviceindex; } int AvrFuseFile::Tokenize(unsigned char *buffer) { const char *gToken[]= { "M103C:", "WDTON:", "OCDEN:", "JTAGEN:", "SPIEN:", "CKOPT:", "EESAVE:", "BOOTSIZE:", "BOOTRST:", "BODLEVEL:", "BODEN:", "SUT:", "CKSEL:", "BLB0:", "BLB1:", "LB:", "M161C:", "CKDIV8:", "CKOUT:", NULL }; int i; i=0; while(gToken[i]) { if(!strcasecmp((const char*)gToken[i],(const char*)buffer)) return(i); i++; } return(i); } #define TokenM103C 0 #define TokenWDTON 1 #define TokenOCDEN 2 #define TokenJTAGEN 3 #define TokenSPIEN 4 #define TokenCKOPT 5 #define TokenEESAVE 6 #define TokenBOOTSIZE 7 #define TokenBOOTRST 8 #define TokenBODLEVEL 9 #define TokenBODEN 10 #define TokenSUT 11 #define TokenCKSEL 12 #define TokenBLB0 13 #define TokenBLB1 14 #define TokenLB 15 #define TokenM161C 16 #define TokenCKDIV8 17 #define TokenCKOUT 18 #define TokenNone 19 int AvrFuseFile::ParseAvrFuseFile(FILE * gFuseFile) { unsigned char c; unsigned char Buffer[256]; char restart=1; unsigned char EventNum=0,Index=0; int Token,TokenOld; unsigned long DataCount; int i, tmp; int res = -1; DataCount=0; TokenOld=TokenNone; do { if(!feof(gFuseFile)) { switch(EventNum) { case 0: /* Start */ restart=1; Index=0; EventNum=1; break; case 1: /* Looking for token */ c=fgetc(gFuseFile); DataCount++; if(!isspace(c)) { if(c==';') /* Start of comment */ { EventNum=4; } else { Buffer[Index++]=c; EventNum=2; } } break; case 2: /* Reading Token */ c=fgetc(gFuseFile); DataCount++; if(isspace(c)) { if(c!=' ') { EventNum=3; Buffer[Index]=0; } else { Buffer[Index++]=c; } } else { Buffer[Index++]=c; if(c==':') /* End of Token char */ { EventNum=3; Buffer[Index]=0; } if(Index>30) restart=0; } break; case 3: /* Token in Buffer */ Token=Tokenize(Buffer); if (Token != TokenNone) res = 0; switch(Token) { case TokenM103C: break; case TokenWDTON: break; case TokenOCDEN: break; case TokenJTAGEN: break; case TokenSPIEN: break; case TokenCKOPT: break; case TokenEESAVE: break; case TokenBOOTSIZE: break; case TokenBOOTRST: break; case TokenBODLEVEL: break; case TokenBODEN: break; case TokenSUT: break; case TokenCKSEL: break; case TokenM161C: break; case TokenCKDIV8: break; case TokenCKOUT: break; case TokenNone: /* printf("%s >>%s<<\n",gToken[TokenOld],Buffer); */ switch(TokenOld) { case TokenM103C: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.M103C=tmp; break; case TokenWDTON: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.WDTON=tmp; break; case TokenOCDEN: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.OCDEN=tmp; break; case TokenJTAGEN: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.JTAGEN=tmp; break; case TokenSPIEN: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.SPIEN=tmp; break; case TokenCKOPT: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.CKOPT=tmp; break; case TokenEESAVE: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.EESAVE=tmp; break; case TokenBOOTSIZE: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.BOOTSIZE=tmp; break; case TokenBOOTRST: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.BOOTRST=tmp; break; case TokenBODLEVEL: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.BODLEVEL=tmp; break; case TokenBODEN: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.BODEN=tmp; break; case TokenSUT: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.SUT=tmp; break; case TokenCKSEL: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.CKSEL=tmp; break; case TokenBLB0: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.BLB0=tmp; break; case TokenBLB1: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.BLB1=tmp; break; case TokenLB: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.LB=tmp; break; case TokenM161C: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.M161C=tmp; break; case TokenCKDIV8: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.CKDIV8=tmp; break; case TokenCKOUT: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.CKOUT=tmp; } break; } EventNum=1; Index=0; TokenOld=Token; break; case 4: /* Skipping Comment */ c=fgetc(gFuseFile); Buffer[Index++]=c; DataCount++; if((c=='\r') || (c=='\n')) /* End of comment */ { if (index == UNKNOWN_DEVICE) { for(i=0; gAVR_Data[i].jtag_id; i++) { if (!(strncasecmp(gAVR_Data[i].name, (const char*)Buffer, strlen(gAVR_Data[i].name)))) { index =i; printf("found dev %s\n", gAVR_Data[i].name); break; } } } Buffer[0]= 0; Index=0; EventNum=1; } break; } } else { restart=0; } } while(restart); return res; } int AvrFuseFile::ReadAvrFuseFile(char * fname) { int res; FILE * fp = fopen(fname, "rb" ); if (fp == 0) return -1; res = ParseAvrFuseFile(fp); fclose(fp); return res; } int AvrFuseFile::WriteAvrFuseFile(char * fname) { int res = 0; FILE * fp = fopen(fname, "wb" ); if (fp == 0) return -1; fprintf(fp,";%s Fuse Bit definitions\n" ";0 => Programmed, 1 => Not Programmed\n", gAVR_Data[index].name); fprintf(fp,"CKSEL: %d\n", gFuseBitsAll.CKSEL); fprintf(fp,"SUT: %d\n", gFuseBitsAll.SUT); fprintf(fp,"BOOTSIZE: %d\n", gFuseBitsAll.BOOTSIZE); fprintf(fp,"WDTON: %d\n", gFuseBitsAll.WDTON); fprintf(fp,"CKDIV8: %d\n", gFuseBitsAll.CKDIV8); fprintf(fp,"CKOUT: %d\n", gFuseBitsAll.CKOUT); fprintf(fp,"TA0SEL: %d\n", gFuseBitsAll.TA0SEL); fprintf(fp,"OCDEN: %d\n", gFuseBitsAll.OCDEN); fprintf(fp,"JTAGEN: %d\n", gFuseBitsAll.JTAGEN); fprintf(fp,"SPIEN: %d\n", gFuseBitsAll.SPIEN); fprintf(fp,"EESAVE: %d\n", gFuseBitsAll.EESAVE); fprintf(fp,"BOOTRST: %d\n", gFuseBitsAll.BOOTRST); fprintf(fp,"; Lock Bit definitions (Need -L command line option to write)\n"); fprintf(fp,"BLB1: %d\n", gFuseBitsAll.BLB1); fprintf(fp,"BLB0: %d\n", gFuseBitsAll.BLB0); fprintf(fp,"LB: %d\n", gFuseBitsAll.LB); fclose(fp); return res; } void AvrFuseFile::DisplayATMegaFuseData(void) { const char *gCKSEL_Data[] = { /* 00000 */ "External Clock - 36p Capacitor Switched in", /* 00001 */ "Internal RC Clock (Invalid CKOPT should not be programmed)", /* 00010 */ "Internal RC Clock (Invalid CKOPT should not be programmed)", /* 00011 */ "Internal RC Clock (Invalid CKOPT should not be programmed)", /* 00100 */ "Internal RC Clock (Invalid CKOPT should not be programmed)", /* 00101 */ "External RC Clock - 36p Capacitor Switched in (-0.9 MHz)", /* 00110 */ "External RC Clock - 36p Capacitor Switched in (0.9-3 MHz)", /* 00111 */ "External RC Clock - 36p Capacitor Switched in (3-8 MHz)", /* 01000 */ "External RC Clock - 36p Capacitor Switched in (8-12 MHz)", /* 01001 */ "Extenal Low Freq Crystal - 36p Capcitors switched in", /* 01010 */ "External Crystal (1 - 16MHz)", /* 01011 */ "External Crystal (1 - 16MHz)", /* 01100 */ "External Crystal (1 - 16MHz)", /* 01101 */ "External Crystal (1 - 16MHz)", /* 01110 */ "External Crystal (1 - 16MHz)", /* 01111 */ "External Crystal (1 - 16MHz)", /* 10000 */ "External Clock", /* 10001 */ "Internal RC Clock (1 MHz Nominal)", /* 10010 */ "Internal RC Clock (2 MHz Nominal)", /* 10011 */ "Internal RC Clock (4 MHz Nominal)", /* 10100 */ "Internal RC Clock (8 MHz Nominal)", /* 10101 */ "External RC Clock (-0.9 MHz)", /* 10110 */ "External RC Clock (0.9-3 MHz)", /* 10111 */ "External RC Clock (3-8 MHz)", /* 11000 */ "External RC Clock (8-12 MHz)", /* 11001 */ "Extenal Low Freq Crystal", /* 11010 */ "External Crystal (0.4 - 0.9MHz)", /* 11011 */ "External Crystal (0.4 - 0.9MHz)", /* 11100 */ "External Crystal (0.9 - 3.0MHz)", /* 11101 */ "External Crystal (0.9 - 3.0MHz)", /* 11110 */ "External Crystal (3.0 - 8MHz)", /* 11111 */ "External Crystal (3.0 - 8MHz)" }; const char *gCKSEL_Data1[] = { /* 00000 */ "External Clock", /* 00001 */ "Reserved", /* 00010 */ "Internal 8 MHz RC Clock", /* 00011 */ "Reserved", /* 00100 */ "External LF Crystal 1K CK", /* 00101 */ "External LF Crystal 32 CK", /* 00110 */ "External LF Crystal 1K CK", /* 00111 */ "External LF Crystal 32 CK", /* 01000 */ "External Ceramic Resonator(0.4 - 0.9 MHz)", /* 01001 */ "External Ceramic Resonator(0.4 - 0.9 MHz)", /* 01010 */ "External Crystal (0.9 - 3MHz)", /* 01011 */ "External Crystal (0.9 - 3MHz)", /* 01100 */ "External Crystal (3 - 8MHz)", /* 01101 */ "External Crystal (3 - 8MHz)", /* 01110 */ "External Crystal (8 - 16MHz)", /* 01111 */ "External Crystal (8 - 16MHz)" }; const char *gTF[]={"True","False"}; unsigned char tmp; unsigned long tmp1; AVR_Data gDeviceData = gAVR_Data[index]; BOOT_Size gDeviceBOOTSize = gBOOT_Size[index]; if((index==ATMEGA162) || (index==AT90CAN128)) { tmp=gFuseBitsAll.CKSEL; printf("CKSEL: %X %s%s\n",gFuseBitsAll.CKSEL,gCKSEL_Data1[tmp], (gFuseBitsAll.CKDIV8)?"":" divided by 8"); } else { tmp=gFuseBitsAll.CKSEL; tmp|=(gFuseBitsAll.CKOPT<<4); printf("CKSEL: %X CKOPT: %d %s\n", gFuseBitsAll.CKSEL,gFuseBitsAll.CKOPT,gCKSEL_Data[tmp]); } printf("SUT: %X ",gFuseBitsAll.SUT); DisplayATMegaStartUpTime(); printf("\n"); tmp1=gDeviceData.flash; tmp1-=gDeviceBOOTSize.size[gFuseBitsAll.BOOTSIZE]; printf("BOOTSIZE: %X Size: %d Bytes Start:0x%5.5lX\n", gFuseBitsAll.BOOTSIZE, gDeviceBOOTSize.size[gFuseBitsAll.BOOTSIZE],tmp1); if((index==ATMEGA128) || (index==ATMEGA64)) { printf("M103C : %d (%s)\n", gFuseBitsAll.M103C ,gTF[gFuseBitsAll.M103C]); printf("WDTON : %d (%s)\n",gFuseBitsAll.WDTON, gTF[gFuseBitsAll.WDTON]); } if((index==ATMEGA162) || (index==AT90CAN128)) { if (index==ATMEGA162) printf("M161C : %d (%s)\n",gFuseBitsAll.M161C, gTF[gFuseBitsAll.M161C]); printf("WDTON : %d (%s)\n",gFuseBitsAll.WDTON, gTF[gFuseBitsAll.WDTON]); printf("CKOUT : %d (%s)\n",gFuseBitsAll.CKOUT, gTF[gFuseBitsAll.CKOUT]); printf("CKDIV8 : %d (%s)\n",gFuseBitsAll.CKDIV8, gTF[gFuseBitsAll.CKDIV8]); } printf("OCDEN : %d (%s)\n",gFuseBitsAll.OCDEN, gTF[gFuseBitsAll.OCDEN]); printf("JTAGEN : %d (%s)\n",gFuseBitsAll.JTAGEN ,gTF[gFuseBitsAll.JTAGEN]); printf("SPIEN : %d (%s)\n",gFuseBitsAll.SPIEN, gTF[gFuseBitsAll.SPIEN]); printf("EESAVE : %d (%s)\n",gFuseBitsAll.EESAVE, gTF[gFuseBitsAll.EESAVE]); printf("BOOTRST : %d (%s)\n",gFuseBitsAll.BOOTRST, gTF[gFuseBitsAll.BOOTRST]); printf("BODLEVEL: 0x%X ",gFuseBitsAll.BODLEVEL); if(index == ATMEGA162) { switch(gFuseBitsAll.BODLEVEL) { case 0x07: printf("(BOD Disabled)"); break; case 0x06: printf("(1.8V)"); break; case 0x05: printf("(2.7V)"); break; case 0x04: printf("(4.3V)"); break; case 0x03: printf("(2.3V)"); break; default: printf("(Reserved)"); break; } printf("\n"); } else if(index == AT90CAN128) { switch(gFuseBitsAll.BODLEVEL) { case 0x07: printf("(BOD Disabled)"); break; case 0x06: printf("(4.1V)"); break; case 0x05: printf("(4.0V)"); break; case 0x04: printf("(3.9V)"); break; case 0x03: printf("(3.8V)"); break; case 0x02: printf("(2.7V)"); break; case 0x01: printf("(2.6V)"); break; default: printf("(2.5V)"); break; } printf("\n"); } else { if(gFuseBitsAll.BODLEVEL) printf("(2.7V)\n"); else printf("(4V)\n"); printf("BODEN : %d (%s)\n",gFuseBitsAll.BODEN, gTF[gFuseBitsAll.BODEN]); } } void AvrFuseFile::DisplayATMegaStartUpTime(void) { /* CKSEL0, SUT1..0 */ const char *gSUT_Xtal[] ={ "258CK + 4ms (Reset) Ceramic Resonator, fast rising power", "258CK + 64ms (Reset) Ceramic Resonator, slow rising power", "1K CK Ceramic Resonator, BOD enabled", "1K CK + 4ms (Reset) Ceramic Resonator, fast rising power", "1K CK + 64ms (Reset) Ceramic Resonator, slow rising power", "16K CK Crystal, BOD enabled", "16K CK + 4ms (Reset), Crystal, fast rising power", "16K CK + 64ms (Reset), Crystal, slow rising power" }; /* SUT1..0 */ const char *gSUT_LowXtal[] ={ "1K CK + 4ms (Reset) fast rising power or BOD Enabled", "1K CK + 64ms (Reset), slow rising power", "32K CK + 64ms (Reset), stable frequency at start-up", "Reserved" }; /* SUT1..0 */ const char *gSUT_ExtRC[] ={ "18 CK, BOD Enabled", "18 CK + 4ms (Reset), Fast rising power", "18 CK + 64ms (Reset), Slow rising power", "6 CK + 4ms (Reset), Fast rising power or BOD Enabled" }; /* SUT1..0 */ const char *gSUT_IntRC[] ={ "6 CK, BOD Enabled", "6 CK + 4ms (Reset), Fast rising power", "6 CK + 64ms (Reset), Slow rising power", "Reserved" }; unsigned char tmp; switch(gFuseBitsAll.CKSEL) { case 0: /* External Clock */ printf("None"); break; case 1: /* Int RC */ case 2: case 3: case 4: printf("%s",gSUT_IntRC[gFuseBitsAll.SUT]); break; case 5: /* Ext RC */ case 6: case 7: case 8: printf("%s",gSUT_ExtRC[gFuseBitsAll.SUT]); break; case 9: /* Low Freq Crystal */ printf("%s",gSUT_LowXtal[gFuseBitsAll.SUT]); break; default: /* Crystal */ tmp=gFuseBitsAll.CKSEL&0x01; tmp<<=2; tmp|=gFuseBitsAll.SUT; printf("%s",gSUT_Xtal[tmp]); break; } } xc3sprog-0+svn795+dfsg/avrfusefile.h000066400000000000000000000054701337255630200174510ustar00rootroot00000000000000/* AVR Fuse file parser Copyright (C) Uwe Bonnes 2009 bon@elektron.ikp.physik.tu-darmstadt.de 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 Modifyied from fuse * Copyright (C) <2001> * antone@sentechsa.com */ #ifndef AVRFUSEFILE_H #define AVRFUSEFILE_H #include typedef struct { /* |128|32|16|162|CAN128*/ unsigned M103C:1; /* ATMega103 Compatibility Mode | x | | | | */ unsigned M161C:1; /* ATMeag161 Compatibility Mode | | | | x| */ unsigned WDTON:1; /* Watchdog Always on | x | | | x| x */ unsigned OCDEN:1; /* Enable On Chip Debug | x | x| x| x| x */ unsigned JTAGEN:1; /* JTAG Enable | x | x| x| x| x */ unsigned SPIEN:1; /* Serial Programming Enable | x | x| x| x| x */ unsigned CKOPT:1; /* Oscillator options | x | x| x| x| X */ unsigned EESAVE:1; /* Preserve EEPROM with Erase | x | x| x| x| x */ unsigned BOOTSIZE:2; /* Depends on Device | x | x| x| x| x */ unsigned BOOTRST:1; /* Enable Booting from Bootblock| x | x| x| x| x */ unsigned BODLEVEL:3; /* BOD Level | x | x| x| x| x */ unsigned BODEN:1; /* Brownout Detector Enable | x | x| x| x| */ unsigned SUT:2; /* Start Up Time | x | x| x| x| x */ unsigned CKSEL:4; /* Clock Select | x | x| x| x| x */ unsigned CKDIV8:1; /* Divide clock by 8 | | | | x| x */ unsigned CKOUT:1; /* Clock Output | | | | x| x */ unsigned TA0SEL:1; /* (Reserved for factory tests) | | | | | x */ unsigned LB:2; /* Lock Bits */ unsigned BLB0:2; unsigned BLB1:2; }FUSE_BITS; class AvrFuseFile { private: int index; /* What device*/ FUSE_BITS gFuseBitsAll; int Tokenize(unsigned char *buffer); int ParseAvrFuseFile(FILE *fp); char devicename[256]; public: AvrFuseFile(int deviceindex =0); int WriteAvrFuseFile(char * fname); int ReadAvrFuseFile(char * fname); int EncodeATMegaFuseBits(void); void DisplayATMegaFuseData(void); void DisplayATMegaStartUpTime(void); }; #endif xc3sprog-0+svn795+dfsg/avrfuseparse.cpp000066400000000000000000000022531337255630200201730ustar00rootroot00000000000000/* AVR .fus file parser Copyright (C) 2009 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de 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 "avrfusefile.h" #include "io_exception.h" #include "javr.h" int main(int argc, char**args) { if(argc < 2) { fprintf(stderr,"Usage: %s infile.fus outfile.fus\n",args[0]); } else { { AvrFuseFile file(UNKNOWN_DEVICE); if (file.ReadAvrFuseFile(args[1])<0) fprintf(stderr, "no valid file given\n"); file.DisplayATMegaFuseData(); file.WriteAvrFuseFile(args[2]); } } } xc3sprog-0+svn795+dfsg/bitfile.cpp000066400000000000000000000412351337255630200171060ustar00rootroot00000000000000/* Xilinx .bit file parser Copyright (C) 2004 Andrew Rogers 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 Changes: Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: Code cleanup for clean -Wall compile. */ #include "bitfile.h" #include "io_exception.h" #include #include #include #include #include #include #include #include "bitrev.h" using namespace std; BitFile::BitFile() : length(0) , buffer(0) , Error(false) , logfile(stderr) , offset(0) , rlength(0) { } int BitFile::readBitfile(FILE *fp) { try { { // Skip the header char hdr[13]; fread(hdr, 1, 13, fp); // 13 byte header } char key; std::string *field; std::string dummy; while(!feof(fp)) { fread(&key, 1, 1, fp); switch(key) { case 'a': field = &ncdFilename; break; case 'b': field = &partName; break; case 'c': field = &date; break; case 'd': field = &dtime; break; case 'e': processData(fp); return 0; default: fprintf(stderr, "Ignoring unknown field '%c'\n", key); field = &dummy; } readField(*field, fp); } throw io_exception("Unexpected end of file"); } catch(...) { fprintf(stderr, "Unknown error\n"); return 2; } if(!length) return 3; return 0; } /* Read in whole file with or without bitflip */ int BitFile::readBIN(FILE *fp, bool do_bitrev) { unsigned int i; fseek(fp, 0, SEEK_END); length = ftell(fp); /* Fix at end */ fseek(fp, 0, SEEK_SET); if(buffer) delete [] buffer; buffer= new byte[length]; if (buffer == 0) return 1; fread(buffer,1, length, fp); if (!do_bitrev) return 0; for(i=0; i>= 1; /* We read two Hex nibbles for each byte*/ fseek(fp, 0, SEEK_SET); if(buffer) delete [] buffer; buffer= new byte[length]; /* FIXME: generate a dummy header*/ if (buffer == 0) return 1; while ((fgets(buf, 1024, fp)) != 0) { int bytes_read = 0; unsigned char value; while (1) { if (buf[bytes_read] == 0x0a || buf[bytes_read] == 0x0d || buf[bytes_read] == 0x20 || buf[bytes_read] == '/') break; sscanf(&buf[bytes_read], "%2hhx", &value); bytes_read += 2; buffer[byte_count++] = bitRevTable[value]; } } length = byte_count; return 0; } /* Adapted from openocd : src/target/image.c : image_ihex_buffer_complete() * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * * * * Copyright (C) 2007,2008 330yvind Harboe * * oyvind.harboe@zylin.com * * * * Copyright (C) 2008 by Spencer Oliver * * spen@spen-soft.co.uk * */ int BitFile::readMCSfile(FILE *fp) { unsigned int full_address = 0; char buf[1024]; fseek(fp, 0, SEEK_END); length = (ftell(fp) >> 1); fseek(fp, 0, SEEK_SET); /* FIXME: Fill in dtime and date from the input file */ if(buffer) delete [] buffer; buffer=new byte[length]; while ((fgets(buf, 1024, fp)) != 0) { uint32_t count; uint32_t address; uint32_t record_type; uint32_t checksum; uint8_t cal_checksum = 0; size_t bytes_read = 0; if (sscanf(&buf[bytes_read], ":%2x%4x%2x", &count, &address, &record_type) != 3) { fprintf(stderr, "Invalid signature %9s\n", buf); return 1; } bytes_read += 9; cal_checksum += (uint8_t)count; cal_checksum += (uint8_t)(address >> 8); cal_checksum += (uint8_t)address; cal_checksum += (uint8_t)record_type; switch (record_type) { case 0: if ((full_address & 0xffff) != address) { full_address = (full_address & 0xffff0000) | address; } while (count-- > 0) { unsigned int value; sscanf(&buf[bytes_read], "%2x", &value); buffer[full_address] = value; cal_checksum += buffer[full_address]; bytes_read += 2; full_address++; } break; case 1: length = full_address; return 0; case 2: { uint16_t upper_address; sscanf(&buf[bytes_read], "%4hx", &upper_address); cal_checksum += (uint8_t)(upper_address >> 8); cal_checksum += (uint8_t)upper_address; bytes_read += 4; if ((full_address >> 4) != upper_address) { full_address = (full_address & 0xffff) | (upper_address << 4); } break; } case 3: { uint32_t dummy; /* "Start Segment Address Record" will not be supported */ /* but we must consume it, and do not create an error. */ while (count-- > 0) { sscanf(&buf[bytes_read], "%2x", &dummy); cal_checksum += (uint8_t)dummy; bytes_read += 2; } break; } case 4: { uint16_t upper_address; sscanf(&buf[bytes_read], "%4hx", &upper_address); cal_checksum += (uint8_t)(upper_address >> 8); cal_checksum += (uint8_t)upper_address; bytes_read += 4; if ((full_address >> 16) != upper_address) { full_address = (full_address & 0xffff) | (upper_address << 16); } break; } case 5: { uint32_t start_address; sscanf(&buf[bytes_read], "%8x", &start_address); cal_checksum += (uint8_t)(start_address >> 24); cal_checksum += (uint8_t)(start_address >> 16); cal_checksum += (uint8_t)(start_address >> 8); cal_checksum += (uint8_t)start_address; bytes_read += 8; break; } default: fprintf(stderr, "unhandled MCS record type: %i", record_type); return 2; } sscanf(&buf[bytes_read], "%2x", &checksum); bytes_read += 2; if ((uint8_t)checksum != (uint8_t)(~cal_checksum + 1)) { /* checksum failed */ fprintf(stderr, "incorrect record checksum found in MCS file"); return 3; } } fprintf(stderr, "premature end of MCS file, no end-of-file record found"); return 4; } // Read in file int BitFile::readFile(FILE *fp, FILE_STYLE in_style) { if(!fp) return 1; switch (in_style) { case STYLE_BIT: return readBitfile(fp); case STYLE_MCS: { int res = readMCSfile(fp); if (res == 0) { unsigned int i; for (i=0; i> 24)]; buffer[i+1] = bitRevTable[0xFF & (val >> 16)]; buffer[i+2] = bitRevTable[0xFF & (val >> 8)]; buffer[i+3] = bitRevTable[0xFF & (val >> 0)]; } length = nlen; } void BitFile::append(char const *fname) { FILE *const fp=fopen(fname,"rb"); if(!fp) throw io_exception(std::string("Cannot open file ") + fname); try { struct stat stats; stat(fname, &stats); size_t const nlen = length + stats.st_size; byte *const nbuf = new byte[nlen]; // copy old part for(size_t i = 0; i < length; i++) nbuf[i] = buffer[i]; delete [] buffer; buffer = nbuf; // append new contents for(size_t i = length; i < nlen; i++) { if(feof(fp)) throw io_exception("Unexpected end of file"); byte b; fread(&b, 1, 1, fp); buffer[i] = bitRevTable[b]; // Reverse the bit order. } length = nlen; fclose(fp); } catch(...) { fclose(fp); throw; } } void BitFile::setLength(unsigned int size) { length = size/8 + ((size%8)?1:0); if(buffer) delete [] buffer; buffer=new byte[length]; memset(buffer, 0xff, length); } void BitFile::setNCDFields(const char * partname) { char outstr[200]; time_t t; struct tm *tmp; if (!ncdFilename.size()) { ncdFilename.assign("XC3SPROG"); ncdFilename.push_back(0); } if (!partName.size()) { partName.assign(partname); partName.push_back(0); } t = time(NULL); tmp = localtime(&t); if (tmp != NULL) { if (!dtime.size()) { if (strftime(outstr, sizeof(outstr), "%Y/%m/%d", tmp)) { date.assign(outstr); date.push_back(0); } } if (!dtime.size()) { if (strftime(outstr, sizeof(outstr), "%T", tmp)) { dtime.assign(outstr); dtime.push_back(0); } } } } unsigned char BitFile::checksum(char *buf) { int i; unsigned char chksum = 0; unsigned char val; for (i = 0; buf[i]; i = i +2) { if (sscanf(buf +i, "%2hhX", &val) == 1) chksum += val; else break; } return (chksum ^ 0xff) + 1; } uint32_t BitFile::saveAs(FILE_STYLE style, const char *device, FILE *fp) { if(length<=0)return length; unsigned int clip; unsigned int i; setNCDFields(device); /* Don't store 0xff bytes from the end of the flash */ for(clip=length-1; (buffer[clip] == 0xff) && clip>0; clip--){}; clip++; /* clip is corrected length, not index */ if (rlength) /* Don't clip is explicit length is requested */ clip = rlength; switch (style) { case STYLE_BIT: case STYLE_BIN: case STYLE_BPI: if(style == STYLE_BIT) { uint8_t buffer[256] = {0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01}; int len; fwrite(buffer, 1, 13, fp); buffer[0] = 'a'; len = ncdFilename.size(); buffer[1] = len >>8; buffer[2] = len & 0xff; fwrite(buffer, 3, 1, fp); fwrite(ncdFilename.c_str(), len, 1, fp); buffer[0] = 'b'; len = partName.size(); buffer[1] = len >>8; buffer[2] = len & 0xff; fwrite(buffer, 3, 1, fp); fwrite(partName.c_str(), len, 1, fp); buffer[0] = 'c'; len = date.size(); buffer[1] = len >>8; buffer[2] = len & 0xff; fwrite(buffer, 3, 1, fp); fwrite(date.c_str(), len, 1, fp); buffer[0] = 'd'; len = dtime.size(); buffer[1] = len >>8; buffer[2] = len & 0xff; fwrite(buffer, 3, 1, fp); fwrite(dtime.c_str(), len, 1, fp); buffer[0] = 'e'; buffer[1] = clip >>24 & 0xff; buffer[2] = clip >>16 & 0xff; buffer[3] = clip >> 8 & 0xff; buffer[4] = clip & 0xff; fwrite(buffer, 5, 1, fp); } for(i=0; i>16) { base = i >> 16; fprintf(fp,":"); sprintf(buf, "02000004%04X%c", base, 0); fprintf(fp, "%s%02X\r\n", buf, checksum(buf)); } if ((i & 0xf) == 0) { fprintf(fp,":"); sprintf(buf, "%02X", (i & 0xf) +1 ); if (clip -i < 0xf) len = sprintf(buf, "%02X%04X00", clip-i, i & 0xffff); else len = sprintf(buf, "10%04X00", i & 0xffff); } len += sprintf(buf+len, "%02X", b); if (((i & 0xf) == 0xf) || (i == clip -1)) { buf[len] = 0; len = fprintf(fp, "%s%02X\r\n", buf, checksum(buf)); } } fprintf(fp,":"); sprintf(buf, "00000001"); fprintf(fp, "%s%02X\r\n", buf, checksum(buf)); break; } default: fprintf(stderr, "Style not yet implemted\n"); } return clip; } void BitFile::error(const string &str) { errorStr=str; Error=true; fprintf(logfile,"%s\n",str.c_str()); } void BitFile::readField(string &field, FILE *fp) { byte t[2]; fread(t,1,2,fp); unsigned short len=(t[0]<<8)+t[1]; for(int i=0; i= length) { fprintf(stderr,"set_bit invalid index %d length %d\n", idx, length*8); throw io_exception(std::string("bit_set_fuse")); } bit = idx % 8; if (blow) buffer[bval] |= (1 << bit); else buffer[bval] &= ~(1 << bit); } int BitFile::get_bit(unsigned int idx) { unsigned int bval, bit; bval = idx / 8; /* Because of the clipping we assume bit 1 if idx is beyond the file length. */ if(bval >= length) return 1; bit = idx % 8; return (buffer[bval] & (1 << bit))? 1 : 0; } BitFile::~BitFile() { if(buffer) delete [] buffer; } const char * BitFile::styleToString(FILE_STYLE style) { switch (style) { case STYLE_BIT: return "BIT"; case STYLE_BIN: return "BIN"; case STYLE_HEX: return "HEX"; case STYLE_HEX_RAW: return "HEXRAW"; case STYLE_MCS: return "MCS"; case STYLE_IHEX: return "IHEX"; case STYLE_JEDEC: return "JEDEC"; case STYLE_AUTO: return "AUTO"; default: return 0; } } int BitFile::styleFromString(const char *stylestr, FILE_STYLE *style) { char * q = strchr((char*)stylestr,':'); int len; if (q) len = q-stylestr; else len = strlen(stylestr); if (!strncasecmp(stylestr, "BIT", len)) *style = STYLE_BIT; else if (!strncasecmp(stylestr, "BIN", len)) *style = STYLE_BIN; else if (!strncasecmp(stylestr, "BPI", len)) *style = STYLE_BPI; else if (!strncasecmp(stylestr, "HEX", len)) *style = STYLE_HEX; else if (!strncasecmp(stylestr, "HEXRAW", len)) *style = STYLE_HEX_RAW; else if (!strncasecmp(stylestr, "MCS", len)) *style = STYLE_MCS; else if (!strncasecmp(stylestr, "IHEX", len)) *style = STYLE_IHEX; else if (!strncasecmp(stylestr, "JEDEC", len)) *style = STYLE_JEDEC; else if (!strncasecmp(stylestr, "AUTO", len)) *style = STYLE_AUTO; else return 1; return 0; } xc3sprog-0+svn795+dfsg/bitfile.h000066400000000000000000000125021337255630200165460ustar00rootroot00000000000000/* Xilinx .bit file parser Copyright (C) 2004 Andrew Rogers 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 BITFILE_H #define BITFILE_H #include #include #include // ----------------------Xilinx .bit file format--------------------------- // 00000000: 00 09 0f f0 0f f0 0f f0 0f f0 00 00 01 61 00 0a *.............a..* // 00000010: 78 66 6f 72 6d 2e 6e 63 64 00 62 00 0c 76 31 30 *xform.ncd.b..v10* // 00000020: 30 30 65 66 67 38 36 30 00 63 00 0b 32 30 30 31 *00efg860.c..2001* // 00000030: 2f 30 38 2f 31 30 00 64 00 09 30 36 3a 35 35 3a */08/10.d..06:55:* // 00000040: 30 34 00 65 00 0c 28 18 ff ff ff ff aa 99 55 66 *04.e..(.......Uf* /* Field 1 2 bytes length 0x0009 (big endian) 9 bytes some sort of header 2 bytes length 0x0001 Field 2 1 byte key 0x61 (The letter "a") 2 bytes length 0x000a (value depends on file name length) 10 bytes string design name "xform.ncd" (including a trailing 0x00) Field 3 1 byte key 0x62 (The letter "b") 2 bytes length 0x000c (value depends on part name length) 12 bytes string part name "v1000efg860" (including a trailing 0x00) Field 4 1 byte key 0x63 (The letter "c") 2 bytes length 0x000b 11 bytes string date "2001/08/10" (including a trailing 0x00) Field 5 1 byte key 0x64 (The letter "d") 2 bytes length 0x0009 9 bytes string time "06:55:04" (including a trailing 0x00) Field 6 1 byte key 0x65 (The letter "e") 4 bytes length 0x000c9090 (value depends on device type, and maybe design details) 8233440 bytes raw bit stream starting with 0xffffffff aa995566 sync word. */ // Modified to reflect parsing - Andrew Rogers // Reference: http://www.fpga-faq.com/FAQ_Pages/0026_Tell_me_about_bit_files.htm //-------------------------------------------------------------------------------- typedef unsigned char byte; enum FILE_STYLE { STYLE_BIT, STYLE_BIN, STYLE_BPI, STYLE_HEX, STYLE_HEX_RAW, STYLE_MCS, STYLE_IHEX , STYLE_JEDEC, STYLE_AUTO}; class BitFile { private: std::string ncdFilename; // key 'a' std::string partName; // key 'b' std::string date; // key 'c' std::string dtime; // key 'd' uint32_t length; // The length of the byte data that follows, multiply by 8 to get bitstream length. byte *buffer; // Each byte is reversed, Xilinx does things MSB first and JTAG does things LSB first! std::string filename; bool Error; std::string errorStr; FILE *logfile; unsigned int offset; unsigned int rlength; /* if != 0 length of data to read/verify*/ private: void error(const std::string &str); void readField(std::string &field, FILE *fp); void processData(FILE *fp); int readBitfile(FILE *fp); int readBIN(FILE *fp, bool do_bitrev); int readHEXRAW(FILE *fp); int readMCSfile(FILE *fp); unsigned char checksum(char * buf); public: BitFile(); ~BitFile(); public: void append(uint32_t val, unsigned cnt); void append(char const *file); int readFile(FILE *fp, FILE_STYLE in_style); public: // Set offset of requested operation in bytes. inline void setOffset(unsigned int of) { offset = of; } // Return offset of requested operation in bytes. inline unsigned int getOffset(void) { return offset; } // Set length of requested operation in bytes. inline void setRLength(unsigned int lt) { rlength = lt; } // Return length of requested operation in bytes. inline unsigned int getRLength(void) { return rlength; } // Return pointer to data buffer. inline byte *getData() { return buffer; } // Return length of bitfile in bits. inline uint32_t getLength() { return length*8; } // Return length of bitfile in bytes. inline uint32_t getLengthBytes() { return length; } inline const char *getError(){ if(!Error)return(""); Error=false; return errorStr.c_str(); } inline const char *getNCDFilename(){return ncdFilename.c_str();} inline const char *getPartName(){return partName.c_str();} inline const char *getDate(){return date.c_str();} inline const char *getTime(){return dtime.c_str();} void setNCDFields(const char * partname); void setLength(unsigned int bit_count); uint32_t saveAs(FILE_STYLE style, const char *device, FILE *fp); int get_bit(unsigned int idx); void set_bit(unsigned int idx, int blow); static const char * styleToString(FILE_STYLE style); static int styleFromString(const char *stylestr, FILE_STYLE *style); }; #endif //BITFILE_H xc3sprog-0+svn795+dfsg/bitparse.cpp000066400000000000000000000070201337255630200172730ustar00rootroot00000000000000/* Xilinx .bit file parser Copyright (C) 2004 Andrew Rogers 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 Changes: Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: Code cleanup for clean -Wall compile. */ #include #include #include #define __STDC_FORMAT_MACROS #include #include #include "bitfile.h" #include "io_exception.h" void usage() { fprintf(stderr, "\nUsage:bitparse [-i input format] [-o output format ][-O outfile] infile\n" " -h\t\tprint this help\n" " -v\t\tverbose output\n" " -O\t\toutput file (parse input file only if not given\n" " -i\t\tinput file format (BIT|BIN|BPI|HEX|MCS|IHEX)\n" " -o\t\toutput file format (BIT|BIN|BPI|HEX|MCS|IHEX)\n"); exit(255); } int main(int argc, char**args) { FILE_STYLE in_style = STYLE_BIT; FILE_STYLE out_style = STYLE_BIT; uint64_t sum = 0L; unsigned int i; const char * outfile = NULL; while(true) { switch(getopt(argc, args, "?i:vo:O:")) { case -1: goto args_done; case 'i': if (BitFile::styleFromString(optarg, &in_style)) { fprintf(stderr, "Unknown format \"%s\"\n", optarg); usage(); } break; case 'o': if (BitFile::styleFromString(optarg, &out_style)) { fprintf(stderr, "Unknown format \"%s\"\n", optarg); usage(); } break; case 'O': outfile = optarg; break; case '?': case 'h': default: usage(); } } args_done: argc -= optind; args += optind; if(argc < 1) usage(); try { BitFile file; FILE* fp; if (*args[0] == '-') fp = stdin; else { fp=fopen(args[0],"rb"); if(!fp) { fprintf(stderr, "Can't open datafile %s: %s\n", args[0], strerror(errno)); return 1; } } file.readFile(fp, in_style); fprintf(stderr, "Created from NCD file: %s\n",file.getNCDFilename()); fprintf(stderr, "Target device: %s\n",file.getPartName()); fprintf(stderr, "Created: %s %s\n",file.getDate(),file.getTime()); fprintf(stderr, "Bitstream length: %u bits %u bytes(0x%06x)\n", file.getLength(),file.getLength()/8,file.getLength()/8); for (i = 0; i < file.getLength()/8; i++) { /* Umprogrammed Bytes are 0xff, so invert to not count them */ sum += (file.getData()[i]) ^0xff; } fprintf(stderr, "64-bit sum: %" PRIu64 "\n", sum); if(outfile) { if(outfile[0] == '-') fp = stdout; else fp = fopen(outfile,"wb"); if (fp) { file.saveAs(out_style,file.getPartName(), fp); fprintf(stderr, "Bitstream saved in format %s as file: %s\n", BitFile::styleToString(out_style), outfile); } else fprintf(stderr," Can't open %s: %s \n", outfile, strerror(errno)); } } catch(io_exception& e) { fprintf(stderr, "IOException: %s", e.getMessage().c_str()); return 1; } } xc3sprog-0+svn795+dfsg/bitrev.cpp000066400000000000000000000032731337255630200167630ustar00rootroot00000000000000#include "bitrev.h" const uint8_t bitRevTable[256] = { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, }; xc3sprog-0+svn795+dfsg/bitrev.h000066400000000000000000000000741337255630200164240ustar00rootroot00000000000000#include "stdint.h" extern const uint8_t bitRevTable[256]; xc3sprog-0+svn795+dfsg/bscan_spi/000077500000000000000000000000001337255630200167205ustar00rootroot00000000000000xc3sprog-0+svn795+dfsg/bscan_spi/README.txt000066400000000000000000000010271337255630200204160ustar00rootroot00000000000000This dir contains simple cores to access the internal SPI-flash via BSCAN/USER1. The bitfiles are provided for your convenience. All IOBs are unused and set to float. The config + JTAG pins have their default pull-up/downs enabled. You have to make your own bitstream if you don't like that. The Spartan-3E Starterkit (ug320.pdf) can have a lot of possible contentions. So BSCAN_SPI needs some more Pins set to work. Often the first run with the -I option still fails. The kit also fails to reboot after some -I run has been done. xc3sprog-0+svn795+dfsg/bscan_spi/bscan_common.v000066400000000000000000000030251337255630200215450ustar00rootroot00000000000000/* from bscan_s6_spi_isf.v */ assign CSB = !(CS_GO && !CS_STOP); assign RAM_DI = MISO; assign TDO1 = RAM_DO; wire rst = CAPTURE || RESET || UPDATE || !SEL1; always @(negedge DRCK1 or posedge rst) if (rst) begin have_header <= 0; CS_GO_PREP <= 0; CS_STOP <= 0; end else begin CS_STOP <= CS_STOP_PREP; if (!have_header) begin if (header[46:15] == 32'h59a659a6) begin len <= {header [14:0],1'b0}; have_header <= 1; if ({header [14:0],1'b0} != 0) begin CS_GO_PREP <= 1; end end end else if (len != 0) begin len <= len -1; end // if (!have_header) end // else: !if(CAPTRE || RESET || UPDATE || !SEL1) reg reset_header = 0; always @(posedge DRCK1 or posedge rst) if (rst) begin CS_GO <= 0; CS_STOP_PREP <= 0; RAM_WADDR <= 0; RAM_RADDR <=0; RAM_WE <= 0; reset_header <= 1; end else begin RAM_RADDR <= RAM_RADDR + 1; RAM_WE <= !CSB; if(RAM_WE) RAM_WADDR <= RAM_WADDR + 1; reset_header <=0; //For the next if, the value of reset_header is probed at rising //clock, before "reset_header<=0" is executed: if(reset_header) header <={47'h000000000000, TDI}; else header <= {header[46:0], TDI}; CS_GO <= CS_GO_PREP; if (CS_GO && (len == 0)) CS_STOP_PREP <= 1; end // else: !if(CAPTURE || RESET || UPDATE || !SEL1) xc3sprog-0+svn795+dfsg/bscan_spi/bscan_s3_spi_isf.v000066400000000000000000000025771337255630200223310ustar00rootroot00000000000000module top ( input gnd ); wire CAPTURE; wire UPDATE; wire DRCK1; wire TDI; wire TDO1; wire CSB; reg [47:0] header; reg [15:0] len; reg have_header = 0; wire MISO; wire MOSI = TDI; wire SEL1; wire SHIFT; wire RESET; reg CS_GO = 0; reg CS_GO_PREP = 0; reg CS_STOP = 0; reg CS_STOP_PREP = 0; reg [13:0] RAM_RADDR; reg [13:0] RAM_WADDR; wire DRCK1_INV = !DRCK1; wire RAM_DO; wire RAM_DI; reg RAM_WE = 0; RAMB16_S1_S1 RAMB16_S1_S1_inst ( .DOA(RAM_DO), .DOB(), .ADDRA(RAM_RADDR), .ADDRB(RAM_WADDR), .CLKA(DRCK1_INV), .CLKB(DRCK1), .DIA(1'b0), .DIB(RAM_DI), .ENA(1'b1), .ENB(1'b1), .SSRA(1'b0), .SSRB(1'b0), .WEA(1'b0), .WEB(RAM_WE) ); BSCAN_SPARTAN3A BSCAN_SPARTAN3A_inst ( .CAPTURE(CAPTURE), .DRCK1(DRCK1), .DRCK2(), .RESET(RESET), .SEL1(SEL1), .SEL2(), .SHIFT(SHIFT), .TCK(), .TDI(TDI), .TMS(), .UPDATE(UPDATE), .TDO1(TDO1), .TDO2(1'b0) ); SPI_ACCESS #(.SIM_DEVICE("3S50AN") ) SPI_ACCESS_inst ( .MISO(MISO), .CLK(DRCK1), .CSB(CSB), .MOSI(MOSI) ); `include "bscan_common.v" endmodule xc3sprog-0+svn795+dfsg/bscan_spi/bscan_s3_spi_isf.vhd000066400000000000000000000107761337255630200226450ustar00rootroot00000000000000library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; library UNISIM; use UNISIM.VComponents.all; entity top is end top; architecture Behavioral of top is signal CAPTURE: std_logic; signal UPDATE: std_logic; signal DRCK1: std_logic; signal TDI: std_logic; signal TDO1: std_logic; signal CSB: std_logic := '1'; signal header: std_logic_vector(47 downto 0); signal len: std_logic_vector(15 downto 0); signal have_header : std_logic := '0'; signal MISO: std_logic; signal MOSI: std_logic; signal SEL1: std_logic; signal SHIFT: std_logic; signal RESET: std_logic; signal CS_GO: std_logic := '0'; signal CS_GO_PREP: std_logic := '0'; signal CS_STOP: std_logic := '0'; signal CS_STOP_PREP: std_logic := '0'; signal RAM_RADDR: std_logic_vector(13 downto 0); signal RAM_WADDR: std_logic_vector(13 downto 0); signal DRCK1_INV : std_logic; signal RAM_DO: std_logic_vector(0 downto 0); signal RAM_DI: std_logic_vector(0 downto 0); signal RAM_WE: std_logic := '0'; begin DRCK1_INV <= not DRCK1; RAMB16_S1_S1_inst : RAMB16_S1_S1 port map ( DOA => RAM_DO, -- Port A 1-bit Data Output DOB => open, -- Port B 1-bit Data Output ADDRA => RAM_RADDR, -- Port A 14-bit Address Input ADDRB => RAM_WADDR, -- Port B 14-bit Address Input CLKA => DRCK1_inv, -- Port A Clock CLKB => DRCK1, -- Port B Clock DIA => "0", -- Port A 1-bit Data Input DIB => RAM_DI, -- Port B 1-bit Data Input ENA => '1', -- Port A RAM Enable Input ENB => '1', -- PortB RAM Enable Input SSRA => '0', -- Port A Synchronous Set/Reset Input SSRB => '0', -- Port B Synchronous Set/Reset Input WEA => '0', -- Port A Write Enable Input WEB => RAM_WE -- Port B Write Enable Input ); BSCAN_SPARTAN3A_inst : BSCAN_SPARTAN3A port map ( CAPTURE => CAPTURE, -- CAPTURE output from TAP controller DRCK1 => DRCK1, -- Data register output for USER1 functions DRCK2 => open, -- Data register output for USER2 functions RESET => RESET, -- Reset output from TAP controller SEL1 => SEL1, -- USER1 active output SEL2 => open, -- USER2 active output SHIFT => SHIFT, -- SHIFT output from TAP controller TCK => open, -- TCK output from TAP controller TDI => TDI, -- TDI output from TAP controller TMS => open, -- TMS output from TAP controller UPDATE => UPDATE, -- UPDATE output from TAP controller TDO1 => TDO1, --TDO1, -- Data input for USER1 function TDO2 => '0' -- Data input for USER2 function ); SPI_ACCESS_inst : SPI_ACCESS generic map ( SIM_DEVICE => "UNSPECIFIED" --"3S50AN", "3S200AN", "3S400AN", "3S700AN", "3S1400AN" ) port map ( MISO => MISO, --TDO1, -- Serial output data from SPI PROM CLK => DRCK1, -- SPI PROM clock input CSB => CSB, -- SPI PROM enable input MOSI => MOSI -- Serial input data to SPI PROM ); MOSI <= TDI; CSB <= '0' when CS_GO = '1' and CS_STOP = '0' else '1'; RAM_DI <= MISO & ""; TDO1 <= RAM_DO(0); -- falling edges process(DRCK1, CAPTURE, RESET, UPDATE, SEL1) begin if CAPTURE = '1' or RESET='1' or UPDATE='1' or SEL1='0' then have_header <= '0'; -- disable CSB CS_GO_PREP <= '0'; CS_STOP <= '0'; elsif falling_edge(DRCK1) then -- disable CSB? CS_STOP <= CS_STOP_PREP; -- waiting for header? if have_header='0' then -- got magic + len if header(46 downto 15) = x"59a659a6" then len <= header(14 downto 0) & "0"; have_header <= '1'; -- enable CSB on rising edge (if len > 0?) if (header(14 downto 0) & "0") /= x"0000" then CS_GO_PREP <= '1'; end if; end if; elsif len /= x"0000" then len <= len - 1; end if; end if; end process; -- rising edges process(DRCK1, CAPTURE, RESET, UPDATE, SEL1) begin if CAPTURE = '1' or RESET='1' or UPDATE='1' or SEL1='0' then -- disable CSB CS_GO <= '0'; CS_STOP_PREP <= '0'; RAM_WADDR <= (others => '0'); RAM_RADDR <= (others => '0'); RAM_WE <= '0'; elsif rising_edge(DRCK1) then RAM_RADDR <= RAM_RADDR + 1; RAM_WE <= not CSB; if RAM_WE='1' then RAM_WADDR <= RAM_WADDR + 1; end if; header <= header(46 downto 0) & TDI; -- enable CSB? CS_GO <= CS_GO_PREP; -- disable CSB on falling edge if CS_GO = '1' and len = x"0000" then CS_STOP_PREP <= '1'; end if; end if; end process; end Behavioral; xc3sprog-0+svn795+dfsg/bscan_spi/bscan_s3a_spi_isf_ext.v000066400000000000000000000023741337255630200233450ustar00rootroot00000000000000module top ( output wire MOSI, output wire CSB, output wire DRCK1, input MISO ); wire CAPTURE; wire UPDATE; wire TDI; wire TDO1; reg [47:0] header; reg [15:0] len; reg have_header = 0; assign MOSI = TDI ; wire SEL1; wire SHIFT; wire RESET; reg CS_GO = 0; reg CS_GO_PREP = 0; reg CS_STOP = 0; reg CS_STOP_PREP = 0; reg [13:0] RAM_RADDR; reg [13:0] RAM_WADDR; wire DRCK1_INV = !DRCK1; wire RAM_DO; wire RAM_DI; reg RAM_WE = 0; RAMB16_S1_S1 RAMB16_S1_S1_inst ( .DOA(RAM_DO), .DOB(), .ADDRA(RAM_RADDR), .ADDRB(RAM_WADDR), .CLKA(DRCK1_INV), .CLKB(DRCK1), .DIA(1'b0), .DIB(RAM_DI), .ENA(1'b1), .ENB(1'b1), .SSRA(1'b0), .SSRB(1'b0), .WEA(1'b0), .WEB(RAM_WE) ); BSCAN_SPARTAN3A BSCAN_SPARTAN3A_inst ( .CAPTURE(CAPTURE), .DRCK1(DRCK1), .DRCK2(), .RESET(RESET), .SEL1(SEL1), .SEL2(), .SHIFT(SHIFT), .TCK(), .TDI(TDI), .TMS(), .UPDATE(UPDATE), .TDO1(TDO1), .TDO2(1'b0) ); `include "bscan_common.v" endmodule xc3sprog-0+svn795+dfsg/bscan_spi/bscan_s3e_starter.v000066400000000000000000000027151337255630200225200ustar00rootroot00000000000000module top ( output wire MOSI, output wire CSB, output wire DRCK1, output wire dac_cs, output wire amp_cs, output wire ad_conv, output wire sf_ce0, output wire fpga_init_b, input MISO ); wire CAPTURE; wire UPDATE; wire TDI; wire TDO1; reg [47:0] header; reg [15:0] len; reg have_header = 0; assign MOSI = TDI ; wire SEL1; wire SHIFT; wire RESET; reg CS_GO = 0; reg CS_GO_PREP = 0; reg CS_STOP = 0; reg CS_STOP_PREP = 0; reg [13:0] RAM_RADDR; reg [13:0] RAM_WADDR; wire DRCK1_INV = !DRCK1; wire RAM_DO; wire RAM_DI; reg RAM_WE = 0; assign dac_cs = 1; assign amp_cs = 1; assign ad_conv = 0; assign sf_ce0 = 1; assign fpga_init_b = 1; RAMB16_S1_S1 RAMB16_S1_S1_inst ( .DOA(RAM_DO), .DOB(), .ADDRA(RAM_RADDR), .ADDRB(RAM_WADDR), .CLKA(DRCK1_INV), .CLKB(DRCK1), .DIA(1'b0), .DIB(RAM_DI), .ENA(1'b1), .ENB(1'b1), .SSRA(1'b0), .SSRB(1'b0), .WEA(1'b0), .WEB(RAM_WE) ); BSCAN_SPARTAN3 BSCAN_SPARTAN3_inst ( .CAPTURE(CAPTURE), .DRCK1(DRCK1), .DRCK2(), .RESET(RESET), .SEL1(SEL1), .SEL2(), .SHIFT(SHIFT), .TDI(TDI), .UPDATE(UPDATE), .TDO1(TDO1), .TDO2(1'b0) ); `include "bscan_common.v" endmodule xc3sprog-0+svn795+dfsg/bscan_spi/bscan_s6_spi_isf_ext.v000066400000000000000000000023271337255630200232050ustar00rootroot00000000000000module top ( output wire MOSI, output wire CSB, output wire DRCK1, input MISO ); wire CAPTURE; wire UPDATE; wire TDI; wire TDO1; reg [47:0] header; reg [15:0] len; reg have_header = 0; assign MOSI = TDI ; wire SEL1; wire SHIFT; wire RESET; reg CS_GO = 0; reg CS_GO_PREP = 0; reg CS_STOP = 0; reg CS_STOP_PREP = 0; reg [13:0] RAM_RADDR; reg [13:0] RAM_WADDR; wire DRCK1_INV = !DRCK1; wire RAM_DO; wire RAM_DI; reg RAM_WE = 0; RAMB16_S1_S1 RAMB16_S1_S1_inst ( .DOA(RAM_DO), .DOB(), .ADDRA(RAM_RADDR), .ADDRB(RAM_WADDR), .CLKA(DRCK1_INV), .CLKB(DRCK1), .DIA(1'b0), .DIB(RAM_DI), .ENA(1'b1), .ENB(1'b1), .SSRA(1'b0), .SSRB(1'b0), .WEA(1'b0), .WEB(RAM_WE) ); BSCAN_SPARTAN6 BSCAN_SPARTAN6_inst ( .CAPTURE(CAPTURE), .DRCK(DRCK1), .RESET(RESET), .RUNTEST(), .SEL(SEL1), .SHIFT(SHIFT), .TCK(), .TDI(TDI), .TMS(), .UPDATE(UPDATE), .TDO(TDO1) ); `include "bscan_common.v" endmodule xc3sprog-0+svn795+dfsg/bscan_spi/bscan_xc5_spi.vhd000066400000000000000000000113551337255630200221500ustar00rootroot00000000000000library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; library UNISIM; use UNISIM.VComponents.all; entity top is port ( MOSI_ext : out std_logic; CSB_ext : out std_logic ); end top; architecture Behavioral of top is signal CAPTURE: std_logic; signal UPDATE: std_logic; signal DRCK1: std_logic; signal TDI: std_logic; signal TDO1: std_logic; signal CSB: std_logic := '1'; signal header: std_logic_vector(47 downto 0); signal len: std_logic_vector(15 downto 0); signal have_header : std_logic := '0'; signal MISO: std_logic; signal MOSI: std_logic; signal SEL1: std_logic; signal SHIFT: std_logic; signal RESET: std_logic; signal CS_GO: std_logic := '0'; signal CS_GO_PREP: std_logic := '0'; signal CS_STOP: std_logic := '0'; signal CS_STOP_PREP: std_logic := '0'; signal RAM_RADDR: std_logic_vector(13 downto 0); signal RAM_WADDR: std_logic_vector(13 downto 0); signal DRCK1_INV : std_logic; signal RAM_DO: std_logic_vector(0 downto 0); signal RAM_DI: std_logic_vector(0 downto 0); signal RAM_WE: std_logic := '0'; begin MOSI_ext <= MOSI; CSB_ext <= CSB; DRCK1_INV <= not DRCK1; RAMB16_S1_S1_inst : RAMB16_S1_S1 port map ( DOA => RAM_DO, -- Port A 1-bit Data Output DOB => open, -- Port B 1-bit Data Output ADDRA => RAM_RADDR, -- Port A 14-bit Address Input ADDRB => RAM_WADDR, -- Port B 14-bit Address Input CLKA => DRCK1_inv, -- Port A Clock CLKB => DRCK1, -- Port B Clock DIA => "0", -- Port A 1-bit Data Input DIB => RAM_DI, -- Port B 1-bit Data Input ENA => '1', -- Port A RAM Enable Input ENB => '1', -- PortB RAM Enable Input SSRA => '0', -- Port A Synchronous Set/Reset Input SSRB => '0', -- Port B Synchronous Set/Reset Input WEA => '0', -- Port A Write Enable Input WEB => RAM_WE -- Port B Write Enable Input ); BSCAN_VIRTEX5_inst : BSCAN_VIRTEX5 generic map ( JTAG_CHAIN => 1 -- Value for USER command. Possible values: (1,2,3 or 4) ) port map ( CAPTURE => CAPTURE, -- CAPTURE output from TAP controller DRCK => DRCK1, -- Data register output for USER functions RESET => RESET, -- Reset output from TAP controller SEL => SEL1, -- USER active output SHIFT => SHIFT, -- SHIFT output from TAP controller TDI => TDI, -- TDI output from TAP controller UPDATE => UPDATE, -- UPDATE output from TAP controller TDO => TDO1 -- Data input for USER function ); -- see XAPP1020 STARTUP_VIRTEX5_inst : STARTUP_VIRTEX5 port map ( CFGCLK => open, -- Config logic clock 1-bit output CFGMCLK => open, -- Config internal osc clock 1-bit output DINSPI => MISO, -- DIN SPI PROM access 1-bit output EOS => open, -- End of Startup 1-bit output TCKSPI => open, -- TCK SPI PROM access 1-bit output CLK => open, -- Clock input for start-up sequence GSR => '0', -- Global Set/Reset input (GSR cannot be used for the port name) GTS => '0', -- Global 3-state input (GTS cannot be used for the port name) USRCCLKO => DRCK1, -- User CCLK 1-bit input USRCCLKTS => '0', -- User CCLK 3-state, 1-bit input USRDONEO => open, -- User Done 1-bit input USRDONETS => open -- User Done 3-state, 1-bit input ); MOSI <= TDI; CSB <= '0' when CS_GO = '1' and CS_STOP = '0' else '1'; RAM_DI <= MISO & ""; TDO1 <= RAM_DO(0); -- falling edges process(DRCK1, CAPTURE, RESET, UPDATE, SEL1) begin if CAPTURE = '1' or RESET='1' or UPDATE='1' or SEL1='0' then have_header <= '0'; -- disable CSB CS_GO_PREP <= '0'; CS_STOP <= '0'; elsif falling_edge(DRCK1) then -- disable CSB? CS_STOP <= CS_STOP_PREP; -- waiting for header? if have_header='0' then -- got magic + len if header(46 downto 15) = x"59a659a6" then len <= header(14 downto 0) & "0"; have_header <= '1'; -- enable CSB on rising edge (if len > 0?) if (header(14 downto 0) & "0") /= x"0000" then CS_GO_PREP <= '1'; end if; end if; elsif len /= x"0000" then len <= len - 1; end if; end if; end process; -- rising edges process(DRCK1, CAPTURE, RESET, UPDATE, SEL1) begin if CAPTURE = '1' or RESET='1' or UPDATE='1' or SEL1='0' then -- disable CSB CS_GO <= '0'; CS_STOP_PREP <= '0'; RAM_WADDR <= (others => '0'); RAM_RADDR <= (others => '0'); RAM_WE <= '0'; elsif rising_edge(DRCK1) then RAM_RADDR <= RAM_RADDR + 1; RAM_WE <= not CSB; if RAM_WE='1' then RAM_WADDR <= RAM_WADDR + 1; end if; header <= header(46 downto 0) & TDI; -- enable CSB? CS_GO <= CS_GO_PREP; -- disable CSB on falling edge if CS_GO = '1' and len = x"0000" then CS_STOP_PREP <= '1'; end if; end if; end process; end Behavioral; xc3sprog-0+svn795+dfsg/bscan_spi/bscan_xc7_spi.vhd000066400000000000000000000145101337255630200221460ustar00rootroot00000000000000-- -- XC3SPROG ISF File for Trenz Electronic TE0741 Kintex module -- Author: Antti Lukats -- converted from V5 version -- -- Green user LED will be steady ON -- Red user LED will be ON during SPI Chip select activation -- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; library UNISIM; use UNISIM.VComponents.all; entity top is port ( RLED : out std_logic; GLED : out std_logic; MOSI_ext : out std_logic; MISO_ext : in std_logic; IO2 : inout std_logic; -- WP IO3 : inout std_logic; -- HOLD/RESET CSB_ext : out std_logic ); end top; architecture Behavioral of top is signal CAPTURE: std_logic; signal UPDATE: std_logic; signal DRCK1: std_logic; signal TDI: std_logic; signal TDO1: std_logic; signal CSB: std_logic := '1'; signal header: std_logic_vector(47 downto 0); signal len: std_logic_vector(15 downto 0); signal have_header : std_logic := '0'; signal MISO: std_logic; signal MOSI: std_logic; signal SEL1: std_logic; signal SHIFT: std_logic; signal RESET: std_logic; signal CS_GO: std_logic := '0'; signal CS_GO_PREP: std_logic := '0'; signal CS_STOP: std_logic := '0'; signal CS_STOP_PREP: std_logic := '0'; signal RAM_RADDR: std_logic_vector(13 downto 0); signal RAM_WADDR: std_logic_vector(13 downto 0); signal DRCK1_INV : std_logic; signal RAM_DO: std_logic_vector(0 downto 0); signal RAM_DI: std_logic_vector(0 downto 0); signal RAM_WE: std_logic := '0'; begin IO2 <= '1'; IO3 <= '1'; RLED <= not CSB; GLED <= '1'; MISO <= MISO_ext; MOSI_ext <= MOSI; CSB_ext <= CSB; DRCK1_INV <= not DRCK1; RAMB16_S1_S1_inst : RAMB16_S1_S1 port map ( DOA => RAM_DO, -- Port A 1-bit Data Output DOB => open, -- Port B 1-bit Data Output ADDRA => RAM_RADDR, -- Port A 14-bit Address Input ADDRB => RAM_WADDR, -- Port B 14-bit Address Input CLKA => DRCK1_inv, -- Port A Clock CLKB => DRCK1, -- Port B Clock DIA => "0", -- Port A 1-bit Data Input DIB => RAM_DI, -- Port B 1-bit Data Input ENA => '1', -- Port A RAM Enable Input ENB => '1', -- PortB RAM Enable Input SSRA => '0', -- Port A Synchronous Set/Reset Input SSRB => '0', -- Port B Synchronous Set/Reset Input WEA => '0', -- Port A Write Enable Input WEB => RAM_WE -- Port B Write Enable Input ); BSCANE2_inst : BSCANE2 generic map ( JTAG_CHAIN => 1 -- Value for USER command. ) port map ( CAPTURE => CAPTURE, -- 1-bit output: CAPTURE output from TAP controller. DRCK => DRCK1, -- 1-bit output: Gated TCK output. When SEL is asserted, DRCK toggles when CAPTURE or -- SHIFT are asserted. RESET => RESET, -- 1-bit output: Reset output for TAP controller. RUNTEST => open, -- 1-bit output: Output asserted when TAP controller is in Run Test/Idle state. SEL => SEL1, -- 1-bit output: USER instruction active output. SHIFT => SHIFT, -- 1-bit output: SHIFT output from TAP controller. TCK => open, -- 1-bit output: Test Clock output. Fabric connection to TAP Clock pin. TDI => TDI, -- 1-bit output: Test Data Input (TDI) output from TAP controller. TMS => open, -- 1-bit output: Test Mode Select output. Fabric connection to TAP. UPDATE => UPDATE, -- 1-bit output: UPDATE output from TAP controller TDO => TDO1 -- 1-bit input: Test Data Output (TDO) input for USER function. ); STARTUPE2_inst : STARTUPE2 generic map ( PROG_USR => "FALSE", -- Activate program event security feature. Requires encrypted bitstreams. SIM_CCLK_FREQ => 0.0 -- Set the Configuration Clock Frequency(ns) for simulation. ) port map ( CFGCLK => open, -- 1-bit output: Configuration main clock output CFGMCLK => open, -- 1-bit output: Configuration internal oscillator clock output EOS => open, -- 1-bit output: Active high output signal indicating the End Of Startup. PREQ => open, -- 1-bit output: PROGRAM request to fabric output CLK => '0', -- 1-bit input: User start-up clock input GSR => '0', -- 1-bit input: Global Set/Reset input (GSR cannot be used for the port name) GTS => '0', -- 1-bit input: Global 3-state input (GTS cannot be used for the port name) KEYCLEARB => '0' , -- 1-bit input: Clear AES Decrypter Key input from Battery-Backed RAM (BBRAM) PACK => '1', -- 1-bit input: PROGRAM acknowledge input USRCCLKO => DRCK1, -- 1-bit input: User CCLK input USRCCLKTS => '0', -- 1-bit input: User CCLK 3-state enable input USRDONEO => '1', -- 1-bit input: User DONE pin output control USRDONETS => '1' -- 1-bit input: User DONE 3-state enable output ); MOSI <= TDI; CSB <= '0' when CS_GO = '1' and CS_STOP = '0' else '1'; RAM_DI <= MISO & ""; TDO1 <= RAM_DO(0); -- falling edges process(DRCK1, CAPTURE, RESET, UPDATE, SEL1) begin if CAPTURE = '1' or RESET='1' or UPDATE='1' or SEL1='0' then have_header <= '0'; -- disable CSB CS_GO_PREP <= '0'; CS_STOP <= '0'; elsif falling_edge(DRCK1) then -- disable CSB? CS_STOP <= CS_STOP_PREP; -- waiting for header? if have_header='0' then -- got magic + len if header(46 downto 15) = x"59a659a6" then len <= header(14 downto 0) & "0"; have_header <= '1'; -- enable CSB on rising edge (if len > 0?) if (header(14 downto 0) & "0") /= x"0000" then CS_GO_PREP <= '1'; end if; end if; elsif len /= x"0000" then len <= len - 1; end if; end if; end process; -- rising edges process(DRCK1, CAPTURE, RESET, UPDATE, SEL1) begin if CAPTURE = '1' or RESET='1' or UPDATE='1' or SEL1='0' then -- disable CSB CS_GO <= '0'; CS_STOP_PREP <= '0'; RAM_WADDR <= (others => '0'); RAM_RADDR <= (others => '0'); RAM_WE <= '0'; elsif rising_edge(DRCK1) then RAM_RADDR <= RAM_RADDR + 1; RAM_WE <= not CSB; if RAM_WE='1' then RAM_WADDR <= RAM_WADDR + 1; end if; header <= header(46 downto 0) & TDI; -- enable CSB? CS_GO <= CS_GO_PREP; -- disable CSB on falling edge if CS_GO = '1' and len = x"0000" then CS_STOP_PREP <= '1'; end if; end if; end process; end Behavioral; xc3sprog-0+svn795+dfsg/bscan_spi/sp3adsp-fg676.ucf000066400000000000000000000001431337255630200216270ustar00rootroot00000000000000net "MISO" LOC = "AF24"; net "MOSI" LOC = "AB15"; net "DRCK1" LOC= "AE24"; net "CSB" LOC = "AA7"; xc3sprog-0+svn795+dfsg/bscan_spi/xc3s1400an.bit000066400000000000000000022110651337255630200211330ustar00rootroot00000000000000 ððððatop.ncdb3s1400anfgg676c 2009/ 4/17d 13:17:20e ìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿª™0¡ 1a î3!<„1¡)1A/1Âc“0áÿÏ0Á122Á2á2¡2a23Aò3b0"0¡P`ˆ’d€€@€€€@€€€@€€€@€€€@€€€@€€€@€€€@€€€@€€€@€€€@€€€@€€€@€€€@€€€@€€€@€€€@€€€@€0|P                  @ 0  0€    €` @ 0ÿÿÿÿ$p$@$@$@$@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÎ@`L@`ŠŠÈÉÀóâÇÏ€D@@ €)408  0@4" €@``p ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 0$p$p$p$p$p$p$@•òòòò$@$@ÿÿÿÿÕÝÿßûÿÿ¿ïÿ÷ÿýÿÿ¿ûÿªªÿÿÿÿÿÿÿÿÁœ@@œL@` ‰€€€ŠÒÃHÄÀDà@ãëƒÇ"€@€ˆ€ €€ @„€ ¸` Àt8Px:€(0080` À8 P04à QÀ’À pàd(@0p@p7h@`@p €(!€€  @ €  p `p 0 Œ0 ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ00$p0$p0$p%N{%N{%N{%N{%N{%N{%N{%N  "w»GG3Ï»"wGG3UDw3ó ?UÿÿÿÿÎ@`Î@`L@`Î @`  Š Š Š Š  €€³¡GCDÓà"³ÀÃàAêÈ@€@ !! Àh` xÀ`à€àÀðP@  Pä1d€À0äT Ø€ €à€À8À€@0€ô@€€ð \pAð\` 4€„ ‚@€€€~p °p0 p 40  0ÿþÿðÿÿÿÿÿÿ€ÿÿÿÿÿÿ€ÿÿ€ÿÿÿÿÿÿ€0$p0$p00 00$@$@$@ ÿÿÿÿÿÿÿÿÿÿˆÿÿÿÿÿÿÿÿM@`   ‹€ƒ€"à@Dã#ƒ#ËÈÀ €ÀP!6€ <8€.`°,   `€ (` @D@<p”€`0 @@0&`@p € p 0 ÿÿÿÿ$p€€0 0¼ @ @  €€@ 0  @ 0 €@0 @@ 0€A€%N•û%Nû%Nû%Nû%Nû%Nû%N ððÌ̪ªÿÿªªÌÌððÿªªÌÌððªª33ÿÿÿÿL@`(€@`L@`(€@@Š(€Š(€Š(€ˆ(ÉÃ×#ƒË×#ÀÇ@!„ÀÀÀà @@`@àà@  @@@@@@0Ppppppp%N•û%Nû%Nû%Nû%Nû%Nû%N ÿÿÿÿÿªªÌÌððÿªªÌÌððÿªªÌÌððªª33ÿÿÿÿ@`@`@`@@ ‚(€‚(€‚(€€(ÀÃ#“É#Ã×#ÓÁ#ÀÇ€À€ÀÀ€!À@@@`ààà€€€€ˆ€@  00¾0p @@p@P@@p€€0€0   @ ÿÿÿÿªÿ00 0 0 ÿÿÿÿ Á €Ç  @ ‘0 € @ 0 ÷ÿ0ÿÿÿÿ €€€&  Pp0  € @@Ä€€@  0€      €   0 €@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@€        Ç(€<.h8Àˆ``@8À@€`¸€€4t)€ €DÁ *@‚€@$@€@@ €€€ €€„€ pP”`° 0 P 4 PP0° 0 0  0p8üüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ00 0$p 0$p$p$p$p0  $@$@$@$@%N•û%Nû%Nû%Nû%Nû%Nû%N %N•û%Nû%Nû%Nû%Nû%Nû%N ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿªªÿÌ̪ªððÿÌ̪ªððÌ̪ªððÿÿÌ̪ªððÿÌ̪ªððððÿªªÌÌÌÌUUÿÿÿÿÁ À9ÀΘ ÀΘ À€ À À ÀÎ ÀL ÀÎ À@ @‹€(Ä€€‹€‹€€‚(€‚(€‚(€Š(€Š(€Š(€ˆ(Ã×â‚ÇÃGËÃÈ¢ÅÛ€ÀËÇÁÃÇÉÇ#ÀÇÉÀÇɃãÉÀ#À€ „0@A@€€@À@@ÀÀ„@À@€@@(* 4€<0,Hà@(€€ 0 ˆ€à€ <6( @@0à@@@àD„@@€€ €€(  PP`p `P `*Pe©@iP pP°  `€ 80 @@@0@0P € p ßÿ€0€ÿÿÿÿ€ €P€€À@  ` € €p   €   €€€ €@0°°Ç €€€@@Pppp0p0 ÿÿÿÿÿÿÿÿ 1@1@ %N•û%Nû%Nû%Nû%Nû%Nû%N %N•û%Nû%Nû%Nû%Nû%Nû%N ÿªªÌÌððÿªªÌÌððÿªªÌÌððªª33ÿÿÿÿªªÿÿªªÌÌððÿÌÌððªªÿÌÌððUU À À À @€Î À ÀL À‚(€‚(€‚(€€(€Š(€Š(€Š(€Ã“É#@ÃÀ“É##“É#ÀÇÉ€ƒÈ×Á#ËÁÃÃÈÇÀ €À €@€@À@€À@!„À<@@@ @`ààà@à  €€€ €€°°`°@D0@ 0 @€ÿ€0€ÿÿÿÿ€ €€€€€&  0@€€p   €   €€€ @€ €Çà@`à  @€@€@`0 0.p`°  0 „€ P0P00€0 ÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$p0$p 0$p$p$p$p $@$@$@$@$@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÏœH L˜H  œ  €‹ ‹  ËÈÊÓÀ"ÄAãóÀˇÀ"€Ã !@€0È*(xPx@10À66 0 @ @0`` @0 ` °   0°0 pp€€ °€0@0@%N•û%Nû%Nû%Nû%Nû%Nû%N ÿªªÌÌððÿªªÌÌððððÿªªÌ̪ª33ÿÿÿÿH ÆH (€ÖH À@0Š(€â(€†(€(À×#ƒÈ×Á#ÀÉÃÀÇÀÀ„@!Àà@@`àà@€@€@ @@@0@00pp ÿÿÿÿ1@%N•û%Nû%Nû%Nû%Nû%Nû%N ÿÿÿÿªªÿððÌÌÿªªððÌÌÿªªÿÌÌððUU H (€H H (€€‚(€‚(€‚(€ÃÉ€ÓËÓÁ˃ÈÇÓ€@€€€!À<àà €€@  @€€€€€ 0`0 @@P@@0@p01@p@@@Lðð €€€@¿ÿÿÿÿÿ  @ € àô 0@ € € À€@€ p €€€0 Ç÷ÂÏ~ö‹Ÿÿ­Ï\þ¹ÞÕ_χ“¾øÂ…‹½Þs_øµÇ?þxø\8q¾×û™G{ôü¹ðB˜;wñÿDï\ø|ø‘_þ—•Üü‹ÞëáXÎ=7÷Ÿîâ©s¯'_?÷ä£áÜ?´_¹õg½÷WÞë½®»Ö¹v> ?~þÍpäüû!=ÿz8yþ¹Î_ á“w÷Âó¡Ô{ ^¿’+‹áÄ#fQ;vï'b'ÀèÅNšå÷¯ÄÎ`b:Eì  aŠriÇN€“ÅN¦;h˜4v°¥ÎûµáŽwüA¿^‘O:ŒgÌ;ÞñxüöLïë,ÆN˜ï®\ˆ–ÅNàÀÍe½Ø)@ã$Yäà[)Ä9À–ŠV:÷rì$ )Zi’•AŸ‚-µß*WË»?¾:táÖ¾¤P´ËU²ûãÓ}ËfVëJì  YZ±€Fqó“–±3€&¹7´¯ÇΛ¢:_)—,5/u˪–¾„Y•úÐÑÕ¦j~Í!wmqêÜþeScøøR¯\1ôBwwgo¼z±Œþõûèg¨Baše#?ú5nô3ò‘Ï€Ã"ÁjLÆÕ”2 K»»-b„Y±ç!/{Íd–ÕW™¢èë²!îæÍÃ^Ô}0mmãåÓ*¬7ÀX:;D¦A;h˜,vûꞇžýêzök›,[ N lc%ܼyûö»ïÞ¼¹VcÕzêTìÜ` !tŠ,dË!ühx©Žg‹gûÀhŽögñ(þ´Žg‹ñÕAŒ™L¥…d¡šg!IÚí°°Ûív²¼;;˜BIÉ“´¾b cZÆ"f^Ð8óI8;˜n·îˆf‡±õºšÁ#Y;ƒV`/Ú[D`4'†ùØ•õOŸwî¼Ûó‰ ê’÷î ð}ËÖõ¥ðëúÔõõ}léaÆëâK;î[’IfSßÙµ÷wømi¯ëì(]·å#l§³f½6ª”‡I[)ÅΚå\;fI;‰R+“UÕÆ÷ëåûòU|÷ÝÛ·oÞ îÿ`tEÿÛ‰~|?®ÝFÑÔÊ¿4¨_cæS)Y(;ÏBHÚíöBñÑcU3_®ý£ÊûÏš'y’VwÃò¤j×§`rzûv­ÿäı#0®lÍöé51ScÛXß٢ؕ¼^ßìÝZ׌!Yý–¯ÕïLFI‚I99ˆ½uûoDȦUõ ji]Ëí8©À4Êû! kb¾1»ÔÛù`tÝ"1܈Lžq_™eyµª‹eG^hôérâ ˆkµöÜ8ý01cV˜»N°6V k³òÍ63¿¡eXeö]U¾Çט +¥ m·WÛ6{še̱]¶d›}ÑÛáuh’Éö©­$Ùü503ÜóÁè’ò’—„­oŸ¡a®ÌçÓ¬î/E¸¼¾½’¬ze«×m´·hÿF¹,oó:°¹íÆaîîð:Dv0ßÜCÃå«›ný`BÒ"rР˱€FȆy¼`+@‡iå z3×)feåK++ÿWUÈW¾´²>ÆÎÖ$žlèÕKòàÒ¦fËÞoœîyèÙþ½‡žý±-–»&$Ì”Þ'ï¹ç±Ç~øÔgO]¸ò«Gþ»ýÞü'/ÿÎék¿wúï~8|6v~0m:![®â«el¥!<“öcg°ŒæÕp-«ã™ÑWr0†vh'a!„…¢ýäåw–óöò÷žIÈÛŧžþFr+vz0uò©7ÒôþYš†ûË>•eÕ¾‘’`t÷…ðÛïägÊ­n'=yw{ùl§N†4k-Õã£è”ÿ|l±}¶–Ï\½•vë‚©[¡ûëáX¸t+vv0}Òùn·“¤áÁpã›î™ÎÝ­ìÖé<„Ÿo…|nuÎQ`—Šö—“+Ýö_ö÷ÚÅbXNúžKËk0šÅÖÜk­vñ™jû±òŽá‰pâµÐ*B~ûįÄΦN«QJªVåöWÊtê¶"O- Æ´Tvz#<ß©>E¬ÛúŸ¦Ê†¿˜L“ÅjU÷œÁTóÕÕvuqê•íb03©þÏ>ßýñ­}Êš¢þÌ3B±Óü~%û¢_+_¬‰…9Ga6ÖÌ·a–L®Â)y0¯—z;[mÆ3(ie9¬Þó¹÷ƒñ½:¬™ŸE+ 'ºƒy±±¼z¦ßƒZg’,TÖV¿y‚)÷À[ïýã—o|4ûÔüë±…þ:,,´Ch_‹L­åÖOWdýÝ"éVÓ.ÇK¦ÞÙ+!œ\,;Õé,­LOòØ9ÁT»B÷•pìâÕ¬ü0u£ú…*L³ÛÕSƒIŸéäõ~ÇÌ£°'Õ8IÝ<´ë.UÞû%f €=顪˜ÕêÞj};j:0µºÕßÙVV珞ëkÔGŠþk ­`D½Á·çûûGûÍ>x½Zçõö•ª¤Ø¢^χ¢“õzu1}:ø,e|?€-¬­•ÚLìüà`í}ŒØa}|7[`¶ì½v>É5òÉѯ~79úµ5Ë«‡Ñ ïñþþÔwVV¾õƒrã[+ßYùß••ïß¾íÞF÷Ì|¿f>y-„võkÔŸ÷ã©×BÑöëŒlX3ŸT“«±}Fí<Œea¹•|ïË—C+´øà­§Ë–V;[íºvìò­ØéÁôi¥Iõ¨lž·C~÷KåfúéêË9uó0®Kå’¶Šð“Ù‘ú!õ+×ëÇÑOž5ŒíÓéò#W—ZÅbrãÞ3Ù±ú—¯¿¹;+˜Jg«_¹®µCèdçÃ/µ®gípº~Á˜™0–VÕ§ºa9¼Q^Ÿòª¥8’WשùŘiÁÔê>^®ò4„¿ºÚªg#}üîUû#¹ß§`$Õ½Ýyû‡òÐJC²´ºTe­ú‚ÕR;ãÊ–ëØ__ai®Ú8^ïz”vv¼ÿTûÅOôwÓ^è¤UËüR5DE:˜ØÝL›µùdSKõìóÀîß´u¾þâ01‡™ë@ߨ 0CòÑOéM< h^gäSòÉg ’ÆNØ\;h˜^ì` yµR, £;Á>èÆNØŽ©ˆ8Ì\§à å!ôbçM¢CÁÄ)D€C©õ„ù‘ÿ g8cg‘Ï8´²Ø @%‰@D£ÿÿÄΠñŠØ À6²Ø Àlu–Óƒ˜ï˜¬Vì`F½N™ï›ÙÕ ß_‰L³N±¾¥! h¢\Ú±“€æZ)ÅÎîÅN¦»vLJ+سtíN) h¦¤Zµ®ÄN¦Y¾á¡ùÀ¤wî.W«üàÓ€&¹{Ív|M{µæR•dÕj1JÐ4©ª`—’ -w|ŠòØ,Qm¬ðSó&ó,Œ¯ØØ”t0-Zíðvì IŠ–Ç+8¬ŽÅNš¦0‡›(`Ÿtw>Øã±€©p#v0£²Ý:êÄðŽw|“Žßzh¥bÞfT6âñû=õ¼ã˜ß…bòo 3­ˆBïüÉ}O\ý¯oÃûö-±óƒév´ÛYŒl&‹4È¥/Të$tÊu–‡:ã{ðŸ«uZ„·_N«­³ïÄÌ€}s¼\ÚgBè–±ÓÄëeì…"‰œL«{—BHz!üÔ‹ƒX¶%C>;1˜FYɪoûzƒXî'åµ+˜L³³—ú÷|YoŸ a>÷ã5Œë¾×Å<Ôë¾X ÁÔj•>Œ÷Wõí|¸×YÓrç1À¦ŽW_Iœ¬7WûMÕ6¿¦g­ö²áþïâ\½¾r‰Â!U^‘Z²kTW¦µqd]\ß&¯V½ÈIŒ­µYc’ ®M[u´m¥{L‰™7µÝi ¨×wü>•¦ƒÎ6ì#u“M»)Œ¨;±wz²Øá€§v:`Ë..°ßòj5ížpˆèN°&W;“Ók…î›ÿÓ{=/—vúÊí#½÷õޛåÒ —>öïeË]ÃW·úóÿhÉß.Zxc3sprog-0+svn795+dfsg/bscan_spi/xc3se-fg320.ucf000066400000000000000000000004161337255630200212640ustar00rootroot00000000000000net "MISO" LOC = "N10"| IOSTANDARD = LVCMOS33 ; net "MOSI" LOC = "T4" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ; net "DRCK1" LOC= "U16"| IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ; net "CSB" LOC = "U3" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 6 ; xc3sprog-0+svn795+dfsg/bscan_spi/xc3se_starter.bit000066400000000000000000010523301337255630200222150ustar00rootroot00000000000000 ððððatop.ncd;UserID=0xFFFFFFFFb 3s500efg320c 2010/02/09d 18:18:15eT€ÿÿÿÿª™Uf0€0``0 1å0À “0À0€ 0 0€0@Pš@.P*€€@0 € €@€0 €€€ 0€ €€€00`0  € p€ÿÿÿÿÿÿÿÿÿÿúúósÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿ 0000 000 0 0 %N{%N{%N{%N{%N{%N{%N{%N  "w0?3U3Ï ?Ý''"w3U»''"wüü3ÿÿÿÿ€€ L À£ À L ÀÐ @ À @` €DŠ “ €DŠ €€D€€(DÁÈÓ€#ÀÇÀ£#À#Ã#ÀÀP€@@@@€€ÀÇðHƒ€  €‡€@x¤À Ph  x ÀÀ` @€@H9@¦p À`€0@ôDP@ÀçÇt>à@@€àq@\hãÏ@ˆ4å@ä@€  @€ 0 0@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿÿÿÿÿÿÿÿÿ$p$p$p0$p$p$p $@$@$@ÿÿÿÿÿÿ€€€€ÿÿÿÿÿÿÿÿÿÿ€ÿÿÿÿ€ @ €œ @€ˆ‰€€ÇÃ"ƒÈTà#GãÀÀ@@!  @ €!@@@P(P h:€Àà 00@@00´@ 80€4 @ pÀ À€€€@ @ € @ °``° @´`°° 00 P 0   @00€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 0$p$p$p$p$p$p$p$p$@$@$@•òòòòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿ¿ÿ¿ïÿ÷ÿÿ¿ÿßïÿðð œ ÀA @œ€‹€‰€€€×ÀÁSÂGÇÆÇÒDCàÀA @@ ( €Ð84\ €`@@Pàð±Ð€à@(`@ 8€`à0à`´€Áð@€6à€€$€ @ `@ ° P t0  0ÿÿÿÿ$p $@$@ ÿÿÿÿÿÿÿÿ»»ÿÿ €@ @€ €ˆ€È€W#È€ @@ <4,@ „ 00ppp¼°  € ð @  €€ 0 @€€ €€00P p  ÿÿÿÿ01@ %N•û%Nû%Nû%Nû%Nû%Nû%N %N•û%Nû%Nû%Nû%Nû%Nû%N ÿÿÿÿªªÿÿªªÌÌððÿªªððÌÌÿÌÌððUUÿªªÌÌððÿððÌ̪ªððÌÌÿªªÌÌUUÿÿÿÿ€€ À À(€ ÀÎ À(€Æ ÀÖ À(€À @€‚(€‚(€‚(€Š(€â(€†(€(É€Ë×Á#ƒÅÓ#ËǃÈ×Á#ÇË#“ÀËÄÃ#@€€@À@@À@€@À<pà @@@@€@àà à à€€ €€(   ` @@@PP0@0 €€ÿÿÿÿ€÷ÿ€ €@@€€À€@R<€ 0@ €€À €p  € °@€  €€€ @€ ÇÁÿÿUª04?> _ ß¿¿_ß ?Àÿÿß 44>>€€€€@@@ @ €€€€€„€€€ €!!!  …  @!„  ‚ À @À €€€€ €€¡@€   ÀÀ€  À @ €€‚„„@!!‚!„  !ˆ!„„„„A„‚„…„@À @‚A    €€‚À…ƒA@  €€ €€ Á€ @€€€€ €€€€€€€A€€€€€€ Á€€€€€€„À ‚„ @À„@„„ ‚À„‘„‘@‚ƒ „€€€‘!@@€@€€€€€À@€€€€€€@€€@€€€‰€€A€@A€€À   ‚‚À„‚ ACCC„ˆÈCAACCÿÿÿÿÿÿêÿ  õõÿÿÿÿÿÿÿÿëÿàðôðÿÿÿÿÿÿÿÿÿÿ<ÿOÿÃÿÿÿÿÿÿ<<ÿÿÿÿÿÿÿÿ<ÿÏ <ýÿÿÿ<<‚( ‚Àa*M¨a*M¨a€ a *@¨ÿÿÿÿÿÿÿÿÿÿþÿÿÿ€€€€ €@À€€€€€‚ÀÀ€€€€À Cÿÿÿÿÿÿÿÿÿððÿÿÿðð‚ ‚À@@€@AAAa ÿÿÿ¯PÀ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ @ €€€  ÀÀ €€€€€€€€€€€€€€„À„À„ÀÀ„À€€€€€€ €€ €€ À À ACC!Cÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ( À‚( ’À‚( ’À€€€€€€   ÀÀ€€€€€€€€€€€€€‚À‚À‚ÀÀÀ€€€€€€€€€À À BCBCCÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ À‚ ’À‚ ’ÀÀ À @ @ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@@@ @ @@@@@@@@@@À € @  @Aÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€D$ €€‹Œ 0¡ 0¡ 0¡0áÿ0Á0ÁÐ0¡ xc3sprog-0+svn795+dfsg/bscan_spi/xc6slx45-fg484.bit000066400000000000000000055233151337255630200216700ustar00rootroot00000000000000 ððððatop.ncd;UserID=0xFFFFFFFFb 6slx45fgg484c 2010/05/03d 18:17:25e¦tÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿª™Uf0¡ 1¡(1A=1a î1€“0áÏ0Á 3<È14!21áÿÿ3!3A32a22¡2Á2á3¡â3 0"0¡P` R© 1 € À  €€€@ €@ A ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ…@ @@@@ !   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ @@@@@€ €€ €„!ÈCÿÿÃÃÿÿÃÃa&  <<<< „@@A €€€€ ÀÀ €€ €€€€€€€€‚À‚ÀÀÀ€€€€€€@€€À À ACACÿÿÿÿÿÿÿÿÿÿÿÿððÿÿÿÿðð‚( ’À‚( ‚À!  ¡@ !A‚€ˆ€À€€ @  !ÀÀÀ€€@€€@€€€€€€€€€€€„À„À„ÀÀÀÀ€€€€€€€€€€€€À À À ACACACÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‚ ’À‚ ’À‚ ‚Àˆ   ‚@ƒ À €€@@À€ˆ€€ÁÀ‘@‚   „ Àƒ €A€À €Á@ A€@@Á‚Aƒ‚BÈCHBq{ÞŽ`@1à @À` !„  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!€€@€ €  €‚!‰ € ‘ƒ€ƒ‘!‘€ €@ÈCÿððÿððÿÿÿÿa‚ ððÿððÿ<ÿ<ÿÿÿÿ<ÿ<þÿÿÿˆ €@ ‚@A¡Á  € €€ À€€ Á@€@€@@€ ‚ ‚„A‚@‚‚@À€À€€€ @ @ @@ ‚€€ƒAÁ€ÁÀ‰ˆˆÀÀ@ˆ À @€…!€‘‘A€@À@ƒ@A!‘€€ €€€€€€€€À!Àˆ‘ˆÀˆÀÀ!‚ ‚À @@ Á ‘Á@ À€€ €€€!‘ˆ‘€€ ‚ ¡@ƒ !!€ÀˆÀ¡ À¡ ˆÁ @@ȈÈÈCACÀÀÀÀŸÿÿÿÿÿÃÿÿóÿÿ ÏÿÿÀÏÿÿÿÿÏÏÏÏŸÿÿÿÿÃÿÿóÿÿ ÏÿÿÀÏÿÿÿÿÿÿÿÀÀÿÿó0ÿÿÃÿÿù ÿÿüÀÿÿðÃÿÿó0ÿÿ™™ÿÿÿÏÏÿÿó0ÿÿÿ<ÿÿù ÿÿüÀÿÿðÃÿÿó0ÿÿÿÿÿ@€,’@ )’@〄)’@ã€-   ÿÿÿÿððÿðUUÿðÿðÿÿððÿðUUÿðÿð€ÿÿÿUUÿÿÿ€„ €   ‚Á  !€A@€¡@ˆ  ˆ  ˆ  !  À€ € À€‰€… Á !À@@€ € ‰‚!€‰…À „ˆ‚ˆ‘@@!A€€!€€€€€€Á‘„€!€‘ ¡ A€€ˆ‚Àˆ@¡ ˆ‚‰@„A „„„@ €ˆ„ À€€ˆ‰€€A€‚‰‚ ! ˆÁ @‚ÈCBAÈCÈCˆððððððÿÿÿÿ ÿÿÿÿÿÿ ÀÿaJˆ¨a Ž…* ÿððÿðÿÿÿÿ<<<<ÿÿÿððÿðÿÿÿ8<<<ÿÿÿÿððÿ ÿ<<ÿÿÿððÿÿ<<ÿ À‚‚„€…„„€€ÀÀ„!À„ „!„  €€€ À‚À€À Cˆÿÿÿÿfffnffff     €€€ À€€€€€€€€‚À‚ÀÀ€€€ €€ À CCÿÿÿÿÿÿÿÿÿÿ( À‚( ’À ‚ €ˆ€ @€€€„À€ACÿÿÿÿÿÿ Àˆ @  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  @@ ˆÀˆÀ¡!       €€€€€€‚@ !@@ €€‚ @€@€€ @€ÈCÈCÿððÿððÿÿÿÿ ¨a ÿÿÿÿÿÿ„€À„ @ˆ€€€ €€€€ˆˆˆˆ  €€ €€‚@€€‘€€À‚ ‚ˆ€€@€ ¡ƒÈC @¡ÿÿÿÿ@@ À  „„  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÀ @ @@ €@‚€À úÿÿÿ  ÀA!@ €€ €@€@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€D$ €€,{E 0¡ 0¡ 0¡0áÿ0Á0!’ä0¡ xc3sprog-0+svn795+dfsg/bscan_spi/xc6slx75-t-fg484.bit000066400000000000000000112672761337255630200221440ustar00rootroot00000000000000 ððððatop.ncd;UserID=0xFFFFFFFFb6slx75tfgg484c 2013/10/23d 17:01:38e%ndÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿª™Uf0¡ 1¡1A=1a î1Âà“0áÏ0Á 3<È14!21áÿÿ3!3A32a22¡2Á2á3¡â3 0"0¡P`¶¡ 1 €@ €‚@ € €€@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@@@@@@@  !€€ €€€ A  @ÀÀˆˆ€€ÁÀ  ÀÀÀ€€€€€€€€€€€€€€€€€€€‚À‚À‚À‚ÀÀÀÀ€€€€€€€€!€€€€ÀÀ À "A"A"ÿÿ<<ÿÿÿÿÿÿÿ<<ÿÿÿÿÿÿÿÿÿÿððÿÿÿÿÿðð( À‚( ’À‚( ’À‚( ‚À ‚€€€€ÀÀˆ „ ! „   !A!!‚…€¡¡A€  ÀÀ„ ‚ @ÀÀÀ€€€€€€€€€€€€€€€€€€€€€„À„À„À„À ÀÀÀ€€€€€€€€€€€€€À À À !ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ À‚ ’À‚ ’À‚ ‚À  Aˆ AÀ‚À  A €@€„ˆ€€AÀ ˆ ˆ „ÀÁÀÀ €@€ƒ@€Á AÁ@ÁÀ ÀBBHBq{ÞŽ`@1à @À` À„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ @@ €@À€‚!„ €„‚ €€€€‚À@€@€"ÿÿÿÿ    „ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@@À@ AA ‚€  !! A  „ˆ„„ „ € €Á€„ À„…  €‚ A@‚€ À €€ € €€€€€ €€€€€Àˆ‚ˆˆÀ‚ €A€€€€  € €‚B‚`Bÿÿ=4€'fNa  a  a  a€ ÿÿ<<<ÿÿ<<<€@ ˆ€€ˆ€„„ €A@ A@AA€‚ ƒ€‚ƒ€ ÀA€‚ À €€€€ € €A€€    €ˆ          @!!¡!!‚ ˆ €„€„ €€€€€„ ‚ ÀÀ   ‚‚ÀƒÀ@ €   ‘! ‚€ €@€€€ € Àˆ‰ˆ„À À@À¡‚À@@@ €€‘€@‘@!€€€€€€€@€ƒ€!€€€ƒ€€€€ @€€€€€€€€€ƒ¡€‰ ‚@ˆ€!‰… ƒ€€@!€A€€€ „‚‚ …Á „Á‚…ÁÀ@  ˆˆ ˆˆ@@ Àˆ À Àˆ ‘Á‚ˆˆÀˆ‘‰ A€ €€€€€€€À €ƒ À‘¡‘‘…ÀÀ¡ˆ €€A@ !@À€€€@€€€A€¡ƒÁ€A€‘€À€€€@€@ „Á À @À@@@‚D"‚B ‚BD"B‚@‚UU<ð<ðÿÿÿÿ?ÿÿÿÿÿðÿÿÿÿ?ÿÿÿÿ_ UU<ð<ðÿÿÿÿ?ÿÿÿÿÿÿÿÿÿÿ?ÿÿÿÿÿ_ ÿÿÿÿÿÿÿÿÿÿÿÿ‚×ÿÿ õÿÿ ¯ÿÿÿÿÿÃÿÿÿððÿÿðÿÿÿªªÿÿ‚×ÿÿ õÿÿ ¯ÿÿððÿÿÃÿÿÿa @  a   a    c ’À㌜ ’Àã ’Àã-  ÿ<< ¾<<<ÿÿÿÿÿ<<¾<<<üÿÿÿððAÃAÿÿÿÿÿÿÿÿððAÃAÿÿÿþÿÿÿˆ „À!‚ @ˆ‚A„!!„À„À„À„„ÀÀ„!„ „ˆ  @ €ˆ ‚À À@€ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ !À ÀˆÀ  !  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@@ @ @@@ €‚ À€ÿÿÀ?ÿ€@!@ @€€€ €@ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€$ €€°† 0¡ 0¡ 0¡ 0¡0áÿ0Á0!¹Z0¡ xc3sprog-0+svn795+dfsg/byte-order.txt000066400000000000000000000011551337255630200175760ustar00rootroot00000000000000The IO routines that shift data out to the JTAG port start with the first byte of the buffer given. Each byte is is output LSB first. If the byte order was the same as the SVF file then the entire buffer would have to be stored and then reversed, causing problems for embedded JTAG servers with limited memory. The table below shows an example of the byte order reversal required for playing an SVF file. SVF IO buffer .. ff .. aa .. 33 .. 00 00 .. 33 .. aa .. ff .. For a Xilinx bit file, which is MSB first, each byte is bit-reversed as shown below. BIT IO buffer ff ff 55 aa cc 33 00 00 .. .. .. .. .. .. .. ..xc3sprog-0+svn795+dfsg/cabledb.cpp000066400000000000000000000120651337255630200170430ustar00rootroot00000000000000/* Programming cable database Copyright (C) 2011, 2012 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de 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 CABLEDB #define CABLEDB "cablelist.txt" #endif #include #include #include #include #include "cabledb.h" #include "cables.h" #include "utilities.h" CableDB::CableDB(const char *cf_name) { cable_t cable; char alias[64]; char cabletype[64]; char freq_string[64]; char options[256]; FILE *fp; if(!cf_name) { if(!(cf_name = getenv("CABLEDB"))) cf_name = CABLEDB; } fp = fopen(cf_name,"rt"); if (fp) { cablename = cf_name; while(!feof(fp)) { int i; char buffer[256]; fgets(buffer,256,fp); // Get next line from file i = strlen(buffer); while (i > 0 && isspace(buffer[i-1])) i--; buffer[i] = 0; if(buffer[0] == '#') continue; if (sscanf(buffer,"%64s %64s %64s %255[^;]", alias, cabletype, freq_string, options) == 4) { if (strchr(freq_string, ':')) { fprintf(stderr,"%s has wrong format!\n", cf_name); break; } else cable.freq = atoi(freq_string); cable.alias = new char[strlen(alias)+1]; strcpy(cable.alias,alias); cable.cabletype = getCableType(cabletype); cable.optstring = new char[strlen(options)+1]; strcpy(cable.optstring,options); cable_db.push_back(cable); } } fclose(fp); } else /* Read from built-in structure */ { char buffer[512]; const char *p = cabledb_string; cablename = "built-in cable list"; while(*p) { int i; for(i=0; p[i] && (p[i] != ';'); i++) { buffer[i] = p[i]; } p += i; while(*p && *p == ';') p++; while(i>0 && isspace(buffer[i-1])) i--; buffer[i] = 0; if(buffer[0] == '#') continue; if (sscanf(buffer,"%64s %64s %d %255[^;]", alias, cabletype, &cable.freq, options) == 4) { cable.alias = new char[strlen(alias)+1]; strcpy(cable.alias,alias); cable.cabletype = getCableType(cabletype); cable.optstring = new char[strlen(options)+1]; strcpy(cable.optstring,options); cable_db.push_back(cable); } } } } CableDB::~CableDB() { unsigned int i; for(i = 0; i < cable_db.size(); i++) { if (cable_db[i].alias != 0) delete [] cable_db[i].alias; if( cable_db[i].optstring != 0) delete [] cable_db[i].optstring; } } /* Return 0 on match*/ int CableDB::getCable(const char *name, struct cable_t *cable) { unsigned int i; for(i = 0; i < cable_db.size(); i++) { if (!(strcasecmp(cable_db[i].alias, name))) { cable->alias = cable_db[i].alias; cable->cabletype = cable_db[i].cabletype; cable->optstring = cable_db[i].optstring; cable->freq = cable_db[i].freq; return 0; } } return 1; } CABLES_TYPES CableDB::getCableType(const char *given_name) { if (strcasecmp(given_name, "pp") == 0) return CABLE_PP; if (strcasecmp(given_name, "ftdi") == 0) return CABLE_FTDI; if (strcasecmp(given_name, "fx2") == 0) return CABLE_FX2; if (strcasecmp(given_name, "xpc") == 0) return CABLE_XPC; return CABLE_UNKNOWN; } const char *CableDB::getCableName(const CABLES_TYPES type ) { switch (type) { case CABLE_PP: return "pp"; case CABLE_FTDI: return "ftdi"; case CABLE_FX2: return "fx2"; case CABLE_XPC: return "xpc"; case CABLE_NONE: return "none"; case CABLE_UNKNOWN: return "unknown"; } return "UNKNOWN"; } int CableDB::dumpCables(FILE *fp_out) { unsigned int i; if (!fp_out) { fprintf(stderr," No valid file to dump Cablelist\n"); return 1; } for(i = 0; i < cable_db.size(); i++) fprintf(fp_out,"%-20s%-8s%-10d%-60s\n", cable_db[i].alias, getCableName(cable_db[i].cabletype), cable_db[i].freq, cable_db[i].optstring); return 0; } xc3sprog-0+svn795+dfsg/cabledb.h000066400000000000000000000027751337255630200165170ustar00rootroot00000000000000/* Programming cable database Copyright (C) 2011 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de 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 CABLEDB_H #define CABLEDB_H #include #include #include enum CABLES_TYPES { CABLE_NONE, CABLE_UNKNOWN, CABLE_PP, CABLE_FTDI, CABLE_FX2, CABLE_XPC }; struct cable_t { char * alias; CABLES_TYPES cabletype; char * optstring; unsigned int freq; }; class CableDB { private: std::vector cable_db; std::string cablename; CABLES_TYPES getCableType(const char *given_name); public: CableDB(const char *cf_name); ~CableDB(void); std::string const& getFile() const { return cablename; }; int getCable(const char *name, struct cable_t *cable); int dumpCables(FILE *fp_out); const char *getCableName(const CABLES_TYPES type ); }; #endif //CABLEDB_H xc3sprog-0+svn795+dfsg/cablelist.cmk000066400000000000000000000002611337255630200174140ustar00rootroot00000000000000#Bring cablelist.txt in a form that we can compile as fallback file(STRINGS ${CABLELIST_DIR}/cablelist.txt cabledb_string) configure_file(${CABLELIST_DIR}/cables.h.in cables.h) xc3sprog-0+svn795+dfsg/cablelist.txt000066400000000000000000000052641337255630200174710ustar00rootroot00000000000000# Alias Type OptString Max_Freq # OptString for ftdi: # VID:PID:PRODDESC:INTERFACE:DBUS_DATA:DBUS_EN:CBUS_DAT:ACBUS_EN # INTERFACE: 0: any, 1: INTERFACE_A, 2: INTERFACE_B, ... # OptString for pp: # OptString for xps: VID:PID # Max_Freq == 0 mean use maximum speed of device # Use 1500000 for all cable connected cables and max for all on board cables ftdi ftdi 1500000 0x0403:0x6010: papilio ftdi 6000000 0x0403:0x6010: minila ftdi 800000 0x0403:0x6010: saturn ftdi 6000000 0x0403:0x6010: ft232h ftdi 1500000 0x0403:0x6014: ft4232h ftdi 1500000 0x0403:0x6011: cm1 ftdi 1500000 0x0403:0x8350: bbv2 ftdi 1500000 0x0403:0x6010::1:0x00:0x10:0x00:0x0 bbv2_2 ftdi 1500000 0x0403:0x6010::2 dlp2232h ftdi 1500000 0x0403:0x6010:DLP-2232H:1:0x00:0x10:0x00:0x0 amontec ftdi 1500000 0x0403:0xcff8::1:0x00:0x10:0x00:0x00 olimex ftdi 1500000 0x15b1:0x0003::1:0x00:0x10:0x00:0x08 ikda ftdi 1500000 0x0403:0x6010::1:0x00:0x00:0x00:0x04 llbbc ftdi 8000000 0x0403:0x6010:LLBBC10:2:0x00:0x00:0x00:0x04 llif ftdi 8000000 0x0403:0x6010:LLBBC_INTERFACE1:2:0x10:0x10:0x00:0x00 llbus ftdi 1500000 0x0403:0x6010:LLBBC_INTERFACE1:2:0x00:0x10:0x00:0x00 plugjtag ftdi 1500000 0x9e88:0x9e8f::1:0x00:0x10:0x00:0x00 ftdijtag ftdi 1500000 0x0403:0x6010:FTDIJTAG:1:0x00:0x10:0x00:0x00 ft2232test ftdi 8000000 0x0403:0x6010:FT2232TEST:1:0x00:0x10:0x00:0x80 l_motctl ftdi 8000000 0x0403:0x6010:L_MOTCTL:1:0x00:0x00:0x00:0x40 l_motctl_avr avr109 8000000 0x0403:0x6010:L_MOTCTL:1:0x00:0x00:0x00:0x00 knob2usb ftdi 0 0x0403:0x6010:KNOB2USB:0:0x00:0x10:0x00:0x40 qm07_pu ftdi 0 0x0403:0x6010:QM07_PU:0:0x00:0x10:0x00:0x04 qm07-pu ftdi 0 0x0403:0x6010:QM07-PU:0:0x00:0x10:0x00:0x04 xpc xpc 0 0x03fd:0x0008 xpc_internal xpc 0 0x03fd:0x0008 llbbc08 fx2 0 0xfffe:0x0018 qdu16 fx2 0 0xfffe:0x0018 pp pp 0 NULL dlc5 pp 0 NULL jtaghs1 ftdi 1500000 0x0403:0x6010:Digilent Adept USB Device:0:0x80:0x80:0x00:0x0 jtaghs1_fast ftdi 30000000 0x0403:0x6010:Digilent Adept USB Device:0:0x80:0x80:0x00:0x0 nexys4 ftdi 6000000 0x0403:0x6010:Digilent USB Device:0:0xe8:0xeb:0x00:0x60 jtaghs2 ftdi 6000000 0x0403:0x6014:Digilent USB Device:0:0xe8:0xeb:0x00:0x60 turtelizer ftdi 1500000 0x0403:0xbdc8:Turtelizer JTAG/RS232 Adapter:0:0x00:0x10:0x00:0x0 arm-usb-ocd-h ftdi 1500000 0x15ba:0x002b::1:0x00:0x10:0x00:0x08 tumpa ftdi 1500000 0x0403:0x8a98:TIAO USB Multi-Protocol Adapter:1 xc3sprog-0+svn795+dfsg/cables.h.in000066400000000000000000000000631337255630200167650ustar00rootroot00000000000000const char cabledb_string[]={"${cabledb_string}"}; xc3sprog-0+svn795+dfsg/cables/000077500000000000000000000000001337255630200162105ustar00rootroot00000000000000xc3sprog-0+svn795+dfsg/cables/ft2232_cable.pdf000066400000000000000000000133661337255630200207640ustar00rootroot00000000000000%PDF-1.2 %Çì¢ 5 0 obj <> stream xœí\]s¹Ñ¾?¿bî0©òxô-å0°&€7øÀ&µ•J9Æl¼ñ± ¶³ï¾¿>Ý’ZjÍÌ10Î .j/¼êÓÓýô¨»Õ-iøw7ô¢ð¿ü÷d³2½—ʨì^¬Dw¶ºç+£¬íªü.d·)g¤Rw¾:šÐ6+gt/}h¸Æ´ÊEÒ9×T#ç2ƒý:ãäÐ{ƒ\ÒËÞºBA®¡ûeõ–vùÏɦ{¼^í½q•`r·þŒ¢ÛÅWa„èu0–~…ß6«g/ŸþñáúוжwdèÖïW;ož¾;8:8|~’½q€zýrµ³ÿæÑO¯»Çýc÷ðÁj·yèç=úp× òwŸ=üÛú¨—¦ ^¬_>E¡O׫?»´4ªW’Yê´ }°é}Œh›•¶ðº¬m¸Æ´ÊEÒ9×T#ç¢`\™2‡K»¾½W^ˆl¸Æ´ÊEÒ9×T#çÒFº>hÆEîeÊúЃ‡T.¢p.éÍÐ;˸ˆÒp à#Âs®Liü:cRé^3çÏÎ#'ûQ®.mçÊÎ¥ –G[¦4³h¼gf\DA®¯‹4l¯<È,ÁûiÐë‡ÎCz0ÞÆ`xŒ¤]@â‚ .ýâ/Os¢ì#¦_:È.»gJ¨vâá.¼ÁAôbGÒÿÊU©ºRMŒÉ|B8ðؤ…OÚ×.ìÐtPfx w0ÒK”ieïƒ6Ѧg“D`48ªâ¾A>UVZÓŸˆòõˆ ¸¼˜2Þ%ñÏ;¶¾;W߯﮵4åKG¦,Gâ =ÛAÇwÊ¢¹© L¡°4BaW¹ …såf\Da\”*W¡ð´›SKå*Ƶ,|,/zùÿ(|ZÖ,åKÜ“Öí’¹(³ÌE<5sÏ\…«d®ÂÅ2W©Jæ".ž¹ˆ«f®²>°ÌE\5´ˆ‹‡qÕÐ".Z¥Ê)n_Ö­Ånï!´p–0 çR~]J+ÿ»-nwÃàmï-ÄS a6ð 5¡0CèxÖAˆ‰(Ö±$­À;)÷…èÓ>³¬Áì OZ®0–ës8¶Ñ§‹>JUa¡,Ö((„n4Új¡‚ƒdÆL$ÊrõÐkÙ(U¡…H„üÃe¹Bð|.É5ªªÑƒO©À5e¹Æih\£©«dic¶¿^; uowì†kë›k¸¶¸lóõp®íÎØrÁ"0T{6•ÂÒ˜e€5Ê7\cãâèG´ÍÃíó!$”f>¡÷q°œ€„ÞÊT=9|ýºú­òÆõ”² ‡Z Åyx8-cpiåz7âÑW–ÞpM52®š•ÕãŽI% [²¾î½(ð£a„2Ê9YÓãnla9ØM\\‰ß]Þ\×7FÚËB[( ÿB<`.g%ÒÁ1ƒ€R¤…svQÑ0J ©ƒL^SÞf¦,@4ôšÐÌ@ÑRÔL·+ !Æ®´ä€æÑû_o®®ÓÏ‚‹Yr{ðò•<¬—°Bìë·¢.‚R€/@V‹9À/Ú²»îž;ØØëX86@o’‚Rafôà{í"Q ¢“"s9p' èØð‚‚?jä„#X,×2 cÚ|F¦L©_*b ÅB ¯Ä’¼­À.0_XF–ƒ æWAÇ3juÚ9:Øûéíãºä¤Ìe9 @Ó’[=~òøí‘𬥠Q–²’«n©ÛMê%†'–ÃÞ)XÕÀѷÓ•Ÿá!Êr@ ü¶dn4Lê» ¨P–‚ÕPHѲS@>¥ÄÇûÈU@9-0@DY ssanûûA8µ•Ò*쇢,‡#¡r¡äoT+9© “6š"Êr@ƒ`éi…Û±ÁÀÒ¢xR,”å€tèµB'€5»mLŠÑi…S¡w˜"ªIHZXÅÏŠ…²´÷ƒ0-"1Eĺf!é@/z",Çã iÆ}YŽGÞþ†j‚N\BÏÌe9"ïzÈ-"u;¢š‡ ß†Ÿç¡BYŽòÃŽHoEôüõ~…#4Æ(‡C”ÅpäU5z?f«5h¤úçÄBYŽ’PB Çn…óîÉ“£Ÿ* ¸ÏË“P¡,Y^{ßr[g ÖJHAqÛ[ž… e9"ƒïصˆüíˆMš †ˆ(ËA²z”ÃVDOÿ²P‘ƒÒEòâ¬P–#‚ÊÖ³‘œÉÔÙ~<|Ó@*»düàYE -Öðw¨¨q/ØR!íB{åb‹ÈßÒ£˜‰öÖOþ´wô§IiÍeÊåÒš#S!!Ãícf‰½õþÁÞþÛé~UE–)w@–kì™OÈ ÏZÌ “€ìpoŸU·y§§K„;àÊÅvƒË.¾2ƒKí­_í=9šî·U`™rd¹ênÙâeV¸dzïù‡/§åwEVD—#ËåwƒÌÌ Ë1‘™„Œ•ÔžWd™²YªÃ\ú3oÌ&\¬”Êå7Õ)wÀ• ò™ú 2—±²3×á Y¦ÜY®Ìd²ø¿Ö㌻»ˆìæe¹ gÈ2åÈr‰Þ ŸA&2æe¹0gÈ2åÈr©Þ f‘ÿǃ„lR²3`‰p\¹dç¸døÌS ó²\¨3`™rd¹to¥ì/a–½œÙ„b…N.Ô+"¢ÜQ.ÝD޶y½¯”oŽÖ¯gN;d€IÓxSA8¬—7•¨3äxÇ:WùÌ–LYnK®ûSÒB¡T/†ñ~˜røv=c‹Ò®°¶ñŽD|Ï™2oKî˜-™r[r×ГÖ9ôÎ {K“[†'Sî€'7 =ƒg®ÇË Ó)wÀ“[†úB<¹=`x2åxrÃÐà‘_ˆ'7 O¦ÜOn<‚‚A[g'mçÛ£ÇsÁàCݬؤ!‡ÕðÔrÝÖcZåâíИ¶iU/9؃è5±ç_éÖÂþËá]ÉWwÌË ÂÎ[9{á`t¾™tP )ß+”ÀÒ-Šè…¦PU9j¨„0 (©Ü?˜v8Uå¨çY ŠD¸ÊÃIëR5¶½Ì…ÎÆìËô½:¢È‹· kK+SôtpóÝëËÝëGÏ»“㜟vÿ8¾:}ß]^täÝæòýÍù)­Ëk°»ŽÂÒµ£×È÷÷øxuòÏÑÜõâõgÒvÒažÐ0°Í± ècµDç–»ü·ýÍÙõ§ß»õéï×§ç›ã‹™ÐÔēËJÝ5ž¥i1xHC@·kRÐŒiö\=Ó˜,oCoM++Ó˜,/¡€—#Yc\j€eD¹FÑPD*Ì’ LSããÅò+Ƶ”Ûø3 j@…g¾•KúÁájÞ—2üà[ºå·Ÿ¿Z:6ì¡X°üäüç7è.à  °`.çЭa¡ÿb Ð@ _Ð8˧!©ÏOºÿ :œwÔ†Ûä!k{WŸòÀEzZÆIgfHåñ ¹((6yXÂ!©Wx Z0 4Î hHúéqÂ×Z¬"‡Àû Ž»ˆ]ÚÓªÏr¦–Äü:‰æàç ‘DËîɫǦê®7,Gw.SÅ?y¡ô×5¢m&5}#+#"–1¢™nT‘<¢gÚü½Ùz›?0´l([¸F·`#–W£õ† ?yJ;tìŸ)<ƪ,Šnãé3\ÑiŒ€/*I~I2¹Mþ2“)L‹Ær}ðœÄ/™>9W·ÀbÔ·E®™›J ©jV0†Ž¾©dðÊs·¾4mTzR*<㋲`ZaF¤ÐxoµŠötŽ50Ý Étô¸ˆXs“üOBZëñc,È.ÜF¢ ¿lMømü¾XIi(ˆxIŸ( òô 6¾]ŸV¥+ðqÚ¡¯öx”óÇÐÝ<›Ë m¾¨¤y¡#ÚfâLó=Ž—˜L—˜œXrj“må¤Å²PØJn† pë)ˆÅo Åy¬#—Cê= Šß ô½*Œ2%îýøO¦µS¤p}^6œ50<ÏÜ0BШÊÙ´Å+¬Ãb{Ã(^—¸˜|é1=»àHÇ´ºb5\#Úfr’¹¶ž&5²¶žñ4\t·O©ãŠÝöÓWó'ì= HÍm9?¤oYI(ä=äðmäÁ\Q)‰IXXdPiŸOá÷ÖÊüù$áÚLn*F©Û/S²uzLãV3®Ñ ¿™\þ[Ò€AK ¥¥ß.ÕöW×Çççݯ7›§Ÿº¢ûpù©ƒ èÞuqSü`/îÖÃB^¤bê?#ã3Ðòg¬Œ:ÔÂ:uš“ù_“H'©5Qž@BìÄ…»:ã20ýÆ6\Ì¥ò§UÂẗüºÞµB[RýHKÄ͇Ì34ÔM•MXnÅ_Eßú.4ÅP` üX%Ü©üÒ¡Ì…êˆA äÎCoâ·s%[ðh1´æ}9è}#r CüW&¸¾9®€™ž+üÊx(Ÿ Fº é#­ý¹=ÀWÝçÿt>›§*…Á$BNF[ZýìŒÏ~Kʇž­FÀÆ AáÂeLÐäŨ3¢!”/J64]hØ+™ãÏÇ'Œ+Xgm>ú½áP‘݇†ý+'“Zï°¢ö“ý sKó› *ú±=£Þ½ðgô…À^4´1¡·h"”<.Åá1d®ñßåõ^Xhd:#Ë7hlP„‚xlÿy¶_ÿó쪻:Û|@Ú!¬ñ‡îòC÷l‡§Ýñ5.:ﺃCÒ‚1üò柸úxz‚¡ðƒgsvq¶¹ÙôÝ—¿âˆàôÿ@ÃÙæô–)°ëúæc÷Ûå§]uÎ8¨²Ý«þ¿/.p?ëÙûimí@iI'º&į£3EÇO5î5…x£½Žãv²ªob÷NÒúU·¯âù]Ú¤£ßánf–Çi\J†ˆ­ß û¦ «F°È 69xÜ* °òx°¢ Á*v‘@㬠 ³~zœðµ|·êÛ´JŦZ1«ˆB°aŒÿºb–ÉB1ñCÿ* í¨Wi\íª x•@㪃( Œ­÷Û²zÈ@–%5EÅKwŲ:$­•’pU wUA–)‹-™cv`ÇA•‡Y7=GÐZð÷Ó rœƒgsqs?uÁÂ$ST¼œêñpÇóA<é……‚7\q#Ï;?EAã˜JÊÏx¨Ùã4® %Js Y‹ý^ÚSŽÈðß~‰m£:}W(´WMúh?ófÚÉŠQDÔCè<¨¹¥1>!=æÝÊ¡â¹n•PÆEG¦YBAÙÚñݶo×¶{ÚlÝO«¾×ßÊR|Oð^ZUO½Oÿ–ùQÈ·`,£ë–q:¬Þg„õ½—]•€ºª#«÷U;°Çã JCRN¸þ}5©œÖ“ü_¨Å›\ZÆEg¡dH$ Ã-ŠAx¥Æ1ŽøÏÌÉ* Œ‹ŠBÉ ŠÙZÁË fY.ÊS¹x(R˸è-”Œ¬HÈÈ‹Žb[.*G*ªWD!$P¶vÜóY»¿–Ýg¼Ï¶•›¥MÁK{JÖ@@ãÛ–Ü Ð¸¶•’š ’P®ÒÒ¦#RBÆÆ‹}EB™RPd ekÇwÛ¾aÛîÙΟWÿߦöendstream endobj 6 0 obj 5019 endobj 4 0 obj <> /Contents 5 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 4 0 R ] /Count 1 >> endobj 1 0 obj <> endobj 8 0 obj <> endobj 7 0 obj <> endobj 2 0 obj <>endobj xref 0 9 0000000000 65535 f 0000005325 00000 n 0000005466 00000 n 0000005266 00000 n 0000005124 00000 n 0000000015 00000 n 0000005104 00000 n 0000005402 00000 n 0000005373 00000 n trailer << /Size 9 /Root 1 0 R /Info 2 0 R /ID [(> startxref 5577 %%EOF xc3sprog-0+svn795+dfsg/cables/ft2232_cable.sch000066400000000000000000000061711337255630200207640ustar00rootroot00000000000000v 20060123 1 C 70100 46800 1 0 0 title-bordered-B.sym C 84100 54600 1 0 1 connector6-1.sym { T 83600 56600 5 10 1 1 0 0 1 refdes=CONN1 } C 74100 50100 1 0 0 lm1084.sym { T 75800 51500 5 10 1 1 0 6 1 refdes=U1 } C 82000 54400 1 0 0 gnd-1.sym N 82100 54700 82100 55100 4 N 82100 55100 82400 55100 4 C 77500 50200 1 0 0 dlp2232m.sym { T 79300 56700 5 10 1 1 0 6 1 refdes=U2 } N 82400 56300 81200 56300 4 { T 81600 56300 5 10 1 1 0 0 1 netname=TCK } N 82400 56000 81200 56000 4 { T 81600 56000 5 10 1 1 0 0 1 netname=TDI } N 82400 55700 81200 55700 4 { T 81600 55700 5 10 1 1 0 0 1 netname=TDO } N 82400 55400 81200 55400 4 { T 81600 55400 5 10 1 1 0 0 1 netname=TMS } T 81100 47900 9 10 1 0 0 0 1 USB-to-JTAG cable based on DLP2232M module T 80400 47400 9 10 1 0 0 0 1 ft2232_cable.sch T 80400 47100 9 10 1 0 0 0 1 1 T 82000 47100 9 10 1 0 0 0 1 1 T 83800 47400 9 10 1 0 0 0 1 1.0 T 83900 47100 9 10 1 0 0 0 1 Dmitry Teytelman C 75700 49800 1 0 0 resistor-1.sym { T 75900 50100 5 10 1 1 0 0 1 refdes=R1 T 76300 50100 5 10 1 1 0 0 1 value=121 } C 75400 47800 1 0 0 jumper-1.sym { T 75700 48300 5 10 1 1 0 0 1 refdes=J1 } C 74600 47800 1 0 0 jumper-1.sym { T 74900 48300 5 10 1 1 0 0 1 refdes=J2 } C 75600 48800 1 90 0 resistor-1.sym { T 75700 49400 5 10 1 1 0 0 1 refdes=R2 T 75700 49100 5 10 1 1 0 0 1 value=121 } C 74800 48800 1 90 0 resistor-1.sym { T 74900 49400 5 10 1 1 0 0 1 refdes=R3 T 74900 49100 5 10 1 1 0 0 1 value=196 } N 74700 47800 74700 47700 4 N 75500 47700 75500 47800 4 N 75100 49900 75100 50100 4 N 74700 49700 74700 49900 4 N 74700 49900 75700 49900 4 N 75500 49700 75500 49900 4 N 76600 49900 76700 49900 4 N 76700 50900 76100 50900 4 N 74000 50900 74000 51800 4 N 74000 50900 74100 50900 4 N 76700 51200 77600 51200 4 N 77500 51200 77500 51500 4 C 76500 49300 1 270 0 capacitor-2.sym { T 77000 48900 5 10 1 1 0 0 1 refdes=C1 T 77400 49100 5 10 0 0 270 0 1 symversion=0.1 T 77000 48700 5 10 1 1 0 0 1 value=10 uF } N 74700 47700 76700 47700 4 N 76700 47700 76700 48400 4 N 76700 49300 76700 51200 4 C 75400 47400 1 0 0 gnd-1.sym C 81400 50600 1 0 0 gnd-1.sym N 81200 50900 81500 50900 4 N 81500 50900 81500 51800 4 N 81500 51800 81200 51800 4 N 81200 51500 81500 51500 4 N 81200 51200 81500 51200 4 C 77000 52200 1 270 0 gnd-1.sym N 77300 52100 77600 52100 4 N 77600 52400 77500 52400 4 N 77500 52400 77500 52100 4 N 77500 51500 77600 51500 4 T 71000 48100 9 10 1 0 0 0 2 Install jumper J1 for 2.5 V JTAG I/O Install jumper J2 for 3.3 V JTAG I/O T 84300 56300 9 10 1 0 0 0 1 TCK T 84300 56000 9 10 1 0 0 0 1 TDI T 84300 55700 9 10 1 0 0 0 1 TDO T 84300 55400 9 10 1 0 0 0 1 TMS T 84300 55100 9 10 1 0 0 0 1 GND T 84300 54800 9 10 1 0 0 0 1 VCC C 73100 51800 1 270 0 led-2.sym { T 72800 51500 5 10 1 1 0 0 1 refdes=D1 } N 73200 51800 77600 51800 4 C 73300 50000 1 90 0 resistor-1.sym { T 73400 50600 5 10 1 1 0 0 1 refdes=R2 T 73400 50300 5 10 1 1 0 0 1 value=196 } C 73100 49700 1 0 0 gnd-1.sym T 71000 56300 9 10 1 0 0 0 3 This simple module does not sense target supply voltage. One could add 74HC125 for level translation. T 71000 55300 9 10 1 0 0 0 3 Operation of FT2232 at 2.5V IO voltage is out of spec of 3.0 V minimum. However experimental setup works fine at 6 MHz. xc3sprog-0+svn795+dfsg/cables/gafrc000066400000000000000000000000331337255630200172110ustar00rootroot00000000000000(component-library "./sym")xc3sprog-0+svn795+dfsg/cables/gschem.log000066400000000000000000000016131337255630200201620ustar00rootroot00000000000000gEDA/gschem version 20060123 gEDA/gschem comes with ABSOLUTELY NO WARRANTY; see COPYING for more details. This is free software, and you are welcome to redistribute it under certain conditions; please see the COPYING file for more details. Read system-gafrc file [/usr/local/share/gEDA/system-gafrc] Did not find optional ~/.gEDA/gafrc file [/home/dim/.gEDA] Read local gafrc file [/home/dim/designs/XC3Sprog/cables/gafrc] Read system-gschemrc file [/usr/local/share/gEDA/system-gschemrc] Did not find optional ~/.gEDA/gschemrc file [/home/dim/.gEDA] Did not find optional local gschemrc file [/home/dim/designs/XC3Sprog/cables/gschemrc] Read init scm file [/usr/local/share/gEDA/scheme/gschem.scm] RC file [/home/dim/designs/XC3Sprog/cables/gafrc] already read in. Opened file [/home/dim/designs/XC3Sprog/cables/par_cable.sch] Printed current schematic to [/home/dim/designs/XC3Sprog/cables/par_cable.ps] xc3sprog-0+svn795+dfsg/cables/par_cable.pdf000066400000000000000000000322101337255630200206110ustar00rootroot00000000000000%PDF-1.2 %Çì¢ 5 0 obj <> stream xœíK³$Çq¥÷÷WÔNÝfÓ©ŒÈÈ—v ѤÃEðB34šLµH 4(IÔpL£/w‡ŸãU·Á®–"Û¸ëësÃ=<ÞÌüÝežÒeÖÿµÿ¾»>­Ó‘—u¹üëS¾|ù”.ß=Í—Ÿ>­Ë¶MB—Sþ=åËu}Í‹ Ë÷O¿¼a×§}-S>Y™«z꨺µˆªu^Ò4Ÿ—uÏót¬ªÊGž¶}UÍ—¿úÝS²œ^ÚÞ]/?z~úó¯÷‹$š%Ë—çߊ0]Þh(Ö”¦r®—’OùWù·ëÓ«Ÿ|ñ³·ñúùžRÙ¦]™/Ï÷ôêë·õÅ/¿øùWõŸò´îÇyyþÙÓ«Ï¿þì~uùѯþâòúÏžÞÐýúÕ_~öÓ·¯ß©HúÇ«Ÿÿäõ_?)æó:¥u/–ðóÏ?{«‰¾}~úÅÈWÉë2-rº—åœÎšÓÈ®Oe“pm©"sUOU·QÕKTÜó«ì§üç÷þXŽ)•ƒT‘¹ª§Žª[‹¨*kÞ§³€ª¬eËvœ“ÔWu‚ª|¬ó´c;!Õ,u$¡_P½n¾¦¼”©@åo5yÞótž ê„T§Téõ@U#¨Zvñ8mØÚ¡R\C*3¨:QÕ‡µ´rnÓrHšâËyÖÒ>ÓZ?_éÖÓÚ”¼G¤qÍþËA{l†>W$ÅŸw‰ý›¬%•–ÚìÒë7Á9MùUîÿ7½Zœ§«µIk|)틸…Ö Ú‡e÷´HíìÃöè¸z? W×xÇÕEØq Õ踆 :®1MWWaÇÕUÞqá:®®ò–ÕUزºÊ[VWaË“œQëǰõp­?¤‘iYh'tJ ´ö÷a=Ú /5Û7ç|lÓ±IsÒ¬®ˆÛk–J*®”YBZ–Ë›2ŸS.«þoß¾Mù(o~ÿOo¾|þì§—wßþí÷¿ùo—ÿõÝ÷ßýãÿ¿üó·ÿòí÷ßÿæûŠ/_|ñÅåÝ?]ÿùÛß'?µÞÈ<íÜ4-™3‰øoL7ýßwÿ[§M‡Ôîm‹cfÕºñ]úa!òÕÏTäÇvÑ+ɦ.Å™Ïxõùõ»ßÿË¿]žóo¿ÿÍ÷×oÿqTߪ.2û-V_¥"Ÿó*#‰6ÖF²Ío¶GkNR‹dT—F{HÕÔÆšÜv·XJ™æ,¦u;§ã‘.{X,‡Ž2f1»ÅY:â=aùˆž;éj§CÌÝl¬ÕŸçkØ‚|mnk_´;À¬5ò¹Ûåe¹Ûo-z;y<Ý"äñp‹ë¶X³ö<6òyÔŽy£,ž·=‹<žÅfr˜f·hÈ‚Ylä#²¸ìS9îfÒ­IÏd'g²›Ä\zG³ä,£v¦|D.eÜØ—dZnMz.;y<—Ý$溚Y¦ô»ÓN>"—ó"DîNÓzkÒsÙÉã¹ì&1—ÞñÈzJæóاvòx.³tu2Eç\î·&G.y8—Ã$æÒ»ž¼ç2;沑Èå.%3'ÎåykÒsÙÉã¹ì&qü÷Þ'¯ë^{ÑËF>"—ë2mù¤\ætkÒsÙÉã¹ì&1—Þûdˆ§ûØN>"—‹änå©\^nMz.;y<—Ý$æÒ{Ÿœe®wdÌe#‘Kéðd=À¹\oMz.;y<—Ý$æÒ{ßž.2jaµ¹:i°5w`âb’±êdUd ‚ŒDv½ñÁöYÂÄïêäžÅ]þ»®˜V#æ}’5캣ÅN ­e+2úf´Ø ªŽ´Êâ U J·¸`:~u‚ªóÕ?FbÌã18­¸:AÕ¹oš_Pu‚ª­È‚ó8ªùÿÛªNPUöe"·ÀJÖÿ9ìT/WmX4{Õžu·J†IrÝlÿìÕ—éÎÚ³›ÚÖõœJã›Ô’i{d£hIJ—Ë.KøuÙÃJ°ÏÁb'[”òÙŽDa²Ôª(Xìäq‹²”<–“,ŠiNǤÛ4n±“Ç-¶¹Z„™¶¿Òñ‚ÅN·˜Ï)Í™,¬w•þw[Ðb'[¬ 4¸ÞéßÞSG.jVwj6ˆ^ˆ^®± z9 z¹&‚¨-uòµï®{e%QgÚ•-E¦&¤ŠÌU`/ ktàÞçÐáE‡ŒÐ¥î™ïô>}n½ìòß“íåLûtüí÷M¶—Cš‹¤4:Ÿs:¥‡].oò4Ÿ›ÔÝûìfâ_¶eÖ^Ü})ë\¦ãü_ŠTëíÈÞ€Þ$±!ã;ó«›µÖˆËǾ>¶{ß»ŒKz1.o¿ºÛìš­pÔ-™:Ë bäÔz¶œ2ø®þóIÝ™/ïžœ«îrZ¾b>õ/v›Ñ¸âHÓr@ ý·Ûh¤;Ñ>r.ÞA_9k ?2]5É0À5$ ¡ÁÐõÆþMN¢£‡2’´·#¾½¤Œë÷Yc²õò‚ý,sÎ:ázÄ^žŠ¬K‘Þ²öÔßÜká阳ڎf5ÈÃÍ*íêÑFÍ*ßiVÇÚx7=šÕw7ÝlVËm³j®x O§ 3yŸtòx\NYÂçƒâ’j\´©ÇÐÆó,œ°wB•<0ñ~“‰ô^H™«0Þ‘]o|øðÚ™ôtLkg–Úm 6C{#£Ú¼èÉô¦Mæ7Œo`r<ç2í§TqéaöÓD™´ç4H€™õýþSf¥-Ï\oÒé÷i©G‡Í:‘Nï˜fíäôðö€ß2Å.Ú×  !Ηž@µZ.à‚ÉOi!ëáÿ|¦S—†ãÏÇïžþÍ–€;þkO + 3½mó äû±ã šíñ,«º¶¥žÉ‚Gsê"£†´¥3¬]`,<¤øuë\@=t•)á>íÔµ+!ÕHw©͇ {[›îݦtÈŸÍ;«n“ÚËT„ìç¡Á¯"Nþ…¤S•üþ™V¦ÚI¹×Þ¤1L‹6†S7žê„ï_*œ‡nf§‹Îu¥‰ÅAôdµTï#•ü¿%Ë4[*Ž eU˜¨d.½™±Ûí›Z葉Jl'É-©•L…ד 2MÞ¦,a"ßUË3©n〪Ælö|V'˜ÖUÖí‘…Ui¥¨eµËm)¥e‘™ª™FˆºA´ô@0Ó˜æé”ù-©Óò‘é˜Þ%ÐådiÞ*Ìãm$:Á´Óz£M›Ýb$šMOhÄÏ"¦,FªÑ9sb !õ{Ö5D*°bÐü>dµkÄÈȦ뎕3ט7Š]Ï3L¢3pKfÅy9حƼQ4°M¸W­ØQÃ*Z *¨ö±­‹Œ T»¬6n8EŒB`£9ët[F¬‡L-4EºÌ&½—DEÓ¨ôjÍ °±QñŽ¢›ŠTñ:òŠgw»ÊF5¯3/?Rå‡ófJ¾*ŒC``±Å,zL[yz'¤×äÀ@EÞ7‹‡ÌÐOò^¯n!­Sw¨1ò `ä]ÓËKæÉ;9 ¡¬5fs¡ÅÙݰÞ$y1Ÿ2‘XzeÌÇ.Ræ½ Ì‹¦¹‰%ãžwõVcbQc`o‘Ñlæ»3ð]æÓ[»IÄUyDÑ #/ò=°k,,i/Y â5@Ùšý㶨N9gn€ycN³ dÛI¹3÷œT5i.zìH¢e•n•òתòÖŸLˆìê‰ëÞéÆö*òâRúQDd^H˜W+2˜‡”| U‡ÀÐbŽàà× ’@{r$2Ì#¨{Á∼Ì3wŠü±NÙ! !,>°ª œÝ£$æÀY{'è“‹ÆŸe½Š’ª UÒ¥ 2äHiîÛpA ”¼La é j'ªƒFƒAmÏ¡bÚ»N©+;õ{zXYb¤*#•ÌîrTƒ€®2].l¯" ¨¬ÛAIdPP†ƒa°À÷ÀHåq -ÖøQmw¿9ÒtFUe˜GPö‚Åy™]ÑR¢ŽÄÕ¡[9œÇÊ@•e ” «¿rJc*™5ÖÚ%£p>ÎA°J¸¨g'Kš‰§†‘JOգʘWÁ¼Ùód¯"¨‚ºÞ3ªÃ0€ÁÀ0¤à{`¤ò8†!¤#‡Lœ©‡h¤®ÐdÂw¨ª+4õ¤ôArbRPï©Î¾mªrí:0|YS=¨Ì B ª-W’Þ(¸°JzFy“–½LV›°Ú¸fØ“uðưÆPö;Sè“á˜Þ¨ôqŒØs5Fªc*QtLTMK’^‘Ò‹VæÑ¢AÑ (0t©¤~`ªòÙ7Q#C×õ™Ùã·FfÀ``¨ƒAôy™‰˜Á8€öC„txµKî)V¨¾ÜÑœc ªÎ<åõÊ œW©f[˜ÿ6EU‹Õš–°²aîЪ¤OŠ"C^2«>Ä%Ó” ‰˜Á°.ǘlCÀšì\‡†€Æ0T5Ǫ…^Z¤b…ƒ± U+Fhâ0*îÕ•Bï !Õ6/mÞЃ|ž±6„QQ`è¹ÌI QjöcÊ1{•aþ¤ž—œvsŒPæƒøýÏ€°ê¡ˆ4w´ª œ}(Û¤ƒI¸;—¶Å®_Ðà¶åCï!»ï  ï®…¾ä±Û©ÜÞ`úŠ,¿ hæ14mâ’‘Œ”ç†cò&CyæÕKCÐŽ·-O}ë*0hǨ j sWý¤Úé¾;9n¶QC‹Ç>å0 h ½—yÁØd†‘U`S0È |ìzS^¤Úgi“4 m„rxG%³“% \¡ª>,ÁªÊ ²ã4Þºï ¼UÝ ÂóÁAà¬12SÙ -#S•Æ¾Ó hdªZ7mî¬b¦*ÝÞJÁ"3UéF\Þ3œFv½‰ FÂÏûßá)bd ‚“ÒÈLekn<)Ì"±K/ŽÇYLm-Í"fV>¶JÆ3ÂÈ@E9¼C#”3S­övò‹™ªtWoÅSЀL“õžk™çúôl°Æì¥(TÏÇyãÈ œ”FæÍÏ#·àì22op Ш $AUŠl1ƒê 礑 ÎI#‹fÞœñ ´W?ÕÅ'„‘ N#óª‡g‘yÕÃSÐȼYÅ J,2ó¦ÊÞ3E‚X„³Òȼñ¬42Pq¼,ª~DÖUxŽ6T:PJŽ¿ò¶sz§ÛNg>¤œ‡>)pÒÒ™ÇU̼²EfCôhZŽItRU–ì16Tá™Ud­4Ïë¸×˜G ø"óh±Š™G‹-2óH°÷ÌPUsÍ*DOÝO¶îÆ«åúžê´§¢1ª~Ò¦¥1ŠQ­Ì[¿¤¾ôßÈ0ªÕŽªûeý5‹yÊö˜aLý¸)2TùaZdhãÀ ËÇÁ†j ŒÔS™ûƒš‘¡ÊOw"‹~NÄ]ŸBe®ÚjA]@[„ V‘×ÌP…`æãÿDæãÿD5”TÌ0Rh‘™<ì=3Ta$˜QÙxL ùt ËÆÎiV}ˆIŠÈ*»=¾P©*fªÒ¬êÃOÉÍÀL¥ó<¿YÔG<Žm‹ ETÕÔíAž-væã±Òë¿û†K™NЭÀD¥`—ƒ˜ªô5e’¸^ÖmÕ‘jdQ« \`¦ªmÕ=V1SÕºkíaƒÌLeÇ´X TR}{‡ÅìQ˜™ïvÈ@Õ¡Åêœõñ¸³Æ}Ñvr&éWz«ÌKGæÓÜ6N"Õ2÷óÕ€Àž^qÔ¶=…7’&*Ý[KçË*;’a‹Ì¼Ö°Š™—"E"0¯SF ÁÒ ìaI浦×Sé“Ì ê!ÓzpÝ ÌT›ŽÛzŽ»~‘JF¤~E/2°¨³ô•]`ªšuoœ"#­öžG¦*}Ð#l *h­wDzrX‚Af¦*ºïTÄT¥§ž‡!0SÙ!…40Pañ±¨3ïgÝ#¤î»Ï)sêÙÎdz±råb*¬Îy…À†ÁhTjùŒ¬:Ø™ ‰³‚¶óêÚy9s'É TƒÀÀ^‹ôx¶Ò²×¬…J°3Pï«,¢¬Wz˜ÏÐr˜‰jç°“¨pЬ! v¸–8XYR³õFØ+æÎS¨0ðöt 9¿I™kO€ck` ÂØÕSÇÆ˜ª$»yáЦ*}ãDè3U²æK™iTO{@‰¼ T‰ÀÀ"V‰À4­C€¢>„‘kî j| r(Db Âʘ~ÓžÛ#Õ${xŒz‡À0Pa$3‹§½y;£ÀL•lÝ‚ã@`‰ÃÞnM*f/²ÈLU󦯫g"Á ,RT™™Êžåªñ‚Iu«%4õÌk· fæ}šNò»Aß{í‰ãÞk``ÇÍÀÜ .SYãÛ [F´ŽRêŒb˜ªò®Û«8]f¤æôyÛ0[ T÷æÌ|šŠƒÅL½’²ß3÷\©JÊþLÜ ¶zwcü®ÜÝvuG1îJÓ÷•UE½.Ð÷ƒ3ÕlS@½s²物J§tý¬bf…¸Ø0¢Gî]D4XÿnEúβÌ1ó¸±ëxÑ‡Ô i` Ââ ,RQ3ƒºcÔ)+샚…>{®Ýv5™j¹éjSUY­##3U-âOí©&u„ Y`ªªÏQs ÌT«].`1UÙyÜ}*ìj‹Sfà=«ˆA$(\Ì<¦.BP:8Ø%M*fPk(¦Ì®^Û(¦Ì@E1­ †že óÈS§˜Gž:Ýæ=4Ÿî6ÅÀ@=#u#Yùœ:ÀÛµª¾WØ(iò:Ãö˜™JŸ«dÏ †bÀ ìaw” æ |Ïún÷ §>yÞg°ÎD*¨‘©jÓ×Q]ŽLUEßúCí"2U-‹>¹Á*fªÊ³>“Á™ÙgD6½ÂÍÞ3E‚X„¾&2Sz•ûïÈ,ò— bfñZuða‹Ì ªä=3PQ$˜EŠ*3S%½È%T넽’hÉÕN0ª¨Ò—þð®vdU칆ÅÞÐz…ƒÆgç‘ëzñrIìzc ‚†e¢¡¯ròa%K„â‘WdöŽÛÅîbQæoÂ¥jÓ-ڢؼ—EM]Cñ¦ªõˆdª*› ̤bÞ“Ef‰æ)E¼¯¤-èPÔÛ«‹·…ìuæ¾Ûb´]UŠÌãÀ*fS¶Èì:Ê‚|'t½)/ùðÚ³Œƒpd„#óZƒ+±¸N8RîTf¥&ÆÈCE£O`v„#³"̺¬d3 Öiçd‘„}'Š3°cudvX:äU”4„,REßÿÆÖ˜A<Ésf Â{Mf¦šõ¹*™ö"tkõKSÔ÷1RM}J’º¾ÀLµé Ö¨ëëöƵëž8ÜÍìagØÃŽ¯Ùƒq©{÷f{ü/2SÍö¦•£èW£ºŠ˜ª$¸{ãS•náóþÈÜ{V1³hé‹ÝƒEf#¦ÔÇ0¼G[ã(0óÒ9$<óÉõÊg¸Ý˜ä)Q» "-p9÷º€Ut)‹þ+ÕãÀT%µ•72M¾›1jºy¬yù7 ¨ª¦*™ÚÅ20UmÅÆWk®³€i·;Òd‹™‡‡HFnÝÊœC¸s{f^(ØØ[0¡4B#d`r“óS…"䧪X 8KxÈ!%žÄD*ì.{”f#àÔ]ô -: îbû 01òB¡q(0Pù}ç€À¼ª(2+ÞÕ^¸_™ïfC8©˜Yv#  ÇÐ{ªyJg°È¬W’¬ìQ+(Š3¨MB ¡raö°„ yUÝܼJ'pâ5¸\Öl÷q°ï LU#,•3•¾š;`ý„*o¬s¶û›ØgvuOq˜«ði¤ÈÜb=žJd±3õþ,ú$u°©J\< b¦ª}·7ÿA7ÌÈ5Ô ßŠ¶S_óËæ˜yàƒŠ˜õ¦G†À¼BPHƒjƒÅ˜[¤¢ *ŽÈ­ýK'pM6 ë¨l4ÐfE˜l–‚v`×þ¥¼ZÇEÌ< l™G”‰À@…ƒD`n‘ãÀÌãNÓÊÖ,`MÓKâN7#N'Økæ û?FÞ ©o ÊT̼ Áo_äw` ÂæÖp‰ÈÊNþ"8¾¥Õö¦¼O^·¯9Gfª³žECϘªê;¨çn¡i©S7˜ªôý°Y˜«hÆÛ,¬ªÈ©jÞmPÇF˜YÔ÷àtŽˆ*ޝBGæ±b3‹Õj×ðÐ!'u ;†ÀÀÆ 0¯ 4}lOŽCÙô[z׬ÀLuÔC1¨Y©êXô½@T³výº$ÞL>àb#0WÑÐØu¤NÃ\`ªªOÕS]L½—ZzdVf*{»Y Ì"aï ïsE"0·Hm,0(G~sUˆ—EšŠŽÓ¨ÎÇvb UúcYôÙ ¨\öqØÖLUú8rØÖLU2ÀÍa_`—j¹Ñ”­¥ŽS6FàÎz¯0ì]õqs|*&2UI ŸCA¦ª¼Æ×!Dvõ(£÷¹ ãÀÈìS˜32M²mì໎Ï䱊™ÇŠ 2³rÞôò• !×p 2òÁx23U±'ˆ°lZ½‚Ù_«ÔpvßyÍ¢á00÷žæuyÍb3¯Yd10¯3ä}` ÂH6êM©yÝÂÁ•‘×,ÒòH±1f^g¸™ŠJ– Æ“™×,*›³,¶¸öÞO×=aþÇH5šhØ5 LT6»ÿÝž· ÿP›·ÀT¥!YyYØð4!Ï6¯æ„ʾ(•iYÈȧa)0Ui‰— bæÙã¢af=ëÈs¶À<ìT±ó"äfÃl‹Î ×=Bn ãÉÈý¦˜òpœ˜y49N̼dhʘ—2«˜y}á˜3»ŽzFá ìzSUµÌk¶§{¼ žRëW¾™}MV5ÔN²¯LÎo¯ s£ý-öÂÞs‰ÌTK»"S•>s¿3Ué[Ñyò™"§™‘,b¿ÐkyÐq.À †ú3f^0NB^0¤!Ÿ¥(1óXr”˜y¹à¬)2/cV1óúÂádvõ âÐõ¦.¢;ìaê…QÇÞ# uè…º5_†÷üâ™ÅÓ>Ž]Gd^‚¬b6`-ÌUØ©F_õÀ ‘Ù·7í–ÔJSU^¦%ˆYþf{Ùcæ%Ï AÔ)ÌÜu{AÔq Ìò·‡¹^@ªYì½Bl™Ç“}gQÇ(r{Of¦²w"qÑÔªàóþ=\Dæõ·ç"óˆÒ´£[·¶ñõO@^Cñ¢GdÜ#l” ¶äž³ˆ™×+¶Ç " =#Ð`OØ£(0ƒ²Áþª¬Ûkßøê9ô1©Jß"Á˜D¦ªR&ÞGH5Ëï G¦ªlob3U%}§j0ÈÌTöö(¼é¨üQ¶€ÀE™ù¾ÄgPzD¡¶èa{fdñ<õÿáldQV1s¯È!õJÚʼ&V5öì¹ÕÄßíYÓ…}o â@*fQ²ÈÌë;{ÏìzS^¨‚YXË5MóHÐ,,0¯ñ¸ÌÇ­‘:\ìˆLUú®˜“Nÿ"¼ep±Wà®ï Ø?fªÙžúÄ–˜ªÄâFÖÀTUì­aÔöSղǧB"SU>ê{©Ð"3SٻŨ‡ TÐC0{fæ{®—Z ‡h1…5SKœVVyZØ®y¬¨‡hö`,oiÓˆ˜Û£?0·H#~‹Œˆ=u©#¯p¬ ÌkÎ0Y=ltG !¯íl™·öœ¨0„LSnæ3©jÛâ|†‘·@1ƒ8‘=f¦ªo7EÏ †bÀ ËãÉÌTgxôV¿ÑÎZ‚ÝU`ª’ï|72Um9^¼LUú1>z‰LUeÓ.‚UÌT%Íf?‚Ef¦Zêk² » TÐ]1{fæ{ªçíÐ]µ˜ÂðÛ v2yä©S Ì#OCy`yšæ‘g3[dæ1¥ÉC` ÂV``‘"ÁÌcÝ{ *Ì0Zâ4 Ì“¢yH`.š‡t‹Þö˱„="^Ð4 ÌTÉžhe1¯´Ó˜W¼ÑägPA¬XE âwº"ö¦E )!ð4ˆ +fQŠ3(œ!%Í*b^c( „¼ áx2ÆS_Δh÷ºS•¤µóQGdªÚísTÔ-¦*qh ]|`ªZ×úiT1SUÙêóGh‘™©ì%¨80r ŒDÀÅ€™ù=ÛóO8´HA÷®/›:éiŽ€¼dhm¨à“‘=} QÙØ`cVÊ¥~¢:÷À¬”7›%“Š™•òn×°q T8ÜQ­öA1¶ÈÌkLPóRäH0µƒJÈ5T<„À–3!¯14!h%{YÀÁedÞNiT ÌÛ)Í6óvJ{lyÔYÅÌãÀ™ˆÒô–‘kpgÖ( Ì<îxD="ê½h®ó6Á}-3ˆ(©˜_d‘™Ç‡F®Á‡XÓã'¶eĽÆïDæ`3ˆ&XCõœœfv½)'Si‹J´;Ú Žm‰Ê.¯„“¨ÀT¥ÃIØ! LU{}3/ŽZ©j«¯æE!Õ¬7oëÌT©¾U†¶À@ƒ#°GQ`fžÏ<´µpBÛR¦n80 çiïÀN/0PᚤYô™\ØÚóR¦Ž#0/ešg楌óKF£ŒI‚Ä#ζ˜y8©ç TØu)ÌZÓâ§3é±¼}f„×cŽSçÀ<àø¹‘È<àÝŒ8xUÌ"B¶Ç ÂéÝP`7œbÀ¬{2{íÏv‚=Y`ªÒ—®ñÅÁÈ´ðÄ¿ð„~d¦JövR©j_ôYV1S•”Bx,2SÍöüöe ú2F`㘩êëš±;³ìQÔ¢LÛ 'Œ]=uœ{f¥˜ul¥40/ERæ¥H³Rܧà<#×`5ìÔóÄ91#Ðp¤,žÐëu‚;ñy« y^`O:+ÌsH½q`Þ*XÅÌk)[dæ‘ÀÝ\F ¡N›ØÃ8æ­‚Ö=¦ç2-óŠ!‹ Ò—Gî¼Ç¨Fg+ÍøÌg¹üëÓbß'(—EŸô¨G ØÈ^«ØïžÒ|Ñÿµÿ¼»^~ôüôç_ï=Í2xþí“üëåM’Õ—"©/•?eRú|}zu¾~þ‡'}¥—Lk/o$`ç&Õðùïž^}¦ÿòöùéÃr±wsàKYç¢oòyÜÝwÚ¤Ô—C-¾IJ©zä̯ܙ6ÿö¸t`oOYñE|Èš€~©{1WÒ¬¥jÈ¢!7Wdñ¡®¼ýjø"1´-­îD+[]$mA´åÇrÎz9¹ÿÒÓ/iïžзH!÷¿n™Š™Ô?Ø­fº¢îVx ý·›h¤»ÐrÞÙˆ]ì{Ø­F°ä#»ŽciRæ*¬Ñ‘]o|xùÊ"qÕDå«ocʧ¦0í’‚ð^d€†J•’~`j±[Óu1VI™¥ÙÓCVeIË¥Ô+Xjô›<,zC/öêºÓ+ô7ô2ë¦25ôõ¶¡· í ½[ö†>Èà ½û‚ }»ÓЛ3ÞЋH«éKûýp3/I?"V(*åŨÜmæÝ‡Q9K²IÜ ÅÞZVz?G#tR›éH e+äRþ 땽'(9Ù[aGã÷0ÑIó¡'0\¤

ÿø¿{ióÓã’Ûuê«ûîZ¿"½ÙDÍëÖy,b󦢀®¡{À¹Û™¦Ãe½­Ç< kì¢ÙXw¨“|Jì ¿Ìj¸4ÀÃ}{^ô*ëʳ•|;[¹™ÅuÓ^Ky¸sïÎ`çžÒ2ËkÒA"ÓÁÃý»^÷+K˜Ç-/Fæn?¼}T^g{Ÿ^'ý½­w?G÷ë¤vÐ#–±˜Qù‹5Ëß‚`ÙôÖ'Ð4ÚßwC´‡ï¯¦À|U‚…™¨rNÓÁÓ½È\…µ:²ëÞ)e}uò¼¾§·ÏvB ·ïäñÞ>‹»§äó‡zûÞéB—ØI{";ëμæ£j°Ö™\cƒ1QC:ÐÛÛðw¨ *w×÷~Í𲿧¥n@ã[|=–LÝt}SÌb/Žhq®dO[ÿJ±ÇæåŽ<íUÆ8†&0ÿ.ª<×Éç—ÕÞ7fïioŸðX—9ïv&µv|t™¤¤U„¿Ò§coÏÝ);I‹ïߌ̳¹Ê6µÏ x„ý_µöôƒÍÒ„NJ5­k¶oƒ—vû†-É¥ñ?Кtþ«÷=õÃoënÍéׯ¾^_¿Ñ7¤y“Ál~ý×Ï_ÆÖ•ìs¾È(»éÓõ×ñeÓN,íSV jŸ¦Cä¯}`oÕ—©øÙ¿u]—ñÁê"+Hi êUÁ¨ÐÞþ{óñ1]ô¥ÿš jL_ý؆aý:â.?ÿìé•>Xøÿ~òúÏbdß31€écd^P5ØH+Ö8ª…·uUQÊ#V]GåÕÊmZRýŸ?ÿù½E\ŸÍÙ;b ìZv‚»– ²¹º½z V;\oÒu‰´Ài­Û¶GÝËhD†üCŸ^Ç’V#ÿNí†Þ=9™÷º!ÔRhfÉ‘Ÿ2ïZÿgûæÆæ>~ƒ4z ÃEÈÁ;Þ¢´J2í­`û ™ÿÀ]8}ç‡æTº÷YæKZ€‹¯7x¡„N}„©UÆž²úN@ÜÕ;vûݲä­-¬ôû!ûVÄŒTSê’ÞÞUÙ×y7)«},T·Iíö­±Å†¥¶’!©ÀTUôƒËr$íÊXî»ô2Ië–t‚uÿä/¡ÑýÍ2¢×OèâQÚöé’þíWfÐI¶¿£×ÓjÝ&¥˜ªôâ8'uë–ÝòX9©ÀTµ[…½ŒFíÓ’ÐÞÑ÷o-ƒJk·DU8‰û;ùºäÙvy^ȱA&ëçYçÌ_×U‘,„wÉ«Ž ÒqýŸÛ‘!öð×›|¿K{~tcUg»LÒÚˆví²1U` j#Jµx3h©¿0Ê·J'K¿Cût¯tÛœŠ^³ÀJ×™WºþwXé ­Zé()F>ÆSJ·^õÏèbR©*Ÿö~«yµU`¨™mÔÿõ¾¾GTYæ_ú PAÕÿ]mJGù‡VÌbÏjJ¶$kµ^f¯—ëûêå­÷­ü)ö®rY²éÌÖ?~ÚIÈãÐKSÙë§D;9Žñ±¦öµÄU¿b¸×„v²­Óøš¥õÛë!­¯Ͳ™ŸÌã¼Íõì@ߺ[iy•Ÿv|ü¬î¿{@o ÿs‰­, Ü@ý­ å¸¸¢},u¤0~ƒtz ÝEÎÄ»§ßþñfì¶™áBƒ^l@µÊ{³„U{!ÉØ*AÔê5î™DöÞ¤nD˜d§÷ÎR™'»1È,¡ßØp_Ä{våð¯ïÏÍmžÁòö,2jmvR.s®£Nï>¯»’ý„ç4^Y-ÔÀôÕz¤ý=û÷©ÈZÜÆãA’ŒÐ[¿âW(7}bþœÕ§hà´íVµç=÷-È<¨Š ú?I¾W¾Å*¸ôûöT\½;*³½.Ô——ëe­Pß.2ˆn¸õÜê÷²Å’ÌI§v¯“M¯²÷˜ÔQRÂz'®}R2V¿á˜玫ñ„ÁÞ앵uã™Ã`¾uÖnßë6êì'\„”ëx» Îi"s–üβõ¶P±¡VJæöàåå3ÚU?ãtüÐÒëžMIAƦ“{>ÿâÆf·pÕ‹]¹£ÍÈ\õÑÐQSSÀh€gþŠQqy|'aѧ/4M²ùó›ÝÂýÝ‹^ƒÀ³Fp6ñØ¡yö?~ysQ§[ðª6;ƒýž;ªÜ#?dŒÜB Ï^_¤óXµÇ{ ›Oºñ`û±Ó¹Õç¿z÷îÆf>¶³–@'Ø{Gv¿‡Qm–¬î²Ž–vÊuµ#k{Ýk™uÝæž]ýïì›m@ ÌÓÂCÄÈ<­¬_ˆmO½Ç¯¶CC~]›1&§£ÜYçöÍ2ÆÍéýˑΧÔþ¶÷|Cóÿ\X¯×]ô‹>+IÊ*)µmåÔ·•OÞVnÛÚ«¶ÛNeØØË§"dä)Q 6R¢|Ñ',¿À¼ïy¡üú¿zùÝÑ/¿Nî—x_‹Ïå_;àò+/”ß Ž9iÈñ䎌ÞS×ñ®EJ:ßO:fÖ!¿½–¥“0©êúöù+¤P'•5Õú"Šº¹Ð^^RIÉsßÐè¯7HíCDW'E7mã¤j8Ög¯÷\ì:¾½„ªÈPÙh79`b5Èž{6òºê 1ØHý;Nk¨šEJ+0TyZ·Ë°ÍŽŸ’/‹: ÍõÁ &‘½?©¤tÛÝöiKaËmèDÿîMìã¿þ@~ns ¶[‰m² È[Ý|ü<ûJìØß»kŸñf;*Šm¾$®N]ÇŸízM‹>sÓ¤´K¤Ç7D˜AJ2)?JéÖ§3éÓœRcpÈ=$Á½xÜúÁ6YdÌ;ª¶#M±—vçsÝ8µ=eôÀ4¯è7µwMS|_Z/½µ^zÝ^É¢ð^/¯8\oò\?ÖY7× Êí­ÇTò]ýï°èƒ´°ìô ð_ö K?0X§Þ/ýW¬Túyér¯ôÝý^ü.´øý|v Å¿¿Pü} ïÁêû Xˆ‘ùÒ 12H 12LË ñ=~A!F†üîb¼þw_?Ø(D'w Üo…ò QÏñO½”J…x¼TˆíQºèR·rûU.Rr?eæg’¹H5\ú£GÌ0-Yj•Òª Ҫ甆¤nÝjO^SRõžöu(@û§zS÷FFDýß—bsE†Î¶g«Ø^Võ@yé3Vâ¼¾óp[[q/u¹m§ÆãRl[¨¸"ó=$,®È0-/®È -/®÷¸Å™/Åï—Ø ׫IÜÙ(ºAî–ù~&Ö?X€%ÙÁ•_š_¿Ñ<¦uiÌ|ë8MîýO¹CCcÇíÎ)¨üNóf߯³‡˜ì2_'ý ˾Zˆá·] |÷äDg°zÓ¥§°ØW ÝFým2Í:ßtE-}O¡ÿvƒ4/z ÝK·žÜ|ÊÛ§¼}ÊÛ§¼ýGäͯÅìG»ã+s¾õì ÙÃÓz!F`z=~×c¢wONdeô/zºX.n¡þ~§6ÏzÔÔú`ròÆïacæÅH¡:É™ø”¯Oùú”¯Oùz(_ãº_ÏWÊvƒªÿ‰~a><Åñ{ؤy5h^ #_z¯qž4H ÿvt'ZÍEÊŸ@®ìe+f«‘áõ.#_Ið»^É„|íåÔÍmOA·]N7Û~{¾† y=è¿ÝD'݉–@÷‘sñ§‘³uÓD±*vÒý^õÜà\àw½æ9[õÐ.OAþ[Ýh6êï‘3T¿=ñ{˜è¤;Ñè>r.þ4r¶ÍÛQ·"»_t¿å·ÝŒòßõþ çl›%ÝÅs¶éU97Û~Ž|®Nû_÷ßž~'݃ö÷ÝAÎÂs¶þX/¬~ÊØ¹Œ}šv|œ? aÿy}½_xIejßU²g²èKJE¼Ùðw®µ½n™ô/ZíêɰÐ~ë_,«î²»¢ÌvÅp¤Ð~ƒAš-…î$eâ9_~9èh¯Íº/¸¤AòZôõ#z è¬Ç}ãw®µß‰ô`³ž0õÚ%£a£þÖ¿°×§º@Z¼½Û¡'л‰Aš-î#çâSÎþkæìOÿ / ÷endstream endobj 6 0 obj 12587 endobj 4 0 obj <> /Contents 5 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 4 0 R ] /Count 1 >> endobj 1 0 obj <> endobj 8 0 obj <> endobj 7 0 obj <> endobj 2 0 obj <>endobj xref 0 9 0000000000 65535 f 0000012894 00000 n 0000013035 00000 n 0000012835 00000 n 0000012693 00000 n 0000000015 00000 n 0000012672 00000 n 0000012971 00000 n 0000012942 00000 n trailer << /Size 9 /Root 1 0 R /Info 2 0 R /ID [( ½$a\\•œ°mO²ÍA)( ½$a\\•œ°mO²ÍA)] >> startxref 13146 %%EOF xc3sprog-0+svn795+dfsg/cables/par_cable.sch000066400000000000000000000125621337255630200206250ustar00rootroot00000000000000v 20060123 1 C 74800 53100 1 0 0 title-bordered-B.sym T 85300 54200 9 10 1 0 0 0 1 IEEE1284-to-JTAG cable, Xilinx parallel cable III compatible T 85300 53700 9 10 1 0 0 0 1 par_cable.sch T 85100 53400 9 10 1 0 0 0 1 1 T 86700 53400 9 10 1 0 0 0 1 1 T 88500 53700 9 10 1 0 0 0 1 1.1 T 88600 53400 9 10 1 0 0 0 1 Dmitry Teytelman C 77300 55500 1 0 0 header26-1.sym { T 77900 60900 5 10 1 1 0 0 1 refdes=J1 } C 90900 57000 1 0 1 connector6-1.sym { T 90800 59000 5 10 1 1 0 6 1 refdes=J2 } C 82900 58400 1 0 0 74125-1.sym { T 84600 59400 5 10 1 1 0 6 1 refdes=U2 T 82900 58400 5 10 0 0 0 0 1 slot=1 } C 84900 61000 1 0 1 74126-1.sym { T 83200 62000 5 10 1 1 0 0 1 refdes=U1 } C 80200 56100 1 0 0 7414-1.sym { T 81000 56900 5 10 1 1 0 0 1 refdes=U3 } T 75400 56800 9 10 1 0 0 0 27 DB25 to header pin translation DB25 IDC26 1 1 2 3 3 5 4 7 5 9 6 11 7 13 8 15 9 17 10 19 11 21 12 23 13 25 14 2 15 4 16 6 17 8 18 10 19 12 20 14 21 16 22 18 23 20 24 22 25 24 C 82900 57200 1 0 0 74125-1.sym { T 84600 58200 5 10 1 1 0 6 1 refdes=U2 T 82900 57200 5 10 0 0 0 0 1 slot=3 } C 82900 55700 1 0 0 74125-1.sym { T 84600 56700 5 10 1 1 0 6 1 refdes=U2 T 82900 55700 5 10 0 0 0 0 1 slot=2 } N 80200 56200 82600 56200 4 N 82600 56600 82600 57800 4 N 82600 57800 82900 57800 4 N 84900 57800 85700 57800 4 { T 85000 57800 5 10 1 1 0 0 1 netname=TCK } N 78700 57000 79300 57000 4 N 82900 58600 82800 58600 4 N 82800 58600 82800 55900 4 N 82800 55900 82900 55900 4 N 82900 57400 82800 57400 4 N 82600 56200 82600 56300 4 N 82600 56300 82900 56300 4 N 82800 57400 81000 57400 4 C 82900 59700 1 0 0 74125-1.sym { T 84600 60700 5 10 1 1 0 6 1 refdes=U2 T 82900 59700 5 10 0 0 0 0 1 slot=4 } N 78700 57800 79000 57800 4 N 79000 57800 79000 59900 4 N 81000 59900 82900 59900 4 C 82600 60000 1 0 0 gnd-1.sym N 82900 60300 82700 60300 4 N 78700 60600 79000 60600 4 N 79000 60600 79000 61600 4 C 86000 61500 1 0 0 resistor-1.sym { T 86200 61800 5 10 1 1 0 0 1 refdes=R5 T 86600 61800 5 10 1 1 0 0 1 value=120 } C 87100 63000 1 270 0 capacitor-1.sym { T 87600 62600 5 10 1 1 0 0 1 refdes=C1 T 88000 62800 5 10 0 0 270 0 1 symversion=0.1 T 87600 62300 5 10 1 1 0 0 1 value=0.1 uF } N 84900 60300 85700 60300 4 N 85700 60300 85700 61600 4 N 84900 61600 86000 61600 4 N 86900 61600 88100 61600 4 { T 87100 61600 5 10 1 1 0 0 1 netname=TDO } C 81400 56100 1 0 0 7414-1.sym { T 82200 56900 5 10 1 1 0 0 1 refdes=U3 T 81400 56100 5 10 0 0 0 0 1 slot=2 } C 85600 62900 1 270 0 resistor-1.sym { T 85900 62600 5 10 1 1 0 0 1 refdes=R3 T 85900 62200 5 10 1 1 0 0 1 value=4.7k } N 85700 61600 85700 62000 4 N 85700 62900 85700 63200 4 N 85200 63200 85200 61200 4 N 85200 61200 84900 61200 4 N 87300 63000 87300 63200 4 C 88200 63000 1 270 0 resistor-1.sym { T 88500 62700 5 10 1 1 0 0 1 refdes=R2 T 88500 62300 5 10 1 1 0 0 1 value=4.7k } N 88300 63000 88300 63200 4 C 87700 61800 1 0 0 gnd-1.sym N 87300 62100 88300 62100 4 C 82900 63000 1 0 0 diode-3.sym { T 83250 63450 5 10 1 1 0 0 1 refdes=D1 T 83200 62800 5 10 1 1 0 0 1 device=1N5817 } N 77300 56200 76500 56200 4 N 89200 57200 89200 56500 4 N 89200 56500 91200 56500 4 N 91200 56500 91200 63200 4 N 91200 63200 89700 63200 4 C 88900 57200 1 0 0 gnd-1.sym N 89200 57500 89000 57500 4 N 79300 57000 79300 59000 4 N 81000 59000 82900 59000 4 N 78700 56600 79300 56600 4 N 85700 57800 85700 58700 4 N 85700 58700 89200 58700 4 { T 88400 58700 5 10 1 1 0 0 1 netname=TCK } N 84900 56300 86100 56300 4 { T 85000 56300 5 10 1 1 0 0 1 netname=TDI } N 86100 56300 86100 58400 4 N 86100 58400 89200 58400 4 { T 88400 58400 5 10 1 1 0 0 1 netname=TDI } N 89200 58100 88100 58100 4 { T 88400 58100 5 10 1 1 0 0 1 netname=TDO } N 88100 58100 88100 61600 4 N 89200 57800 87900 57800 4 { T 88400 57800 5 10 1 1 0 0 1 netname=TMS } N 87900 57800 87900 59000 4 N 84900 59000 87900 59000 4 { T 85000 59000 5 10 1 1 0 0 1 netname=TMS } N 83800 63200 88800 63200 4 { T 86400 63200 5 10 1 1 0 0 1 netname=Vcc } N 80700 63200 76500 63200 4 N 76500 63200 76500 56200 4 C 80700 63100 1 0 0 resistor-1.sym { T 80900 63400 5 10 1 1 0 0 1 refdes=R1 T 81300 63400 5 10 1 1 0 0 1 value=120 } C 80700 61500 1 0 0 resistor-1.sym { T 80900 61800 5 10 1 1 0 0 1 refdes=R4 T 81300 61800 5 10 1 1 0 0 1 value=120 } N 82900 61600 81600 61600 4 N 80700 61600 79000 61600 4 N 81600 63200 82900 63200 4 C 77100 57900 1 0 0 gnd-1.sym N 77300 58200 77200 58200 4 N 77200 58200 77200 60200 4 N 77200 60200 77300 60200 4 N 78700 58600 78800 58600 4 N 78800 59800 78700 59800 4 N 78800 58600 78800 60200 4 N 78800 60200 78700 60200 4 C 88800 63000 1 0 0 diode-3.sym { T 89150 63450 5 10 1 1 0 0 1 refdes=D2 T 89100 62800 5 10 1 1 0 0 1 device=1N5817 } C 80100 59800 1 0 0 resistor-1.sym { T 80300 60100 5 10 1 1 0 0 1 refdes=R6 T 80700 60100 5 10 1 1 0 0 1 value=330 } N 79000 59900 80100 59900 4 C 80100 58900 1 0 0 resistor-1.sym { T 80300 59200 5 10 1 1 0 0 1 refdes=R7 T 80700 59200 5 10 1 1 0 0 1 value=330 } C 80100 57300 1 0 0 resistor-1.sym { T 80300 57600 5 10 1 1 0 0 1 refdes=R8 T 80700 57600 5 10 1 1 0 0 1 value=330 } C 79300 56500 1 0 0 resistor-1.sym { T 79500 56800 5 10 1 1 0 0 1 refdes=R9 T 79900 56800 5 10 1 1 0 0 1 value=330 } C 79300 56100 1 0 0 resistor-1.sym { T 79500 55900 5 10 1 1 0 0 1 refdes=R10 T 79900 55900 5 10 1 1 0 0 1 value=330 } N 79300 56200 78700 56200 4 N 78700 57400 80100 57400 4 N 79300 59000 80100 59000 4 xc3sprog-0+svn795+dfsg/cables/sym/000077500000000000000000000000001337255630200170205ustar00rootroot00000000000000xc3sprog-0+svn795+dfsg/cables/sym/dlp2232m.csv000066400000000000000000000016621337255630200210070ustar00rootroot000000000000001 io line l SI/WUB 2 io line l BCBUS3 3 io line l BCBUS2 4 io line l BCBUS1 5 io line l BCBUS0 6 io line l BDBUS7 7 io line l BDBUS6 8 io line l BDBUS5 9 io line l BDBUS4 10 io line l BDBUS3 11 io line l BDBUS2 12 io line l BDBUS1 13 io line l BDBUS0 14 pwr line l GND 15 pwr line l GND 16 io line l VCCSW 17 io line l VCCIOB 18 io line l VCCIOA 19 io line l EXTVCC 20 io line l PORTVCC 40 io line r ADBUS0/TCK/SK 39 io line r ADBUS1/TDI/DU 38 io line r ADBUS2/TDO/D1 37 io line r ADBUS3/TMS/CS 36 io line r ADBUS4/GPIOL0 35 io line r ADBUS5/GPIOL1 34 io line r ADBUS6/GPIOL2 33 io line r ADBUS7/GPIOL3 32 io line r ACBUS0/GPIOH0 31 io line r ACBUS1/GPIOH1 30 io line r ACBUS2/GPIOH2 29 io line r ACBUS3/GPIOH3 28 io line r SI/WUA 27 io line r _RSTIN_ 26 io line r _RSTOUT_ 25 pwr line r GND 24 pwr line r GND 23 pwr line r GND 22 pwr line r GND 21 io line r VCCUSB xc3sprog-0+svn795+dfsg/cables/sym/dlp2232m.ods000066400000000000000000000207311337255630200207770ustar00rootroot00000000000000PKÛ»4…l9Š..mimetypeapplication/vnd.oasis.opendocument.spreadsheetPKÛ»4Configurations2/statusbar/PKÛ»4'Configurations2/accelerator/current.xmlPKPKÛ»4Configurations2/floater/PKÛ»4Configurations2/popupmenu/PKÛ»4Configurations2/progressbar/PKÛ»4Configurations2/menubar/PKÛ»4Configurations2/toolbar/PKÛ»4Configurations2/images/Bitmaps/PKÛ»4 content.xmlí]sÚ8†ï÷W0¾Ø;EÈ& a“t²ÛÍ4i:…´½ë[€¦þI„ðïW¶l#Hp°Ø¾Ð ò9ÒÑñƒ,¿qþá9ð;O„q…:êZº‘GÃÙ…õ8þô­—œGÓ)uÉÀ‹ÜE@BÜ(ò¹#½C>PG/¬ æ”B>î ŠI˜{ tëAÚ–*ábåWvOuoAžEUçÄvÃOª·œëÞÃ˪Ή­Lªî>ª:?sL#™õ Æ‚nEñìÓð×…5"@¸\.–ÎQÄfÁôh°[ØÅ æ§Vž ‰O’Æ8DG涸j|‰­R¸&„UN øÅYåO³ÊD<Ív¤ÆcV™Ôxóô:^õÓëxºo€Å|Ç9éÃ{y0}¸¿[³À‚ªm%¶©r+wSYëþQ¡&Ꚇkw»=¨ÞkÖËRó%£‚0ÍÜ-5w±ï‚×’&픀<%˜à'‰à;l¨ÆÜÛYõû»‘;'^ÓßrÃ$3Ù¶1Ž^惦J8‡EÁTž`Š]<âúüò\Á_wÔûä$^Xw‹gÚá#«#AÏ­ê¯.¬?qñ¿ õÖêhõÅT¸Ä'Ìh2zY°¼µ1žGI^´TxwÕE”ïꇲ3F%P|I9ÿ]8pW³r¼²S‚º ­§8éãFðn„ŠÆ²˜Ó«wüEZ¹§^b&yg‚Þ™Fƒ #ø˜I¥¬0i:¯13_R/3ºGö©sBôZÓ1PŠÖ)H0‚Ù­Ó&&a"£a6EëÔ ¤‰˜È¨˜@Ñ:}i2&ªEÇŒ—ÌPQ4òñóMëÐdLT‹Žih;šŒ‰ŒŽY7߆ÃÑ÷Ö1¡é˜È™ 0qûк¥HS2‘‘2âªuPhZ&2bfÝPüýc,¹h¶&fÚF̬Š/_D…½×¢Šž¡B«ômwHïLÆUªQÀñð}jŽvqÌe¤6ßÜ›ÇÖ±¡Í;3ïl„ [²ño¡{ïdžv£ê˜ÕFØpàø~‡£Ö±¡ [޶a£?~¹}¸;ÄW#û±¡éàŽYÏÛÇŠö]S´¯Í³ü¿6N‡X|±ú…Ì÷ì°qªØ8Äj­ýØÐæ8faNíl¤¿IÙø·}ó m%ŸcVò5ÂRl´o¾¡é¢ŽÑEaÃVl´n¾akº¨mtÑFØp­›oØš.j]´n6Òý-ñ}ü~Ph‚¨mѺ¡øùu4¾ýü³uThR¨m¤Ð&¨xx· MµÍjàÚ¹8ÌjàýÐÄOÛüfÀ !‘Ð4O»ÍÓ Ñv$ômÔj‘: mGBS8m£pÖMÄ·áðqôÖŸ è%y³ÉfðÌ¥gÉ&¬¯wrG6#BìyŒpžo¾zte£Aöòc¯›ï šüq¦!s‚½d‹úÍíWyÄ„þLV™ã”ßùÆöE}KkñwI˜ükB±© 8ËU±±lº÷¬Þ|­s;Še*òj7ö Í Õ.µù»íj¸üPKQ|†fêaPKÛ»4 styles.xmlÝXmoÛ6þ¾_!(CÑ“%9¯vcåË0ìC;}ùŒDÉD)R )ÛÙ¯ï‘eÉ’-ÛÐuDäs/|îxwÖýá¤Þ I8Ûøñ"ò=ÌRžVlü/Ÿ îü‡ä§{žç$Å댧u‰™ ¤z¢Xz ÌäÚnnüZ°5G’È5C%–k•®y…™ZwÑkcÊ®esÅ ¸+­ðAÍÖØž,zœoÙ€»Ò™@û¹Â œvÅs>Wø ió åe…9ñâ@ ûºñ·JUë0Üï÷‹ýå‚‹"ŒW«Uhv[‡ÓWÕ‚T–†˜bmL†ñ"¶Ä ÍõOc».±º|Äb65H¡AT官»b‚št‹ÄìÜ0à~x/³ùá½Ìº²%RÛ‰˜Ü…ïaÓüzÿî˜ ¢œkKc{T¥‚T³iÑ]yÎy몰Ը»Œ¢«Ð>wÐû³ð½ ‹<= OM[Æy9FàâÞé4õ½¦„ôÊVâjTΡ>å(ÅA†S*“{›[í²gŸ5Gÿ]} Þ'Ädì{GUú´ñ_¡ŠË·-Ä>ú^G_ET qÞ!AtqðÃóÖ>£-/ш¥vãŪ[/_t‹ ̰ /¹'R>çN8Ex³n{„s;Ã9ªiÓ9œæÆASYƒSê;øq)¨äPúS•’Á£rã/äTH B j;”`œWAF¤BL7¬hqMØQXw‡¡œ9ހ䜯)bE XÇÌ,¤¼fJÀy¾|òO…¸˜ˆ$œ85Á8Ãn¯Ñ8¶uÔ¬kŇÓ,jõ¶ûcšû›:ª#áJîmEo {/†–™?ôì¼æ©$, Láä2R‹¡­Ž´æ§1Sqtõ!rçØq u_7q%jì(x*9uÞôcæ°¸%?·Ž¨˜8ß0ÏŸÜí‚ו™²ŒãBúgŸK‰?•Å&1)‡v|‘ç|´­F§Æ&AkÙ<þÀ ZJTµIÎ2¢L‹Ø!Zã×o^êí¦MTU´á3è%×™hXÉa ~µÆŸ.má´ðG,ÏËzmyk§ï o÷LøM©h†l¢%©ÓgÀ5˰€1;Œä”d=ÉôdƒjÅ'M²£æ¿õaI±…Ir!ëÔšg˜µä,_ÄNŸX=iÂ}..¿c¤¿ ý39ÓÑ …˜‚’×B÷¦œœr+Œ4™pЗ#*ñ3=(?*Ýø)ÂP6ÙêÚ,!‚íø¦RþTæü½`6ŒÆ/¢Ô…c¥‚+¤¯~õJ»¿Š†N†'“Jó¨“x’ý¦ÒÝ”¢'^«Þ™ª2öG0CŸôh þ%Ï@ŒŠ@=C²…Ãû`o-ç¢w/]·M ¢Åru}KìR"QÀŹÞé/Šß_}äJéÑ;ZD«»+;…Ó^5î|Oa~u³ïR8ˆÅó!\þÏB¨÷¹Èô÷pX¼¼º!Ì3•Ý»ˆÌÇ@*”Ùw=€‰nc'ˆÒ¯º½²Ì•ó‹4Ò?-I4ï2fpà#¥þ»´=Ÿâádýj6J$[ò8.™E­éÜ@Ó½òg½OîÍ ¶ªù+·[pòððpž.6+Õ 'ñסtý›HŸÐRÓZÿ Ò OpenOffice.org/2.0$Linux OpenOffice.org_project/680m5$Build-90112006-05-27T10:26:492006-05-27T10:46:53en-US3PT50SPKÛ»4Thumbnails/thumbnail.png5”{X’WÇIRxËgÙQçûÔÓp¹.¨ˆ—L}½>6¦í±‘%¡CL–‰«/Åë²Rk­Ò¤@stYD›)f›hÞ/t¡q1‡æ¥Pºëâ^Lÿ8çüqÎó;ßßçû=ç`ݰ( ˆ‹ÜŒ¬G‘!Â8 sï²aOŒ‹ OäW™„÷¸Obñ wzÍÌ(=˜öFhøÿý‡ú;‡ò½¢£škƨÉ{¥V!Ã'PÉSØ/T«}ô筬̖gÑM2ü•¢?®kMR28ªÇIŲ¾Xzýæ¨Ð>•ŠWŸšqÂÊd¥ˆ:¸­‡Å;»qºPR郴.K·N¥¦ÀdbExNùsã°#z³ÛàŽþµÿ@LÝw°LLÕ Ò €vÅ =ìæ´$i«‹ƒ¾ç™2r©ˆ·Àx<̶dÏ8P\ «ÁñsÅ*“ÑÒVæ9Æ–Ø®­q®¬å\Ò‘ží÷x¬8•}Ÿä¸âÏÅÌÅ@D|OõZ ëѯ7ÀÑdæ¸Ù\­Ú.ž?}b«GyOèE;UŽSiëï'[XŠkÛ§7„ƒ~ÒñçÇöùâÐ\÷k¡-™Šãbµ°6È«â`, GmH·ˆ«æ¤TûÍaäZáayعj!±D¬.æ©Ü„úàª"»WLhIFérÊ®’öÀêº\öôÆ@Ú>c‚ŒíoH¶É$ÚiÌdìÄGY›)#®g #Øîýú¥¦Ó  |M:$ÝâHq¹£”ÉÿV vM…~ÕáÊ'ò: °ÆÙ­gòÐ ¢†¤ò‹@#ÂeOÄ]#·ÉfB^½b 3?øqÊ<ìÿF%HuˆFᣆ"O׃WÐ'µÅÇ€u†Ò1*ÙP)ý +ÎÞÞQÆTFq5×ÏÔJFX–½Cg¬ö7ØÝ~£Ü¤í¥­û74O'¿6_ˆzÔÓldÏŒ¥5g+µåI7GO«G4¾6G¬×”{÷¹"õ Ý^£Ú0P„(½o¼÷A’ì«DKjÔƒªÙEؾn€öòÎ['ÿÎìt"×í‰äèBórÝzkÜôg€Ð0Š8hsR–ñ²Øž$Á•ã;Ñ­¡[Êß:! ¬ÏÝý)xÛLAYLhZàÜê9¯|èÞY›Ù•û-æ¸^0µÈƹ©Ú,Ø×Q n5t¼„2òù)kp'ĵô³Iä ²†DdÙÁtÞ»³€Lt[kèP%^³ž³öüöü—ßkÇ%$|}EŽ2“;Ò*â/CÔŸoX¥û‚ßwÀS_ê-F$üF¼©Œ–8—Ýt‹9IÐRï[l ¹äéò¢Ú¹ò©çW:.aÛ]xEènB çé´ÏnˆXº¦~ÎY`¿-^5òn)Ÿ Ò£ _:¦w3¥-`4t¬¡59ˬnû‡m03ƒ» CÄcÔ ¡¤IÔ·ä‡Ò''“X£»ã¦„³]÷“síJúhá…|Z³wÃÐgn³z(#A×ñ.‡‚ÈùMZ&éê‰ æËæ‚Êx³âΉyïe 7ÑÏâ3ú`wô¡ù'§€í2R!YÈ™ý-—ð©fÝá¿÷ÇI‡YÞÄ+”’&&”]Wʼn]ßž`Ìþã{³HÍÂ~º+'øGkØù‹Èöî»–Ú²ÒJÐcf‘D+) •fÇ]¦ôå{ ¿%*.Š)`ýPKrK½#TPKÛ»4 settings.xmlí™]Sê:†ïϯpz{F) a„=åC¥åËÞ¥m„hšô$)ýI)ìÑîv‹¥ÌœÙ£7Ø&yÖÛ•d­•öêÇÊÅ'KÈ8¢¤®ÏTå›:ˆÌëÊxÔ>½T~4þº¢ÏÏȆ5‡Ú¾ ‰8åPÙ…ŸÈá„×¢æºâ3R£€#^#À…¼&ìõ Ù «½ï]Û‹î¬0"¯ue!„W+‚ 8 Êg”Í ÅjµZØ´îºÚ”<£ù¾¦¢ÞïMQJ Db6ÆJªz^ˆ®•“­È®iìü°{üÆÕÖ@ôsŠtCßœlo‡ÒêŠ4Y["üôš’4î㘠âÈÂPcŒ¨§ìÅÚ“ˆ¥¡^~…| |ŸÅqÈSäˆEºX)VÇw!š/¥/Ï/ŠûòO]à"âÀtâ¶`ŠaÐsb2¹`r (°ñkJChLçH|&ôãc¡(î±[>ã”=Rބܳ$oW²ÍäGòS¹\͆îR†Þ(F¢O÷ÿ‚²Ö8dÙÇ¢ÇÔï<”ç}¯ÿ|Íh 7tyŠ{JÙà;½9Ç­VO *róß;j“ AÝÄxžLN¸ù>š¥5oÂξ3¿ H)/Š<ï ›QŒ-ÀRsL韌®5)uG’“ëž¡€ý85š*5ë*sfßÒ³fZcAƒÐ@S¦Ú×GÃÚ%Æ·(Å¥ñ 0‡Ù͘Ñ~žf@0ÿþ€Šc¡; Ås{äÚ¢˜²Óp K•r©t‘1ï~˜×#x¥ ¸”î»D§AG–ÎG1² $2ÒÞã¾Ç h¬]‹bnÀxFÈňA€7¢:àÆ':{|[2Í‚¹œïÔò°˜9Çñ‰5â¡x÷´Dzü2¢qÈ£OlჄ׹¼JK8‰¾Ô<¦ü &*QÚŒº#èz¿‹AÑ0–ÅV*n©ÕĆøŽ.«!Jð:Ã3¤–þ…_>Ò>6þPK/¾"tzPKÛ»4META-INF/manifest.xmlµ•KjÃ0@÷=…ÑÞVÛU1q-ôé&òØè‡f’ÛWäÓ6”¦X; HïFi±Ú[Sí0’ö®OÍ£¨Ð)ßk7vâcý^¿ˆÕòaaÁé‰ÛÓ ÊëÃN¤èZ¤©u`‘ZV­èz¯’EÇí×ùídZ>Tð  Öybì„`´ÎyÊ뛣«¹V4"BO[DÈŒ©ð¶RÈ»œ·)oÞ zLñ˜ =KbàDˆeð Ì¡R¥§æbw Æc!xð!…|R!|ôcD*wÒSêÅàì½)×F$ùªÙB ¢Ž;Ùߟ Jnêž&éF] þ–ÃrÆ=Ë©Wo³Ÿÿ×Ì¿s‰iv¬E†Ùžõ6ÙmHòiØ7Î Ÿ·°ÈœÿÅsiòÇ·¸üPKÌMfBQPKÛ»4…l9Š..mimetypePKÛ»4TConfigurations2/statusbar/PKÛ»4'ŒConfigurations2/accelerator/current.xmlPKÛ»4ãConfigurations2/floater/PKÛ»4Configurations2/popupmenu/PKÛ»4QConfigurations2/progressbar/PKÛ»4‹Configurations2/menubar/PKÛ»4ÁConfigurations2/toolbar/PKÛ»4÷Configurations2/images/Bitmaps/PKÛ»4Q|†fêa 4content.xmlPKÛ»4ÇB×'_ Óstyles.xmlPKÛ»4Íd ©©jmeta.xmlPKÛ»4rK½#T9Thumbnails/thumbnail.pngPKÛ»4/¾"tz ¢settings.xmlPKÛ»4ÌMfBQPMETA-INF/manifest.xmlPKîÕxc3sprog-0+svn795+dfsg/cables/sym/dlp2232m.src000066400000000000000000000047051337255630200210040ustar00rootroot00000000000000# This is the template file for creating symbols with tragesym # every line starting with '#' is a comment line. [options] # rotate_labels rotates the pintext of top and bottom pins # wordswap swaps labels if the pin is on the right side an looks like this: # "PB1 (CLK)" wordswap=yes rotate_labels=no sort_labels=no generate_pinseq=yes sym_width=3000 pinwidthvertical=300 pinwidthhorizontal=300 [geda_attr] # name will be printed in the top of the symbol # if you have a device with slots, you'll have to use slot= and slotdef= # use comment= if there are special information you want to add version=20060123 name=DLP2232M device=DLP2232M refdes=U? footprint=DIP40 description=DLP Design USB module documentation=http://www.dlpdesign.com/usb/2232m.shtml author=Dmitry Teytelman numslots=0 #slot=1 #slotdef=1: #slotdef=2: #slotdef=3: #slotdef=4: #comment= #comment= #comment= [pins] # tabseparated list of pin descriptions # pinnr is the physical number of the pin # seq is the pinseq= attribute, leave it blank if it doesn't matter # type can be (in, out, io, oc, oe, pas, tp, tri, clk, pwr) # style can be (line,dot,clk,dotclk,none). none if only want to add a net # posit. can be (l,r,t,b) or empty for nets # net specifies the name of the Vcc or GND name # label represents the pinlabel. # negation lines can be added with _Q_ # if you want to add a "_" or "\" use "\_" and "\\" as escape sequences #----------------------------------------------------- #pinnr seq type style posit. net label #----------------------------------------------------- 1 io line l SI/WUB 2 io line l BCBUS3 3 io line l BCBUS2 4 io line l BCBUS1 5 io line l BCBUS0 6 io line l BDBUS7 7 io line l BDBUS6 8 io line l BDBUS5 9 io line l BDBUS4 10 io line l BDBUS3 11 io line l BDBUS2 12 io line l BDBUS1 13 io line l BDBUS0 14 pwr line l GND 15 pwr line l GND 16 io line l VCCSW 17 io line l VCCIOB 18 io line l VCCIOA 19 io line l EXTVCC 20 io line l PORTVCC 40 io line r ADBUS0/TCK/SK 39 io line r ADBUS1/TDI/DU 38 io line r ADBUS2/TDO/D1 37 io line r ADBUS3/TMS/CS 36 io line r ADBUS4/GPIOL0 35 io line r ADBUS5/GPIOL1 34 io line r ADBUS6/GPIOL2 33 io line r ADBUS7/GPIOL3 32 io line r ACBUS0/GPIOH0 31 io line r ACBUS1/GPIOH1 30 io line r ACBUS2/GPIOH2 29 io line r ACBUS3/GPIOH3 28 io line r SI/WUA 27 io line r _RSTIN_ 26 io line r _RSTOUT_ 25 pwr line r GND 24 pwr line r GND 23 pwr line r GND 22 pwr line r GND 21 io line r VCCUSB xc3sprog-0+svn795+dfsg/cables/sym/dlp2232m.src.0000066400000000000000000000030231337255630200211320ustar00rootroot00000000000000# This is the template file for creating symbols with tragesym # every line starting with '#' is a comment line. [options] # rotate_labels rotates the pintext of top and bottom pins # wordswap swaps labels if the pin is on the right side an looks like this: # "PB1 (CLK)" wordswap=yes rotate_labels=no sort_labels=no generate_pinseq=yes sym_width=3000 pinwidthvertical=300 pinwidthhorizontal=300 [geda_attr] # name will be printed in the top of the symbol # if you have a device with slots, you'll have to use slot= and slotdef= # use comment= if there are special information you want to add version=20060123 name=DLP2232M device=DLP2232M refdes=U? footprint=DIP40 description=DLP Design USB module documentation=http://www.dlpdesign.com/usb/2232m.shtml author=Dmitry Teytelman numslots=0 #slot=1 #slotdef=1: #slotdef=2: #slotdef=3: #slotdef=4: #comment= #comment= #comment= [pins] # tabseparated list of pin descriptions # pinnr is the physical number of the pin # seq is the pinseq= attribute, leave it blank if it doesn't matter # type can be (in, out, io, oc, oe, pas, tp, tri, clk, pwr) # style can be (line,dot,clk,dotclk,none). none if only want to add a net # posit. can be (l,r,t,b) or empty for nets # net specifies the name of the Vcc or GND name # label represents the pinlabel. # negation lines can be added with _Q_ # if you want to add a "_" or "\" use "\_" and "\\" as escape sequences #----------------------------------------------------- #pinnr seq type style posit. net label #----------------------------------------------------- xc3sprog-0+svn795+dfsg/cables/sym/dlp2232m.sym000066400000000000000000000172731337255630200210310ustar00rootroot00000000000000v 20060123 1 P 100 6100 400 6100 1 0 0 { T 300 6150 5 8 1 1 0 6 1 pinnumber=1 T 300 6050 5 8 0 1 0 8 1 pinseq=1 T 450 6100 9 8 1 1 0 0 1 pinlabel=SI/WUB T 450 6100 5 8 0 1 0 2 1 pintype=io } P 100 5800 400 5800 1 0 0 { T 300 5850 5 8 1 1 0 6 1 pinnumber=2 T 300 5750 5 8 0 1 0 8 1 pinseq=2 T 450 5800 9 8 1 1 0 0 1 pinlabel=BCBUS3 T 450 5800 5 8 0 1 0 2 1 pintype=io } P 100 5500 400 5500 1 0 0 { T 300 5550 5 8 1 1 0 6 1 pinnumber=3 T 300 5450 5 8 0 1 0 8 1 pinseq=3 T 450 5500 9 8 1 1 0 0 1 pinlabel=BCBUS2 T 450 5500 5 8 0 1 0 2 1 pintype=io } P 100 5200 400 5200 1 0 0 { T 300 5250 5 8 1 1 0 6 1 pinnumber=4 T 300 5150 5 8 0 1 0 8 1 pinseq=4 T 450 5200 9 8 1 1 0 0 1 pinlabel=BCBUS1 T 450 5200 5 8 0 1 0 2 1 pintype=io } P 100 4900 400 4900 1 0 0 { T 300 4950 5 8 1 1 0 6 1 pinnumber=5 T 300 4850 5 8 0 1 0 8 1 pinseq=5 T 450 4900 9 8 1 1 0 0 1 pinlabel=BCBUS0 T 450 4900 5 8 0 1 0 2 1 pintype=io } P 100 4600 400 4600 1 0 0 { T 300 4650 5 8 1 1 0 6 1 pinnumber=6 T 300 4550 5 8 0 1 0 8 1 pinseq=6 T 450 4600 9 8 1 1 0 0 1 pinlabel=BDBUS7 T 450 4600 5 8 0 1 0 2 1 pintype=io } P 100 4300 400 4300 1 0 0 { T 300 4350 5 8 1 1 0 6 1 pinnumber=7 T 300 4250 5 8 0 1 0 8 1 pinseq=7 T 450 4300 9 8 1 1 0 0 1 pinlabel=BDBUS6 T 450 4300 5 8 0 1 0 2 1 pintype=io } P 100 4000 400 4000 1 0 0 { T 300 4050 5 8 1 1 0 6 1 pinnumber=8 T 300 3950 5 8 0 1 0 8 1 pinseq=8 T 450 4000 9 8 1 1 0 0 1 pinlabel=BDBUS5 T 450 4000 5 8 0 1 0 2 1 pintype=io } P 100 3700 400 3700 1 0 0 { T 300 3750 5 8 1 1 0 6 1 pinnumber=9 T 300 3650 5 8 0 1 0 8 1 pinseq=9 T 450 3700 9 8 1 1 0 0 1 pinlabel=BDBUS4 T 450 3700 5 8 0 1 0 2 1 pintype=io } P 100 3400 400 3400 1 0 0 { T 300 3450 5 8 1 1 0 6 1 pinnumber=10 T 300 3350 5 8 0 1 0 8 1 pinseq=10 T 450 3400 9 8 1 1 0 0 1 pinlabel=BDBUS3 T 450 3400 5 8 0 1 0 2 1 pintype=io } P 100 3100 400 3100 1 0 0 { T 300 3150 5 8 1 1 0 6 1 pinnumber=11 T 300 3050 5 8 0 1 0 8 1 pinseq=11 T 450 3100 9 8 1 1 0 0 1 pinlabel=BDBUS2 T 450 3100 5 8 0 1 0 2 1 pintype=io } P 100 2800 400 2800 1 0 0 { T 300 2850 5 8 1 1 0 6 1 pinnumber=12 T 300 2750 5 8 0 1 0 8 1 pinseq=12 T 450 2800 9 8 1 1 0 0 1 pinlabel=BDBUS1 T 450 2800 5 8 0 1 0 2 1 pintype=io } P 100 2500 400 2500 1 0 0 { T 300 2550 5 8 1 1 0 6 1 pinnumber=13 T 300 2450 5 8 0 1 0 8 1 pinseq=13 T 450 2500 9 8 1 1 0 0 1 pinlabel=BDBUS0 T 450 2500 5 8 0 1 0 2 1 pintype=io } P 100 2200 400 2200 1 0 0 { T 300 2250 5 8 1 1 0 6 1 pinnumber=14 T 300 2150 5 8 0 1 0 8 1 pinseq=14 T 450 2200 9 8 1 1 0 0 1 pinlabel=GND T 450 2200 5 8 0 1 0 2 1 pintype=pwr } P 100 1900 400 1900 1 0 0 { T 300 1950 5 8 1 1 0 6 1 pinnumber=15 T 300 1850 5 8 0 1 0 8 1 pinseq=15 T 450 1900 9 8 1 1 0 0 1 pinlabel=GND T 450 1900 5 8 0 1 0 2 1 pintype=pwr } P 100 1600 400 1600 1 0 0 { T 300 1650 5 8 1 1 0 6 1 pinnumber=16 T 300 1550 5 8 0 1 0 8 1 pinseq=16 T 450 1600 9 8 1 1 0 0 1 pinlabel=VCCSW T 450 1600 5 8 0 1 0 2 1 pintype=io } P 100 1300 400 1300 1 0 0 { T 300 1350 5 8 1 1 0 6 1 pinnumber=17 T 300 1250 5 8 0 1 0 8 1 pinseq=17 T 450 1300 9 8 1 1 0 0 1 pinlabel=VCCIOB T 450 1300 5 8 0 1 0 2 1 pintype=io } P 100 1000 400 1000 1 0 0 { T 300 1050 5 8 1 1 0 6 1 pinnumber=18 T 300 950 5 8 0 1 0 8 1 pinseq=18 T 450 1000 9 8 1 1 0 0 1 pinlabel=VCCIOA T 450 1000 5 8 0 1 0 2 1 pintype=io } P 100 700 400 700 1 0 0 { T 300 750 5 8 1 1 0 6 1 pinnumber=19 T 300 650 5 8 0 1 0 8 1 pinseq=19 T 450 700 9 8 1 1 0 0 1 pinlabel=EXTVCC T 450 700 5 8 0 1 0 2 1 pintype=io } P 100 400 400 400 1 0 0 { T 300 450 5 8 1 1 0 6 1 pinnumber=20 T 300 350 5 8 0 1 0 8 1 pinseq=20 T 450 400 9 8 1 1 0 0 1 pinlabel=PORTVCC T 450 400 5 8 0 1 0 2 1 pintype=io } P 3700 6100 3400 6100 1 0 0 { T 3500 6150 5 8 1 1 0 0 1 pinnumber=40 T 3500 6050 5 8 0 1 0 2 1 pinseq=21 T 3350 6100 9 8 1 1 0 6 1 pinlabel=ADBUS0/TCK/SK T 3350 6100 5 8 0 1 0 8 1 pintype=io } P 3700 5800 3400 5800 1 0 0 { T 3500 5850 5 8 1 1 0 0 1 pinnumber=39 T 3500 5750 5 8 0 1 0 2 1 pinseq=22 T 3350 5800 9 8 1 1 0 6 1 pinlabel=ADBUS1/TDI/DU T 3350 5800 5 8 0 1 0 8 1 pintype=io } P 3700 5500 3400 5500 1 0 0 { T 3500 5550 5 8 1 1 0 0 1 pinnumber=38 T 3500 5450 5 8 0 1 0 2 1 pinseq=23 T 3350 5500 9 8 1 1 0 6 1 pinlabel=ADBUS2/TDO/D1 T 3350 5500 5 8 0 1 0 8 1 pintype=io } P 3700 5200 3400 5200 1 0 0 { T 3500 5250 5 8 1 1 0 0 1 pinnumber=37 T 3500 5150 5 8 0 1 0 2 1 pinseq=24 T 3350 5200 9 8 1 1 0 6 1 pinlabel=ADBUS3/TMS/CS T 3350 5200 5 8 0 1 0 8 1 pintype=io } P 3700 4900 3400 4900 1 0 0 { T 3500 4950 5 8 1 1 0 0 1 pinnumber=36 T 3500 4850 5 8 0 1 0 2 1 pinseq=25 T 3350 4900 9 8 1 1 0 6 1 pinlabel=ADBUS4/GPIOL0 T 3350 4900 5 8 0 1 0 8 1 pintype=io } P 3700 4600 3400 4600 1 0 0 { T 3500 4650 5 8 1 1 0 0 1 pinnumber=35 T 3500 4550 5 8 0 1 0 2 1 pinseq=26 T 3350 4600 9 8 1 1 0 6 1 pinlabel=ADBUS5/GPIOL1 T 3350 4600 5 8 0 1 0 8 1 pintype=io } P 3700 4300 3400 4300 1 0 0 { T 3500 4350 5 8 1 1 0 0 1 pinnumber=34 T 3500 4250 5 8 0 1 0 2 1 pinseq=27 T 3350 4300 9 8 1 1 0 6 1 pinlabel=ADBUS6/GPIOL2 T 3350 4300 5 8 0 1 0 8 1 pintype=io } P 3700 4000 3400 4000 1 0 0 { T 3500 4050 5 8 1 1 0 0 1 pinnumber=33 T 3500 3950 5 8 0 1 0 2 1 pinseq=28 T 3350 4000 9 8 1 1 0 6 1 pinlabel=ADBUS7/GPIOL3 T 3350 4000 5 8 0 1 0 8 1 pintype=io } P 3700 3700 3400 3700 1 0 0 { T 3500 3750 5 8 1 1 0 0 1 pinnumber=32 T 3500 3650 5 8 0 1 0 2 1 pinseq=29 T 3350 3700 9 8 1 1 0 6 1 pinlabel=ACBUS0/GPIOH0 T 3350 3700 5 8 0 1 0 8 1 pintype=io } P 3700 3400 3400 3400 1 0 0 { T 3500 3450 5 8 1 1 0 0 1 pinnumber=31 T 3500 3350 5 8 0 1 0 2 1 pinseq=30 T 3350 3400 9 8 1 1 0 6 1 pinlabel=ACBUS1/GPIOH1 T 3350 3400 5 8 0 1 0 8 1 pintype=io } P 3700 3100 3400 3100 1 0 0 { T 3500 3150 5 8 1 1 0 0 1 pinnumber=30 T 3500 3050 5 8 0 1 0 2 1 pinseq=31 T 3350 3100 9 8 1 1 0 6 1 pinlabel=ACBUS2/GPIOH2 T 3350 3100 5 8 0 1 0 8 1 pintype=io } P 3700 2800 3400 2800 1 0 0 { T 3500 2850 5 8 1 1 0 0 1 pinnumber=29 T 3500 2750 5 8 0 1 0 2 1 pinseq=32 T 3350 2800 9 8 1 1 0 6 1 pinlabel=ACBUS3/GPIOH3 T 3350 2800 5 8 0 1 0 8 1 pintype=io } P 3700 2500 3400 2500 1 0 0 { T 3500 2550 5 8 1 1 0 0 1 pinnumber=28 T 3500 2450 5 8 0 1 0 2 1 pinseq=33 T 3350 2500 9 8 1 1 0 6 1 pinlabel=SI/WUA T 3350 2500 5 8 0 1 0 8 1 pintype=io } P 3700 2200 3400 2200 1 0 0 { T 3500 2250 5 8 1 1 0 0 1 pinnumber=27 T 3500 2150 5 8 0 1 0 2 1 pinseq=34 T 3350 2200 9 8 1 1 0 6 1 pinlabel=RSTIN T 3350 2200 5 8 0 1 0 8 1 pintype=io } L 2906 2324 3350 2324 3 0 0 0 -1 -1 P 3700 1900 3400 1900 1 0 0 { T 3500 1950 5 8 1 1 0 0 1 pinnumber=26 T 3500 1850 5 8 0 1 0 2 1 pinseq=35 T 3350 1900 9 8 1 1 0 6 1 pinlabel=RSTOUT T 3350 1900 5 8 0 1 0 8 1 pintype=io } L 2726 2024 3350 2024 3 0 0 0 -1 -1 P 3700 1600 3400 1600 1 0 0 { T 3500 1650 5 8 1 1 0 0 1 pinnumber=25 T 3500 1550 5 8 0 1 0 2 1 pinseq=36 T 3350 1600 9 8 1 1 0 6 1 pinlabel=GND T 3350 1600 5 8 0 1 0 8 1 pintype=pwr } P 3700 1300 3400 1300 1 0 0 { T 3500 1350 5 8 1 1 0 0 1 pinnumber=24 T 3500 1250 5 8 0 1 0 2 1 pinseq=37 T 3350 1300 9 8 1 1 0 6 1 pinlabel=GND T 3350 1300 5 8 0 1 0 8 1 pintype=pwr } P 3700 1000 3400 1000 1 0 0 { T 3500 1050 5 8 1 1 0 0 1 pinnumber=23 T 3500 950 5 8 0 1 0 2 1 pinseq=38 T 3350 1000 9 8 1 1 0 6 1 pinlabel=GND T 3350 1000 5 8 0 1 0 8 1 pintype=pwr } P 3700 700 3400 700 1 0 0 { T 3500 750 5 8 1 1 0 0 1 pinnumber=22 T 3500 650 5 8 0 1 0 2 1 pinseq=39 T 3350 700 9 8 1 1 0 6 1 pinlabel=GND T 3350 700 5 8 0 1 0 8 1 pintype=pwr } P 3700 400 3400 400 1 0 0 { T 3500 450 5 8 1 1 0 0 1 pinnumber=21 T 3500 350 5 8 0 1 0 2 1 pinseq=40 T 3350 400 9 8 1 1 0 6 1 pinlabel=VCCUSB T 3350 400 5 8 0 1 0 8 1 pintype=io } B 400 100 3000 6300 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1 T 3400 6500 8 10 1 1 0 6 1 refdes=U? T 400 6500 9 10 1 0 0 0 1 DLP2232M T 400 6700 5 10 0 0 0 0 1 device=DLP2232M T 400 6900 5 10 0 0 0 0 1 footprint=DIP40 T 400 7100 5 10 0 0 0 0 1 author=Dmitry Teytelman T 400 7300 5 10 0 0 0 0 1 documentation=http://www.dlpdesign.com/usb/2232m.shtml T 400 7500 5 10 0 0 0 0 1 description=DLP Design USB module T 400 7700 5 10 0 0 0 0 1 numslots=0 xc3sprog-0+svn795+dfsg/cables/sym/lm1084.sym000066400000000000000000000011211337255630200204720ustar00rootroot00000000000000v 20060123 1 B 300 300 1400 1000 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1 P 1700 800 2000 800 1 0 1 { T 1800 1100 5 10 0 0 0 0 1 pinnumber=2 T 1800 900 5 10 1 1 0 0 1 pinseq=2 T 1600 800 9 10 1 1 0 6 1 pinlabel=Vout } P 0 800 300 800 1 0 0 { T 200 900 5 10 1 1 0 6 1 pinnumber=3 T 0 1000 5 10 0 0 0 0 1 pinseq=3 T 400 800 9 10 1 1 0 0 1 pinlabel=Vin } P 1000 0 1000 300 1 0 0 { T 1100 100 5 10 1 1 0 0 1 pinnumber=1 T 200 100 5 10 0 0 0 0 1 pinseq=1 T 1000 400 9 10 1 1 0 3 1 pinlabel=Adjust } T 300 1400 9 10 1 0 0 0 1 LM1084 T 300 1700 8 10 0 0 0 0 1 device=LM317 T 1700 1400 8 10 1 1 0 6 1 refdes=U? xc3sprog-0+svn795+dfsg/contrib/000077500000000000000000000000001337255630200164175ustar00rootroot00000000000000xc3sprog-0+svn795+dfsg/contrib/xc3sprog_411.bb000066400000000000000000000005311337255630200210600ustar00rootroot00000000000000# xc3sprog build file LICENSE="GPL" DESCRIPTION="suite of utilities for programming Xilinx FPGAs, CPLDs, and EEPROMs" HOMEPAGE="http://sourceforge.net/projects/xc3sprog" DEPENDS += "libftdi" SRC_URI = "svn://xc3sprog.svn.sourceforge.net/svnroot/xc3sprog;proto=https;module=trunk" SRCREV = ${PV} S="${WORKDIR}/trunk" PR = "r0" inherit cmake xc3sprog-0+svn795+dfsg/debug.cpp000066400000000000000000000053441337255630200165570ustar00rootroot00000000000000/* JTAG debugging code Copyright (C) 2004 Andrew Rogers 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 Changes: Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: Modified to support the changes in IOParport class. */ #include #include "iobase.h" #include "ioparport.h" #include "iodebug.h" using namespace std; void testPP(); void testDebug(); void printBit(unsigned char *data, int bit); void getSwitches(IOBase *io); void getID(IOBase *io); int main(int argc, char**args) { testPP(); return 0; } void testDebug() { IODebug io; unsigned char tdi[]={0x3a,0xa3}; unsigned char tdo[10]; io.setTapState(IOBase::SHIFT_DR); io.shiftTDITDO(tdi,tdo,16,false); for(int i=0; i<2; i++)fprintf(stderr, "TDO %02x\n",tdo[i]); } void testPP() { IOParport io(0); unsigned char tdi[]={0,0,0,0,0,0,0,0}; unsigned char tdo[100]; io.setTapState(IOBase::SHIFT_DR); io.shiftTDITDO(tdi,tdo,64); for(int i=0; i<8; i++)fprintf(stderr, "TDO %02x\n",tdo[i]); fprintf(stderr, "\n"); getSwitches(&io); getID(&io); } void printBit1(bool val) { if(val)fprintf(stderr, "|=| "); else fprintf(stderr, "| | "); } void getID(IOBase *io) { unsigned char tdo[100]; unsigned char tdi[]={0xfe,0x09}; io->setTapState(IOBase::SHIFT_IR); io->shiftTDI(tdi,14); io->setTapState(IOBase::RUN_TEST_IDLE); io->setTapState(IOBase::SHIFT_DR); io->shiftTDO(tdo,64); for(int i=0; i<8; i++)fprintf(stderr, "TDO %02x\n",tdo[i]); fprintf(stderr, "\n"); } void getSwitches(IOBase *io) { unsigned char tdo[100]; unsigned char tdi[]={0xff,0x01}; io->setTapState(IOBase::SHIFT_IR); io->shiftTDI(tdi,14); io->setTapState(IOBase::SHIFT_DR); io->shiftTDO(tdo,600); int swi[]={506,509,518,521,539,536,557,569}; for(int i=0; i<8; i++){ int bit=swi[i]; bool val=(tdo[bit/8]>>(bit%8))&1; printBit1(val); } fprintf(stderr, "\n"); for(int i=0; i<8; i++){ int bit=swi[i]; bool val=(tdo[bit/8]>>(bit%8))&1; printBit1(!val); } fprintf(stderr, "\n\n"); } void printBit(unsigned char *data, int bit) { fprintf(stderr, "bit %d = %d\n",bit,(data[bit/8]>>(bit%8))&1); } xc3sprog-0+svn795+dfsg/debug.h000066400000000000000000000007041337255630200162170ustar00rootroot00000000000000/*hardware access*/ #define HW_FUNCTIONS 0x00000001 #define HW_DETAILS 0x00000002 /* protocoll primitives*/ #define PP_FUNCTIONS 0x00000010 #define PP_DETAILS 0x00000020 /* user level protocal*/ #define UP_FUNCTIONS 0x00000100 #define UP_DETAILS 0x00000200 /*chip primitive functions*/ #define CP_FUNCTIONS 0x00001000 #define CP_DETAILS 0x00002000 /*user program functions */ #define UL_FUNCTIONS 0x00010000 #define UL_DETAILS 0x00020000 xc3sprog-0+svn795+dfsg/detectchain.cpp000066400000000000000000000073401337255630200177420ustar00rootroot00000000000000/* JTAG chain detection Copyright (C) 2004 Andrew Rogers 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 Changes: Sandro Amato [sdroamt@netscape.net] 26 Jun 2006 [applied 13 Jul 2006]: Print also the location of the devices found in the jtag chain to be used from jtagProgram.sh script... Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: Code cleanup for clean -Wall compile. Added support for FT2232 driver. */ #include #include #include #include #include "io_exception.h" #include "ioparport.h" #include "iofx2.h" #include "ioxpc.h" #include "ioftdi.h" #include "iodebug.h" #include "jtag.h" #include "devicedb.h" #include "cabledb.h" #include "utilities.h" extern char *optarg; void usage(void) { fprintf(stderr, "\nUsage: detectchain [-c cable_type] [-v]\n" " -v\tverbose output\n" " -J val\tRun at max with given JTAG Frequency, 0(default) means max. Rate of device\n" " \tOnly used for FTDI cables for now\n\n" " Supported cable types: pp, ftdi, fx2, xpc\n" " \tOptional pp arguments:\n" " \t\t[-d device] (e.g. /dev/parport0)\n" " \tOptional fx2/ftdi/xpc arguments:\n" " \t\t[-V vendor] (idVendor)\n" " \t\t[-P product] (idProduct)\n" " \t\t[-S description] (Product string)\n" " \t\t[-s serial] (SerialNumber string)\n" " \tOptional ftdi arguments:\n" " \t\t\t(NONE\t\t(0x0403:0x0610) or\n" " \t\t\t IKDA\t\t(0x0403:0x0610, EN_N on ACBUS2) or\n" " \t\t\t OLIMEX\t\t(0x15b1:0x0003, EN on ADBUS4, LED on ACBUS3))\n" " \t\t\t AMONTEC\t(0x0403:0xcff8, EN on ADBUS4)\n" " \tOptional xpc arguments:\n"); exit(255); } int main(int argc, char **args) { bool verbose = false; bool use_ftd2xx = false; char *cablename = 0; char const *dev = 0; char const *serial = 0; unsigned int jtag_freq = 0; std::auto_ptr io; int res; struct cable_t cable; // Start from parsing command line arguments while(true) { switch(getopt(argc, args, "?hvc:d:J:LS:")) { case -1: goto args_done; case 'v': verbose = true; break; case 'J': jtag_freq = atoi(optarg); break; case 'L': use_ftd2xx = true; break; case 'c': cablename = optarg; break; case 'd': dev = optarg; break; case 's': serial = optarg; break; case '?': case 'h': default: usage(); } } args_done: // Get rid of options //fprintf(stderr, "argc: %d\n", argc); argc -= optind; args += optind; //fprintf(stderr, "argc: %d\n", argc); if((argc != 0) || (cablename == 0)) usage(); CableDB cabledb(0); res = cabledb.getCable(cablename, &cable); res |= getIO( &io, &cable, dev, serial, verbose, use_ftd2xx, jtag_freq); if (res) /* some error happend*/ { if (res == 1) exit(1); else usage(); } io.get()->setVerbose(verbose); Jtag jtag(io.get()); jtag.setVerbose(verbose); DeviceDB db(0); if (verbose) fprintf(stderr, "Using %s\n", db.getFile().c_str()); detect_chain(&jtag, &db); return 0; } xc3sprog-0+svn795+dfsg/devicedb.cpp000066400000000000000000000120671337255630200172360ustar00rootroot00000000000000/* JTAG chain device database Copyright (C) 2004 Andrew Rogers 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 Changes: Dmitry Teytelman [dimtey@gmail.com] 19 May 2006 [applied 13 Aug 2006]: Code cleanup for clean -Wall compile. Modified loadDevice() to ignore 4 MSBs of IDCODE - used for device revision code. */ #ifndef DEVICEDB #define DEVICEDB "devlist.txt" #endif #include #include #include #include #include "devicedb.h" #include "devices.h" using namespace std; DeviceDB::DeviceDB(const char *fname) { // Fall back to environment or default if no file specified if (!fname) { fname = getenv("XCDB"); if (!fname) fname = DEVICEDB; } FILE *fp=fopen(fname,"rt"); if(fp) { // Read device list from file. filename = fname; int lineno = 0; while (!feof(fp)) { char buffer[256]; // read next line from file if (fgets(buffer,256,fp) == NULL) break; lineno++; if (parseLine(buffer) != 0) fprintf(stderr, "ERROR: Invalid syntax in device list '%s' line %d\n", fname, lineno); } fclose(fp); } else { // Read devce list from built-in data. const char *p = fb_string; filename = "built-in device list"; int lineno = 0; while (*p != '\0') { char buffer[256]; unsigned int i; for (i = 0; i < sizeof(buffer) - 1; i++) { if (p[i] == '\0' || p[i] == ';') break; buffer[i] = p[i]; } buffer[i] = '\0'; p += i; if (*p == ';') p++; lineno++; if (parseLine(buffer) != 0) fprintf(stderr, "ERROR: Invalid syntax in built-in device list line %d\n", lineno); } } } // Parse one line from a device list file. // If the file contains a device description, add it to the database. // Return 0 on success, -1 on error. int DeviceDB::parseLine(const char *linebuf) { // ignore comment lines if (linebuf[0] == '#') return 0; // ignore empty lines for (unsigned int i = 0; ; i++) { if (linebuf[i] == '\0') return 0; if (!isspace(linebuf[i])) break; } device_t dev; unsigned int idcode; int irlen; unsigned int id_cmd; // allocate buffer for description vector textvec(strlen(linebuf) + 1); char *textbuf = &(textvec.front()); // parse line: idcode, irlength, idcommand, description if (sscanf(linebuf, "%08x %d %x %s", &idcode, &irlen, &id_cmd, textbuf) != 4) return -1; // add to database dev.idcode = idcode & 0x0fffffff; dev.irlen = irlen; dev.id_cmd = id_cmd; dev.text = string(textbuf); dev_db.push_back(dev); return 0; } // Find the device with specified IDCODE and return its properties. const DeviceDB::device_t * DeviceDB::findDevice(DeviceID idcode) { // look in list of recently used devices for (unsigned int i = 0, n = dev_used.size(); i < n; i++) { if ((idcode & 0x0fffffff) == dev_used[i]->idcode) return dev_used[i]; } // look in list of all devices for (unsigned int i = 0, n = dev_db.size(); i < n; i++) { if ((idcode & 0x0fffffff) == dev_db[i].idcode) { dev_used.push_back(&(dev_db[i])); return &(dev_db[i]); } } // unknown device return NULL; } // Find the device with specified IDCODE and return its IR length, // or return 0 if the IDCODE is unknown. int DeviceDB::idToIRLength(DeviceID idcode) { const device_t *dev = findDevice(idcode); return (dev) ? (dev->irlen) : 0; } // Find the device with specified IDCODE and returns its IDCODE instruction. uint32_t DeviceDB::idToIDCmd(DeviceID idcode) { const device_t *dev = findDevice(idcode); return (dev) ? (dev->id_cmd) : 0; } // Find the device with specified IDCODE and return a description, // or return NULL if the IDCODE is unknown. const char * DeviceDB::idToDescription(DeviceID idcode) { const device_t *dev = findDevice(idcode); return (dev) ? (dev->text.c_str()) : NULL; } int DeviceDB::dumpDevices(FILE *fp_out) const { unsigned int i; for(i = 0; i < dev_db.size(); i++) fprintf(fp_out,"%08x %6d 0x%04x %s\n", (unsigned int)dev_db[i].idcode, dev_db[i].irlen, (unsigned int)dev_db[i].id_cmd, dev_db[i].text.c_str()); return 0; } xc3sprog-0+svn795+dfsg/devicedb.h000066400000000000000000000033231337255630200166760ustar00rootroot00000000000000/* JTAG chain device database Copyright (C) 2004 Andrew Rogers 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 Changes: Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: Code cleanup for clean -Wall compile. */ #ifndef DEVICEDB_H #define DEVICEDB_H #include #include #include // Integer type to hold device IDCODE. typedef uint32_t DeviceID; class DeviceDB { private: struct device_t { DeviceID idcode; // IDCODE of this device int irlen; // instruction register length. uint32_t id_cmd; // instruction to request IDCODE std::string text; // description }; std::vector dev_db; std::vector dev_used; std::string filename; public: DeviceDB(const char *fname); std::string getFile() const { return filename; } int idToIRLength(DeviceID idcode); uint32_t idToIDCmd(DeviceID idcode); const char * idToDescription(DeviceID idcode); int dumpDevices(FILE *fp_out) const; private: int parseLine(const char *linebuf); const device_t * findDevice(DeviceID idcode); }; #endif xc3sprog-0+svn795+dfsg/devices.h.in000066400000000000000000000000561337255630200171600ustar00rootroot00000000000000const char fb_string[] ={"${fb_string}"}; xc3sprog-0+svn795+dfsg/devices.in.h000066400000000000000000000000511337255630200171530ustar00rootroot00000000000000const char fb_string[]={"${fb_string}"}; xc3sprog-0+svn795+dfsg/devlist.cmk000066400000000000000000000002461337255630200171270ustar00rootroot00000000000000#Bring devlist.txt in a form that we can compile as fallback file(STRINGS ${DEVLIST_DIR}/devlist.txt fb_string) configure_file(${DEVLIST_DIR}/devices.h.in devices.h) xc3sprog-0+svn795+dfsg/devlist.txt000066400000000000000000000214201337255630200171710ustar00rootroot00000000000000# IDCODE IR_len ID_Cmd Text 03631093 6 0x09 XA7A100T 0362e093 6 0x09 XC7A15T 0362D093 6 0x09 XC7A35T 03632093 6 0x09 XC7A75T 03636093 6 0x09 XC7A200T 03642093 6 0x9 XC7K30T 03647093 6 0x9 XC7K70T 0364c093 6 0x9 XC7K160T 03651093 6 0x9 XC7K325T 03656093 6 0x9 XC7K410T 03747093 6 0x09 XC7K355T 03751093 6 0x09 XC7K480T 03752093 6 0x09 XC7K420T 03667093 6 0x9 XC7VX330T 03671093 6 0x9 XC7V585T 03682093 6 0x9 XC7VX415T 03687093 6 0x9 XC7VX485T 03691093 6 0x9 XC7VX690T 03692093 6 0x9 XC7VX550T 03696093 6 0x9 XC7VX980T 03722093 6 0x9 XC7Z010 03727093 6 0x9 XC7Z020 0372c093 6 0x9 XC7Z030 03731093 6 0x9 XC7Z045 03736093 6 0x9 XC7Z100 04244093 10 0x3c9 XC6VLX75T(L) 0424a093 10 0x3c9 XC6VLX130T(L) 0424c093 10 0x3c9 XC6VLX195T(L) 04250093 10 0x3c9 XC6VLX240T(L) 04252093 10 0x3c9 XC6VLX365T(L) 04256093 10 0x3c9 XC6VLX550T(L) 0423a093 10 0x3c9 XC6VLX760(L) 04286093 10 0x3c9 XC6VSX315T(L) 04288093 10 0x3c9 XC6VSX475T(L) 042c4093 10 0x3c9 XC6VCX75T 042ca093 10 0x3c9 XC6VCX130T 042cc093 10 0x3c9 XC6VCX195T 042d0093 10 0x3c9 XC6VCX240T 04000093 6 0x9 XC6SLX4 04001093 6 0x9 XC6SLX9 04002093 6 0x9 XC6SLX16 04004093 6 0x9 XC6SLX25 04024093 6 0x9 XC6SLX25T 04008093 6 0x9 XC6SLX45 04028093 6 0x9 XC6SLX45T 0400e093 6 0x9 XC6SLX75 0402e093 6 0x9 XC6SLX75T 04011093 6 0x9 XC6SLX100 04031093 6 0x9 XC6SLX100T 0401d093 6 0x9 XC6SLX150 0403d093 6 0x9 XC6SLX150T 01658093 10 0x3c9 XC4VLX15 0167C093 10 0x3c9 XC4VLX25 016A4093 10 0x3c9 XC4VLX40 016B4093 10 0x3c9 XC4VLX60 016D8093 10 0x3c9 XC4VLX80 01700093 10 0x3c9 XC4VLX100 01718093 10 0x3c9 XC4VLX160 01734093 10 0x3c9 XC4VLX200 02068093 10 0x3c9 XC4VSX25 02088093 10 0x3c9 XC4VSX25 020b0093 10 0x3c9 XC4VSX25 01e58093 10 0x3c9 XC4VFX12 01e64093 10 0x3c9 XC4VFX20 01e8c093 14 0x3c9 XC4VFX40 01eb4093 14 0x3c9 XC4VFX60 01ee4093 14 0x3c9 XC4VFX100 01f14093 14 0x3c9 XC4VFX140 0286e093 10 0x3c9 XC5VLX30 02896093 10 0x3c9 XC5VLX50 028ae093 10 0x3c9 XC5VLX85 028d6093 10 0x3c9 XC5VLX110 028ec093 10 0x3c9 XC5VLX155 0290c093 10 0x3c9 XC5VLX220 0295c095 10 0x3c9 XC5VLX330 02a56093 10 0x3c9 XC5VLX20T 02a6e093 10 0x3c9 XC5VLX30T 02a96093 10 0x3c9 XC5VLX50T 02aae093 10 0x3c9 XC5VLX85T 02ad6093 10 0x3c9 XC5VLX110T 02aec093 10 0x3c9 XC5VLX155T 02b0c093 10 0x3c9 XC5VLX220T 02b5c093 10 0x3c9 XC5VLX330T 02e72093 10 0x3c9 XC5SX35T 02e9a093 10 0x3c9 XC5SX50T 02ece093 10 0x3c9 XC5SX95T 02f3e093 10 0x3c9 XC5SX260T 04502093 10 0x3c9 XC5VTX150T 0453e093 10 0x3c9 XC5VTX240T 03276093 10 0x3c9 XC5VFX30T 032c6093 10 0x3c9 XC5VFX70T 032d8093 14 0x3c9 XC5VFX100T 03300093 14 0x3c9 XC5VFX130T 03334093 14 0x3c9 XC5VFX200T 0140d093 6 0x9 XC3S50 01414093 6 0x9 XC3S200 0141c093 6 0x9 XC3S400 01428093 6 0x9 XC3S1000 01434093 6 0x9 XC3S1500 01440093 6 0x9 XC3S2000 01448093 6 0x9 XC3S4000 01450093 6 0x9 XC3S5000 01C10093 6 0x9 XC3S100E 01C1A093 6 0x9 XC3S250E 01C22093 6 0x9 XC3S500E 01C2E093 6 0x9 XC3S1200E 01C3A093 6 0x9 XC3S1600E 02210093 6 0x9 XC3S50A 02218093 6 0x9 XC3S200A 02220093 6 0x9 XC3S400A 02228093 6 0x9 XC3S700A 02230093 6 0x9 XC3S1400A 02610093 6 0x9 XC3S50AN 02618093 6 0x9 XC3S200AN 02620093 6 0x9 XC3S400AN 02628093 6 0x9 XC3S700AN 02630093 6 0x9 XC3S1400AN 03840093 6 0x9 XC3SD1800 0384E093 6 0x9 XC3SD3400 01008093 6 0x9 XC2V40 01010093 6 0x9 XC2V80 01018093 6 0x9 XC2V250 01020093 6 0x9 XC2V500 01028093 6 0x9 XC2V1000 01030093 6 0x9 XC2V1500 01038093 6 0x9 XC2V2000 01040093 6 0x9 XC2V3000 01050093 6 0x9 XC2V4000 01060093 6 0x9 XC2V6000 01070093 6 0x9 XC2V8000 05044093 8 0xfe XCF01S 05045093 8 0xfe XCF02S 05046093 8 0xfe XCF04S 05057093 16 0xfe XCF08P 05058093 16 0xfe XCF16P 05059093 16 0xfe XCF32P 00608093 5 0x9 XC2S15 0060c093 5 0x9 XC2S30 00610093 5 0x9 XC2S50 00614093 5 0x9 XC2S100 00618093 5 0x9 XC2S150 0061c093 5 0x9 XC2S200 #XC95XL 09602093 8 0xfe XC9536XL 09604093 8 0xfe XC9572XL 09608093 8 0xfe XC95144XL 09616093 8 0xfe XC95288XL #XC95XV 09702093 8 0xfe XC9536XV 09704093 8 0xfe XC9572XV 09708093 8 0xfe XC95144XV 09716093 8 0xfe XC95288XV #XC2C 06c1c093 8 0x1 XC2C32_VQ44 06c1d093 8 0x1 XC2C32_PC44/64 06c1b093 8 0x1 XC2C32A_QF32 06d1d093 8 0x1 XC2C32A_PC44 06e1b093 8 0x1 XC2C32A_CP56 06e1c093 8 0x1 XC2C32A_VQ44 06e1d093 8 0x1 XC2C32A_PC44/64 06c5a093 8 0x1 XC2C64-PC44 06c5b093 8 0x1 XC2C64-CP132 06c5c093 8 0x1 XC2C64-VQ100 06c5d093 8 0x1 XC2C64-CP56 06c5e093 8 0x1 XC2C64-VQ44 06e59093 8 0x1 XC2C64A-QF48 06e5a093 8 0x1 XC2C64A-PC44 06e5b093 8 0x1 XC2C64A-CP132 06e5c093 8 0x1 XC2C64A-VQ100 06e5d093 8 0x1 XC2C64A-CP56 06e5e093 8 0x1 XC2C64A-VQ44 06d8a093 8 0x1 XC2C128_VQ100 06d8b093 8 0x1 XC2C128_CP132 06d8c093 8 0x1 XC2C128_TQ144 06d8e093 8 0x1 XC2C128_FT256 06d4a093 8 0x1 XC2C256_VQ100 06d4b093 8 0x1 XC2C256_CP132 06d4c093 8 0x1 XC2C256_TQ144 06d4d093 8 0x1 XC2C256_PQ208 06d4e093 8 0x1 XC2C256_FT256 06d5a093 8 0x1 XC2C384_FG324 06d5b093 8 0x1 XC2C384_CP204 06d5c093 8 0x1 XC2C384_TQ144 06d5d093 8 0x1 XC2C384_PQ208 06d5e093 8 0x1 XC2C384_FT256 06d7a093 8 0x1 XC2C512_FG324 06d7c093 8 0x1 XC2C512_PQ208 06d7e093 8 0x1 XC2C512_FT256 #unsupported #Virtex2 01020093 6 5 XC2V500 #XC95 09502093 8 0xfd XC9536 09504093 8 0xfd XC9572 09506093 8 0xfd XC95108 09508093 8 0xfd XC95144 09512093 8 0xfd XC95216 09516093 8 0xfd XC95288 #XC18 05024093 8 0xfd XC18V01 05025093 8 0xfd XC18V02 05026093 8 0xfd XC18V04 05023093 8 0xfd XC18V512 0a001093 8 0x09 SystemACE ##Atmel #list should not care for the version part 0978203f 4 0x1 AT90USB 0958103f 4 0x1 AT90CAN32 0968103f 4 0x1 AT90CAN64 0978103f 4 0x1 AT90CAN128 0970403f 4 0x1 ATmega1281 0970303f 4 0x1 ATmega1280 0980103f 4 0x1 ATmega2561 0980203f 4 0x1 ATmega2560 0970203f 4 0x1 ATmega128 0960803f 4 0x1 ATMEGA640 0960603f 4 0x1 ATMEGA6450 0960503f 4 0x1 ATMEGA645 0960403f 4 0x1 ATMEGA6490 0960303f 4 0x1 ATMEGA649 0960a03f 4 0x1 ATMEGA644p 0960903f 4 0x1 ATMEGA644 0960603f 4 0x1 ATMEGA650 0960203f 4 0x1 ATmega64 0950103f 4 0x1 ATmega323 0950203f 4 0x1 ATmega32 0940a03f 4 0x1 ATmega164p 0940703f 4 0x1 ATmega165(p) 0940403f 4 0x1 ATmega162 0940503f 4 0x1 ATmega169(p) 0950b03f 4 0x1 ATMega329 0950c03f 4 0x1 ATMega3290 0960b03f 4 0x1 ATMega649 0960c03f 4 0x1 ATMega6490 0940303f 4 0x1 ATmega16 0940403f 4 0x1 ATmega162 0940503f 4 0x1 ATmega169 0964203f 4 0x3 ATxmega64A3 0964403f 4 0x3 ATxmega96A3 0964e03f 4 0x3 ATxmega64A1 0964c03f 4 0x3 ATxmega64A3R 0964d03f 4 0x3 ATxmega96A3R 0965003f 4 0x3 ATxmega96A1 0974a03f 4 0x3 ATxmega128AR 0974c03f 4 0x3 ATxmega128A 0984203f 4 0x3 ATxmega256A3 0984303f 4 0x3 ATxmega256A3B #AT91 in JTAG Mode 05b1703f 3 0x2 AT91SAM7X256 #ARM 7 in ICE Mode (e.g. AT91SAM7X) 3f0f0f0f 4 0xe ARM-ICE-MODE 4f1f0f0f 4 0xe ARM-ICE-MODE(ARM7TDMI-S rev4) #AVR32 01e8203f 5 0x1 AT32AP7000 #STM 06410041 5 0x1 STM32L1_Med_density 06411041 5 0x1 STM32F2 06412041 5 0x1 STM32F1_Low_density 06414041 5 0x1 STM32F1_High_density 06416041 5 0x1 STM32L15 06418041 5 0x1 STM32F1_Connectivity_line 06420041 5 0x1 STM32F1_Low_Med_density_value 06428041 5 0x1 STM32F1_High_density_value 06430041 5 0x1 STM32F1_XL_density 06422041 5 0x1 STM32F30x 06432041 5 0x1 STM32F373 06413041 5 0x1 STM32F4 #ARM Debug 3BA00477 4 0xe ARM_Cortex-M3_r1p1-01rel0 4BA00477 4 0xe ARM-Cortex-M4F_r0p1 #Analog Devices 027c80cb 5 0x0002 ADSP-BF537 #Unsure about IR_Len... 0270817f 11 0x1 BCM2835 #Manufacturer list 00000093 99 0 Xilinx_Unknown 0000003f 99 0 Atmel_Unknown xc3sprog-0+svn795+dfsg/fallback/000077500000000000000000000000001337255630200165165ustar00rootroot00000000000000xc3sprog-0+svn795+dfsg/fallback/xguff/000077500000000000000000000000001337255630200176355ustar00rootroot00000000000000xc3sprog-0+svn795+dfsg/fallback/xguff/spi_defs.h000066400000000000000000000063031337255630200216040ustar00rootroot00000000000000/* -*- c++ -*- */ /* * Copyright 2004 Free Software Foundation, Inc. * * This file is part of GNU Radio * * GNU Radio 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, or (at your option) * any later version. * * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef INCLUDED_SPI_DEFS_H #define INCLUDED_SPI_DEFS_H /* * defines for the VRQ_SPI_READ and VRQ_SPI_WRITE commands * * SPI == "Serial Port Interface". SPI is a 3 wire bus plus a * separate enable for each peripheral. The common lines are SCLK, * SDI and SDO. The FX2 always drives SCLK and SDI, the clock and * data lines from the FX2 to the peripheral. When enabled, a * peripheral may drive SDO, the data line from the peripheral to the * FX2. * * The SPI_READ and SPI_WRITE commands are formatted identically. * Each specifies which peripherals to enable, whether the bits should * be transmistted Most Significant Bit first or Least Significant Bit * first, the number of bytes in the optional header, and the number * of bytes to read or write in the body. * * The body is limited to 64 bytes. The optional header may contain * 0, 1 or 2 bytes. For an SPI_WRITE, the header bytes are * transmitted to the peripheral followed by the the body bytes. For * an SPI_READ, the header bytes are transmitted to the peripheral, * then len bytes are read back from the peripheral. */ /* * SPI_FMT_* goes in wIndexL */ #define SPI_FMT_xSB_MASK (1 << 7) # define SPI_FMT_LSB (1 << 7) // least signficant bit first # define SPI_FMT_MSB (0 << 7) // most significant bit first #define SPI_FMT_HDR_MASK (3 << 5) # define SPI_FMT_HDR_0 (0 << 5) // 0 header bytes # define SPI_FMT_HDR_1 (1 << 5) // 1 header byte # define SPI_FMT_HDR_2 (2 << 5) // 2 header bytes /* * SPI_ENABLE_* goes in wIndexH * * For the software interface, the enables are active high. * For reads, it's an error to have more than one enable set. * * [FWIW, the hardware implements them as active low. Don't change the * definitions of these. They are related to usrp_rev1_regs.h] */ #define SPI_ENABLE_FPGA 0x01 // select FPGA #define SPI_ENABLE_CODEC_A 0x02 // select AD9862 A #define SPI_ENABLE_CODEC_B 0x04 // select AD9862 B #define SPI_ENABLE_reserved 0x08 #define SPI_ENABLE_TX_A 0x10 // select d'board TX A #define SPI_ENABLE_RX_A 0x20 // select d'board RX A #define SPI_ENABLE_TX_B 0x40 // select d'board TX B #define SPI_ENABLE_RX_B 0x80 // select d'board RX B /* * If there's one header byte, it goes in wValueL. * * If there are two header bytes, they go in wValueH | wValueL. * The transmit order of the bytes (and bits within them) is * determined by SPI_FMT_*SB */ #endif /* INCLUDED_SPI_DEFS_H */ xc3sprog-0+svn795+dfsg/fallback/xguff/usrp_commands.h000066400000000000000000000065141337255630200226660ustar00rootroot00000000000000/* * USRP - Universal Software Radio Peripheral * * Copyright (C) 2003,2004 Free Software Foundation, Inc. * * 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 _USRP_COMMANDS_H_ #define _USRP_COMMANDS_H_ #include #include #define MAX_EP0_PKTSIZE 64 // max size of EP0 packet on FX2 // ---------------------------------------------------------------- // Vendor bmRequestType's // ---------------------------------------------------------------- #define VRT_VENDOR_IN 0xC0 #define VRT_VENDOR_OUT 0x40 // ---------------------------------------------------------------- // USRP Vendor Requests // // Note that Cypress reserves [0xA0,0xAF]. // 0xA0 is the firmware load function. // ---------------------------------------------------------------- // IN commands #define VRQ_GET_STATUS 0x80 #define GS_TX_UNDERRUN 0 // wIndexL // returns 1 byte #define GS_RX_OVERRUN 1 // wIndexL // returns 1 byte #define VRQ_I2C_READ 0x81 // wValueL: i2c address; length: how much to read #define VRQ_SPI_READ 0x82 // wValue: optional header bytes // wIndexH: enables // wIndexL: format // len: how much to read // OUT commands #define VRQ_SET_LED 0x01 // wValueL off/on {0,1}; wIndexL: which {0,1} #define VRQ_FPGA_LOAD 0x02 # define FL_BEGIN 0 // wIndexL: begin fpga programming cycle. stalls if trouble. # define FL_XFER 1 // wIndexL: xfer up to 64 bytes of data # define FL_END 2 // wIndexL: end programming cycle, check for success. // stalls endpoint if trouble. #define VRQ_FPGA_WRITE_REG 0x03 // wIndexL: regno; data: 32-bit regval MSB first #define VRQ_FPGA_SET_RESET 0x04 // wValueL: {0,1} #define VRQ_FPGA_SET_TX_ENABLE 0x05 // wValueL: {0,1} #define VRQ_FPGA_SET_RX_ENABLE 0x06 // wValueL: {0,1} // see below VRQ_FPGA_SET_{TX,RX}_RESET #define VRQ_SET_SLEEP_BITS 0x07 // wValueH: mask; wValueL: bits. set bits given by mask to bits # define SLEEP_ADC0 0x01 # define SLEEP_ADC1 0x02 # define SLEEP_DAC0 0x04 # define SLEEP_DAC1 0x08 #define VRQ_I2C_WRITE 0x08 // wValueL: i2c address; data: data #define VRQ_SPI_WRITE 0x09 // wValue: optional header bytes // wIndexH: enables // wIndexL: format // len: how much to write #define VRQ_FPGA_SET_TX_RESET 0x0a // wValueL: {0, 1} #define VRQ_FPGA_SET_RX_RESET 0x0b // wValueL: {0, 1} // ------------------------------------------------------------------- // we store the hashes at fixed addresses in the FX2 internal memory #define USRP_JTAG_CONFIG_ADDR 0xe1d0 #define USRP_HASH_SLOT_0_ADDR 0xe1e0 #define USRP_HASH_SLOT_1_ADDR 0xe1f0 #endif /* _USRP_COMMANDS_H_ */ xc3sprog-0+svn795+dfsg/fallback/xguff/usrp_interfaces.h000066400000000000000000000027521337255630200232100ustar00rootroot00000000000000/* -*- c++ -*- */ /* * Copyright 2003 Free Software Foundation, Inc. * * This file is part of GNU Radio * * GNU Radio 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, or (at your option) * any later version. * * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef _USRP_INTERFACES_H_ #define _USRP_INTERFACES_H_ /* * We've now split the USRP into 3 separate interfaces. * * Interface 0 contains only ep0 and is used for command and status. * Interface 1 is the Tx path and it uses ep2 OUT BULK. * Interface 2 is the Rx path and it uses ep6 IN BULK. */ #define USRP_CMD_INTERFACE 0 #define USRP_CMD_ALTINTERFACE 0 #define USRP_CMD_ENDPOINT 0 #define USRP_TX_INTERFACE 1 #define USRP_TX_ALTINTERFACE 0 #define USRP_TX_ENDPOINT 2 // streaming data from host to FPGA #define USRP_RX_INTERFACE 2 #define USRP_RX_ALTINTERFACE 0 #define USRP_RX_ENDPOINT 6 // streaming data from FPGA to host #endif /* _USRP_INTERFACES_H_ */ xc3sprog-0+svn795+dfsg/io_exception.h000066400000000000000000000020541337255630200176160ustar00rootroot00000000000000/* Copyright (C) 2008 Thomas Preusser 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 IO_EXCEPTION_H #define IO_EXCEPTION_H #include class io_exception { std::string const msg; public: io_exception(std::string const& _msg = "") : msg(_msg) {} ~io_exception() {} public: operator std::string const&() const { return getMessage(); } std::string const& getMessage() const { return msg; } }; #endif xc3sprog-0+svn795+dfsg/iobase.cpp000066400000000000000000000054071337255630200167330ustar00rootroot00000000000000/* JTAG low level functions and base class for cables Copyright (C) 2004 Andrew Rogers Additions (C) 2005-2011 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de 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 Changes: Sandro Amato [sdroamt@netscape.net] 26 Jun 2006 [applied 13 Jul 2006]: Added a 'dotted' progress bar Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: Code cleanup for clean -Wall compile. Extensive changes to support FT2232 driver. Moved progress bar to ioparport.cpp and ioftdi.cpp. */ #include "iobase.h" #include "utilities.h" #include #include #include using namespace std; IOBase::IOBase() { verbose = false; memset( ones,0xff,CHUNK_SIZE); memset(zeros, 0,CHUNK_SIZE); memset(tms_buf, 0,CHUNK_SIZE); tms_len = 0; } int IOBase::Init(struct cable_t *cable, const char *devopt, unsigned int freq) { return 0; } void IOBase::flush_tms(int force) { if (tms_len) tx_tms(tms_buf, tms_len, force); memset(tms_buf, 0,CHUNK_SIZE); tms_len = 0; } void IOBase::set_tms(bool val) { if( tms_len + 1 > CHUNK_SIZE*8) flush_tms(false); if(val) tms_buf[tms_len/8] |= (1 <<(tms_len &0x7)); tms_len++; } void IOBase::shiftTDITDO(const unsigned char *tdi, unsigned char *tdo, int length, bool last) { if(length==0) return; flush_tms(false); txrx_block(tdi, tdo, length,last); return; } void IOBase::shiftTDI(const unsigned char *tdi, int length, bool last) { shiftTDITDO(tdi, NULL, length,last); } // TDI gets a load of zeros, we just record TDO. void IOBase::shiftTDO(unsigned char *tdo, int length, bool last) { shiftTDITDO(NULL, tdo, length,last); } // TDI gets a load of zeros or ones, and we ignore TDO void IOBase::shift(bool tdi, int length, bool last) { int len = length; unsigned char *block = (tdi)?ones:zeros; flush_tms(false); while (len > CHUNK_SIZE*8) { txrx_block(block, NULL, CHUNK_SIZE*8, false); len -= (CHUNK_SIZE*8); } shiftTDITDO(block, NULL, len, last); } void IOBase::Usleep(unsigned int usec) { flush_tms(false); flush(); xc3sprog_Usleep(usec); } xc3sprog-0+svn795+dfsg/iobase.h000066400000000000000000000042751337255630200164020ustar00rootroot00000000000000/* JTAG low level functions and base class for cables Copyright (C) 2004 Andrew Rogers Additions (C) 2005-2013 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de 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 Changes: Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: Code cleanup for clean -Wall compile. Extensive changes to support FT2232 driver. */ #ifndef IOBASE_H #define IOBASE_H #define BLOCK_SIZE 65536 #define CHUNK_SIZE 128 #define TICK_COUNT 2048 #include "cabledb.h" class IOBase { protected: bool verbose; unsigned char ones[CHUNK_SIZE], zeros[CHUNK_SIZE]; unsigned char tms_buf[CHUNK_SIZE]; unsigned int tms_len; /* in Bits*/ protected: IOBase(); public: virtual ~IOBase() {} public: virtual int Init(struct cable_t *cable, const char *devopt, unsigned int freq); virtual void flush() {} virtual void Usleep(unsigned int usec); public: void setVerbose(bool v) { verbose = v; } void shiftTDITDO(const unsigned char *tdi, unsigned char *tdo, int length, bool last=true); void shiftTDI(const unsigned char *tdi, int length, bool last=true); void shiftTDO(unsigned char *tdo, int length, bool last=true); void shift(bool tdi, int length, bool last=true); void set_tms(bool value); void flush_tms(int force); protected: virtual void txrx_block(const unsigned char *tdi, unsigned char *tdo, int length, bool last)=0; virtual void tx_tms(unsigned char *pat, int length, int force)=0; virtual void settype(int subtype) {} private: void nextTapState(bool tms); }; #endif // IOBASE_H xc3sprog-0+svn795+dfsg/iodebug.cpp000066400000000000000000000035201337255630200171010ustar00rootroot00000000000000/* Monitor JTAG signals instead of using physical cable Copyright (C) 2004 Andrew Rogers 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 "iodebug.h" using namespace std; bool IODebug::txrx(bool tms, bool tdi) { int tdo; fprintf(stderr, "txrx(%d,%d) enter tdo>",tms,tdi); scanf("%d",&tdo); return tdo!=0; } void IODebug::tx(bool tms, bool tdi) { fprintf(stderr, "tx(%d,%d)\n",tms,tdi); } void IODebug::tx_tdi_byte(unsigned char tdi_byte) { } void IODebug::txrx_block(const unsigned char *tdi, unsigned char *tdo, int length, bool last) { int i=0; int j=0; unsigned char tdo_byte=0; unsigned char tdi_byte=tdi[j]; while(i>1; i++; if((i%8)==0){ // Next byte tdo[j]=tdo_byte; // Save the TDO byte tdo_byte=0; j++; tdi_byte=tdi[j]; // Get the next TDI byte } }; tdo_byte=tdo_byte+(txrx(last, (tdi_byte&1)==1)<<(i%8)); tdo[j]=tdo_byte; return; } void IODebug::tx_tms(unsigned char *pat, int length, int force) { int i; unsigned char tms = pat[0]; for (i = 0; i < length; i++) { tx((tms & 0x01),false); tms = tms >> 1; } } xc3sprog-0+svn795+dfsg/iodebug.h000066400000000000000000000022461337255630200165520ustar00rootroot00000000000000/* Monitor JTAG signals instead of using physical cable Copyright (C) 2004 Andrew Rogers 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 IODEBUG_H #define IODEBUG_H #include "iobase.h" class IODebug : public IOBase { public: IODebug() : IOBase(){} void tx(bool tms, bool tdi); bool txrx(bool tms, bool tdi); void tx_tdi_byte(unsigned char tdi_byte); void tx_tms(unsigned char *pat, int length, int force); protected: void txrx_block(const unsigned char *tdi, unsigned char *tdo, int length, bool last); }; #endif // IODEBUG_H xc3sprog-0+svn795+dfsg/ioftdi.cpp000066400000000000000000000543661337255630200167570ustar00rootroot00000000000000/* JTAG GNU/Linux FTDI FT2232 low-level I/O Copyright (C) 2005-2013 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de Copyright (C) 2006 Dmitry Teytelman 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 "ioftdi.h" #include "io_exception.h" #include "utilities.h" using namespace std; IOFtdi::IOFtdi(bool u) : IOBase(), bptr(0), calls_rd(0), calls_wr(0), retries(0) { use_ftd2xx = u; char *fname = getenv("FTDI_DEBUG"); if (fname) fp_dbg = fopen(fname,"wb"); else fp_dbg = NULL; #ifdef USE_FTD2XX ftd2xx_handle = 0; #endif ftdi_handle = 0; verbose = false; } int IOFtdi::Init(struct cable_t *cable, const char *serial, unsigned int freq) { unsigned char buf1[5]; unsigned char buf[9] = { SET_BITS_LOW, 0x00, 0x0b, TCK_DIVISOR, 0x03, 0x00 , SET_BITS_HIGH,0x00, 0x00}; char *description = NULL; char descstring[256]; unsigned int vendor = VENDOR_FTDI, product = DEVICE_DEF; unsigned int channel = 0; unsigned int dbus_data =0, dbus_en = 0xb, cbus_data= 0, cbus_en = 0; unsigned int divisor; int res; char *p = cable->optstring; /* set for now. If we have a fast device, correct later */ if ((freq == 0 )|| (freq >= 6000000)) /* freq = 0 means max rate, 3 MHz for now*/ divisor = 0; else divisor = 6000000/freq - ((6000000&freq)?0:1); if (divisor > 0xffff) divisor = 0xffff; buf[4] = divisor & 0xff; buf[5] = (divisor >> 8) & 0xff; /* split string by hand for more flexibility*/ if (p) { vendor = strtol(p, NULL, 0); p = strchr(p,':'); if(p) p ++; } if (p) { product = strtol(p, NULL, 0); p = strchr(p,':'); if(p) p ++; } if (p) { char *q = strchr(p,':'); int len = q ? q-p : strlen(p); if (len>0) { int num; num = (len>255)?255:len; strncpy(descstring, p, num); descstring[num] = 0; description = descstring; } p = q; if(p) p ++; } if (p) { channel = strtol(p, NULL, 0); p = strchr(p,':'); if(p) p ++; } if (p) { dbus_data = strtol(p, NULL, 0); p = strchr(p,':'); if(p) p ++; } if (p) { dbus_en |= strtol(p, NULL, 0); p = strchr(p,':'); if(p) p ++; } if (p) { cbus_data = strtol(p, NULL, 0); p = strchr(p,':'); if(p) p ++; } if (p) { cbus_en = strtol(p, NULL, 0); p = strchr(p,':'); if(p) p ++; } if (verbose) { fprintf(stderr, "Cable %s type %s VID 0x%04x PID 0x%04x", cable->alias, getCableName(cable->cabletype), vendor, product); if (description) fprintf(stderr, " Desc \"%s\"", description); if (serial) fprintf(stderr, " Serial %s", serial); fprintf(stderr, " dbus data %02x enable %02x cbus data %02x data %02x\n", dbus_data, dbus_en, cbus_data, cbus_en); } if (!use_ftd2xx) { // allocate and initialize FTDI structure ftdi_handle = ftdi_new(); // Set interface if (channel > 2) { fprintf(stderr, "Invalid MPSSE channel: %d", channel); res = 2; goto ftdi_fail; } res =ftdi_set_interface(ftdi_handle, (ftdi_interface)channel); if(res <0) { fprintf(stderr, "ftdi_set_interface: %s\n", ftdi_get_error_string(ftdi_handle)); goto ftdi_fail; } // Open device res = ftdi_usb_open_desc(ftdi_handle, vendor, product, description, serial); if (res == 0) { res = ftdi_set_bitmode(ftdi_handle, 0x00, BITMODE_RESET); if(res < 0) { fprintf(stderr, "ftdi_set_bitmode: %s", ftdi_get_error_string(ftdi_handle)); goto ftdi_fail; } res = ftdi_usb_purge_buffers(ftdi_handle); if(res < 0) { fprintf(stderr, "ftdi_usb_purge_buffers: %s", ftdi_get_error_string(ftdi_handle)); goto ftdi_fail; } //Set the lacentcy time to a low value res = ftdi_set_latency_timer(ftdi_handle, 1); if( res <0) { fprintf(stderr, "ftdi_set_latency_timer: %s", ftdi_get_error_string(ftdi_handle)); goto ftdi_fail; } // Set mode to MPSSE res = ftdi_set_bitmode(ftdi_handle, 0xfb, BITMODE_MPSSE); if(res< 0) { fprintf(stderr, "ftdi_set_bitmode: %s", ftdi_get_error_string(ftdi_handle)); goto ftdi_fail; } /* FIXME: Without this read, consecutive runs on the FT2232H may hang */ ftdi_read_data(ftdi_handle, buf1,5); /* Check if we have a fast clock cabable device*/ switch(ftdi_handle->type) { case TYPE_2232H: case TYPE_4232H: #ifdef DRIVE_OPEN_COLLECTOR case TYPE_232H: #endif device_has_fast_clock = true; break; default: device_has_fast_clock = false; } } else /* Unconditionally try ftd2xx on error*/ { fprintf(stderr, "Could not open FTDI device (using libftdi): %s\n", ftdi_get_error_string(ftdi_handle)); ftdi_free(ftdi_handle); ftdi_handle = 0; } } #ifdef USE_FTD2XX if (ftdi_handle == 0) { DWORD dwNumDevs; res = FT_CreateDeviceInfoList(&dwNumDevs); if (res != FT_OK) { fprintf(stderr, "FT_CreateDeviceInfoList failed \n"); goto fail; } if (dwNumDevs <1) { fprintf(stderr, "No FTDI device found (using FTD2XX)\n"); res = 1; goto fail; } #if defined (__linux) res = FT_SetVIDPID(vendor, product); if (res != FT_OK) { fprintf(stderr, "FT_SetVIDPID failed \n"); goto fail; } if(serial && description && (dwNumDevs>1)) fprintf(stderr, "On linux device selection may fail due to missing LOCID\n"); if((serial || description) && (channel == INTERFACE_B)) fprintf(stderr, "On linux device selection second channnel fails due to missing LOCID\n"); #else if ((vendor != 0x0403) || ((product != 0x6001) && (product != 0x6010) && (product != 0x6006))) fprintf(stderr,"FTD2XX/WIN: Can't set VID/PID to %04x:%04x. Expect failure\n", vendor, product); #endif if(serial) res = FT_OpenEx((void*)serial, FT_OPEN_BY_SERIAL_NUMBER, &ftd2xx_handle); else if(description) res = FT_OpenEx((void*)description, FT_OPEN_BY_DESCRIPTION, &ftd2xx_handle); else { if (channel == INTERFACE_B) res = FT_Open (1, &ftd2xx_handle); else res = FT_Open (0, &ftd2xx_handle); } if (res != FT_OK) { fprintf(stderr, "FTD2XX Open failed\n"); goto fail; } { FT_DEVICE ftDevice; res = FT_GetDeviceInfo( ftd2xx_handle, &ftDevice, NULL, NULL, NULL, NULL); if (res == FT_OK) { switch (ftDevice) { case FT_DEVICE_2232H: case FT_DEVICE_4232H: case FT_DEVICE_232H: device_has_fast_clock = true; break; default: device_has_fast_clock = false; } } } res = FT_ResetDevice(ftd2xx_handle); if (res != FT_OK) { fprintf(stderr, "FT_ResetDevice failed\n"); goto fail; } res = FT_SetBitMode(ftd2xx_handle, 0xfb, BITMODE_MPSSE); if (res != FT_OK) { fprintf(stderr, "FT_SetBitMode failed\n"); goto fail; } res = FT_Purge(ftd2xx_handle, FT_PURGE_RX | FT_PURGE_TX); if (res != FT_OK) { fprintf(stderr, "FT_Purge failed\n"); goto fail; } res = FT_SetLatencyTimer(ftd2xx_handle, 2); if (res != FT_OK) { fprintf(stderr, "FT_SetLatencyTimer failed\n"); goto fail; } res = FT_SetTimeouts(ftd2xx_handle, 1000, 1000); if (res != FT_OK) { fprintf(stderr, "FT_SetTimeouts failed\n"); goto fail; } } #endif #ifdef USE_FTD2XX if (!ftd2xx_handle && !ftdi_handle) #else if (!ftdi_handle) #endif { fprintf(stderr, "Unable to access FTDI device with either libftdi or FTD2XX\n"); res = 1; goto fail; } else if(ftdi_handle) fprintf(stderr, "Using Libftdi, "); else fprintf(stderr, "Using FTD2XX, "); // Prepare for JTAG operation buf[1] |= dbus_data; buf[2] |= dbus_en; buf[7] = cbus_data; buf[8] = cbus_en; mpsse_add_cmd(buf, 9); mpsse_send(); /* On H devices, use the non-divided clock*/ if (device_has_fast_clock && ((freq == 0) ||(freq > 458))) { if ((freq == 0) ||(freq >= 30000000)) /* freq = 0 means max rate, 30 MHz for now*/ divisor = 0; else divisor = 30000000/freq -((30000000%freq)?0:1); if (divisor > 0xffff) divisor = 0xffff; #ifndef DIS_DIV_5 #define DIS_DIV_5 0x8a #endif buf[0] = DIS_DIV_5; buf[1] = TCK_DIVISOR; buf[2] = divisor & 0xff; buf[3] = (divisor >> 8) & 0xff; mpsse_add_cmd(buf, 4); mpsse_send(); tck_freq = 30000000/(1+divisor); } else tck_freq = 6000000/(1+divisor); if (verbose) { if (tck_freq > 1000000) fprintf(stderr,"Using JTAG frequency %3d.%03d MHz from undivided clock", tck_freq/1000000,(tck_freq%1000000)/1000); else fprintf(stderr,"Using JTAG frequency %3d.%03d kHz from undivided clock", tck_freq/1000, tck_freq%1000); } fprintf(stderr, "\n"); return 0; ftdi_fail: fail: return res; } void IOFtdi::settype(int sub_type) { subtype = sub_type; } void IOFtdi::txrx_block(const unsigned char *tdi, unsigned char *tdo, int length, bool last) { unsigned char rbuf[TX_BUF]; unsigned const char *tmpsbuf = tdi; unsigned char *tmprbuf = tdo; /* If we need to shift state, treat the last bit separate*/ unsigned int rem = (last)? length - 1: length; unsigned char buf[TX_BUF]; unsigned int buflen = TX_BUF - 3 ; /* we need the preamble*/ unsigned int rembits; /*out on -ve edge, in on +ve edge */ if (rem/8 > buflen) { while (rem/8 > buflen) { /* full chunks*/ buf[0] = ((tdo)?(MPSSE_DO_READ |MPSSE_READ_NEG):0) |((tdi)?MPSSE_DO_WRITE:0)|MPSSE_LSB|MPSSE_WRITE_NEG; buf[1] = (buflen-1) & 0xff; /* low lenbth byte */ buf[2] = ((buflen-1) >> 8) & 0xff; /* high lenbth byte */ mpsse_add_cmd (buf, 3); if(tdi) { mpsse_add_cmd (tmpsbuf, buflen); tmpsbuf+=buflen; } rem -= buflen * 8; if (tdo) { if (readusb(tmprbuf,buflen) != buflen) { fprintf(stderr,"IO_JTAG_MPSSE::shiftTDITDO:" "Failed to read block 0x%x bytes\n", buflen ); } tmprbuf+=buflen; } } } rembits = rem % 8; rem = rem - rembits; if (rem %8 != 0 ) fprintf(stderr,"IO_JTAG_MPSSE::shiftTDITDO: Programmer error\n"); buflen = rem/8; if(rem) { buf[0] = ((tdo)?(MPSSE_DO_READ|MPSSE_READ_NEG):0) |((tdi)?MPSSE_DO_WRITE:0)|MPSSE_LSB|MPSSE_WRITE_NEG; buf[1] = (buflen - 1) & 0xff; /* low length byte */ buf[2] = ((buflen - 1) >> 8) & 0xff; /* high length byte */ mpsse_add_cmd (buf, 3); if(tdi) { mpsse_add_cmd (tmpsbuf, buflen ); tmpsbuf += buflen; } } if (buflen >=(TX_BUF - 4)) { /* No space for the last data. Send and evenually read As we handle whole bytes, we can use the receiv buffer direct*/ if(tdo) { readusb(tmprbuf, buflen); tmprbuf+=buflen; } buflen = 0; } if( rembits) { /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) (use if TCK/SK starts at 0) */ buf[0] = ((tdo)?(MPSSE_DO_READ|MPSSE_READ_NEG):0) |((tdi)?MPSSE_DO_WRITE:0)|MPSSE_LSB|MPSSE_BITMODE|MPSSE_WRITE_NEG; buf[1] = rembits-1; /* length: only one byte left*/ mpsse_add_cmd (buf, 2); if(tdi) mpsse_add_cmd (tmpsbuf,1) ; buflen ++; } if(last) { bool lastbit = false; if(tdi) lastbit = (*tmpsbuf & (1<< rembits)); /* TMS/CS with LSB first on -ve TCK/SK edge, read on +ve edge - use if TCK/SK is set to 0*/ buf[0] = MPSSE_WRITE_TMS|((tdo)?(MPSSE_DO_READ|MPSSE_READ_NEG):0)| MPSSE_LSB|MPSSE_BITMODE|MPSSE_WRITE_NEG; buf[1] = 0; /* only one bit */ buf[2] = (lastbit) ? 0x81 : 1 ; /* TMS set */ mpsse_add_cmd (buf, 3); buflen ++; } if(tdo) { if (!last) { readusb(tmprbuf, buflen); if (rembits) /* last bits for incomplete byte must get shifted down*/ tmprbuf[buflen-1] = tmprbuf[buflen-1]>>(8-rembits); } else { /* we need to handle the last bit. It's much faster to read into an extra buffer than to issue two USB reads */ readusb(rbuf, buflen); if(!rembits) rbuf[buflen-1] = (rbuf[buflen - 1]& 0x80)?1:0; else { /* TDO Bits are shifted downwards, so align them We only shift TMS once, so the relevant bit is bit 7 (0x80) */ rbuf[buflen-2] = rbuf[buflen-2]>>(8-rembits) | ((rbuf[buflen - 1]&0x80) >> (7 - rembits)); buflen--; } memcpy(tmprbuf,rbuf,buflen); } } } void IOFtdi::tx_tms(unsigned char *pat, int length, int force) { unsigned char buf[3] = {MPSSE_WRITE_TMS|MPSSE_LSB|MPSSE_BITMODE| MPSSE_WRITE_NEG, 0, pat[0]}; int len = length, i, j=0; if (!len) return; while (len>0) { /* Attention: Bug in FT2232L(D?, H not!). With 7 bits TMS shift, static TDO value gets set to TMS on last TCK edge*/ buf[1] = (len >6)? 5: (len-1); buf[2] = 0x80; for (i=0; i < (buf[1]+1); i++) { buf[2] |= (((pat[j>>3] & (1<< (j &0x7)))?1:0)< 0) read += last_read; while (((int)read 0) read += last_read; else last_errno = errno; timeout++; } if (timeout >= 1000) { fprintf(stderr,"readusb waiting too long for %ld bytes, only %d read\n", len, last_read); if (last_errno) { fprintf(stderr,"error %s\n", strerror(last_errno)); deinit(); throw io_exception(); } } if (last_read <0) { fprintf(stderr,"Error %d str: %s\n", -last_read, strerror(-last_read)); deinit(); throw io_exception(); } } if(fp_dbg) { unsigned int i; fprintf(fp_dbg,"readusb len %ld:", len); for(i=0; i= TX_BUF) mpsse_send(); memcpy(usbuf + bptr, buf, len); bptr += len; } void IOFtdi::mpsse_send() { if(bptr == 0) return; if(fp_dbg) fprintf(fp_dbg,"mpsse_send %d\n", bptr); #ifdef USE_FTD2XX if (ftd2xx_handle) { DWORD written, last_written; int res, timeout = 0; calls_wr++; res = FT_Write(ftd2xx_handle, usbuf, bptr, &written); if(res != FT_OK) { fprintf(stderr, "mpsse_send: Initial write failed\n"); throw io_exception(); } while ((written < bptr) && ( timeout <100 )) { calls_wr++; res = FT_Write(ftd2xx_handle, usbuf+written, bptr - written, &last_written); if(res != FT_OK) { fprintf(stderr, "mpsse_send: Write failed\n"); throw io_exception(); } written += last_written; timeout++; } if (timeout == 100) { fprintf(stderr,"mpsse_send: Timeout \n"); throw io_exception(); } if(written != bptr) { fprintf(stderr,"mpsse_send: Short write %ld vs %d\n", (unsigned long int)written, bptr); throw io_exception(); } } else #endif { calls_wr++; int written = ftdi_write_data(ftdi_handle, usbuf, bptr); if(written != (int) bptr) { fprintf(stderr,"mpsse_send: Short write %d vs %d at run %d, Err: %s\n", written, bptr, calls_wr, ftdi_get_error_string(ftdi_handle)); throw io_exception(); } } bptr = 0; } void IOFtdi::flush() { mpsse_send(); } /* Short delays may be prolonged by flush causing an additional frame sent * out on a next microframe. * * So make the FTDI toggle TCK for delays < 20 ms */ void IOFtdi::Usleep(unsigned int usec) { flush_tms(false); if(usec < 20000) { /* Make sure, we don't overflow and we round up!*/ unsigned int ticks; ticks = (usec * (tck_freq/100) + (tck_freq/100) - 1)/(1000000/100); if (device_has_fast_clock) { /* Use the "clock for ..." commands*/ unsigned char buf[3] = {0x8f}; /* Clock For n x 8 bits*/ if (ticks > 8 ) { buf[1] = ((ticks / 8) ) & 0xff; buf[2] = ((ticks / 8) >> 8 ) & 0xff; mpsse_add_cmd(buf, 3); ticks %= 8; } if (ticks) { buf[0] = 0x8e; /*Clock For n bits*/ buf[1] = ticks -1; mpsse_add_cmd(buf, 2); } } else { unsigned char buf[3]; if (ticks > 8) { buf[0] = MPSSE_DO_WRITE|MPSSE_LSB|MPSSE_WRITE_NEG; buf[1] = ((ticks / 8) ) & 0xff; buf[2] = ((ticks / 8) >> 8) & 0xff; mpsse_add_cmd (buf, 3); buf[0] = 0; while (ticks > 8) { mpsse_add_cmd (buf, 1); ticks -= 8; } } if (ticks) { buf[0] = MPSSE_DO_WRITE|MPSSE_LSB|MPSSE_BITMODE|MPSSE_WRITE_NEG; buf[1] = ticks -1; buf[2] = 0; mpsse_add_cmd (buf, 1); } } } else { flush(); xc3sprog_Usleep(usec); } } xc3sprog-0+svn795+dfsg/ioftdi.h000066400000000000000000000040251337255630200164070ustar00rootroot00000000000000/* JTAG GNU/Linux FTDI FT2232 low-level I/O Copyright (C) 2006 Dmitry Teytelman Additions (C) 2005-2013 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de 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 IOFTDI_H #define IOFTDI_H #if defined (__WIN32__) # include #endif #include #include #ifdef USE_FTD2XX #include #endif #include "iobase.h" #include "cabledb.h" #define VENDOR_FTDI 0x0403 #define DEVICE_DEF 0x6010 #define TX_BUF (4096) class IOFtdi : public IOBase { protected: #ifdef USE_FTD2XX FT_HANDLE ftd2xx_handle; #endif struct ftdi_context *ftdi_handle; unsigned char usbuf[TX_BUF]; int buflen; bool use_ftd2xx; struct cable_t *cable; unsigned int bptr; int calls_rd, calls_wr, subtype, retries; FILE *fp_dbg; bool device_has_fast_clock; unsigned int tck_freq; public: IOFtdi(bool use_ftd2xx); ~IOFtdi(); int Init(struct cable_t *cable, const char * serial, unsigned int freq); void settype(int subtype); void txrx_block(const unsigned char *tdi, unsigned char *tdo, int length, bool last); void tx_tms(unsigned char *pat, int length, int force); void flush(void); void Usleep(unsigned int usec); private: void deinit(void); void mpsse_add_cmd(unsigned char const *buf, int len); void mpsse_send(void); unsigned int readusb(unsigned char * rbuf, unsigned long len); }; #endif // IOFTDI_H xc3sprog-0+svn795+dfsg/iofx2.cpp000066400000000000000000000235721337255630200165230ustar00rootroot00000000000000/* JTAG low-level I/O to FX2 Using I2C addresses above 0x80 in the USRP/XGUFF framework Copyright (C) 2005-2011 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de 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 "iofx2.h" #include "io_exception.h" #include "utilities.h" IOFX2::IOFX2() : IOBase(), bptr(0), calls_rd(0) , calls_wr(0) { } int IOFX2::Init(struct cable_t *cable, char const *serial, unsigned int freq) { unsigned int vendor = 0xfffe, product = 0x0018; char descstring[256]; char *p = cable->optstring; char *description = 0; int res; /* split string by hand for more flexibility*/ if (p) { vendor = strtol(p, NULL, 0); p = strchr(p,':'); if(p) p ++; } if (p) { product = strtol(p, NULL, 0); p = strchr(p,':'); if(p) p ++; } if (p) { char *q = strchr(p,':'); int len; if (q) len = q-p-1; else len = strlen(p); if (len >0) strncpy(descstring, p, (len>256)?256:len); p = q; if(p) p ++; } if (verbose) { fprintf(stderr, "Cable %s type %s VID 0x%04x PID %04x", cable->alias, getCableName(cable->cabletype), vendor, product); if (description) fprintf(stderr, " Desc %s", description); if (serial) fprintf(stderr, " Serial %s", serial); fprintf(stderr, "\n"); } // Open device res = fx2_usb_open_desc(vendor, product, description, serial); if(res) { fprintf(stderr," Can't open device, res: %d\n", res); return res; } return 0; } IOFX2::~IOFX2() { usrp_close_interface (fx2_dev); } void IOFX2::txrx_block(const unsigned char *tdi, unsigned char *tdo, int length, bool last) { unsigned char sdummy[1]={0}; unsigned char *tmpsbuf = ( unsigned char *)tdi; unsigned char *tmprbuf = tdo; unsigned int rem = (last)? length - 1: length; int i2c_write_addr; if (tdi && tdo) { i2c_write_addr = USRP_CLOCK_INOUT_BYTES; while (rem > USRP_CMD_SIZE*8) { usrp_i2c_write(i2c_write_addr, tmpsbuf, USRP_CMD_SIZE); usrp_i2c_read(i2c_write_addr, tmprbuf, USRP_CMD_SIZE); tmpsbuf+= USRP_CMD_SIZE; tmprbuf+= USRP_CMD_SIZE; rem = rem - USRP_CMD_SIZE*8; } if (rem/8) { usrp_i2c_write(i2c_write_addr, tmpsbuf, rem/8); usrp_i2c_read(i2c_write_addr, tmprbuf, rem/8); tmpsbuf+= rem/8; tmprbuf+= rem/8; rem = rem%8; } if (last) rem++; if (last) i2c_write_addr = USRP_CLOCK_INOUT_BITS_LAST; else i2c_write_addr = USRP_CLOCK_INOUT_BITS; if(rem) { sdummy[0] = *tmpsbuf; usrp_i2c_write(i2c_write_addr, sdummy, rem); usrp_i2c_read (USRP_CLOCK_INOUT_BITS, sdummy, 1); *tmprbuf = sdummy[0]>>(8-rem); } } else if (tdi) { i2c_write_addr = USRP_CLOCK_OUT_BYTES; while (rem > USRP_CMD_SIZE*8) { usrp_i2c_write(i2c_write_addr, tmpsbuf, USRP_CMD_SIZE); tmpsbuf+=USRP_CMD_SIZE; rem = rem - USRP_CMD_SIZE*8; } if (rem/8) { usrp_i2c_write(i2c_write_addr, tmpsbuf, rem/8); tmpsbuf+= rem/8; rem = rem%8; } if (last) rem++; if (last) i2c_write_addr = USRP_CLOCK_INOUT_BITS_LAST; else i2c_write_addr = USRP_CLOCK_INOUT_BITS; if(rem) { sdummy[0] = *tmpsbuf; usrp_i2c_write(i2c_write_addr, sdummy, rem); } } else { i2c_write_addr = USRP_CLOCK_IN_BYTES; while (rem > USRP_CMD_SIZE*8) { usrp_i2c_read(i2c_write_addr, tmprbuf, USRP_CMD_SIZE); tmprbuf+=USRP_CMD_SIZE; rem = rem - USRP_CMD_SIZE*8; } if (rem/8) { usrp_i2c_read(i2c_write_addr, tmprbuf, rem/8); tmprbuf+= rem/8; rem = rem%8; } if (last) rem++; if (last) i2c_write_addr = USRP_CLOCK_INOUT_BITS_LAST; else i2c_write_addr = USRP_CLOCK_INOUT_BITS; if(rem) { sdummy[0] = 0; usrp_i2c_write(i2c_write_addr, sdummy, rem); usrp_i2c_read (USRP_CLOCK_INOUT_BITS, sdummy, 1); *tmprbuf = sdummy[0]>>(8-rem); } } } void IOFX2::tx_tms(unsigned char *pat, int length, int force) { if (length > USRP_CMD_SIZE*8) fprintf(stderr, "ToDo: Break up long TMS sequences\n"); usrp_i2c_write( USPR_CLOCK_OUT_TMS, pat, length); } #define fx2_error_return(code, str) do { \ error_str = str; \ return code; \ } while(0); int IOFX2::fx2_usb_open_desc(int vendor, int product, const char* description, const char* serial) { /* Adapted from libftdi:ftdi_usb_open_desc() Opens the first device with a given, vendor id, product id, description and serial. */ struct usb_bus *bus; struct usb_device *dev; char string[256]; usb_init(); if (usb_find_busses() < 0) fx2_error_return(-1, "usb_find_busses() failed"); if (usb_find_devices() < 0) fx2_error_return(-2, "usb_find_devices() failed"); for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product) { if (!(fx2_dev = usb_open(dev))) fx2_error_return(-4, "usb_open() failed"); if (description != NULL) { if (usb_get_string_simple(fx2_dev, dev->descriptor.iProduct, string, sizeof(string)) <= 0) { usb_close (fx2_dev); fx2_error_return(-8, "unable to fetch product description"); } if (strncmp(string, description, sizeof(string)) != 0) { if (usb_close (fx2_dev) != 0) fx2_error_return(-10, "unable to close device"); continue; } } if (serial != NULL) { if (usb_get_string_simple(fx2_dev, dev->descriptor.iSerialNumber, string, sizeof(string)) <= 0) { usb_close (fx2_dev); fx2_error_return(-9, "unable to fetch serial number"); } if (strncmp(string, serial, sizeof(string)) != 0) { if (usb_close (fx2_dev) != 0) fx2_error_return(-10, "unable to close device"); continue; } } if (usb_close (fx2_dev) != 0) fx2_error_return(-10, "unable to close device"); fx2_dev = usrp_open_interface (dev, USRP_CMD_INTERFACE, USRP_CMD_ALTINTERFACE); if (fx2_dev) return 0; else fx2_error_return(-4, "usb_open() failed"); } } } // device not found fx2_error_return(-3, "device not found"); } struct usb_dev_handle * IOFX2::usrp_open_interface (struct usb_device *dev, int interface, int altinterface) { /* Taken von usrp usrp_prims.cc*/ struct usb_dev_handle *udh = usb_open (dev); if (udh == 0) return 0; if (usb_set_configuration (udh, 1) < 0){ fprintf (stderr, "%s: usb_claim_interface: failed conf %d\n", __FUNCTION__,interface); fprintf (stderr, "%s\n", usb_strerror()); usb_close (udh); return 0; } if (usb_claim_interface (udh, interface) < 0){ fprintf (stderr, "%s:usb_claim_interface: failed interface %d\n", __FUNCTION__,interface); fprintf (stderr, "%s\n", usb_strerror()); usb_close (udh); return 0; } if (usb_set_altinterface (udh, altinterface) < 0){ fprintf (stderr, "%s:usb_set_alt_interface: failed\n", __FUNCTION__); fprintf (stderr, "%s\n", usb_strerror()); usb_release_interface (udh, interface); usb_close (udh); return 0; } return udh; } bool IOFX2::usrp_close_interface (struct usb_dev_handle *udh) { // we're assuming that closing an interface automatically releases it. if(verbose) fprintf(stderr, "USB Read Transactions: %d USB Write Transactions %d\n", calls_rd, calls_wr); return usb_close (udh) == 0; } bool IOFX2::usrp_i2c_write(int i2c_addr, const void *buf, int len) { if (len < 1 || len > MAX_EP0_PKTSIZE) return false; calls_wr++; //int i; // fprintf(stderr, "usrp_i2c_write Addr 0x%02x len %d: ", i2c_addr, len); //for(i=0; i MAX_EP0_PKTSIZE) return false; calls_rd++; ret = write_cmd (fx2_dev, VRQ_I2C_READ, i2c_addr, 0, (unsigned char *) buf, len) == len; //int i; //fprintf(stderr, "usrp_i2c_read Addr 0x%02x len %d: ", i2c_addr, len); //for(i=0; i #include #else #include #endif #include "iobase.h" #include "cabledb.h" #define USRP_VENDOR 0xfffe #define USRP_DEVICE 0x0018 /* Not yet defined in usrp*/ #define USRP_CLOCK_INOUT_BYTES 0x80 #define USRP_CLOCK_OUT_BYTES 0x81 #define USRP_CLOCK_IN_BYTES 0x81 #define USRP_CLOCK_INOUT_BITS 0x82 #define USRP_CLOCK_INOUT_BITS_LAST 0x83 #define USPR_CLOCK_OUT_TMS 0x84 #define USRP_CMD_SIZE 64 class IOFX2 : public IOBase { protected: int bptr, calls_rd, calls_wr; public: IOFX2(); int Init(struct cable_t *cable, char const *serial, unsigned int freq); ~IOFX2(); void txrx_block(const unsigned char *tdi, unsigned char *tdo, int length, bool last); void tx_tms(unsigned char *pat, int length, int force); private: struct usb_dev_handle *fx2_dev; /// String representation of last error const char *error_str; int fx2_usb_open_desc(int vendor, int product, const char* description, const char* serial); struct usb_dev_handle * usrp_open_interface (struct usb_device *dev, int interface, int altinterface); bool usrp_close_interface (struct usb_dev_handle *udh); bool usrp_i2c_write(int address, const void *buf, int len); bool usrp_i2c_read (int i2c_addr, void *buf, int len); int write_cmd (struct usb_dev_handle *udh, int request, int value, int index, unsigned char *bytes, int len); }; #endif // IOFX2_H xc3sprog-0+svn795+dfsg/ioparport.cpp000066400000000000000000000424131337255630200175060ustar00rootroot00000000000000/* JTAG GNU/Linux parport device io Copyright (C) 2004 Andrew Rogers Additions for Byte Blaster Cable (C) 2005-2011 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de 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 Changes: Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: Code cleanup for clean -Wall compile. Changes to support new IOBase interface. Support for byte counting and progress bar. */ #include #include #include #include #ifdef __linux__ // Default parport device #ifndef PPDEV # define PPDEV "/dev/parport0" #endif #include # include # include #include #elif defined (__FreeBSD__) || defined(__MACH__) // Default parport device #ifndef PPDEV # define PPDEV "/dev/parport0" #include #endif #include # include # include # define PARPORT_CONTROL_STROBE STROBE # define PARPORT_CONTROL_AUTOFD AUTOFEED # define PARPORT_CONTROL_INIT INIT # define PARPORT_CONTROL_SELECT SELECTIN /* DLC 5 Schematics: http://www.xilinx.com/itp/xilinx4/data/docs/pac/appendixb.html Pin Connectes for a 25 pin parallel port connector http://www.kabelfaq.de/-> parallel Pin 15 is nERR*/ # define PARPORT_STATUS_ERROR nFAULT /* PIN 13 is SELECT (Printer is online)*/ # define PARPORT_STATUS_SELECT SELECT /* PIN 12 is PE */ # define PARPORT_STATUS_PAPEROUT PERROR /* PIN 10 is nACK */ # define PARPORT_STATUS_ACK nACK /* PIN 11 is nBusy */ # define PARPORT_STATUS_BUSY nBUSY #elif defined (__WIN32__) // Default parport device #ifndef PPDEV # define PPDEV "\\\\.\\$VDMLPT1" #endif #include #include #include #include "par_nt.h" /*FIXME: These defines fit numerically, but not logically*/ # define PARPORT_CONTROL_STROBE PARALLEL_INIT # define PARPORT_CONTROL_AUTOFD PARALLEL_AUTOFEED # define PARPORT_CONTROL_INIT PARALLEL_PAPER_EMPTY # define PARPORT_CONTROL_SELECT PARALLEL_OFF_LINE # define PARPORT_STATUS_ERROR PARALLEL_OFF_LINE # define PARPORT_STATUS_SELECT PARALLEL_POWER_OFF # define PARPORT_STATUS_PAPEROUT PARALLEL_NOT_CONNECTED # define PARPORT_STATUS_ACK PARALLEL_BUSY # define PARPORT_STATUS_BUSY PARALLEL_SELECTED #endif #include #include #include "ioparport.h" #include "debug.h" #define NO_CABLE 0 #define IS_PCIII 1 #define IS_BBLST 2 #define BIT_MASK(b) (1<<(b)) /* Attention: PARPORT_STATUS_BUSY reflects the inverted input */ /* Attention: PARPORT_CONTROL_AUTOFD write zero to output */ /* Altera Byteblaster Definitions */ #define BBLST_DEF_BYTE 0 #define BBLST_ENABLE_N PARPORT_CONTROL_AUTOFD /* Base + 2, Inv */ #define BBLST_TCK_VALUE BIT_MASK(0) /* Base */ #define BBLST_TMS_VALUE BIT_MASK(1) /* Base */ #define BBLST_TDI_VALUE BIT_MASK(6) /* Base */ #define BBLST_RESET_VALUE BIT_MASK(3) /* Base, Inv by Open Collector Transistor */ #define BBLST_TDO_MASK PARPORT_STATUS_BUSY /* Base + 1, Input */ #define BBLST_LB_IN_MASK PARPORT_STATUS_PAPEROUT /* Base + 1, Input */ #define BBLST_LB_OUT_VALUE BIT_MASK(7) /* Base */ #define BBLST_ACK_OUT_VALUE BIT_MASK(5) #define BBLST_ACK_IN_MASK PARPORT_STATUS_ACK /* Xilinx Parallel Cable III Definitions */ #define PCIII_PROG_EN_N BIT_MASK(4) #define PCIII_DEF_BYTE PCIII_PROG_EN_N #define PCIII_TCK_VALUE BIT_MASK(1) /* Base */ #define PCIII_TMS_VALUE BIT_MASK(2) /* Base */ #define PCIII_TDI_VALUE BIT_MASK(0) /* Base */ #define PCIII_TDO_MASK PARPORT_STATUS_SELECT #define PCIII_CHECK_OUT BIT_MASK(6) #define PCIII_CHECK_IN1 PARPORT_STATUS_BUSY #define PCIII_CHECK_IN2 PARPORT_STATUS_PAPEROUT using namespace std; int IOParport::detectcable(void) { unsigned char data=0, status, control; write_data(fd, data); read_status(fd, &status); read_control(fd, &control); if ((status == 0) || (status == 0xff)) { fprintf(stderr,"IOParport::detectcable status 0x%02x control %02x" " Check system driver setup\n", status, control); return NO_CABLE; } /* Error_n should is hardwired to ground on a byteblaster cable*/ if (!(status & PARPORT_STATUS_ERROR)) { if (debug & HW_DETAILS) fprintf(stderr,"Trying Byteblaster\n"); /* D5/ACK and D7/PE should be connected*/ if (( (data & BBLST_LB_OUT_VALUE) && !(status & BBLST_LB_IN_MASK)) || (!(data & BBLST_LB_OUT_VALUE) && (status & BBLST_LB_IN_MASK))) { /* The difference is in D7/PE if the card is unpowered*/ if(( (data & BBLST_ACK_OUT_VALUE) && (status & BBLST_ACK_IN_MASK))|| (!(data & BBLST_ACK_OUT_VALUE) && !(status & BBLST_ACK_IN_MASK))) { fprintf(stderr,"Unpowered Byteblaster cable\n"); return NO_CABLE; } /*We have an unpowered Xilinx cable if D6/Busy/PE are connected */ else if ( ( (data & PCIII_CHECK_OUT) && !(status & PCIII_CHECK_IN1))|| (!(data & PCIII_CHECK_OUT) && (status & PCIII_CHECK_IN1))|| ( (data & PCIII_CHECK_OUT) && (status & PCIII_CHECK_IN2))|| (!(data & PCIII_CHECK_OUT) && !(status & PCIII_CHECK_IN2))) { fprintf(stderr,"Unpowered Parallel Cable III cable\n"); return NO_CABLE; } else { fprintf(stderr,"No dongle found\n"); return NO_CABLE; } } /* now try all 4 permuttation */ data = (data & BBLST_LB_OUT_VALUE) ? (data & ~BBLST_LB_OUT_VALUE) : (data | BBLST_LB_OUT_VALUE); write_data(fd, data); read_status(fd, &status); if (( (data & BBLST_LB_OUT_VALUE) && !(status & BBLST_LB_IN_MASK)) || (!(data & BBLST_LB_OUT_VALUE) && (status & BBLST_LB_IN_MASK)) || ( (data & BBLST_ACK_OUT_VALUE) && !(status & BBLST_ACK_IN_MASK))|| (!(data & BBLST_ACK_OUT_VALUE) && (status & BBLST_ACK_IN_MASK))) { fprintf(stderr,"Missing reaction for Altera cable(1)\n"); return NO_CABLE; } data = (data & BBLST_ACK_OUT_VALUE) ? (data & ~BBLST_ACK_OUT_VALUE) : (data | BBLST_ACK_OUT_VALUE); write_data(fd, data); read_status(fd, &status); if (( (data & BBLST_LB_OUT_VALUE) && !(status & BBLST_LB_IN_MASK)) || (!(data & BBLST_LB_OUT_VALUE) && (status & BBLST_LB_IN_MASK)) || ( (data & BBLST_ACK_OUT_VALUE) && !(status & BBLST_ACK_IN_MASK))|| (!(data & BBLST_ACK_OUT_VALUE) && (status & BBLST_ACK_IN_MASK))) { fprintf(stderr,"Missing reaction for Altera cable(2)\n"); return NO_CABLE; } data = (data & BBLST_LB_OUT_VALUE) ? (data & ~BBLST_LB_OUT_VALUE) : (data | BBLST_LB_OUT_VALUE); write_data(fd, data); read_status(fd, &status); if (( (data & BBLST_LB_OUT_VALUE) && !(status & BBLST_LB_IN_MASK)) || (!(data & BBLST_LB_OUT_VALUE) && (status & BBLST_LB_IN_MASK)) || ( (data & BBLST_ACK_OUT_VALUE) && !(status & BBLST_ACK_IN_MASK))|| (!(data & BBLST_ACK_OUT_VALUE) && (status & BBLST_ACK_IN_MASK))) { fprintf(stderr,"Missing reaction for Altera cable(3)\n"); return NO_CABLE; } data = (data & BBLST_ACK_OUT_VALUE) ? (data & ~BBLST_ACK_OUT_VALUE) : (data | BBLST_ACK_OUT_VALUE); write_data(fd, data); read_status(fd, &status); if (( (data & BBLST_LB_OUT_VALUE) && !(status & BBLST_LB_IN_MASK)) || (!(data & BBLST_LB_OUT_VALUE) && (status & BBLST_LB_IN_MASK)) || ( (data & BBLST_ACK_OUT_VALUE) && !(status & BBLST_ACK_IN_MASK))|| (!(data & BBLST_ACK_OUT_VALUE) && (status & BBLST_ACK_IN_MASK))) { fprintf(stderr,"Missing reaction for Altera cable(4)\n"); return NO_CABLE; } fprintf(stderr,"Found ByteBlaster Cable\n"); def_byte = BBLST_DEF_BYTE; tdi_value = BBLST_TDI_VALUE; tms_value = BBLST_TMS_VALUE; tck_value = BBLST_TCK_VALUE; tdo_mask = BBLST_TDO_MASK; tdo_inv = 1; read_control(fd, &control); control |= BBLST_ENABLE_N; write_control(fd, control); return IS_BBLST; } else { /*Probably Xilinx cable */ /* Check for D6/BUSY/PE Connection and for D4/Select Feedback */ if ( ( (data & PCIII_CHECK_OUT) && (status & PCIII_CHECK_IN1))|| (!(data & PCIII_CHECK_OUT) && !(status & PCIII_CHECK_IN1))|| ( (data & PCIII_CHECK_OUT) && !(status & PCIII_CHECK_IN2))|| (!(data & PCIII_CHECK_OUT) && (status & PCIII_CHECK_IN2))) { fprintf(stderr,"No dongle found\n"); return NO_CABLE; } /* 20100708: This check will only work with U1 on the DLC(clone) * from a high drive family like LVC and a not so strong driver at the end * of the JTAG chain, like an XCF0x. * E.G. Digilent S3 drives TDO-A with an LVC, while the * original DLC5 only has an HC125, and so the HC125 can not drive the line * low consitstantly * * So disable this check if ((status & PCIII_TDO_MASK) && (!(data & PCIII_PROG_EN_N))) { fprintf(stderr,"Missing power for Parallel Cable III\n"); return NO_CABLE;} */ data = (data & PCIII_CHECK_OUT) ? (data & ~PCIII_CHECK_OUT) : (data |PCIII_CHECK_OUT); write_data(fd, data); read_status(fd, &status); if ( ( (data & PCIII_CHECK_OUT) && (status & PCIII_CHECK_IN1))|| (!(data & PCIII_CHECK_OUT) && !(status & PCIII_CHECK_IN1))|| ( (data & PCIII_CHECK_OUT) && !(status & PCIII_CHECK_IN2)) || (!(data & PCIII_CHECK_OUT) && (status & PCIII_CHECK_IN2))) { fprintf(stderr,"Missing reaction on XILINX Cable(1)\n"); return NO_CABLE; } data = (data & PCIII_CHECK_OUT) ? (data & ~PCIII_CHECK_OUT) : (data | PCIII_CHECK_OUT); write_data(fd, data); read_status(fd, &status); if ( ( (data & PCIII_CHECK_OUT) && (status & PCIII_CHECK_IN1))|| (!(data & PCIII_CHECK_OUT) && !(status & PCIII_CHECK_IN1))|| ( (data & PCIII_CHECK_OUT) && !(status & PCIII_CHECK_IN2))|| (!(data & PCIII_CHECK_OUT) && (status & PCIII_CHECK_IN2))) { fprintf(stderr,"Missing reaction on XILINX Cable(2)\n"); return NO_CABLE; } fprintf(stderr,"Found Xilinx Parallel Cable III\n"); def_byte = PCIII_DEF_BYTE; tdi_value = PCIII_TDI_VALUE; tms_value = PCIII_TMS_VALUE; tck_value = PCIII_TCK_VALUE; tdo_mask = PCIII_TDO_MASK; tdo_inv = 0; return IS_PCIII; } } IOParport::IOParport() : IOBase(), total(0), debug(0) { } int IOParport::Init(struct cable_t *cable, const char *dev, unsigned int freq) { int res; // Try to obtain device from environment or use default if not given if(!dev) { if(!(dev = getenv("XCPORT"))) dev = PPDEV; } #if defined (__linux__) || defined(__FreeBSD__) // Try to open parport device if((fd = open(dev, O_RDWR)) == -1) #elif defined(__WIN32__) if ((fd = CreateFile(dev, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) #endif { fprintf(stderr,"Could not access parallel device '%s': %s\n", dev, strerror(errno)); return -1; } #if defined (__linux__) // Lock port res = ioctl(fd, PPCLAIM); if(res) { fprintf(stderr, "Port %s already in use\n", dev); return res; } // Switch to compatibility mode int const mode = IEEE1284_MODE_COMPAT; res = ioctl(fd, PPNEGOT, &mode); if(res) { fprintf(stderr,"IEEE1284 compatibility not available on dev %s\n", dev); return res; } #endif (void) res; cabletype = detectcable(); if(cabletype == NO_CABLE) { fprintf(stderr, "No adapter found\n"); return 1; } return 0; } bool IOParport::txrx(bool tms, bool tdi) { unsigned char ret; bool retval; unsigned char data=def_byte; // D4 pin5 TDI enable if(tdi)data|=tdi_value; // D0 pin2 if(tms)data|=tms_value; // D2 pin4 write_data(fd, data); data|=tck_value; // clk high D1 pin3 write_data(fd, data); total++; read_status(fd, &ret); //data=data^2; // clk low //write_data(fd, data); //read_status(fd, &ret); retval = (ret&tdo_mask)?!tdo_inv:tdo_inv; if (debug & HW_FUNCTIONS) fprintf(stderr,"IOParport::txrx tms %s tdi %s tdo %s \n", (tms)?"true ":"false", (tdi)?"true ":"false", (retval)?"true ":"false"); return retval; } void IOParport::tx(bool tms, bool tdi) { unsigned char data=def_byte; // D4 pin5 TDI enable if (debug & HW_FUNCTIONS) fprintf(stderr,"tx tms %s tdi %s\n",(tms)?"true ":"false", (tdi)?"true ":"false"); if(tdi)data|=tdi_value; // D0 pin2 if(tms)data|=tms_value; // D2 pin4 write_data(fd, data); //delay(2); data|=tck_value; // clk high total++; write_data(fd, data); //delay(2); //data=data^2; // clk low //write_data(fd, data); //delay(2); } void IOParport::tx_tdi_byte(unsigned char tdi_byte) { int k; for (k = 0; k < 8; k++) tx(false, (tdi_byte>>k)&1); } void IOParport::txrx_block(const unsigned char *tdi, unsigned char *tdo, int length, bool last) { int i=0; int j=0; unsigned char tdo_byte=0; unsigned char tdi_byte; unsigned char data=def_byte; if (tdi) tdi_byte = tdi[j]; while(i>1; i++; if((i%8)==0){ // Next byte if(tdo) tdo[j]=tdo_byte; // Save the TDO byte tdo_byte=0; j++; if (tdi) tdi_byte=tdi[j]; // Get the next TDI byte } }; tdo_byte=tdo_byte+(txrx(last, (tdi_byte&1)==1)<<(i%8)); if(tdo) tdo[j]=tdo_byte; write_data(fd, data); /* Make sure, TCK is low */ return; } void IOParport::tx_tms(unsigned char *pat, int length, int force) { int i; unsigned char tms; unsigned char data=def_byte; for (i = 0; i < length; i++) { if ((i & 0x7) == 0) tms = pat[i>>3]; tx((tms & 0x01), true); tms = tms >> 1; } write_data(fd, data); /* Make sure, TCK is low */ } IOParport::~IOParport() { if (cabletype == IS_BBLST) { unsigned char control; read_control(fd, &control); control &= ~BBLST_ENABLE_N; write_control(fd, control); } #ifdef __linux__ ioctl (fd, PPRELEASE); close (fd); #elif defined(__FreeBSD__) close (fd); #elif defined(__WIN32__) CloseHandle((HANDLE)(fd)); #endif if (verbose) fprintf(stderr, "Total bytes sent: %d\n", total>>3); } #define XC3S_OK 0 #define XC3S_EIO 1 #define XC3S_ENIMPL 2 int IOParport::write_data(FD_HANDLE fd, unsigned char data) { int status; #ifdef __linux__ status = ioctl(fd, PPWDATA, &data); return status == 0 ? XC3S_OK : -XC3S_EIO; #elif defined (__FreeBSD__) status = ioctl(fd, PPISDATA, &data); return status == 0 ? XC3S_OK : -XC3S_EIO; #elif defined(__WIN32__) DWORD dummy; status = DeviceIoControl((HANDLE)(fd), NT_IOCTL_DATA, &data, sizeof(data), NULL, 0, (LPDWORD)&dummy, NULL); return status != 0 ? XC3S_OK : -XC3S_EIO; #else return -XC3S_ENIMPL; #endif } int IOParport::write_control(FD_HANDLE fd, unsigned char control) { int status; #ifdef __linux__ status = ioctl(fd, PPWCONTROL, &control); return status == 0 ? XC3S_OK : -XC3S_EIO; #elif defined (__FreeBSD__) status = ioctl(fd, PPISCTRL, &control); return status == 0 ? XC3S_OK : -XC3S_EIO; #elif defined(__WIN32__) DWORD dummyc; DWORD dummy; /*FIXME: hamlib used much more compicated expression*/ status = DeviceIoControl((HANDLE)(fd),NT_IOCTL_CONTROL, &control, sizeof(control), &dummyc, sizeof(dummyc), (LPDWORD)&dummy, NULL); return status != 0 ? XC3S_OK : -XC3S_EIO; #else return -XC3S_ENIMPL; #endif } int IOParport::read_control(FD_HANDLE fd, unsigned char *control) { int status; #ifdef __linux status = ioctl(fd, PPRCONTROL, control); return status == 0 ? XC3S_OK : -XC3S_EIO; #elif defined (__FreeBSD__) status = ioctl(fd, PPIGCTRL, control); return status == 0 ? XC3S_OK : -XC3S_EIO; #elif defined (__WIN32__) char ret; DWORD dummy; status = DeviceIoControl((HANDLE)(fd), NT_IOCTL_CONTROL, NULL, 0, &ret, sizeof(ret), (LPDWORD)&dummy, NULL); *control = ret ^ S1284_INVERTED; return status == 0 ? XC3S_OK : -XC3S_EIO; #else return -XC3S_ENIMPL; #endif } int IOParport::read_status(FD_HANDLE fd, unsigned char *status) { int ret; #ifdef __linux__ ret = ioctl(fd, PPRSTATUS, status); return ret == 0 ? XC3S_OK : -XC3S_EIO; #elif defined (__FreeBSD__) ret = ioctl(fd, PPIGSTATUS, status); return ret == 0 ? XC3S_OK : -XC3S_EIO; #elif defined (__WIN32__) unsigned char res; DWORD dummy; ret = DeviceIoControl((HANDLE)(fd), NT_IOCTL_STATUS, NULL, 0, &res, sizeof(res), (LPDWORD)&dummy, NULL); *status = res ; return ret == 0 ? XC3S_OK : -XC3S_EIO; #else return -XC3S_ENIMPL; #endif } xc3sprog-0+svn795+dfsg/ioparport.h000066400000000000000000000040661337255630200171550ustar00rootroot00000000000000/* JTAG GNU/Linux parport device io Copyright (C) 2004 Andrew Rogers Additions (C) 2005-2011 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de 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 Changes: Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: Code cleanup for clean -Wall compile. Changes to support new IOBase interface. */ #ifndef IOPARPORT_H #define IOPARPORT_H #include "iobase.h" #if defined (__WIN32__) # include # if !defined(HANDLE) # define HANDLE void* # endif # define FD_HANDLE HANDLE #else # define FD_HANDLE int #endif class IOParport : public IOBase { protected: FD_HANDLE fd; int total, cabletype, debug; unsigned char def_byte, tdi_value, tms_value, tck_value, tdo_mask, tdo_inv; int write_data(FD_HANDLE fd, unsigned char data); int write_control(FD_HANDLE fd, unsigned char control); int read_control(FD_HANDLE fd, unsigned char *control); int read_status(FD_HANDLE fd, unsigned char *status); public: IOParport(); int Init(struct cable_t *cable, const char *dev, unsigned int freq); ~IOParport(); void tx(bool tms, bool tdi); bool txrx(bool tms, bool tdi); void tx_tdi_byte(unsigned char tdi_byte); void tx_tms(unsigned char *pat, int length, int force); public: void txrx_block(const unsigned char *tdi, unsigned char *tdo, int length, bool last); private: void delay(int del); int detectcable(void); }; #endif // IOPARPORT_H xc3sprog-0+svn795+dfsg/ioxpc.cpp000066400000000000000000000470741337255630200166210ustar00rootroot00000000000000/* JTAG low-level I/O to DLC9(10?) cables As reversed engineered by kolja waschk Adapted from urjtag/trunk/jtag/xpc.c Copyright (C) 2008 Kolja Waschk Copyright (C) 2009-2011 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de 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 #define __STDC_FORMAT_MACROS #include #include #include #include #include #include #include "ioxpc.h" #include "io_exception.h" IOXPC::IOXPC() : IOBase(), bptr(0), calls_rd(0) , calls_wr(0), call_ctrl(0), subtype(0) { } int IOXPC::Init(struct cable_t *cable, char const *serial, unsigned int freq) { int res; unsigned char buf[2]; unsigned long long lserial=0; char descstring[256]; char *description = 0; char *p = cable->optstring; int r; unsigned int vendor = 0x03fd, product= 0x0008; char *fname = getenv("XPC_DEBUG"); if (fname) fp_dbg = fopen(fname,"wb"); else fp_dbg = NULL; /* split string by hand for more flexibility*/ if (p) { vendor = strtol(p, NULL, 0); p = strchr(p,':'); if(p) p ++; } if (p) { product = strtol(p, NULL, 0); p = strchr(p,':'); if(p) p ++; } if (p) { char *q = strchr(p,':'); int len; if (q) len = q-p-1; else len = strlen(p); if (len >0) strncpy(descstring, p, (len>256)?256:len); p = q; if(p) p ++; } if(!(strcasecmp(cable->alias,"xpc_internal"))) subtype = XPC_INTERNAL; // Open device if(serial) sscanf(serial,"%Lx", &lserial); res = xpc_usb_open_desc(vendor, product, description, lserial); if (res < 0) { fprintf(stderr,"No dongle found\n"); return res; } res = xpcu_request_28(xpcu, 0x11); if (res < 0) { fprintf(stderr,"pcu_request_28 failed\n"); return res; } res = xpcu_write_gpio(xpcu, XPC_PROG); if (res < 0) { fprintf(stderr,"xpcu_write_gpio failed\n"); return res; } res = xpcu_read_firmware_version(xpcu, buf); if (res < 0) { fprintf(stderr,"xpcu_read_firmware_version: failed\n"); return res; } res = xpcu_read_cpld_version(xpcu, buf); if (res < 0) { fprintf(stderr,"xpcu_read_cpld_version: failed\n"); return res; } if (verbose) { fprintf(stderr, "firmware version = 0x%02x%02x (%u)\n", buf[1], buf[0], buf[1]<<8| buf[0]); fprintf(stderr, "CPLD version = 0x%02x%02x (%u)\n", buf[1], buf[0], buf[1]<<8| buf[0]); if(hid) #ifdef __WIN32__ fprintf(stderr, "DLC HID = 0x%015" PRIx64 "\n", hid); #else fprintf(stderr, "DLC HID = 0x%015llx\n", hid); #endif } if(!buf[1] && !buf[0]) { fprintf(stderr,"Warning: version '0' can't be correct." " Please try resetting the cable\n"); return 1; } if (subtype == XPC_INTERNAL) { res = xpcu_select_gpio(xpcu, 0); if (res < 0) { usb_close(xpcu); fprintf(stderr, "Error Setting internal mode: "); return 2; } } else { unsigned char zero[2] = {0,0}; r = xpcu_output_enable(xpcu, 0); if (r>=0) r = xpcu_request_28(xpcu, 0x11); if (r>=0) r = xpcu_output_enable(xpcu, 1); if (r>=0) r = xpcu_shift(xpcu, 0xA6, 2, 2, zero, 0, NULL); if (r>=0) r = xpcu_request_28(xpcu, 0x12); if (r<0) { usb_close(xpcu); fprintf(stderr, "Setting external mode: "); return 3; } } return 0; } IOXPC::~IOXPC() { xpcu_output_enable(xpcu, 0); xpc_close_interface (xpcu); if(fp_dbg) fclose(fp_dbg); } int IOXPC::xpcu_output_enable(struct usb_dev_handle *xpcu, int enable) { if(usb_control_msg(xpcu, 0x40, 0xB0, enable ? 0x18 : 0x10, 0, NULL, 0, 1000) <0) { fprintf(stderr, "usb_control_msg(%x) %s\n", enable, usb_strerror()); return -1; } call_ctrl++; return 0; } int IOXPC::xpcu_request_28(struct usb_dev_handle *xpcu, int value) { /* Typical values seen during autodetection of chain configuration: 0x11, 0x12 */ if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0028, value, NULL, 0, 1000)<0) { fprintf(stderr, "usb_control_msg(0x28 %x) %s\n", value, usb_strerror()); return -1; } call_ctrl++; return 0; } /* ---------------------------------------------------------------------- */ int IOXPC::xpcu_write_gpio(struct usb_dev_handle *xpcu, unsigned char bits) { if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0030, bits, NULL, 0, 1000)<0) { fprintf(stderr, "usb_control_msg(0x30.0x%02x) (write port E) %s\n", bits, usb_strerror()); return -1; } call_ctrl++; if (fp_dbg) fprintf(fp_dbg, "w%02x ", bits); return 0; } /* ---------------------------------------------------------------------- */ int IOXPC::xpcu_read_gpio(struct usb_dev_handle *xpcu, unsigned char *bits) { if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0038, 0, (char*)bits, 1, 1000)<0) { fprintf(stderr, "usb_control_msg(0x38) (read port E) %s\n", usb_strerror()); return -1; } call_ctrl++; if (fp_dbg) fprintf(fp_dbg, "r%02x ", bits[0]); return 0; } /* ---------------------------------------------------------------------- */ int IOXPC::xpcu_read_cpld_version(struct usb_dev_handle *xpcu, unsigned char *buf) { if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0050, 0x0001, (char*)buf, 2, 1000)<0) { fprintf(stderr, "usb_control_msg(0x50.1) (read_cpld_version) %s\n", usb_strerror()); return -1; } call_ctrl++; return 0; } /* ---------------------------------------------------------------------- */ int IOXPC::xpcu_read_hid(struct usb_dev_handle *xpcu) { int i; char buf[8]; hid = 0; int rc = usb_control_msg(xpcu, 0xC0, 0xB0, 0x0042, 0x001, buf, 8, 1000); if(rc<0) { return rc; } for (i=6; i>= 0; i--) hid = (hid<<8) +buf[i]; call_ctrl++; return 0; } /* ---------------------------------------------------------------------- */ int IOXPC::xpcu_read_firmware_version(struct usb_dev_handle *xpcu, unsigned char *buf) { if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0050, 0x0000, (char*)buf, 2, 1000)<0) { fprintf(stderr, "usb_control_msg(0x50.0) (read_firmware_version) %s\n", usb_strerror()); return -1; } call_ctrl++; return 0; } void hint_loadfirmware(struct usb_device *dev) { fprintf(stderr, "\nFirmware doesn't support unique number readout! If unique \n" "number is needed for board destinction, try overloading(!)\n" "with an firmware from ../Xilinx/nn.n/ISE/data\n" "e.g. with fxload -t fx2lp -I -D /dev/bus/usb/%s/%s\n" "and e.g. firmware ../Xilinx/nn.n/ISE/data/xusb_emb.hex for SP601\n" "or e.g. firmware ../Xilinx/nn.n/ISE/data/xusb_xp2.hex for DLC10\n" "\n", dev->bus->dirname, dev->filename); } int IOXPC::xpcu_select_gpio(struct usb_dev_handle *xpcu, int int_or_ext ) { if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0052, int_or_ext, NULL, 0, 1000)<0) { fprintf(stderr, "usb_control_msg(0x52.x) (select gpio) %s\n", usb_strerror()); return -1; } call_ctrl++; return 0; } /* === A6 transfer (TDI/TMS/TCK/RDO) === * * Vendor request 0xA6 initiates a quite universal shift operation. The data * is passed directly to the CPLD as 16-bit words. * * The argument N in the request specifies the number of state changes/bits. * * State changes are described by the following bulk write. It consists * of ceil(N/4) little-endian 16-bit words, each describing up to 4 changes: * * Care has to be taken that N is NOT a multiple of 4. * The CPLD doesn't seem to handle that well. * * Bit 0: Value for first TDI to shift out. * Bit 1: Second TDI. * Bit 2: Third TDI. * Bit 3: Fourth TDI. * * Bit 4: Value for first TMS to shift out. * Bit 5: Second TMS. * Bit 6: Third TMS. * Bit 7: Fourth TMS. * * Bit 8: Whether to raise/lower TCK for first bit. * Bit 9: Same for second bit. * Bit 10: Third bit. * Bit 11: Fourth bit. * * Bit 12: Whether to read TDO for first bit * Bit 13: Same for second bit. * Bit 14: Third bit. * Bit 15: Fourth bit. * * After the bulk write, if any of the bits 12..15 was set in any word, a * bulk_read shall follow to collect the TDO data. * * TDO data is shifted in from MSB to LSB and transferred 32-bit little-endian. * In a "full" word with 32 TDO bits, the earliest one reached bit 0. * The earliest of 31 bits however would be bit 1. A 17 bit transfer has the LSB * as the MSB of uint16_t[0], other bits are in uint16_t[1]. * * However, if the last packet is smaller than 16, only 2 bytes are transferred. * If there's only one TDO bit, it arrives as the MSB of the 16-bit word, uint16_t[0]. * uint16_t[1] is then skipped. * * For full 32 bits blocks, the data is aligned. The last non 32-bits block arrives * non-aligned and has to be re-aligned. Half-words (16-bits) transfers have to be * re-aligned too. */ int IOXPC::xpcu_shift(struct usb_dev_handle *xpcu, int reqno, int bits, int in_len, unsigned char *in, int out_len, unsigned char *out ) { if(usb_control_msg(xpcu, 0x40, 0xB0, reqno, bits, NULL, 0, 1000)<0) { fprintf(stderr, "usb_control_msg(0x40.0x%02x 0x%02x) (shift) %s\n", reqno, bits, usb_strerror()); return -1; } call_ctrl++; if(fp_dbg) { int i; fprintf(fp_dbg, "###\n"); fprintf(fp_dbg, "reqno = %02X\n", reqno); fprintf(fp_dbg, "bits = %d\n", bits); fprintf(fp_dbg, "in_len = %d, in_len*2 = %d\n", in_len, in_len * 2); fprintf(fp_dbg, "out_len = %d, out_len*8 = %d\n", out_len, out_len * 8); fprintf(fp_dbg, "a6_display(\"%02X\", \"", bits); for(i=0;i 0 && out != NULL) { if(usb_bulk_read(xpcu, 0x86, (char*)out, out_len, 1000)<0) { fprintf(stderr, "\nusb_bulk_read error(shift): %s\n", usb_strerror()); return -1; } calls_rd++; } if(fp_dbg) { int i; fprintf(fp_dbg, "\""); for(i=0;iin_bits >> 2); if ((xts->in_bits & 3) != 0) in_len += 2; //cpld returns the read data (tdo) in 32 bit words out_len = 2 * (xts->out_bits >> 4); if ((xts->out_bits & 15) != 0) out_len += 2; if(xts->out != NULL) { r = xpcu_shift (xpcu, 0xA6, xts->in_bits, in_len, xts->buf, out_len, xts->buf); } else { r = xpcu_shift (xpcu, 0xA6, xts->in_bits, in_len, xts->buf, 0, NULL); } if(r >= 0 && xts->out_bits > 0) { int i; unsigned int aligned_32bitwords, aligned_bytes; unsigned int shift, bit_num, bit_val; aligned_32bitwords = xts->out_bits/32; aligned_bytes = aligned_32bitwords*4; memcpy(xts->out, xts->buf, aligned_bytes); xts->out_done = aligned_bytes*8; //This data is not aligned if (xts->out_bits % 32) { shift = xts->out_bits % 16; //we can also receive a 16-bit word in which case if (shift) //the MSB starts in the least significant 16 bit word shift = 16 - shift; //and it shifts the same way for 32 bit if //out_bits > 16 and ( shift = 32 - out_bits % 32 ) if (fp_dbg) fprintf(fp_dbg, "out_done %d shift %d\n", xts->out_done, shift); for (i = aligned_bytes*8; i < xts->out_bits; i++) { bit_num = i + shift; bit_val = xts->buf[bit_num/8] & (1<<(bit_num%8)); if(!(xts->out_done % 8)) xts->out[xts->out_done/8] = 0; if (bit_val) xts->out[xts->out_done/8] |= (1<<(xts->out_done%8)); xts->out_done++; } } if (fp_dbg) { int i; fprintf(fp_dbg, "Shifted data"); for( i = 0; i < out_len; i++) { fprintf(fp_dbg, " %02x", xts->out[i]); } fprintf(fp_dbg, "\n"); } } xts->in_bits = 0; xts->out_bits = 0; return r; } /* ---------------------------------------------------------------------- */ void IOXPC::xpcu_add_bit_for_ext_transfer( xpc_ext_transfer_state_t *xts, bool in, bool tms, bool is_real ) { int bit_idx = (xts->in_bits & 3); int buf_idx = (xts->in_bits - bit_idx) >> 1; if(bit_idx == 0) { xts->buf[buf_idx] = 0; xts->buf[buf_idx+1] = 0; } xts->in_bits++; if(is_real) { if(in) xts->buf[buf_idx] |= (0x01<buf[buf_idx] |= (0x10<out) { xts->buf[buf_idx+1] |= (0x11<out_bits++; } else { xts->buf[buf_idx+1] |= (0x01<>3] & (1<>3]; else tdi = 0; if(out) out[i>>3] = 0; } xpcu_write_gpio(xpcu, XPC_PROG | XPC_TCK | ((last)? XPC_TMS : 0) | ((tdi & 0x01)? XPC_TDI : 0)); if(out) { xpcu_read_gpio(xpcu, &d); out[i>>3] |= ((d & XPC_TDO) == XPC_TDO)?(i%8):0; } xpcu_write_gpio(xpcu, XPC_PROG | 0 | ((last)? XPC_TMS : 0) | ((tdi & 0x01)? XPC_TDI : 0)); tdi = tdi >> 1; } } else { int j; xpc_ext_transfer_state_t xts; xts.out = (out)? out: NULL; xts.in_bits = 0; xts.out_bits = 0; xts.out_done = 0; for(i=0,j=0; i=0; i++) { int tdi; if (in) { if ((i & 0x7 ) == 0) tdi = in[i>>3]; } else tdi = 0; xpcu_add_bit_for_ext_transfer( &xts, (tdi & 1), (i== len-1)?last:0, 1 ); tdi >>= 1; if(xts.in_bits == (2*CPLD_MAX_BYTES - 1)) { j = xpcu_do_ext_transfer( &xts ); } } if(xts.in_bits > 0 && j>=0) { /* CPLD doesn't like multiples of 4; add one dummy bit */ if((xts.in_bits & 3) == 0) { xpcu_add_bit_for_ext_transfer( &xts, 0, 0, 0 ); } j = xpcu_do_ext_transfer( &xts ); } } } void IOXPC::tx_tms(unsigned char *in, int len, int force) { int i; if (fp_dbg) { fprintf(fp_dbg, "---\n"); fprintf(fp_dbg, "transfer size %d\n", len); fprintf(fp_dbg, "TMS: "); for(i=0;i>3] & 1<<(i%8))?'1':'0'); fprintf(fp_dbg, "\n"); } if (subtype == XPC_INTERNAL) { unsigned char tms; for (i = 0; i < len; i++) { if ((i & 0x7) == 0) tms = in[i>>3]; xpcu_write_gpio(xpcu, XPC_PROG | XPC_TCK | ((tms & 0x01)? XPC_TMS : 0) | XPC_TDI); xpcu_write_gpio(xpcu, XPC_PROG | 0 | ((tms & 0x01)? XPC_TMS : 0) | XPC_TDI); tms = tms >> 1; } } else { int j; xpc_ext_transfer_state_t xts; xts.out = NULL; xts.in_bits = 0; xts.out_bits = 0; xts.out_done = 0; for(i=0,j=0; i=0; i++) { xpcu_add_bit_for_ext_transfer( &xts, 1, (in[i>>3] & (1<<(i%8))), 1 ); if(xts.in_bits == (2*CPLD_MAX_BYTES - 1)) { j = xpcu_do_ext_transfer( &xts ); } } if(xts.in_bits > 0 && j>=0) { /* CPLD doesn't like multiples of 4; add one dummy bit */ if((xts.in_bits & 3) == 0) { xpcu_add_bit_for_ext_transfer( &xts, 0, 0, 0 ); } j = xpcu_do_ext_transfer( &xts ); } } } #define xpc_error_return(code, str) do { \ error_str = str; \ return code; \ } while(0); int IOXPC::xpc_usb_open_desc(int vendor, int product, const char* description, unsigned long long int lserial) { /* Adapted from libftdi:ftdi_usb_open_desc() Opens the first device with a given, vendor id, product id, description and serial. */ struct usb_bus *bus; struct usb_device *dev; char string[256]; usb_init(); if (usb_find_busses() < 0) xpc_error_return(-1, "usb_find_busses() failed"); if (usb_find_devices() < 0) xpc_error_return(-2, "usb_find_devices() failed"); for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if (dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product) { if (!(xpcu = usb_open(dev))) xpc_error_return(-4, "usb_open() failed"); if (description != NULL) { if (usb_get_string_simple(xpcu, dev->descriptor.iProduct, string, sizeof(string)) <= 0) { usb_close (xpcu); xpc_error_return(-8, "unable to fetch product description"); } if (strncmp(string, description, sizeof(string)) != 0) { if (usb_close (xpcu) != 0) xpc_error_return(-10, "unable to close device"); continue; } } if (usb_set_configuration (xpcu, dev->config[0].bConfigurationValue) < 0) { fprintf (stderr, "%s: usb_set_configuration: failed conf %d\n", __FUNCTION__, dev->config[0].bConfigurationValue); fprintf (stderr, "%s\n", usb_strerror()); usb_close (xpcu); xpc_error_return(-10, "unable to set configuration"); } if (usb_claim_interface (xpcu, 0) < 0){ fprintf (stderr, "%s:usb_claim_interface: failed interface 0\n", __FUNCTION__); fprintf (stderr, "%s\n", usb_strerror()); usb_close (xpcu); xpc_error_return(-11, "unable to claim interface"); } #if 0 int rc = xpcu_read_hid(xpcu); if (rc < 0) { if (rc == -EPIPE) { if (lserial != 0) { hint_loadfirmware(dev); return 0; } } else fprintf(stderr, "usb_control_msg(0x42.1 %s\n", usb_strerror()); } else if ((lserial != 0) && (lserial != hid)) { usb_close (xpcu); continue; } #else hid = 0; #endif return 0; } } } // device not found xpc_error_return(-3, "device not found"); } bool IOXPC::xpc_close_interface (struct usb_dev_handle *udh) { // we're assuming that closing an interface automatically releases it. if(verbose) fprintf(stderr, "USB Read Transactions: %d Write Transactions: %d" " Control Transaction %d\n", calls_rd, calls_wr, call_ctrl); return usb_close (udh) == 0; } xc3sprog-0+svn795+dfsg/ioxpc.h000066400000000000000000000063741337255630200162640ustar00rootroot00000000000000/* JTAG low-level I/O to DLC9(10?) cables Using I2C addresses above 0x80 in the USRP/XGUFF framework Copyright (C) 2005-2011 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de 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 IOXPC_H #define IOXPC_H #if defined (__WIN32__) #include #include #else #include #endif #include "iobase.h" #define XPC_VENDOR 0x03fd #define XPC_DEVICE 0x0008 #define XPC_INTERNAL 1 #define XPC_PROG (1<<3) #define XPC_TCK (1<<2) #define XPC_TMS (1<<1) #define XPC_TDI (1<<0) #define XPC_TDO (1<<0) /* * send max 4096 bytes to CPLD * this is equal to 8192 TDI plus 8192 TDO bits */ #define CPLD_MAX_BYTES (1<<12) /* * Buffer has to hold 8192 bits for write, each 2 bytes hold 4 bits for write, so this has to be 4096 * Buffer has to hold 8192 bits for read, each byte holds 8 bits for read, so this has to be 1024 * Therefore, buffer size -> CPLD_MAX_BYTES */ typedef struct { int in_bits; int out_bits; int out_done; unsigned char *out; unsigned char buf[CPLD_MAX_BYTES]; } xpc_ext_transfer_state_t; class IOXPC : public IOBase { protected: int bptr, calls_rd, calls_wr, call_ctrl; int subtype; unsigned long long hid; FILE *fp_dbg; public: IOXPC(); int Init(struct cable_t *cable, char const *serial, unsigned int freq); ~IOXPC(); void txrx_block(const unsigned char *tdi, unsigned char *tdo, int length, bool last); void tx_tms(unsigned char *pat, int length, int force); private: struct usb_dev_handle *xpcu; /// String representation of last error const char *error_str; int xpcu_output_enable(struct usb_dev_handle *xpcu, int enable); int xpcu_request_28(struct usb_dev_handle *xpcu, int value); int xpcu_write_gpio(struct usb_dev_handle *xpcu, unsigned char bits); int xpcu_read_gpio(struct usb_dev_handle *xpcu, unsigned char *bits); int xpcu_read_cpld_version(struct usb_dev_handle *xpcu, unsigned char *buf); int xpcu_read_hid(struct usb_dev_handle *xpcu); int xpcu_read_firmware_version(struct usb_dev_handle *xpcu, unsigned char *buf); int xpcu_select_gpio(struct usb_dev_handle *xpcu, int int_or_ext ); int xpcu_shift(struct usb_dev_handle *xpcu, int reqno, int bits, int in_len, unsigned char *in, int out_len, unsigned char *out ); void xpcu_add_bit_for_ext_transfer( xpc_ext_transfer_state_t *xts, bool in, bool tms, bool is_real ); int xpcu_do_ext_transfer( xpc_ext_transfer_state_t *xts ); int xpc_usb_open_desc(int vendor, int product, const char* description, unsigned long long int serial); bool xpc_close_interface (struct usb_dev_handle *udh); }; #endif // IOXPC_H xc3sprog-0+svn795+dfsg/javr.cpp000066400000000000000000000115321337255630200164270ustar00rootroot00000000000000#include #include "javr.h" int jAVR(Jtag &jtag, unsigned int id, char * flashfile, bool verify, bool lock, const char * eepromfile, const char * fusefile) { /*bool menu = (!flashfile && !eepromfile && !fusefile);*/ unsigned short partnum = (id>>12) & 0xffff; int i; AVR_Data gDeviceData; BOOT_Size gDeviceBOOTSize; int Index; /* Find Device index*/ Index=UNKNOWN_DEVICE; for (i=0; i< gAVR_Data[i].jtag_id; i++) if (gAVR_Data[i].jtag_id == partnum) { gDeviceData=gAVR_Data[i]; Index=i; gDeviceBOOTSize=gBOOT_Size[i]; break; } if(Index==UNKNOWN_DEVICE) { fprintf(stderr, "Unknown device\n"); return 1; } fprintf(stderr, "%s, Rev %c with",gDeviceData.name,((id>>28) & 0xf)+'A'); fprintf(stderr, " %ldK Flash, %u Bytes EEPROM and %u Bytes RAM\r\n", gDeviceData.flash/1024, gDeviceData.eeprom, gDeviceData.ram); ProgAlgAVR alg (jtag, gDeviceData.fp_size); if (fusefile) { //EncodeATMegaFuseBits(); } else { byte fuses[4]; alg.read_fuses(fuses); fprintf(stderr, "Extended Fuse Byte: 0x%02x High Fuse Byte: 0x%02x" " Low Fuse Byte: 0x%02x LOCK Byte 0x%02x\n", fuses[FUSE_EXT], fuses[FUSE_HIGH], fuses[FUSE_LOW], fuses[FUSE_LOCK]); } if (eepromfile) { } else { byte eeprom[16]; int i; alg.read_eeprom(0xff0, eeprom, 16); fprintf(stderr, "EEPROM at 0xff0:"); for (i=0; i<16; i++) fprintf(stderr, " %02x ", eeprom[i]); fprintf(stderr, "\n"); } if (flashfile) { SrecFile file; if(file.readSrecFile(flashfile, 0) <0) return 1; if (file.getLength() == 0) { fprintf(stderr, "%s or %s.rom not found or no valid SREC File\n", flashfile, flashfile); goto bailout; } if (verify) { byte buffer[gDeviceData.fp_size]; int count = 0; unsigned int i, j, k, match; for (i = file.getStart(); i < file.getEnd() ; i+= gDeviceData.fp_size) { unsigned int to_read; fprintf(stdout, "\rVerify page %4d/%4d", i/gDeviceData.fp_size, file.getLength()/gDeviceData.fp_size); fflush(stderr); if ( i< (file.getEnd() - gDeviceData.fp_size)) to_read = gDeviceData.fp_size; else to_read = (file.getEnd() -i); alg.pageread_flash(i, buffer, to_read); match = memcmp(buffer, file.getData()+i, to_read); if (match !=0) { fprintf(stderr, "\n"); for (j = 0; j< to_read; j +=32) { match = memcmp(buffer+j, file.getData()+i+j, 32); if (match !=0) { fprintf(stderr, "Mismatch at address: 0x%08x\n", i+j); fprintf(stderr, "Device: "); for(k =0; k<32; k++) fprintf(stderr, "%02x ", buffer[j+k]); fprintf(stderr, "\nFile : "); for(k =0; k<32; k++) fprintf(stderr, "%02x ", file.getData()[i+j +k ]); fprintf(stderr, "\n : "); for(k =0; k<32; k++) { if(buffer[j+k] != file.getData()[i+j+k]) { fprintf(stderr, "^^^"); count++; } else fprintf(stderr, " "); } fprintf(stderr, "\n"); } } } if (count >10) return 1; } if(count) { fprintf(stderr, "Chip Verify failed\n"); goto bailout; } else fprintf(stderr, "\tSuccess \n"); } else { unsigned int i; if (alg.erase()) { fprintf(stderr, "Chip Erase failed\n"); goto bailout; } else fprintf(stderr, "Chip Erase success\n"); if (file.getStart() & gDeviceData.fp_size) { fprintf(stderr, " File doesn't start at Page Border, aborting\n"); goto bailout; } for (i= file.getStart(); i < file.getLength()-gDeviceData.fp_size; i += gDeviceData.fp_size) { fprintf(stdout, "\rWriting page %4d/%4d", i/gDeviceData.fp_size, file.getLength()/gDeviceData.fp_size); if (alg.pagewrite_flash(i, file.getData()+i, gDeviceData.fp_size)) { fprintf(stderr, "\nError writing page %d\n", i/gDeviceData.fp_size); goto bailout; } fflush(stderr); } /* eventual last page is not full. Fill it up with FILL_BYTE)*/ if (i != file.getLength()) { byte *buffer = new byte[gDeviceData.fp_size]; memcpy(buffer, file.getData()+i,file.getLength() -i); memset(buffer + (file.getLength() -i), FILL_BYTE, gDeviceData.fp_size- (file.getLength() -i)); if (alg.pagewrite_flash(i, buffer, gDeviceData.fp_size)) { fprintf(stderr, "\nError writing page %d\n", i/gDeviceData.fp_size); goto bailout; } else { fprintf(stdout, "\rWriting page %4d/%4d", i/gDeviceData.fp_size, file.getEnd()/gDeviceData.fp_size); fflush(stderr); } } fprintf(stderr, " done.\n" "Bytes from 0x%05x to 0x%05x filled with 0x%02x\n", file.getEnd(), i+gDeviceData.fp_size -1, FILL_BYTE); } } return 0; bailout: return 1; } xc3sprog-0+svn795+dfsg/javr.h000066400000000000000000000055221337255630200160760ustar00rootroot00000000000000/********************************************************************\ * * Atmel AVR JTAG Programmer for Altera Byteblaster Hardware \********************************************************************/ #include "progalgavr.h" #define FILL_BYTE 0xFF /* These defines must be in the same order as data in gAVR_Data[] array */ #define ATMEGA128 0 #define ATMEGA64 1 #define ATMEGA323 2 #define ATMEGA32 3 #define ATMEGA16 4 #define ATMEGA162 5 #define ATMEGA169 6 #define AT90CAN128 7 #define UNKNOWN_DEVICE 0xFF typedef struct { unsigned short jtag_id; unsigned short eeprom; unsigned long flash; unsigned short ram; unsigned int fp_size; /* Flash Pagesize in Bytes*/ const char *name; }AVR_Data; /* Must be in same sequence as gAVR_Data[] */ const AVR_Data gAVR_Data[]= {/* jtag_id eeprom flash ram fp_size name */ {0x9702, 4096 , 131072UL , 4096 , 0 , "ATMega128"}, {0x9602, 2048 , 65536UL , 4096 , 0 , "ATMega64"}, {0x9501, 1024 , 32768UL , 2048 , 0 , "ATMega323"}, {0x9502, 1024 , 32768UL , 2048 , 0 , "ATMega32"}, {0x9403, 512 , 16384UL , 1024 , 0 , "ATMega16"}, {0x9404, 512 , 16384UL , 1024 , 128 , "ATMega162"}, {0x9405, 512 , 16384UL , 1024 , 0 , "ATMega169"}, {0x9781, 4096 , 131072UL , 4096 , 256 , "AT90CAN128"}, {0x9681, 2048 , 65536UL , 4096 , 256 , "AT90CAN64"}, {0x9581, 1024 , 32768UL , 2048 , 256 , "AT90CAN32"}, {0,0, 0, 0, 0, "Unknown"} }; typedef struct { unsigned short size[4]; /* BOOTSZ0, BOOTSZ1 Mapping size in bytes */ }BOOT_Size; /* Must be in same sequence as gAVR_Data[] */ const BOOT_Size gBOOT_Size[]={ {{(4096*2),(2048*2),(1024*2),(512*2)}}, /* ATMega128 */ {{(4096*2),(2048*2),(1024*2),(512*2)}}, /* ATMega64 */ {{(2048*2),(1024*2),(512*2 ),(256*2)}}, /* ATMega323 */ {{(2048*2),(1024*2),(512*2 ),(256*2)}}, /* ATMega32 */ {{(1024*2),(512*2 ),(256*2 ),(128*2)}}, /* ATMega16 */ {{(1024*2),(512*2 ),(256*2 ),(128*2)}}, /* ATMega162 */ {{(1024*2),(512*2 ),(256*2 ),(128*2)}}, /* ATMega169 */ {{(4096*2),(2048*2),(1024*2),(512*2)}} /* AT90CAN128 */ }; int jAVR(Jtag &jtag, unsigned int i, char * flashfile, bool verify, bool lock, const char * eepromfile, const char * fusefile); xc3sprog-0+svn795+dfsg/javr/000077500000000000000000000000001337255630200157215ustar00rootroot00000000000000xc3sprog-0+svn795+dfsg/javr/CMakeLists.txt000066400000000000000000000007011337255630200204570ustar00rootroot00000000000000# Project project(javr) SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}") cmake_minimum_required(VERSION 2.6) include_directories (${XC3SPROG_SOURCE_DIR}) link_directories (${XC3SPROG_BINARY_DIR}/xc3sproglib) add_executable(javr javr.cpp srecdec.cpp parse.cpp menu.cpp avr_jtag.cpp fuse.cpp jtag.cpp) target_link_libraries(javr xc3sproglib ${LIBFTDI_LIBRARIES} ${LIBFTD2XX_LIBRARIES} ${CONDITIONAL_LIBS}) install(TARGETS javr DESTINATION bin) xc3sprog-0+svn795+dfsg/javr/Changelog.old000066400000000000000000000000751337255630200203120ustar00rootroot00000000000000080515: javr.c: Bufferbegin fuer WriteEepromBlock korrigiert.xc3sprog-0+svn795+dfsg/javr/avr_jtag.cpp000066400000000000000000000464031337255630200202310ustar00rootroot00000000000000/********************************************************************\ * $Id: avr_jtag.c,v 1.9 2003/09/28 14:43:11 anton Exp $ * $Log: avr_jtag.c,v $ * Revision 1.9 2003/09/28 14:43:11 anton * Added some needed fflush(stdout)s * * Revision 1.8 2003/09/28 14:31:04 anton * Added --help command, display GPL * * Revision 1.7 2003/09/28 12:52:52 anton * Small printing fix in verify * * Revision 1.6 2003/09/28 12:49:45 anton * Updated Version, Changed Error printing in Verify * * Revision 1.3 2003/09/27 19:21:59 anton * Added support for Linux compile * * Revision 1.2 2003/09/24 20:18:08 anton * Added Verify option - Not tested yet * * Revision 1.1.1.1 2003/09/24 15:35:57 anton * Initial import into CVS * \********************************************************************/ #include #include #include #include #include #include #include "javr.h" #include "iobase.h" #include "jtag_javr.h" #include "debug.h" #define AVR_JTAG_M #include "avr_jtag.h" #undef AVR_JTAG_M #define MAX_BLOCK_SIZE 256 #ifndef NEWFUNCTIONS unsigned short Send_AVR_Prog_Command(unsigned short command) { char array[15],output[16]; int i; unsigned short mask; /* Convert command to binary array */ for(mask=0x01,i=0;mask;mask<<=1, i++) { if(command&mask) array[i]='1'; else array[i]='0'; } Send_Data_Output(15,array,output); mask=ArrayToUS(15,output); if (debug& UL_FUNCTIONS) fprintf(stderr,"Send_AVR_Prog_Command send 0x%04x rec 0x%04x\n", command, mask); return(mask); } /********************************************************************\ * * * Use JTAG Reset Register to put AVR in Reset * * * \********************************************************************/ void ResetAVR(void) { char x[]={'1'}; /* High corresponds to external reset low */ if (debug& UL_FUNCTIONS) fprintf(stderr,"ResetAVR\n"); Send_Instruction(4,AVR_RESET); Send_Data(1,x); } /********************************************************************\ * * * Use JTAG Reset Register to take AVR out of Reset * * * \********************************************************************/ void ResetReleaseAVR(void) { char x[]={'0'}; /* High corresponds to external reset low */ if (debug& UL_FUNCTIONS) fprintf(stderr,"ResetReleaseAVR\n"); Send_Instruction(4,AVR_RESET); Send_Data(1,x); Send_Instruction(4,BYPASS); } void AVR_Prog_Enable(void) { const char *inst=SIG_PROG_EN ; /* Prog Enable Signature (ATMega 128) */ if (debug& UL_FUNCTIONS) fprintf(stderr,"AVR_Prog_Enable\n"); Send_Instruction(4,PROG_ENABLE); Send_Data(16,inst); } void AVR_Prog_Disable(void) { const char *inst="0000000000000000"; if (debug& UL_FUNCTIONS) fprintf(stderr,"AVR_Prog_Disable\n"); Send_Instruction(4,PROG_ENABLE); Send_Data(16,inst); } #endif /********************************************************************\ * * * Convert a binary character array into a short * * LSB of Number is first in Array * * * \********************************************************************/ unsigned short ArrayToUS(unsigned char Size, char *ptr) { unsigned short tmp,mask; unsigned char i; tmp=0; mask=1; for(i=0;i= T_WLRH_CE+999) { fprintf(stderr,"\Erase failed! Aborting\n"); // return 1; } printf("\nDevice Erased\n"); } static unsigned char gPageBuffer[(MAX_BLOCK_SIZE+1)*8+1]; /* Each bit in block is converted to 1 char */ //static unsigned char bPageBuffer[(MAX_BLOCK_SIZE+2)]; /********************************************************************\ * * * AVR_Prog_Enable() must be executed before this command * * * \********************************************************************/ void ReadFlashPage(unsigned pagenumber, unsigned pagesize, unsigned char *dest) { unsigned tmp; unsigned short instr; unsigned char *ptr,tmp1,mask; char *cptr; unsigned int i; Send_Instruction(4,PROG_COMMANDS); Send_AVR_Prog_Command(0x2302); /* Enter Flash Read */ tmp=pagenumber*pagesize; //tmp<<=7; /* Page Size is 2^7=128 words */ tmp>>=1; /* Get Word Address of Page (word = 2 bytes ) */ if ((gDeviceData.Index==AT90USB1287) || (gDeviceData.Index==ATMEGA640)) { instr=0x0b00; instr|=(tmp>>16); Send_AVR_Prog_Command(instr); /* Enter Extended High Address Byte */ } instr=0x0700; instr|=((tmp>>8) & 0xff); Send_AVR_Prog_Command(instr); /* Enter High Address Byte */ instr=0x0300; instr|=(tmp&0xFF); Send_AVR_Prog_Command(instr); /* Enter Low Address Byte */ Send_Instruction(4,PROG_PAGEREAD); #if 1 switch(gDeviceData.Index) { case AT90USB1287: case AT90CAN128: case ATMEGA640: cptr = (char*)gPageBuffer; for (i=0; i>16); Send_AVR_Prog_Command(instr); /* Enter Extended High Address Byte */ } instr=0x0700; instr|=((tmp>>8) & 0xff); Send_AVR_Prog_Command(instr); /* Enter High Address Byte */ instr=0x0300; instr|=(tmp&0xFF); Send_AVR_Prog_Command(instr); /* Enter Low Address Byte */ Send_Instruction(4,PROG_PAGELOAD); switch(gDeviceData.Index) { case AT90USB1287: case AT90CAN128: case ATMEGA640: cptr=(char*)gPageBuffer; for(i=0;i= T_WLRH_CE+999) { fprintf(stderr,"\nWriting page %4d failed! Aborting\n", i); return 0; } return(1); /* Page succesfully written */ } /********************************************************************\ * * * AVR_Prog_Enable() must be executed before this command * * * \********************************************************************/ unsigned short ReadFlashWord(unsigned address) { unsigned short instr; unsigned short tmp; Send_Instruction(4,PROG_COMMANDS); Send_AVR_Prog_Command(0x2302); /* Enter Flash Read */ instr=0x0700; instr|=(address>>8); Send_AVR_Prog_Command(instr); /* Enter High Address Byte */ instr=0x0300; instr|=(address&0xFF); Send_AVR_Prog_Command(instr); /* Enter Low Address Byte */ Send_AVR_Prog_Command(0x3200); instr=Send_AVR_Prog_Command(0x3600); /* Low Byte */ tmp=Send_AVR_Prog_Command(0x3700); /* High Byte */ instr&=0xFF; tmp<<=8; tmp|=instr; return(tmp); } /********************************************************************\ * * * AVR_Prog_Enable() must be executed before this command * * * \********************************************************************/ unsigned char ReadEepromByte(unsigned address) { unsigned short instr; unsigned short tmp; Send_Instruction(4,PROG_COMMANDS); Send_AVR_Prog_Command(0x2303); /* Enter EEPROM Read */ instr=0x0700; instr|=(address>>8); Send_AVR_Prog_Command(instr); /* Enter High Address Byte */ instr=0x0300; instr|=(address&0xFF); Send_AVR_Prog_Command(instr); /* Enter Low Address Byte */ instr|=0x3300; Send_AVR_Prog_Command(instr); Send_AVR_Prog_Command(0x3200); tmp=Send_AVR_Prog_Command(0x3300); /* Read Byte */ return((unsigned char)tmp); } #define EEPROM_READ_PAGE_SIZE 16 /********************************************************************\ * * * AVR_Prog_Enable() must be executed before this command * * Page size to read is 16 bytes * \********************************************************************/ void ReadEepromPage(unsigned pagenumber, unsigned char *dest) { unsigned short instr; unsigned short tmp, address; int i; Send_Instruction(4,PROG_COMMANDS); Send_AVR_Prog_Command(0x2303); /* Enter Read EEPROM */ address=pagenumber*EEPROM_READ_PAGE_SIZE; for(i=0;i>8); Send_AVR_Prog_Command(instr); /* Enter High Address Byte */ instr=0x0300; instr|=(address&0xFF); Send_AVR_Prog_Command(instr); /* Enter Low Address Byte */ instr=0x3300; instr|=(address&0xFF); tmp=Send_AVR_Prog_Command(instr); tmp=Send_AVR_Prog_Command(0x3200); tmp=Send_AVR_Prog_Command(0x3300); /* Read Byte */ *dest++=(unsigned char)tmp; address++; } } /********************************************************************\ * * * AVR_Prog_Enable() must be executed before this command * * Page size to write is either 4 or 8 bytes * \********************************************************************/ int WriteEepromPage(unsigned short pagenumber, unsigned char pagesize, unsigned char *src) { int i; unsigned short instr,address,tmp; struct timeval actualtime, endtime; unsigned char tmp1; Send_Instruction(4,PROG_COMMANDS); Send_AVR_Prog_Command(0x2311); /* Enter EEPROM Write */ address=pagenumber*pagesize; /* Page is 8 Bytes for ATmega128 */ /* Page is 4 Bytes for ATmega16, 32 */ instr=0x0700; instr|=(address>>8); Send_AVR_Prog_Command(instr); /* Enter High Address Byte */ i=pagesize; while(i--) { instr=0x0300; instr|=(address&0xFF); Send_AVR_Prog_Command(instr); /* Enter Low Address Byte */ address++; tmp1=*src++; instr=0x1300; instr|=tmp1; Send_AVR_Prog_Command(instr); /* Enter Data Byte */ Send_AVR_Prog_Command(0x3700); /* Latch Data */ Send_AVR_Prog_Command(0x7700); Send_AVR_Prog_Command(0x3700); } Send_AVR_Prog_Command(0x3300); /* Write Page */ Send_AVR_Prog_Command(0x3100); Send_AVR_Prog_Command(0x3300); Send_AVR_Prog_Command(0x3300); gettimeofday( &actualtime, NULL ); endtime.tv_usec=(actualtime.tv_usec+T_WLRH)% 1000000; endtime.tv_sec=actualtime.tv_sec+(actualtime.tv_usec+T_WLRH)/1000000; do { tmp=Send_AVR_Prog_Command(0x3300); tmp&=0x0200; gettimeofday( &actualtime, NULL ); if (( actualtime.tv_sec > endtime.tv_sec ) || (( actualtime.tv_sec == endtime.tv_sec ) && ( actualtime.tv_usec > endtime.tv_usec ))) { printf("\nProblem Writing EEPROM Page: %d !!!\n",pagenumber); return(0); } }while(!tmp); return(1); /* Page succesfully written */ } int ReadEepromBlock(unsigned startaddress, unsigned length, unsigned char *dest) { unsigned char buffer[EEPROM_READ_PAGE_SIZE]; unsigned pagenumber; int i,count=0; if(startaddress>=gDeviceData.eeprom) return(0); pagenumber=startaddress/EEPROM_READ_PAGE_SIZE; if(startaddress+length>gDeviceData.eeprom) { length=gDeviceData.eeprom-startaddress; } if(!length) { length=1; } i=startaddress%EEPROM_READ_PAGE_SIZE; for(;;) { ReadEepromPage(pagenumber,buffer); for(;igDeviceData.flash) { length=gDeviceData.flash; /* Do not try and program more than flash size */ } blocksize = gDeviceData.pagesize; printf("Flash Page Size: %d\n",blocksize); assert(blocksize<=sizeof(buffer)); pagenumber=startaddress/blocksize; index=startaddress%blocksize; number_of_pages=length/blocksize; src += index + pagenumber * blocksize; if((length%blocksize) || index) number_of_pages++; len=length-1; for(i=0;i < number_of_pages; i++) { if (index) { memset(buffer,0xFF,MAX_BLOCK_SIZE); memcpy(buffer+index, src, MAX_BLOCK_SIZE -index); index=0; src+=MAX_BLOCK_SIZE -index; } else { memcpy(buffer, src, MAX_BLOCK_SIZE); src+=MAX_BLOCK_SIZE; } if(!WriteFlashPage(pagenumber, blocksize,buffer)) return; /* Error Writing Flash */ printf(" "); printf("\rWritten Flash page %4d",pagenumber); pagenumber++; } printf("\nWritten Flash from 0x%lX to 0x%lX\n",startaddress,startaddress+len); } int ReadFlashBlock(unsigned startaddress, unsigned length, unsigned char *dest) { unsigned char buffer[MAX_BLOCK_SIZE]; unsigned blocksize; unsigned pagenumber; unsigned i; int count=0; blocksize = gDeviceData.pagesize; if(startaddress>=gDeviceData.flash) return(0); pagenumber=startaddress/blocksize; if(startaddress+length>gDeviceData.flash) { length=gDeviceData.flash-startaddress; } if(!length) { length=1; } i=startaddress%blocksize; for(;;) { ReadFlashPage(pagenumber,blocksize,buffer); printf("\rReading page %4d", pagenumber); fflush(stdout); for(;i>=1; } else break; } return(1<2048) { bsize=2048; } if(bsize<256) { bsize=256; } bstart=startaddress; for(i=0;;) { putchar('.'); fflush(stdout); AVR_Prog_Enable(); ReadFlashBlock(bstart,bsize,buffer); AVR_Prog_Disable(); for(k=0;k=length) return(error); } bstart+=bsize; } } xc3sprog-0+svn795+dfsg/javr/avr_jtag.h000066400000000000000000000050751337255630200176760ustar00rootroot00000000000000/*************************************************************************\ * Copyright (C) <2001> * antone@sentechsa.com * * 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 * \*************************************************************************/ /********************************************************************\ * $Id: avr_jtag.h,v 1.4 2005/03/23 21:03:49 anton Exp $ * $Log: avr_jtag.h,v $ * Revision 1.4 2005/03/23 21:03:49 anton * Added GPL License to source files * * Revision 1.3 2003/09/27 19:21:59 anton * Added support for Linux compile * * Revision 1.2 2003/09/24 20:18:08 anton * Added Verify option - Not tested yet * * Revision 1.1.1.1 2003/09/24 15:35:57 anton * Initial import into CVS * \********************************************************************/ #ifdef __WIN32__ #include #define usleep(x) Sleep((x+999)/1000) #endif unsigned short Send_AVR_Prog_Command(unsigned short command); void ResetAVR(void); void ResetReleaseAVR(void); void AVR_Prog_Enable(void); void AVR_Prog_Disable(void); unsigned short ArrayToUS(unsigned char Size, char *ptr); void ChipErase(void); void ReadFlashPage(unsigned pagenumber, unsigned pagesize, unsigned char *dest); int WriteFlashPage(unsigned pagenumber, unsigned pagesize, unsigned char *src); unsigned short ReadFlashWord(unsigned address); unsigned char ReadEepromByte(unsigned address); void ReadEepromPage(unsigned pagenumber, unsigned char *dest); int WriteEepromPage(unsigned short pagenumber, unsigned char pagesize, unsigned char *src); int ReadEepromBlock(unsigned startaddress, unsigned length, unsigned char *dest); void WriteEepromBlock(unsigned startaddress, unsigned length, unsigned char *src); void WriteFlashBlock(unsigned long startaddress, unsigned long length, unsigned char *src); int ReadFlashBlock(unsigned startaddress, unsigned length, unsigned char *dest); int VerifyFlashBlock(unsigned startaddress, unsigned length, unsigned char *src); xc3sprog-0+svn795+dfsg/javr/compiler.h000066400000000000000000000016771337255630200177170ustar00rootroot00000000000000/*************************************************************************\ * Copyright (C) <2001> * antone@sentechsa.com * * 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 __GNUC__ #include #endif xc3sprog-0+svn795+dfsg/javr/fuse.cpp000066400000000000000000000643431337255630200174010ustar00rootroot00000000000000/*************************************************************************\ * Copyright (C) <2001> * antone@sentechsa.com * * 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 * \*************************************************************************/ /********************************************************************\ * Routines to handle the Fuse and Lock bits of the ATMega * * $Id: fuse.c,v 1.4 2005/03/23 21:03:49 anton Exp $ * $Log: fuse.c,v $ * Revision 1.4 2005/03/23 21:03:49 anton * Added GPL License to source files * * Revision 1.3 2005/03/23 20:16:12 anton * Updates by Uwe Bonnes to add support for AT90CAN128 * * Revision 1.2 2003/09/27 19:21:59 anton * Added support for Linux compile * * Revision 1.1.1.1 2003/09/24 15:35:57 anton * Initial import into CVS * \********************************************************************/ #define NO_JTAG_DISABLE #include #include #include "javr.h" #include "avr_jtag.h" #include "jtag_javr.h" #define FUSE_M #include "fuse.h" #undef FUSE_M /* M128 M323 M16 M162 M169P CAN128 USB1287 M640 * M64 M32 M169A M1280 * M329 M1281 * M3290 M2560 * M649 M2560 * M6490 * E7 ------ ------ ------ ------ ------- ------ ------ ------ * E6 ------ ------ ------ ------ ------- ------ ------ ------ * E5 ------ ------ ------ ------ ------- ------ ------ ------ * E4 ------ ------ ------ M161C ------- ------ ------ ------ * E3 ----- ----- ----- BODL2 BODL2 BODL2 HWBE ----- * E2 ----- ----- ----- BODL0 BODL0 BODL0 BODL2 BODL2 * E1 M103C ----- ----- BODL1 BODL1 BODL1 BODL0 BODL0 * E0 WDTON ----- ----- ------ RSTDIS TA0SEL BODL1 BODL1 * ** H7 OCDEN OCDEN OCDEN OCDEN OCDEN OCDEN OCDEN OCDEN ** H6 JTAGEN JTAGEN JTAGEN JTAGEN JTAGEN JTAGEN JTAGEN JTAGEN ** H5 SPIEN SPIEN SPIEN SPIEN SPIEN SPIEN SPIEN SPIEN * H4 CKOPT ----- CKOPT WDTON WDTON WDTON WDTON WDTON ** H3 EESAVE EESAVE EESAVE EESAVE EESAVEE EESAVE EESAVE EESAVE ** H2 BOOTS1 BOOTS1 BOOTS1 BOOTS1 BOOTS11 BOOTS1 BOOTS1 BOOTS1 ** H1 BOOTS0 BOOTS0 BOOTS0 BOOTS0 BOOTS00 BOOTS0 BOOTS0 BOOTS0 ** H0 BOOTRS BOOTRS BOOTRS BOOTRS BOOTRSS BOOTRS BOOTRS BOOTRS * * L7 BODLVL BODLVL BODLVL CKDIV8 CKDIV8L CKDIV8 CKDIV8 CKDIV8 * L6 BODEN BODEN BODEN CKOUT CKOUT CKOUT CKOUT CKOUT * L5 SUT1 ---- SUT1 SUT1 SUT1 SUT1 SUT1 SUT1 * L4 SUT0 ---- SUT0 SUT0 SUT0 SUT0 SUT0 SUT0 ** L3 CKSEL3 CKSEL3 CKSEL3 CKSEL3 CKSEL33 CKSEL3 CKSEL3 CKSEL3 ** L2 CKSEL2 CKSEL2 CKSEL2 CKSEL2 CKSEL22 CKSEL2 CKSEL2 CKSEL2 ** L1 CKSEL1 CKSEL1 CKSEL1 CKSEL1 CKSEL11 CKSEL1 CKSEL1 CKSEL1 ** L0 CKSEL0 CKSEL0 CKSEL0 CKSEL0 CKSEL00 CKSEL0 CKSEL0 CKSEL0 * * LO7 ---- ---- ---- ----- ------ ----- ----- ----- * LO6 ---- ---- ---- ----- ------ ----- ----- ----- * LO5 LB12 LB12 LB12 BLB12 BBLB12 BLB12 BLB12 BLB12 * LO4 LB11 LB11 LB11 BLB11 BBLB11 BLB11 BLB11 BLB11 * LO3 LB02 LB02 LB02 BLB02 BBLB02 BLB02 BLB02 BLB02 * LO2 LB01 LB01 LB01 BLB01 BBLB01 BLB01 BLB01 BLB01 * LO1 B1 B1 B1 LB1 LLB1 LB1 LB1 LB1 * LO0 B1 B1 B1 LB1 LLB1 LB1 LB1 LB1 * * * Brownout Levels * ATMEGA323 3.5/4.0/4.5 2.4/2.7/3.2 * ATMEGA32 3.6/4.0/4.2 2.5/2.7/2.9 * ATMEGA16 3.6/4.0/4.5 2.5/2.7/3.2 * ATMEGA64 3.7/4.0/4.5 2.4/2.6/2.9 * ATMEAG128 * ATMEGA162 RES RES RES 2.1/2.3/2.5 4.1/4.3/4.5 2.5/2.7/2.9 1.7/1.8/2.0 disabled * ATMEGA169 RES RES reserved reserved 4.1/4.3/4.5 2.5/2.7/2.9 1.7/1.8/2.0 disabled * ATMEGA169A * ATMEGA329 * ATMEGA3290 * ATMEGA649 * ATMEGA6490 * AT90CAN128 2.5 2.6 2.7 3.8 3.9 4.0 4.1 disabled * AT90CAN32 2.5 2.6 2.7 3.8 3.9 4.0 4.1 disabled * AT90CAN64 2.5 2.6 2.7 3.8 3.9 4.0 4.1 disabled * AT90USB1287 4.1/4.3/4.5 3.3/3.5/3.7 3.2/3.4/3.6 2.4/2.6/2.8 reserved reserved reserved disabled */ #define BVAL(v,b) (((1<<(b))&(v))?1:0) void DecodeATMegaFuseBits(void) { gFuseBitsAll.OCDEN = BVAL(gFuseByte[1],7); gFuseBitsAll.JTAGEN = BVAL(gFuseByte[1],6); gFuseBitsAll.SPIEN = BVAL(gFuseByte[1],5); gFuseBitsAll.EESAVE = BVAL(gFuseByte[1],3); gFuseBitsAll.BOOTSIZE = (gFuseByte[1]>>1) & 0x03; gFuseBitsAll.BOOTRST = BVAL(gFuseByte[1],0); gFuseBitsAll.CKSEL = (gFuseByte[0] ) & 0x0f; gLockBitsAll.LB = (gLockByte ) & 0x03; gLockBitsAll.BLB0 = (gLockByte >>2) & 0x03; gLockBitsAll.BLB1 = (gLockByte >>4) & 0x03; switch(gDeviceData.Index) { case ATMEGA16: case ATMEGA32: case ATMEGA323: break; case ATMEGA64: case ATMEGA128: gFuseBitsAll.M103C = BVAL(gFuseByte[2],1); gFuseBitsAll.WDTON = BVAL(gFuseByte[2],0); break; case ATMEGA162: gFuseBitsAll.M161C = BVAL(gFuseByte[2],4); gFuseBitsAll.BODLEVEL = (gFuseByte[2]>>1)&0x07; break; case ATMEGA169: case ATMEGA329: case ATMEGA3290: case ATMEGA649: case ATMEGA6490: gFuseBitsAll.BODLEVEL = (gFuseByte[2]>>1)&0x07; gFuseBitsAll.RESETDIS = BVAL(gFuseByte[2],0); break; case AT90CAN32: case AT90CAN64: case AT90CAN128: gFuseBitsAll.BODLEVEL = (gFuseByte[2]>>1)&0x07; gFuseBitsAll.TA0SEL = BVAL(gFuseByte[2],0); break; case AT90USB1287: gFuseBitsAll.HWBE = BVAL(gFuseByte[2],3); case ATMEGA640: case ATMEGA1280: case ATMEGA1281: case ATMEGA2560: case ATMEGA2561: gFuseBitsAll.BODLEVEL = (gFuseByte[2] )&0x07; break; case UNKNOWN_DEVICE: break; } switch(gDeviceData.Index) { case ATMEGA16: case ATMEGA32: case ATMEGA64: case ATMEGA128: gFuseBitsAll.CKOPT = BVAL(gFuseByte[1],4); gFuseBitsAll.BODLEVEL = BVAL(gFuseByte[0],7); gFuseBitsAll.BODEN = BVAL(gFuseByte[0],6); gFuseBitsAll.SUT = (gFuseByte[0]>>4) & 0x3; break; case ATMEGA323: gFuseBitsAll.BODLEVEL = BVAL(gFuseByte[0],7); gFuseBitsAll.BODEN = BVAL(gFuseByte[0],6); break; case ATMEGA162: case ATMEGA169: case ATMEGA329: case ATMEGA3290: case ATMEGA649: case ATMEGA6490: case AT90CAN32: case AT90CAN64: case AT90CAN128: case AT90USB1287: case ATMEGA640: case ATMEGA1280: case ATMEGA1281: case ATMEGA2560: case ATMEGA2561: gFuseBitsAll.WDTON = BVAL(gFuseByte[1],4); gFuseBitsAll.CKDIV8 = BVAL(gFuseByte[0],7); gFuseBitsAll.CKOUT = BVAL(gFuseByte[0],6); gFuseBitsAll.SUT = (gFuseByte[0]>>4) & 0x3; break; case UNKNOWN_DEVICE: break; } } /* Logical Values are inverted in FLASH */ void EncodeATMegaFuseBits(void) { unsigned char tmp; switch(gDeviceData.Index) { case ATMEGA16: case ATMEGA32: case ATMEGA323: gFuseByte[2]=0xff; break; case ATMEGA64: case ATMEGA128: tmp=0xFC; tmp|=(gFuseBitsAll.M103C<<1); tmp|=(gFuseBitsAll.WDTON<<0); gFuseByte[2]=tmp; break; case ATMEGA162: tmp=0xE1; tmp|=(gFuseBitsAll.M161C << 4); tmp|=(gFuseBitsAll.BODLEVEL << 1); gFuseByte[2]=tmp; break; case ATMEGA169: case ATMEGA329: case ATMEGA3290: case ATMEGA649: case ATMEGA6490: tmp=0xf0; tmp|=(gFuseBitsAll.BODLEVEL << 1); tmp|=(gFuseBitsAll.RESETDIS ); gFuseByte[2]=tmp; break; case AT90CAN32: case AT90CAN64: case AT90CAN128: tmp=0xFC; tmp|=(gFuseBitsAll.M103C<<1); tmp|=(gFuseBitsAll.WDTON<<0); gFuseByte[2]=tmp; break; case AT90USB1287: tmp=0xf4; tmp &= ~(gFuseBitsAll.HWBE << 3); case ATMEGA640: case ATMEGA1280: case ATMEGA1281: case ATMEGA2560: case ATMEGA2561: tmp|=(gFuseBitsAll.BODLEVEL ); gFuseByte[2]=tmp; break; case UNKNOWN_DEVICE: break; } tmp = (gFuseBitsAll.OCDEN << 7); tmp |= (gFuseBitsAll.JTAGEN << 6); tmp |= (gFuseBitsAll.SPIEN << 5); tmp |= (gFuseBitsAll.WDTON << 4); tmp |= (gFuseBitsAll.EESAVE << 3); tmp |= (gFuseBitsAll.BOOTRST <<0); tmp |= (gFuseBitsAll.BOOTSIZE <<1); switch(gDeviceData.Index) { case ATMEGA16: case ATMEGA32: case ATMEGA64: case ATMEGA128: tmp &= 0xef; tmp |= (gFuseBitsAll.CKOPT <<4); break; case ATMEGA323: tmp &= 0xef; break; case ATMEGA162: case ATMEGA169: case AT90CAN128: case AT90USB1287: case ATMEGA640: case ATMEGA1280: case ATMEGA1281: case ATMEGA2560: case ATMEGA2561: case AT90CAN32: case AT90CAN64: case ATMEGA329: case ATMEGA3290: case ATMEGA649: case ATMEGA6490: case UNKNOWN_DEVICE: break; } gFuseByte[1]=tmp; tmp = gFuseBitsAll.CKSEL; switch(gDeviceData.Index) { case ATMEGA16: case ATMEGA32: case ATMEGA64: case ATMEGA128: tmp |= gFuseBitsAll.SUT <<4; case ATMEGA323: tmp |= gFuseBitsAll.BODLEVEL <<7; tmp |= gFuseBitsAll.BODEN <<6; break; default: tmp |= gFuseBitsAll.CKDIV8 <<7; tmp |= gFuseBitsAll.CKOUT <<6; tmp |= gFuseBitsAll.SUT <<4; } gFuseByte[0]=tmp; tmp=0xC0; tmp|=gLockBitsAll.LB; tmp|=(gLockBitsAll.BLB0<<2); tmp|=(gLockBitsAll.BLB1<<4); gLockByte=tmp; } void DisplayATMegaFuseData(void) { unsigned char tmp; uint32_t bootsize; double bod_val= 0.0; printf("Fuse Bits: 0=\"Programmed\" => True\n"); switch(gDeviceData.Index) { case ATMEGA64: case ATMEGA323: case ATMEGA32: case ATMEGA16: case UNKNOWN_DEVICE: break; case ATMEGA128: case ATMEGA162: case ATMEGA169: case ATMEGA329: case ATMEGA3290: case ATMEGA649: case ATMEGA6490: case AT90CAN32: case AT90CAN64: case AT90CAN128: case AT90USB1287: case ATMEGA640: case ATMEGA1280: case ATMEGA1281: case ATMEGA2560: case ATMEGA2561: printf("Extended Fuse Byte: 0x%2.2X ",gFuseByte[2]); } printf("High Fuse Byte: 0x%2.2X ",gFuseByte[1]); printf("Low Fuse Byte: 0x%2.2X\n",gFuseByte[0]); tmp=gFuseBitsAll.CKSEL; switch(gDeviceData.Index) { case UNKNOWN_DEVICE: break; case ATMEGA128: case ATMEGA16: case ATMEGA32: tmp|=(gFuseBitsAll.CKOPT<<4); printf("CKSEL: %X CKOPT: %d %s\n",gFuseBitsAll.CKSEL,gFuseBitsAll.CKOPT,gCKSEL_Data[tmp]); break; case ATMEGA323: printf("CKSEL: %X %s \n",gFuseBitsAll.CKSEL,gCKSEL_Data1[tmp]); break; default: printf("CKSEL: %X %s%s\n",gFuseBitsAll.CKSEL,gCKSEL_Data1[tmp], (gFuseBitsAll.CKDIV8)?"":" divided by 8"); } switch(gDeviceData.Index) { case ATMEGA32: break; default: printf("SUT: %X ",gFuseBitsAll.SUT); DisplayATMegaStartUpTime(); printf("\n"); } bootsize = 256<<((~gFuseBitsAll.BOOTSIZE & 3) + gDeviceData.bootsize); switch(gDeviceData.Index) { case ATMEGA128: case ATMEGA64: printf("M103C : %d (%s)\n",gFuseBitsAll.M103C ,gTF[gFuseBitsAll.M103C]); printf("WDTON : %d (%s)\n",gFuseBitsAll.WDTON ,gTF[gFuseBitsAll.WDTON]); break; case ATMEGA323: case ATMEGA16: case ATMEGA32: break; case ATMEGA162: printf("M61C : %d (%s)\n",gFuseBitsAll.M161C ,gTF[gFuseBitsAll.M161C]); printf("BODLEVEL: %d\n",gFuseBitsAll.BODLEVEL); break; case ATMEGA169: case ATMEGA329: case ATMEGA3290: case ATMEGA649: case ATMEGA6490: printf("BODLEVEL: %d\n",gFuseBitsAll.BODLEVEL); printf("RESETDIS: %d (%s)\n",gFuseBitsAll.RESETDIS,gTF[gFuseBitsAll.RESETDIS]); break; case AT90CAN32: case AT90CAN64: case AT90CAN128: printf("BODLEVEL: %d\n",gFuseBitsAll.BODLEVEL); printf("TA0SEL: %d (%s)\n",gFuseBitsAll.TA0SEL ,gTF[gFuseBitsAll.TA0SEL]); break; case AT90USB1287: printf("HWBE : %d (%s)\n",gFuseBitsAll.HWBE ,gTF[gFuseBitsAll.HWBE ]); case ATMEGA640: case ATMEGA1280: case ATMEGA1281: case ATMEGA2560: case ATMEGA2561: printf("BODLEVEL: %d\n",gFuseBitsAll.BODLEVEL); break; case UNKNOWN_DEVICE: break; } switch(gDeviceData.Index) { case ATMEGA64: case ATMEGA128: case ATMEGA16: case ATMEGA32: case ATMEGA323: printf("OCDEN : %d (%s)\n",gFuseBitsAll.OCDEN ,gTF[gFuseBitsAll.OCDEN]); printf("JTAGEN : %d (%s)\n",gFuseBitsAll.JTAGEN ,gTF[gFuseBitsAll.JTAGEN]); printf("SPIEN : %d (%s)\n",gFuseBitsAll.SPIEN ,gTF[gFuseBitsAll.SPIEN]); printf("WDTON : %d (%s)\n",gFuseBitsAll.WDTON ,gTF[gFuseBitsAll.WDTON]); printf("EESAVE : %d (%s)\n",gFuseBitsAll.EESAVE ,gTF[gFuseBitsAll.EESAVE]); printf("BOOTSIZE: %X Size: %d Bytes", gFuseBitsAll.BOOTSIZE, bootsize); if (bootsize) printf(" Start:0x%5.5lX\n", gDeviceData.flash - bootsize); else printf("\n"); printf("BOOTRST : %d (%s)\n",gFuseBitsAll.BOOTRST ,gTF[gFuseBitsAll.BOOTRST]); break; case ATMEGA162: case ATMEGA169: case ATMEGA329: case ATMEGA3290: case ATMEGA649: case ATMEGA6490: case AT90CAN32: case AT90CAN64: case AT90CAN128: case AT90USB1287: case ATMEGA640: case ATMEGA1280: case ATMEGA1281: case ATMEGA2560: case ATMEGA2561: printf("OCDEN : %d (%s)\n",gFuseBitsAll.OCDEN ,gTF[gFuseBitsAll.OCDEN]); printf("JTAGEN : %d (%s)\n",gFuseBitsAll.JTAGEN ,gTF[gFuseBitsAll.JTAGEN]); printf("SPIEN : %d (%s)\n",gFuseBitsAll.SPIEN ,gTF[gFuseBitsAll.SPIEN]); printf("WDTON : %d (%s)\n",gFuseBitsAll.WDTON ,gTF[gFuseBitsAll.WDTON]); printf("EESAVE : %d (%s)\n",gFuseBitsAll.EESAVE ,gTF[gFuseBitsAll.EESAVE]); printf("BOOTSIZE: %X Size: %d Bytes", gFuseBitsAll.BOOTSIZE, bootsize); if (bootsize) printf(" Start:0x%5.5lX\n", gDeviceData.flash - bootsize); else printf("\n"); printf("BOOTRST : %d (%s)\n",gFuseBitsAll.BOOTRST ,gTF[gFuseBitsAll.BOOTRST]); printf("CKDIV8 : %d (%s)\n",gFuseBitsAll.CKDIV8 ,gTF[gFuseBitsAll.CKDIV8]); printf("CKOUT : %d (%s)\n",gFuseBitsAll.CKOUT ,gTF[gFuseBitsAll.CKOUT]); break; case UNKNOWN_DEVICE: break; } switch(gDeviceData.Index) { case ATMEGA323: case ATMEGA16: case ATMEGA32: case ATMEGA64: case ATMEGA128: bod_val = (gFuseBitsAll.BODEN)?((gFuseBitsAll.BODLEVEL)?4.0:2.7):0.0; break; case AT90CAN32: case AT90CAN64: case AT90CAN128: switch (gFuseBitsAll.BODLEVEL) { case 0 : bod_val = 2.5; break; case 1 : bod_val = 2.6; break; case 2 : bod_val = 2.7; break; case 3 : bod_val = 3.8; break; case 4 : bod_val = 3.9; break; case 5 : bod_val = 4.0; break; case 6 : bod_val = 4.1; break; case 7 : bod_val = 0.0; break; } break; case AT90USB1287: switch (gFuseBitsAll.BODLEVEL) { case 0 : bod_val = 4.3; break; case 1 : bod_val = 3.5; break; case 2 : bod_val = 3.4; break; case 3 : bod_val = 2.6; break; case 7 : bod_val = 0.0; break; default: bod_val = 1000; } break; case ATMEGA162: switch (gFuseBitsAll.BODLEVEL) { case 3 : bod_val = 2.3; break; case 4 : bod_val = 4.3; break; case 5 : bod_val = 2.7; break; case 6 : bod_val = 1.8; break; case 7 : bod_val = 0.0; break; default: bod_val = 1000; } break; case ATMEGA640: case ATMEGA1280: case ATMEGA1281: case ATMEGA2560: case ATMEGA2561: case ATMEGA169: case ATMEGA329: case ATMEGA3290: case ATMEGA649: case ATMEGA6490: switch (gFuseBitsAll.BODLEVEL) { case 4 : bod_val = 4.3; break; case 5 : bod_val = 2.7; break; case 6 : bod_val = 1.8; break; case 7 : bod_val = 0.0; break; default: bod_val = 1000; } case UNKNOWN_DEVICE: break; } if (bod_val > 0.01) { if (bod_val > 100) printf("Reserved Brownout Threshold\n"); else printf("Brownout Threshold %1.1f Volt\n", bod_val); } else printf("Brownout Disabled\n"); printf("Lock Byte: 0x%2.2X \n",gLockByte); printf("BLB0 : %d\n",gLockBitsAll.BLB0); printf("BLB1 : %d\n",gLockBitsAll.BLB1); printf("LB : %d\n",gLockBitsAll.LB); } void DisplayATMegaStartUpTime(void) { unsigned char tmp; switch(gFuseBitsAll.CKSEL) { case 0: /* External Clock */ printf("None"); break; case 1: /* Int RC */ case 2: case 3: case 4: printf("%s",gSUT_IntRC[gFuseBitsAll.SUT]); break; case 5: /* Ext RC */ case 6: case 7: case 8: printf("%s",gSUT_ExtRC[gFuseBitsAll.SUT]); break; case 9: /* Low Freq Crystal */ printf("%s",gSUT_LowXtal[gFuseBitsAll.SUT]); break; default: /* Crystal */ tmp=gFuseBitsAll.CKSEL&0x01; tmp<<=2; tmp|=gFuseBitsAll.SUT; printf("%s",gSUT_Xtal[tmp]); break; } } void ReadATMegaFuse(void) { Send_Instruction(4,PROG_COMMANDS); Send_AVR_Prog_Command(0x2304); Send_AVR_Prog_Command(0x3A00); switch(gDeviceData.Index) { case ATMEGA323: case ATMEGA32: case ATMEGA64: break; default: gFuseByte[2]=(unsigned char)Send_AVR_Prog_Command(0x3E00); /* Ext Fuse Byte */ } gFuseByte[1]=(unsigned char)Send_AVR_Prog_Command(0x3200); /* High Fuse Byte */ gFuseByte[0]=(unsigned char)Send_AVR_Prog_Command(0x3600); /* Low Fuse Byte */ gLockByte=(unsigned char)Send_AVR_Prog_Command(0x3700); DecodeATMegaFuseBits(); } void WriteATMegaFuse(void) { unsigned short tmp; unsigned long timeout; #ifdef NO_JTAG_DISABLE if(gFuseBitsAll.JTAGEN) { gFuseBitsAll.JTAGEN=0; /* Force JTAGEN */ gFuseByte[1]&=~(1<<6); /* Force Bit Low */ } #endif Send_Instruction(4,PROG_COMMANDS); Send_AVR_Prog_Command(0x2340); /* Enter Fuse Write */ switch(gDeviceData.Index) { case ATMEGA323: case ATMEGA32: case ATMEGA64: break; default: tmp=0x1300; tmp|=gFuseByte[2]; Send_AVR_Prog_Command(tmp); Send_AVR_Prog_Command(0x3B00); /* Write Extended Fuse Byte */ Send_AVR_Prog_Command(0x3900); Send_AVR_Prog_Command(0x3B00); Send_AVR_Prog_Command(0x3B00); timeout=1000; do { tmp=Send_AVR_Prog_Command(0x3B00); tmp&=0x0200; timeout--; if(!timeout) { printf("\nProblem Writing Fuse Extended Byte!!!\n"); return; } }while(!tmp); printf("\nFuse Extended Byte Written"); } tmp=0x1300; tmp|=gFuseByte[1]; Send_AVR_Prog_Command(tmp); Send_AVR_Prog_Command(0x3700); /* Write Fuse High Byte */ Send_AVR_Prog_Command(0x3500); Send_AVR_Prog_Command(0x3700); Send_AVR_Prog_Command(0x3700); timeout=1000; do { tmp=Send_AVR_Prog_Command(0x3700); tmp&=0x0200; timeout--; if(!timeout) { printf("\nProblem Writing Fuse High Byte!!!\n"); return; } }while(!tmp); printf("\nFuse High Byte Written"); tmp=0x1300; tmp|=gFuseByte[0]; Send_AVR_Prog_Command(tmp); Send_AVR_Prog_Command(0x3300); /* Write Fuse Low Byte */ Send_AVR_Prog_Command(0x3100); Send_AVR_Prog_Command(0x3300); Send_AVR_Prog_Command(0x3300); timeout=1000; do { tmp=Send_AVR_Prog_Command(0x3300); tmp&=0x0200; timeout--; if(!timeout) { printf("\nProblem Writing Fuse Low Byte!!!\n"); return; } }while(!tmp); printf("\nFuse Low Byte Written\n"); } #if 1 #define EOLINE "\n" #else #define EOLINE "\n" #endif void WriteATMegaFuseFile(char *name) { FILE *fp; fp=fopen(name,"wb"); if(!fp) { fprintf(stderr,"\nCould open write file %s\n",name); return; } fprintf(fp,";%s Fuse Bit definitions" EOLINE,gDeviceData.name); fprintf(fp,";0 => Programmed, 1 => Not Programmed" EOLINE); fprintf(fp,";"); switch(gDeviceData.Index) { case ATMEGA323: case ATMEGA32: case ATMEGA64: break; default: fprintf(fp,"Ext 0x%02x ", gFuseByte[2]); } fprintf(fp,"High 0x%02x Low 0x%02x Lock 0x%02x" EOLINE, gFuseByte[1], gFuseByte[0], gLockByte); switch(gDeviceData.Index) { case ATMEGA64: case ATMEGA128: fprintf(fp,"M103C: %d" EOLINE,gFuseBitsAll.M103C); fprintf(fp,"WDTON: %d" EOLINE,gFuseBitsAll.WDTON); case ATMEGA16: case ATMEGA32: fprintf(fp,"SUT: %d" EOLINE,gFuseBitsAll.SUT); fprintf(fp,"CKOPT: %d" EOLINE,gFuseBitsAll.CKOPT); case ATMEGA323: fprintf(fp,"OCDEN: %d" EOLINE,gFuseBitsAll.OCDEN); fprintf(fp,"JTAGEN: %d" EOLINE,gFuseBitsAll.JTAGEN); fprintf(fp,"SPIEN: %d" EOLINE,gFuseBitsAll.SPIEN); fprintf(fp,"EESAVE: %d" EOLINE,gFuseBitsAll.EESAVE); fprintf(fp,"BOOTSIZE: %d" EOLINE,gFuseBitsAll.BOOTSIZE); fprintf(fp,"BOOTRST: %d" EOLINE,gFuseBitsAll.BOOTRST); fprintf(fp,"BODLEVEL: 0x%X" EOLINE,gFuseBitsAll.BODLEVEL); fprintf(fp,"BODEN: %d" EOLINE,gFuseBitsAll.BODEN); fprintf(fp,"CKSEL: 0x%X" EOLINE,gFuseBitsAll.CKSEL); break; case ATMEGA162: fprintf(fp,"M161C: %d" EOLINE,gFuseBitsAll.M161C); fprintf(fp,"BODLEVEL: 0x%X" EOLINE,gFuseBitsAll.BODLEVEL); fprintf(fp,"OCDEN: %d" EOLINE,gFuseBitsAll.OCDEN); fprintf(fp,"JTAGEN: %d" EOLINE,gFuseBitsAll.JTAGEN); fprintf(fp,"SPIEN: %d" EOLINE,gFuseBitsAll.SPIEN); fprintf(fp,"WDTON: %d" EOLINE,gFuseBitsAll.WDTON); fprintf(fp,"EESAVE: %d" EOLINE,gFuseBitsAll.EESAVE); fprintf(fp,"BOOTSIZE: %d" EOLINE,gFuseBitsAll.BOOTSIZE); fprintf(fp,"BOOTRST: %d" EOLINE,gFuseBitsAll.BOOTRST); fprintf(fp,"CKDIV8: %d" EOLINE,gFuseBitsAll.CKDIV8); fprintf(fp,"CKOUT: %d" EOLINE,gFuseBitsAll.CKOUT); fprintf(fp,"SUT: %d" EOLINE,gFuseBitsAll.SUT); fprintf(fp,"CKSEL: 0x%X" EOLINE,gFuseBitsAll.CKSEL); break; case ATMEGA169: case ATMEGA329: case ATMEGA3290: case ATMEGA649: case ATMEGA6490: fprintf(fp,"BODLEVEL: 0x%X" EOLINE,gFuseBitsAll.BODLEVEL); fprintf(fp,"RESETDIS: 0x%X" EOLINE,gFuseBitsAll.RESETDIS); fprintf(fp,"OCDEN: %d" EOLINE,gFuseBitsAll.OCDEN); fprintf(fp,"JTAGEN: %d" EOLINE,gFuseBitsAll.JTAGEN); fprintf(fp,"SPIEN: %d" EOLINE,gFuseBitsAll.SPIEN); fprintf(fp,"WDTON: %d" EOLINE,gFuseBitsAll.WDTON); fprintf(fp,"EESAVE: %d" EOLINE,gFuseBitsAll.EESAVE); fprintf(fp,"BOOTSIZE: %d" EOLINE,gFuseBitsAll.BOOTSIZE); fprintf(fp,"BOOTRST: %d" EOLINE,gFuseBitsAll.BOOTRST); fprintf(fp,"CKDIV8: %d" EOLINE,gFuseBitsAll.CKDIV8); fprintf(fp,"CKOUT: %d" EOLINE,gFuseBitsAll.CKOUT); fprintf(fp,"SUT: %d" EOLINE,gFuseBitsAll.SUT); fprintf(fp,"CKSEL: 0x%X" EOLINE,gFuseBitsAll.CKSEL); fprintf(fp,"CKSEL: 0x%X" EOLINE,gFuseBitsAll.CKSEL); break; case AT90CAN32: case AT90CAN64: case AT90CAN128: fprintf(fp,"BODLEVEL: 0x%X" EOLINE,gFuseBitsAll.BODLEVEL); fprintf(fp,"TA0SEL: 0x%X" EOLINE,gFuseBitsAll.TA0SEL); fprintf(fp,"OCDEN: %d" EOLINE,gFuseBitsAll.OCDEN); fprintf(fp,"JTAGEN: %d" EOLINE,gFuseBitsAll.JTAGEN); fprintf(fp,"SPIEN: %d" EOLINE,gFuseBitsAll.SPIEN); fprintf(fp,"WDTON: %d" EOLINE,gFuseBitsAll.WDTON); fprintf(fp,"EESAVE: %d" EOLINE,gFuseBitsAll.EESAVE); fprintf(fp,"BOOTSIZE: %d" EOLINE,gFuseBitsAll.BOOTSIZE); fprintf(fp,"BOOTRST: %d" EOLINE,gFuseBitsAll.BOOTRST); fprintf(fp,"CKDIV8: %d" EOLINE,gFuseBitsAll.CKDIV8); fprintf(fp,"CKOUT: %d" EOLINE,gFuseBitsAll.CKOUT); fprintf(fp,"SUT: %d" EOLINE,gFuseBitsAll.SUT); fprintf(fp,"CKSEL: 0x%X" EOLINE,gFuseBitsAll.CKSEL); fprintf(fp,"CKSEL: 0x%X" EOLINE,gFuseBitsAll.CKSEL); break; case AT90USB1287: fprintf(fp,"HWBE: 0x%X" EOLINE,gFuseBitsAll.HWBE); case ATMEGA640: case ATMEGA1280: case ATMEGA1281: case ATMEGA2560: case ATMEGA2561: fprintf(fp,"BODLEVEL: 0x%X" EOLINE,gFuseBitsAll.BODLEVEL); fprintf(fp,"OCDEN: %d" EOLINE,gFuseBitsAll.OCDEN); fprintf(fp,"JTAGEN: %d" EOLINE,gFuseBitsAll.JTAGEN); fprintf(fp,"SPIEN: %d" EOLINE,gFuseBitsAll.SPIEN); fprintf(fp,"WDTON: %d" EOLINE,gFuseBitsAll.WDTON); fprintf(fp,"EESAVE: %d" EOLINE,gFuseBitsAll.EESAVE); fprintf(fp,"BOOTSIZE: %d" EOLINE,gFuseBitsAll.BOOTSIZE); fprintf(fp,"BOOTRST: %d" EOLINE,gFuseBitsAll.BOOTRST); fprintf(fp,"CKDIV8: %d" EOLINE,gFuseBitsAll.CKDIV8); fprintf(fp,"CKOUT: %d" EOLINE,gFuseBitsAll.CKOUT); fprintf(fp,"SUT: %d" EOLINE,gFuseBitsAll.SUT); fprintf(fp,"CKSEL: 0x%X" EOLINE,gFuseBitsAll.CKSEL); fprintf(fp,"CKSEL: 0x%X" EOLINE,gFuseBitsAll.CKSEL); break; case UNKNOWN_DEVICE: break; } fprintf(fp,"; Lock Bit definitions (Need -L command line option to write)" EOLINE); fprintf(fp,"BLB1: %d" EOLINE,gLockBitsAll.BLB1); fprintf(fp,"BLB0: %d" EOLINE,gLockBitsAll.BLB0); fprintf(fp,"LB: %d" EOLINE,gLockBitsAll.LB); fclose(fp); } void SetATMegaFuseDefault(void) { gFuseByte[0]=0xE1; gFuseByte[1]=0x99; gFuseByte[2]=0xFD; gLockByte=0xFF; DecodeATMegaFuseBits(); } void WriteATMegaLock(void) { unsigned short tmp; unsigned long timeout; if(gLockByteUpdated) /* Only Write Lock Bits if defined in Fuse File */ { Send_Instruction(4,PROG_COMMANDS); Send_AVR_Prog_Command(0x2320); /* Enter Lock Write */ tmp=0x13C0; tmp|=gLockByte; printf("Lockbits: %2.2X\n",gLockByte); Send_AVR_Prog_Command(tmp); Send_AVR_Prog_Command(0x3300); /* Write Fuse High Byte */ Send_AVR_Prog_Command(0x3100); Send_AVR_Prog_Command(0x3300); Send_AVR_Prog_Command(0x3300); timeout=1000; do { tmp=Send_AVR_Prog_Command(0x3300); tmp&=0x0200; timeout--; if(!timeout) { printf("\nProblem Writing Lock Bits!!!\n"); return; } }while(!tmp); printf("\nLock Bits Written"); } } xc3sprog-0+svn795+dfsg/javr/fuse.h000066400000000000000000000227371337255630200170470ustar00rootroot00000000000000/*************************************************************************\ * Copyright (C) <2001> * antone@sentechsa.com * * 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 * \*************************************************************************/ /********************************************************************\ * Common Fuse Definitions for AVR ATMega Devices * * $Id: fuse.h,v 1.4 2005/03/23 21:03:49 anton Exp $ * $Log: fuse.h,v $ * Revision 1.4 2005/03/23 21:03:49 anton * Added GPL License to source files * * Revision 1.3 2005/03/23 20:16:12 anton * Updates by Uwe Bonnes to add support for AT90CAN128 * * Revision 1.2 2003/09/27 19:21:59 anton * Added support for Linux compile * * Revision 1.1.1.1 2003/09/24 15:35:57 anton * Initial import into CVS * \********************************************************************/ typedef struct { /* |128|32|323|16 |162|169|CAN128|USB128 */ unsigned M103C:1; /* ATMega103 Compatibility Mode | x | | | | | | | */ unsigned M161C:1; /* ATMeag161 Compatibility Mode | | | | | x| | | */ unsigned WDTON:1; /* Watchdog Always on | x | | | | x| x | x | x */ unsigned OCDEN:1; /* Enable On Chip Debug | x | x| x | x | x| x | x | x */ unsigned JTAGEN:1; /* JTAG Enable | x | x| x | x | x| x | x | x */ unsigned SPIEN:1; /* Serial Programming Enable | x | x| x | x | x| x | x | x */ unsigned CKOPT:1; /* Oscillator options | x | x| | x | x| x | x | x */ unsigned EESAVE:1; /* Preserve EEPROM during chip Erase | x | x| x | x | x| x | x | x */ unsigned BOOTSIZE:2; /* Depends on Device | x | x| x | x | x| x | x | x */ unsigned BOOTRST:1; /* Enable Booting from Bootblock | x | x| x | x | x| x | x | x */ unsigned BODLEVEL:3; /* BOD Level | x | x| x | x | x| x | x | x */ unsigned BODEN:1; /* Brownout Detector Enable | x | x| x | x | x| x | | */ unsigned SUT:2; /* Start Up Time | x | x| | x | x| x | x | x */ unsigned CKSEL:4; /* Clock Select | x | x| x | x | x| x | x | x */ unsigned CKDIV8:1; /* Divide clock by 8 | | | | | x| x | x | x */ unsigned CKOUT:1; /* Clock Output | | | | | x| x | x | x */ unsigned TA0SEL:1; /* (Reserved for factory tests) | | | | | | | x | */ unsigned HWBE:1; /* Hardware Boot Enable | | | | | | | | x */ unsigned RESETDIS:1; /* Disable Hardware Reset | | | | | | x | | */ }FUSE_BITS_ALL; typedef struct { unsigned LB:2; /* Lock Bits */ unsigned BLB0:2; unsigned BLB1:2; }LOCK_BITS_ALL; #ifdef FUSE_M /* CKOPT, CKSEL3..0 */ const char *gCKSEL_Data[]={ /* 00000 */ "External Clock - 36p Capacitor Switched in", /* 00001 */ "Internal RC Clock (Invalid CKOPT should not be programmed)", /* 00010 */ "Internal RC Clock (Invalid CKOPT should not be programmed)", /* 00011 */ "Internal RC Clock (Invalid CKOPT should not be programmed)", /* 00100 */ "Internal RC Clock (Invalid CKOPT should not be programmed)", /* 00101 */ "External RC Clock - 36p Capacitor Switched in (-0.9 MHz)", /* 00110 */ "External RC Clock - 36p Capacitor Switched in (0.9-3 MHz)", /* 00111 */ "External RC Clock - 36p Capacitor Switched in (3-8 MHz)", /* 01000 */ "External RC Clock - 36p Capacitor Switched in (8-12 MHz)", /* 01001 */ "Extenal Low Freq Crystal - 36p Capcitors switched in", /* 01010 */ "External Crystal (1 - 16MHz)", /* 01011 */ "External Crystal (1 - 16MHz)", /* 01100 */ "External Crystal (1 - 16MHz)", /* 01101 */ "External Crystal (1 - 16MHz)", /* 01110 */ "External Crystal (1 - 16MHz)", /* 01111 */ "External Crystal (1 - 16MHz)", /* 10000 */ "External Clock", /* 10001 */ "Internal RC Clock (1 MHz Nominal)", /* 10010 */ "Internal RC Clock (2 MHz Nominal)", /* 10011 */ "Internal RC Clock (4 MHz Nominal)", /* 10100 */ "Internal RC Clock (8 MHz Nominal)", /* 10101 */ "External RC Clock (-0.9 MHz)", /* 10110 */ "External RC Clock (0.9-3 MHz)", /* 10111 */ "External RC Clock (3-8 MHz)", /* 11000 */ "External RC Clock (8-12 MHz)", /* 11001 */ "Extenal Low Freq Crystal", /* 11010 */ "External Crystal (0.4 - 0.9MHz)", /* 11011 */ "External Crystal (0.4 - 0.9MHz)", /* 11100 */ "External Crystal (0.9 - 3.0MHz)", /* 11101 */ "External Crystal (0.9 - 3.0MHz)", /* 11110 */ "External Crystal (3.0 - 8MHz)", /* 11111 */ "External Crystal (3.0 - 8MHz)" }; const char *gCKSEL_Data1[]={ /* 00000 */ "External Clock", /* 00001 */ "Reserved", /* 00010 */ "Internal 8 MHz RC Clock", /* 00011 */ "Reserved", /* 00100 */ "External LF Crystal 1K CK", /* 00101 */ "External LF Crystal 32 CK", /* 00110 */ "External LF Crystal 1K CK", /* 00111 */ "External LF Crystal 32 CK", /* 01000 */ "External Ceramic Resonator(0.4 - 0.9 MHz)", /* 01001 */ "External Ceramic Resonator(0.4 - 0.9 MHz)", /* 01010 */ "External Crystal (0.9 - 3MHz)", /* 01011 */ "External Crystal (0.9 - 3MHz)", /* 01100 */ "External Crystal (3 - 8MHz)", /* 01101 */ "External Crystal (3 - 8MHz)", /* 01110 */ "External Crystal (8 - 16MHz)", /* 01111 */ "External Crystal (8 - 16MHz)" }; const char *gTF[]={"True","False"}; /* CKSEL0, SUT1..0 */ const char *gSUT_Xtal[]={ "258CK + 4ms (Reset) Ceramic Resonator, fast rising power", "258CK + 64ms (Reset) Ceramic Resonator, slow rising power", "1K CK Ceramic Resonator, BOD enabled", "1K CK + 4ms (Reset) Ceramic Resonator, fast rising power", "1K CK + 64ms (Reset) Ceramic Resonator, slow rising power", "16K CK Crystal, BOD enabled", "16K CK + 4ms (Reset), Crystal, fast rising power", "16K CK + 64ms (Reset), Crystal, slow rising power" }; /* SUT1..0 */ const char *gSUT_LowXtal[]={ "1K CK + 4ms (Reset) fast rising power or BOD Enabled", "1K CK + 64ms (Reset), slow rising power", "32K CK + 64ms (Reset), stable frequency at start-up", "Reserved" }; /* SUT1..0 */ const char *gSUT_ExtRC[]={ "18 CK, BOD Enabled", "18 CK + 4ms (Reset), Fast rising power", "18 CK + 64ms (Reset), Slow rising power", "6 CK + 4ms (Reset), Fast rising power or BOD Enabled" }; /* SUT1..0 */ const char *gSUT_IntRC[]={ "6 CK, BOD Enabled", "6 CK + 4ms (Reset), Fast rising power", "6 CK + 64ms (Reset), Slow rising power", "Reserved" }; unsigned char gFuseByte[3]; unsigned char gLockByte,gLockByteUpdated; FUSE_BITS_ALL gFuseBitsAll; LOCK_BITS_ALL gLockBitsAll; #else extern const char *gCKSEL_Data[]; extern const char *gTF[]; extern const char *gSUT_Xtal[]; extern const char *gSUT_LowXtal[]; extern const char *gSUT_ExtRC[]; extern const char *gSUT_IntRC[]; extern unsigned char gFuseByte[3]; extern unsigned char gLockByte,gLockByteUpdated; extern FUSE_BITS_ALL gFuseBitsAll; extern LOCK_BITS_ALL gLockBitsAll; #endif void DecodeATMegaFuseBits(void); void EncodeATMegaFuseBits(void); void DisplayATMegaFuseData(void); void DisplayATMegaStartUpTime(void); void ReadATMegaFuse(void); void WriteATMegaFuse(void); void WriteATMegaFuseFile(char *name); void SetATMegaFuseDefault(void); void WriteATMegaLock(void); xc3sprog-0+svn795+dfsg/javr/javr.cpp000066400000000000000000000276201337255630200173760ustar00rootroot00000000000000/********************************************************************\ * Commandline utility to program AVR ATmegas with JTAG interface * * $Id: javr.c,v 1.6 2003/09/28 14:31:04 anton Exp $ * $Log: javr.c,v $ * Revision 1.6 2003/09/28 14:31:04 anton * Added --help command, display GPL * * Revision 1.5 2003/09/28 12:44:15 anton * Updated Verify to show progress '.' * * Revision 1.3 2003/09/27 19:21:59 anton * Added support for Linux compile * * Revision 1.2 2003/09/24 20:18:08 anton * Added Verify option - Not tested yet * * Revision 1.1.1.1 2003/09/24 15:35:57 anton * Initial import into CVS * \********************************************************************/ #include "compiler.h" #include #include #include #include #include #include "srecdec.h" #include "fuse.h" #include "avr_jtag.h" #include "parse.h" #include "menu.h" #include "debug.h" #include "io_exception.h" #include "ioparport.h" #include "ioftdi.h" #include "iofx2.h" #include "ioxpc.h" #include "jtag_javr.h" #include "devicedb.h" #include "utilities.h" #include "jtag.h" #define USBDESCRIPTION "USB2CUST" #define PPDEV "/dev/parport0" #define DEVICEDB "/usr/local/share/XC3Sprog/devlist.txt" #define JAVR_M #include "javr.h" #undef JAVR_M void usage() { fprintf(stderr, "\nUsage: javr [-v] [-c cable_type] [-p chainpos] [-L ] [-e eepromfile] [-f fusefile] [romfile]\n" " -?\t\tprint this help\n" " -v\t\tverbose output\n" " -j\t\tDetect JTAG chain, nothing else\n" " -T[val]\tTest chain integrity val times (0 = forever) or 10000 times default\n" " -J[val]\tRun at max with given JTAG Frequency, 0(default) means max. Rate of device\n" " \tOnly used for FTDI cables for now\n\n" " -C\t\tVerify device against File (no programming)\n" " Supported cable types: pp, ftdi, fx2, xpc\n" " \tOptional pp arguments:\n" " \t\t[-d device] (e.g. /dev/parport0)\n" " \tOptional fx2/ftdi arguments:\n" " \t\t[-s serial] (SerialNumber string)\n" " \tOptional ftdi arguments:\n" " \t\t[-t subtype]\n" " \t\t[-t subtype]\n" " \t\t\t(NONE\t\t(0x0403:0x0610) or\n" " \t\t\t IKDA\t\t(0x0403:0x0610, EN_N on ACBUS2/ACBUS7/ACBUS8) or\n" " \t\t\t OLIMEX\t\t(0x15b1:0x0003, JTAG_EN_N on ADBUS4, LED on ACBUS3)) or\n" " \t\t\t AMONTEC\t(0x0403:0xcff8, JTAG_EN_N on ADBUS4)\n" " \tOptional xpc arguments:\n" " \t\t[-t subtype] (NONE or INT (Internal Chain on XPC, doesn't work for now on DLC10))\n" " chainpos\n" "\tPosition in JTAG chain: 0 - closest to TDI (default)\n\n" "\t[-l ] (Program Lockbits if defined in fusefile)\n" "\t[-e eepromfile]\n" "\t[-f fusefile] (default extension: .fus; leave fuses untouched if no file found)\n" "Enter menu if no ROM file given\n" "\n" "\n"); exit(255); } extern char *optarg; extern int optind; SrecRd gEepromInfo; SrecRd gSourceInfo; int main(int argc, char **args) { unsigned long tmp; bool verbose = false; bool use_ftd2xx = false; bool gLockOption = false; bool gDisplayMenu = false; bool gVerifyOption = false; bool gProgramFlash = false; bool gProgramEeprom = false; bool gProgramFuseBits = false; unsigned int jtag_freq; struct cable_t cable; char const *dev = 0; char const *eepromfile= 0; static char DefName[256]; int chainpos = 0; char const *serial = 0; char *devicedb = NULL; const char *cablename; DeviceDB db(devicedb); std::auto_ptr io; int res; gFuseName = 0; // Start from parsing command line arguments while(true) { switch(getopt(argc, args, "?hJ:Lc:Cd:e:f:jp:s:v")) { case -1: goto args_done; case 'v': verbose = true; break; case 'l': gLockOption = true; break; case 'J': jtag_freq = atoi(optarg); break; case 'L': use_ftd2xx = true; break; case 'C': gVerifyOption = true; break; case 'c': cablename = optarg; break; case 'e': eepromfile = optarg; break; case 'f': gFuseName = optarg; break; case 'd': dev = optarg; break; case 'p': chainpos = atoi(optarg); break; case 's': serial = optarg; break; case '?': case 'h': default: usage(); } } args_done: if((argc < 1) ||(cablename == 0)) usage(); // Get rid of options //printf("argc: %d\n", argc); argc -= optind; args += optind; //printf("argc: %d\n", argc); if(argc < 0) usage(); AllocateFlashBuffer(); if(argc == 0) gDisplayMenu=1; else { FILE *fp; char fname[256]; strncpy(fname,args[0],250); fp=fopen(fname,"rb"); if(!fp) { strcat(fname,".rom"); fp=fopen(fname,"rb"); if (!fp) { printf("Error opening file %s or %s\n",args[0], fname); return 1; } } printf("Reading Flash Data from %s\n", fname); memset(gFlashBuffer,FILL_BYTE,gFlashBufferSize); gSourceInfo=ReadData(fp,gFlashBuffer,gFlashBufferSize); fclose(fp); if (gSourceInfo.Bytes_Read) { gProgramFlash=1; printf("Flash Data from 0x%lX to 0x%lX, Length: %ld\n" ,gSourceInfo.StartAddr,gSourceInfo.EndAddr,gSourceInfo.Bytes_Read); } else printf("Invalid flash data\n"); { int i; char * ptr = args[0]; for (i=0; i<256 && *ptr != '.'; i++) { DefName[i] = *ptr; ptr++; } DefName[i] = 0; } if (!gFuseName) gFuseName=DefName; if(!eepromfile) eepromfile= DefName; else gFuseBitsAll.EESAVE = 1; strncpy(fname, eepromfile, 250); fp = fopen(fname,"rb"); if(fp==NULL) { strcat(fname,".eep"); fp=fopen(fname,"rb"); if (!fp) printf("Error Opening Eeprom File: %s or %s\n",eepromfile, fname); } if(fp) { printf("Reading Eeprom Data from %s\n",fname); gEepromInfo=ReadData(fp,gEEPROMBuffer,MAX_EEPROM_SIZE); fclose(fp); if(gEepromInfo.Bytes_Read) { gProgramEeprom=1; printf("Eeprom Data from 0x%lX to 0x%lX, Length: %ld\n" ,gEepromInfo.StartAddr,gEepromInfo.EndAddr,gEepromInfo.Bytes_Read); } else printf("0 Bytes Eeprom Data\n"); } } // Produce release info from CVS tags printf("Release $Rev$\nPlease provide feedback on success/failure/enhancement requests! Check Sourceforge SVN!\n"); CableDB cabledb(0); res = cabledb.getCable(cablename, &cable); res = getIO( &io, &cable, dev, serial, verbose, use_ftd2xx, jtag_freq); if (res) /* some error happend*/ { if (res == 1) exit(1); else usage(); } io.get()->setVerbose(verbose); Jtag jtag = Jtag(io.operator->()); if (verbose) fprintf(stderr, "Using %s\n", db.getFile().c_str()); int num=jtag.getChain(); for(int i=0; i0){ jtag.setDeviceIRLength(i,length); printf(" Desc: %15s IR length: %d\n",db.idToDescription(id),length); } else{ printf("not found in '%s'.\n", db.getFile().c_str()); } } tmp = jtag.getDeviceID(chainpos); tmp>>=1; gJTAG_ID.manuf_id=tmp; tmp>>=11; gJTAG_ID.partnumber=tmp; tmp>>=16; gJTAG_ID.version=tmp; DisplayJTAG_ID(); switch(gDeviceData.Index) { case ATMEGA128: case ATMEGA64: case ATMEGA32: case ATMEGA16: case ATMEGA162: case ATMEGA169: case ATMEGA329: case ATMEGA3290: case ATMEGA649: case ATMEGA6490: case AT90CAN32: case AT90CAN64: case AT90CAN128: case AT90USB1287: case ATMEGA640: case ATMEGA1280: case ATMEGA1281: case ATMEGA2560: case ATMEGA2561: break; default: fprintf(stderr,"Supported devices: "); fprintf(stderr,"ATMega128"); fprintf(stderr," ,ATMega64"); fprintf(stderr," ,ATMega32"); fprintf(stderr," ,ATMega16"); fprintf(stderr," ,ATMega162"); fprintf(stderr," ,ATMega169"); fprintf(stderr," ,AT90CAN32"); fprintf(stderr," ,AT90CAN64"); fprintf(stderr," ,AT90CAN128"); fprintf(stderr," ,AT90USB1287"); fprintf(stderr," ,ATMega640"); fprintf(stderr," ,ATMega1280"); fprintf(stderr," ,ATMega1281"); fprintf(stderr," ,ATMega2560"); fprintf(stderr," ,ATMega2561"); fprintf(stderr,"\n"); exit(-1); break; } JTAG_Init(&jtag, io.operator->()); if(jtag.selectDevice(chainpos)<0){ fprintf(stderr,"Invalid chain position %d, position must be less than %d (but not less than 0).\n",chainpos,num); exit(-1); } ResetAVR(); AVR_Prog_Enable(); /* printf(">>>%4.4X<<<\n",ReadFlashWord(0x00)); */ if(gFuseName) { if(GetParamInfo()) { EncodeATMegaFuseBits(); printf("\nProgramming Fuse Bits\n"); DisplayATMegaFuseData(); WriteATMegaFuse(); } else printf("\n%s or %s.fus is not a valid fuse file\n", gFuseName, gFuseName); } else { ReadATMegaFuse(); } AVR_Prog_Disable(); if(gProgramFlash && !gVerifyOption) { printf("\nErasing Flash"); if(gFuseBitsAll.EESAVE) { printf(" and EEPROM"); } AVR_Prog_Enable(); ChipErase(); printf("\nProgramming Flash\n"); WriteFlashBlock(gSourceInfo.StartAddr,gSourceInfo.EndAddr-gSourceInfo.StartAddr+1 , gFlashBuffer); AVR_Prog_Disable(); } if(gProgramFlash && gVerifyOption) { int i; printf("\nVerifying Flash\n"); i=VerifyFlashBlock(gSourceInfo.StartAddr,gSourceInfo.EndAddr-gSourceInfo.StartAddr+1 , gFlashBuffer); printf("\nFlash Verified with %d errors\n",i); } if(gProgramEeprom) { if(!gProgramFlash || !gFuseBitsAll.EESAVE) { printf("EEPROM was not erased before programming - EEPROM NOT reprogrammed\n"); } else { printf("\nProgramming EEPROM\n"); AVR_Prog_Enable(); WriteEepromBlock(gEepromInfo.StartAddr,gEepromInfo.EndAddr-gEepromInfo.StartAddr+1 , gEEPROMBuffer+gEepromInfo.StartAddr); AVR_Prog_Disable(); } } if(gProgramFuseBits) { if(gLockOption) /* Command line option -L must be present */ { printf("\nProgramming Lock bits\n"); AVR_Prog_Enable(); WriteATMegaLock(); /* Will only program if bits defined in fuse file */ AVR_Prog_Disable(); } } if(gDisplayMenu) DisplayMenu(); AVR_Prog_Disable(); ResetReleaseAVR(); //OUT(gPort,0xFF); return(0); } void AllocateFlashBuffer(void) { unsigned short tmp; gFlashBufferSize=MAX_FLASH_SIZE; gFlashBuffer=(unsigned char*)malloc(gFlashBufferSize); if(!gFlashBuffer) { gFlashBufferSize/=2; gFlashBuffer=(unsigned char*)malloc(gFlashBufferSize); if(!gFlashBuffer) { gFlashBufferSize/=2; gFlashBuffer=(unsigned char*)malloc(gFlashBufferSize); } } tmp=(unsigned short)(gFlashBufferSize/1024UL); if(gFlashBuffer) { printf("Allocated flash buffer of %dK\n",tmp); } else { printf("\nCould not allocate flash buffer of %dK\n",tmp); exit(-1); } } void DisplayJTAG_ID(void) { int i; gDeviceData.Index=UNKNOWN_DEVICE; switch(gJTAG_ID.manuf_id) { case 0x01F: /* ATMEL */ printf("ATMEL "); i=-1; for(;;) { i++; if(gAVR_Data[i].jtag_id) { if(gJTAG_ID.partnumber==gAVR_Data[i].jtag_id) { gDeviceData=gAVR_Data[i]; break; } } else { gDeviceData=gAVR_Data[i]; break; } } printf("%s, Rev %c with",gDeviceData.name,gJTAG_ID.version+'A'); /*Bon 041213*/ printf(" %ldK Flash, %u Bytes EEPROM and %u Bytes RAM\n",gDeviceData.flash/1024,gDeviceData.eeprom, gDeviceData.ram); break; default: printf("Unknown Manufacturer 0x%02x\n", gJTAG_ID.manuf_id); break; } } xc3sprog-0+svn795+dfsg/javr/javr.h000066400000000000000000000137611337255630200170440ustar00rootroot00000000000000/********************************************************************\ * * Atmel AVR JTAG Programmer for Altera Byteblaster Hardware * * Dec 2001 Ver 0.1 Initial Version * Compiled using Turbo C - Only Supports 64K * Only ATMega128 Supported * * Jun 2002 Ver 1.0 Updated to Compile using GCC * Supports 128K * * May 2003 Ver 2.0 Added support for ATMega32 and ATMega16 * Use ioperm in cygwin environment * Should then work on Win2000 and WinXP under * cygwin * * Jun 2003 Ver 2.1 Added support for ATMega64 (untested) * Jul 2003 Ver 2.2 Added support for ATMega162 * Sep 2003 Ver 2.3 Added support for ATMega169 (no fuses yet) * Sep 2003 Ver 2.4 Added verify flag (-V) * * $Id: javr.h,v 1.4 2003/09/28 14:31:04 anton Exp $ * $Log: javr.h,v $ * Revision 1.4 2003/09/28 14:31:04 anton * Added --help command, display GPL * * Revision 1.3 2003/09/28 12:49:45 anton * Updated Version, Changed Error printing in Verify * * Revision 1.2 2003/09/27 19:21:59 anton * Added support for Linux compile * * Revision 1.1.1.1 2003/09/24 15:35:57 anton * Initial import into CVS * \********************************************************************/ #define MAX_FLASH_SIZE (1024UL*128UL) /* 128K */ #define MAX_EEPROM_SIZE 16384 #define FILL_BYTE 0xFF typedef struct { unsigned version:4; unsigned manuf_id:11; unsigned short partnumber; }JTAG_ID; typedef struct { unsigned long Instruction; char BREAKPT; }SCAN_1_Info; /* These defines must be in the same order as data in gAVR_Data[] array */ enum avr_known_devices { ATMEGA128 = 0, ATMEGA64 = 1, ATMEGA323 = 2, ATMEGA32 = 3, ATMEGA16 = 4, ATMEGA162 = 5, ATMEGA169 = 6, AT90CAN128 = 7, AT90USB1287 = 8, ATMEGA640 = 9, ATMEGA1280 = 10, ATMEGA1281 = 11, ATMEGA2560 = 12, ATMEGA2561 = 13, AT90CAN32 = 14, AT90CAN64 = 15, ATMEGA329 = 16, ATMEGA3290 = 17, ATMEGA649 = 18, ATMEGA6490 = 19, UNKNOWN_DEVICE = 0xff }; typedef struct { unsigned short jtag_id; unsigned short eeprom; unsigned long flash; unsigned short ram; unsigned char bootsize; /* 0: 128/256/512/1024 1: 256/512/1024/2048 2: 512/...*/ unsigned int pagesize; /* in Bytes, 128 or 256*/ avr_known_devices Index; /* Use To access array of Device Specific routines */ const char *name; }AVR_Data; /* Flash Write Timing: T_WLRH is 5 ms in the datasheet */ #define T_WLRH 7000 /* Chip erase Timing: T_WLRH_CE is 10 ms in the datasheet */ #define T_WLRH_CE 12000 #ifdef JAVR_M char gVersionStr[]="2.4"; JTAG_ID gJTAG_ID; int gPort; //int debug=UP_FUNCTIONS|UP_DETAILS|UL_FUNCTIONS|UL_DETAILS; //int debug = UP_FUNCTIONS|PP_FUNCTIONS|PP_DETAILS; //int debug = UL_FUNCTIONS|UP_FUNCTIONS|HW_FUNCTIONS|HW_DETAILS; //int debug = UL_FUNCTIONS|UP_FUNCTIONS|PP_FUNCTIONS|HW_FUNCTIONS|HW_DETAILS|PP_DETAILS; int debug = 0; //int debug = HW_FUNCTIONS|HW_DETAILS; char gOldTAPState,gTAPState; char gTMS; const char *gTAPStateNames[16]= { "EXIT2_DR", "EXIT1_DR", "SHIFT_DR", "PAUSE_DR", "SELECT_IR_SCAN", "UPDATE_DR", "CAPTURE_DR", "SELECT_DR_SCAN", "EXIT2_IR", "EXIT1_IR", "SHIFT_IR", "PAUSE_IR", "RUN_TEST_IDLE", "UPDATE_IR", "CAPTURE_IR", "TEST_LOGIC_RESET" }; const AVR_Data gAVR_Data[]= { /* jtag_id eeprom flash ram bootsize, pagesize, Index , name */ {0x9702, 4096 , 131072UL , 4096 , 2 , 256, ATMEGA128 , "ATMega128"}, {0x9602, 2048 , 65536UL , 4096 , 2 , 256, ATMEGA64 , "ATMega64"}, {0x9501, 1024 , 32768UL , 2048 , 1 , 128, ATMEGA323 , "ATMega323"}, {0x9502, 1024 , 32768UL , 2048 , 1 , 256, ATMEGA32 , "ATMega32"}, {0x9403, 512 , 16384UL , 1024 , 0 , 128, ATMEGA16 , "ATMega16"}, {0x9404, 512 , 16384UL , 1024 , 0 , 128, ATMEGA162 , "ATMega162"}, {0x9405, 512 , 16384UL , 1024 , 0 , 128, ATMEGA169 , "ATMega169"}, {0x9781, 4096 , 131072UL , 4096 , 2 , 256, AT90CAN128 , "AT90CAN128"}, {0x9782, 4096 , 131072UL , 8192 , 2 , 256, AT90USB1287 , "AT90USB1287"}, {0x9608, 4096 , 65536UL , 8192 , 2 , 256, ATMEGA640 , "ATMega640"}, {0x9703, 4096 , 131072UL , 8192 , 2 , 256, ATMEGA1280 , "ATMega1280"}, {0x9704, 4096 , 131072UL , 8192 , 2 , 256, ATMEGA1281 , "ATMega1281"}, {0x9801, 4096 , 262144UL , 8192 , 2 , 256, ATMEGA2560 , "ATMega2560"}, {0x9802, 4096 , 262144UL , 8192 , 2 , 256, ATMEGA2561 , "ATMega2561"}, {0x9781, 1024 , 32768UL , 2048 , 2 , 256, AT90CAN32 , "AT90CAN32"}, {0x9781, 2048 , 65536UL , 4096 , 2 , 256, AT90CAN64 , "AT90CAN64"}, {0x950B, 512 , 16384UL , 1024 , 1 , 128, ATMEGA329 , "ATMega329"}, {0x950c, 512 , 16384UL , 1024 , 1 , 128, ATMEGA3290 , "ATMega3290"}, {0x960b, 512 , 16384UL , 1024 , 1 , 256, ATMEGA649 , "ATMega649"}, {0x960c, 512 , 16384UL , 1024 , 1 , 256, ATMEGA6490 , "ATMega6490"}, {0, 0, 0, 0, 0, 0, UNKNOWN_DEVICE, "Unknown"} }; AVR_Data gDeviceData; unsigned char *gFlashBuffer; unsigned char gEEPROMBuffer[MAX_EEPROM_SIZE]; unsigned long gFlashBufferSize; #else extern int gPort; extern int debug; extern char gOldTAPState,gTAPState; extern char gTMS; extern const char *gTAPStateNames[16]; extern const char *gICEBreakerRegs[16]; extern const char gICEBreakerRegSizes[16]; extern JTAG_ID gJTAG_ID; extern AVR_Data gDeviceData; extern unsigned char *gFlashBuffer; extern unsigned char gEEPROMBuffer[]; extern unsigned long gFlashBufferSize; #endif void DisplayJTAG_ID(void); void AllocateFlashBuffer(void); xc3sprog-0+svn795+dfsg/javr/jtag.cpp000066400000000000000000000122641337255630200173570ustar00rootroot00000000000000#include "jtag.h" #include "iobase.h" #include "javr.h" #include #include #include "debug.h" static Jtag *avr_j; static IOBase *avr_io; static void BitArraytoByteArray(const char * Data, unsigned char *bData, int Size) { int i,j; unsigned char bvalue; if (debug& UL_FUNCTIONS) fprintf(stderr, "BitArraytoByteArray Size %2d ", Size); if (debug& UL_DETAILS) { if (Size < 17) { for (i=Size-1; i>=0; i--) fprintf(stderr, "%c",(Data[i]=='1')?'1':'0'); } } bvalue=0; j = 0; for (i=0; i= 7) { j=0; bvalue = 0; } else j++; } if (debug& UL_FUNCTIONS) { fprintf(stderr, " Result 0x"); if (Size%8) fprintf(stderr, "%02x", bData[Size/8]); for(i=Size/8; i >0; i--) fprintf(stderr, "%02x", bData[i-1]); fprintf(stderr, "\n"); } } static void ByteArraytoBitArray(char * Output, unsigned char *bOutput, int Size) { int i,j; unsigned char bvalue; bvalue=0; j = 0; for (i=0; i= 7) { j=0; } else j++; } if (debug& UL_FUNCTIONS) fprintf(stderr, "ByteArraytoBitArray size %d ", Size); if (debug& UL_DETAILS) { fprintf(stderr, "0x"); for (i=(Size>64)?63:Size-1;i>=0; i-=8) fprintf(stderr, "%02x",bOutput[i/8]); fprintf(stderr, " "); for (i=(Size>64)?63:Size-1;i>=0; i--) fprintf(stderr, "%c",Output[i]); } if (debug& UL_FUNCTIONS) fprintf(stderr, "\n"); } void JTAG_Init(Jtag *j, IOBase *io) { avr_j = j; avr_io = io; } void Send_Instruction(int Size, const char *Data){ unsigned char inst[1]; if (Size !=4){ fprintf(stderr," Unexpected size %d\n",Size); return; } else { BitArraytoByteArray(Data, inst, 4); if (debug& UL_FUNCTIONS) fprintf(stderr,"Send_Instruction 0x%02x\n",inst[0]); } avr_j->shiftIR(inst, 0); } void Send_Data(int Size, const char *Data) { int bSize= Size/8; unsigned char * bData; bSize+=(Size%8)?1:0; bData=(byte*) malloc(bSize*sizeof(unsigned char)); if (debug& UL_FUNCTIONS) fprintf(stderr,"Send_Data Size %d\n",Size); if (!bData ) { fprintf(stderr,"Send_Data: malloc failed\n"); return; } BitArraytoByteArray(Data, bData, Size); avr_j->shiftDR(bData,0, Size, 0, true); free(bData); } void Send_bData_Output(int Size, unsigned char *Data, unsigned char *Output) { if (debug& UL_FUNCTIONS) fprintf(stderr,"Send_bData_Output\n"); avr_j->shiftDR(Data,Output,Size, 0, 1); } void Send_Data_Output(int Size, char *Data, char *Output) { int bSize= Size/8 + ((Size%8)?1:0); unsigned char * bData, * bOutput; bData = (unsigned char*) malloc(bSize*sizeof(unsigned char)); bOutput = (unsigned char*) malloc(bSize*sizeof(unsigned char)); if (!bData || !bOutput) { fprintf(stderr,"Send_Data_Output: malloc failed\n"); if(bData) free(bData); if(bOutput) free(bOutput); return; } if (debug& UL_FUNCTIONS) fprintf(stderr,"Send_Data_Output Size %d bSize %d\n", Size, bSize); BitArraytoByteArray(Data, bData, Size); avr_j->shiftDR(bData,bOutput,Size, 0, 1); ByteArraytoBitArray(Output,bOutput,Size); free(bData); free(bOutput); } #ifdef NEWFUNCTIONS unsigned short Send_AVR_Prog_Command(unsigned short command) { unsigned char array[2],output[2]; unsigned short mask; ShortToByteArray(command,&array[0]); avr_j->shiftDR(array,output,15,0,1); mask=ByteArrayToShort(output); if (debug& UL_FUNCTIONS) fprintf(stderr,"Send_AVR_Prog_Command d send 0x%04x rec 0x%04x\n", command, mask); return(mask); } /********************************************************************\ * * * Use JTAG Reset Register to put AVR in Reset * * * \********************************************************************/ void ResetAVR(void) { unsigned char x[1]={0xff}; /* High corresponds to external reset low */ fprintf(stderr,"ResetAVR(new)\n"); Send_Instruction(4,AVR_RESET); avr_j->shiftDR(x,0,1,0,1); } /********************************************************************\ * * * Use JTAG Reset Register to take AVR out of Reset * * * \********************************************************************/ void ResetReleaseAVR(void) { unsigned char x[1]={0}; /* High corresponds to external reset low */ fprintf(stderr,"ResetReleaseAVR(new)\n"); Send_Instruction(4,AVR_RESET); avr_j->shiftDR(x,0,1,0,1); } void AVR_Prog_Enable(void) { unsigned char inst[2]; fprintf(stderr,"AVR_Prog_Enable(New)\n"); ShortToByteArray(0xA370,&inst[0]); Send_Instruction(4,PROG_ENABLE); avr_j->shiftDR(inst,0,16,0,1); } void AVR_Prog_Disable(void) { unsigned char inst[2]; fprintf(stderr,"AVR_Prog_Disable(new)\n"); ShortToByteArray(0,&inst[0]); Send_Instruction(4,PROG_ENABLE); avr_j->shiftDR(inst,0,16,0,1); } #endif xc3sprog-0+svn795+dfsg/javr/jtag_javr.h000066400000000000000000000042171337255630200200450ustar00rootroot00000000000000#include "ioparport.h" #include "jtag.h" #include "iobase.h" #undef NEWFUNCTIONS //#define NEWFUNCTIONS /* JTAG Instructions 4 bits long for AVR */ #ifndef NEWFUNCTIONS /* Bits are reversed */ #define EXTEST "0000" /* 0x0 */ #define IDCODE "1000" /* 0x1 */ #define SAMPLE_PRELOAD "0100" /* 0x2 */ #define BYPASS "1111" /* 0xF */ #define AVR_RESET "0011" /* 0xC */ #define PROG_ENABLE "0010" /* 0x4 */ #define PROG_COMMANDS "1010" /* 0x5 */ #define PROG_PAGELOAD "0110" /* 0x6 */ #define PROG_PAGEREAD "1110" /* 0x7 */ #define SIG_PROG_EN "0000111011000101" /* 0xA370 */ #else #define EXTEST "0000" /* 0x0 */ #define IDCODE "0001" /* 0x1 */ #define SAMPLE_PRELOAD "0010" /* 0x2 */ #define BYPASS "1111" /* 0xF */ #define AVR_RESET "1100" /* 0xC */ #define PROG_ENABLE "0100" /* 0x4 */ #define PROG_COMMANDS "0101" /* 0x5 */ #define PROG_PAGELOAD "0110" /* 0x6 */ #define PROG_PAGEREAD "0111" /* 0x7 */ #define SIG_PROG_EN "1010001101110000" /* 0xA370 */ #endif void JTAG_Init(Jtag *j, IOBase *io); void Send_Instruction(int Size, const char *Data); void Send_Data(int Size, const char *Data); void Send_Data_Output(int Size, char *Data, char *Output); void Send_bData_Output(int Size, unsigned char *Data, unsigned char *Output); //unsigned long ReadJTAGID(void); /*Helper*/ inline void LongToByteArray(unsigned long l, byte *b){ b[0]=(byte)(l&0xff); b[1]=(byte)((l>>8)&0xff); b[2]=(byte)((l>>16)&0xff); b[3]=(byte)((l>>24)&0xff); } inline void ShortToByteArray(unsigned short l, byte *b){ b[0]=(byte)(l&0xff); b[1]=(byte)((l>>8)&0xff); } inline unsigned long ByteArrayToLong(byte *b){ return (b[3]<<24)+(b[2]<<16)+(b[1]<<8)+b[0]; } inline unsigned long ByteArrayToShort(byte *b){ return (b[1]<<8)+b[0]; } xc3sprog-0+svn795+dfsg/javr/menu.cpp000066400000000000000000000237471337255630200174060ustar00rootroot00000000000000/*************************************************************************\ * Copyright (C) <2001> * antone@sentechsa.com * * 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 * \*************************************************************************/ /********************************************************************\ * $Id: menu.c,v 1.3 2005/03/23 21:03:49 anton Exp $ * $Log: menu.c,v $ * Revision 1.3 2005/03/23 21:03:49 anton * Added GPL License to source files * * Revision 1.2 2003/09/27 19:21:59 anton * Added support for Linux compile * * Revision 1.1.1.1 2003/09/24 15:35:57 anton * Initial import into CVS * \********************************************************************/ #include #include #include #include #include "avr_jtag.h" #include "fuse.h" #include "parse.h" #include "srecdec.h" #include "javr.h" #define MENU_M #include "menu.h" #undef MENU_M void dummy(struct MENU_ITEM *ptr) { switch(ptr->selection) { case 'q': case 'Q': case 'X': case 'x': gExitMenu=1; break; default: unsigned char val = 1; AVR_Prog_Enable(); //WriteEepromBlock(0x24, 35, (unsigned char*)"This is a Test of EEPROM Writing. 01234567890QWERTYUIOP"); WriteEepromBlock(0xffc, 1, &val); printf("%s Selected\n",ptr->title); AVR_Prog_Disable(); { int i; AVR_Prog_Enable(); //printf("Read %d\n",ReadEepromBlock(0x23,40,gFlashBuffer)); printf("Flash: %d\n",ReadFlashBlock(2, 40,gFlashBuffer)); AVR_Prog_Disable(); for(i=0;i<41;i++) { printf("%2.2X ",*(gFlashBuffer+i)); } } break; } } const struct MENU_ITEM gMenuItem[]= { {'1',"Read Fuse Bits",ReadFuseBits}, {'2',"Write Fuse Bits",WriteFuseBits}, {'3',"Read Flash - Display",ReadFlashDisplay}, {'4',"Write Flash",dummy}, {'5',"Read EEPROM - Display",ReadEepromDisplay}, {'6',"Write EEPROM",dummy}, {'7',"Erase Flash + Eeprom (EESAVE == 1)",EraseDevice}, {'8',"Read Flash - To File",ReadFlashWriteFile}, {'9',"Read EEPROM - To File",ReadEEPROMWriteFile}, {'q',"Quit",dummy}, {0,NULL,NULL} }; #define BUFSIZE 256 void DisplayMenu(void) { int i,c; char buffer[BUFSIZE]; gExitMenu=0; do { printf("\n\n"); for(i=0;;i++) { if(!gMenuItem[i].title) break; printf("\t%c)\t%s\n",gMenuItem[i].selection,gMenuItem[i].title); } printf("\n\t"); fgets(buffer, BUFSIZE, stdin); c=buffer[0]; for(i=0;;i++) { if(!gMenuItem[i].title) break; if(c==gMenuItem[i].selection) { gMenuItem[i].function((struct MENU_ITEM *)&gMenuItem[i]); } } }while(!gExitMenu); } void ReadFuseBits(struct MENU_ITEM *ptr) { int c; char buffer[BUFSIZE]; ptr=ptr; AVR_Prog_Enable(); ReadATMegaFuse(); AVR_Prog_Disable(); DecodeATMegaFuseBits(); DisplayATMegaFuseData(); printf("\nDo you want to write a fuse file ? (Y/N) "); fgets(buffer, BUFSIZE, stdin); c=buffer[0]; switch(c) { case 'y': case 'Y': printf("\nFilename ? "); fgets(buffer, BUFSIZE, stdin); buffer[strlen(buffer) -1] = 0; WriteATMegaFuseFile(buffer); break; } } void WriteFuseBits(struct MENU_ITEM *ptr) { char buffer[BUFSIZE], *p; ptr=ptr; SetATMegaFuseDefault(); /* Any bits not defined in the fuse file will be the default value */ printf("\nFilename ? "); fgets(buffer, BUFSIZE, stdin); switch(buffer[0]) { case 0: /* Do not try and load with obvious invalid file name */ case ' ': case '\r': case '\n': break; default: p=strchr(buffer, '\n'); if (p) *p = '\0'; p=strchr(buffer, '\r'); if (p) *p = '\0'; gFuseName=buffer; GetParamInfo(); EncodeATMegaFuseBits(); break; } DisplayATMegaFuseData(); printf("\nAre you sure you want to write the above fuse data ? (YES) "); fgets(buffer, BUFSIZE, stdin); switch(buffer[0]) { case 'y': case 'Y': switch(buffer[1]) { case 'e': case 'E': AVR_Prog_Enable(); WriteATMegaFuse(); WriteATMegaLock(); AVR_Prog_Disable(); break; } break; } } void EraseDevice(struct MENU_ITEM *ptr) { char buffer[BUFSIZE]; ptr=ptr; printf("If EESAVE == 0 then EEPROM will NOT be erased\n"); printf("\nAre you sure you want to erase the device ? (YES) "); fgets(buffer, BUFSIZE, stdin); switch(buffer[0]) { case 'y': case 'Y': switch(buffer[1]) { case 'e': case 'E': AVR_Prog_Enable(); ChipErase(); AVR_Prog_Disable(); break; } break; } } unsigned long gFlashDisplayStart=0xFFFFFFFFUL-0xFFUL; void ReadFlashDisplay(struct MENU_ITEM *ptr) { char buffer[BUFSIZE],tmp; int i,j,base,tmp1; unsigned long add; AVR_Prog_Enable(); ptr=ptr; printf("\nStart Address ? "); fgets(buffer, BUFSIZE, stdin); switch(buffer[0]) { case 0: case ' ': case '\r': case '\n': gFlashDisplayStart+=0x100; break; default: // sscanf(buffer,"%I",&gFlashDisplayStart); /* Read Octal, Decimal or Hex */ sscanf(buffer,"%li",&gFlashDisplayStart); /* Read Octal, Decimal or Hex */ break; } add=gFlashDisplayStart>>8; if(add>(gDeviceData.flash>>8)) /* Wrap on End of Flash */ add=0; ReadFlashBlock(add<<8,256,(unsigned char*) buffer); add<<=8; /* Get Block Start Address */ for(i=0;i<16;i++) { base=i*16; printf("%5.5lX: ",add); add+=16; for(j=0;j<16;j++) { tmp1=buffer[base+j]; tmp1&=0xFF; printf("%2.2X",tmp1); } printf(" : "); for(j=0;j<16;j++) { tmp=buffer[base+j]; if(isprint(tmp)) putchar(tmp); else putchar('.'); } printf("\n"); } printf("\n"); AVR_Prog_Disable(); fgets(buffer, BUFSIZE, stdin); } void ReadFlashWriteFile(struct MENU_ITEM *ptr) { char buffer[BUFSIZE] = {0}; unsigned long add; FILE *fp; char *p; AVR_Prog_Enable(); ptr=ptr; printf("\nFile Name [atmega.bin] ? "); fgets(buffer, BUFSIZE, stdin); switch(buffer[0]) { case 0: case ' ': case '\r': case '\n': strcpy(buffer,"atmega.bin"); break; default: break; } /* clean up the name */ if ((p = strchr(buffer, '\r')) != 0) *p = '\0'; if ((p = strchr(buffer, '\n')) != 0) *p = '\0'; fp=fopen(buffer,"wb"); if(!fp) { printf("\nError opening file %s !!!\n",buffer); return; } add=gDeviceData.flash; printf("Reading %ld bytes from device %s\n",add,gDeviceData.name); ReadFlashBlock(0,add,gFlashBuffer); /* Read whole device */ printf("\nWriting binary file %s",buffer); fwrite(gFlashBuffer,add,1,fp); fclose(fp); AVR_Prog_Disable(); printf(" done\n"); } void ReadEEPROMWriteFile(struct MENU_ITEM *ptr) { char buffer[BUFSIZE]; unsigned long add; FILE *fp; AVR_Prog_Enable(); ptr=ptr; printf("\nFile Name [atmega_ee.bin] ? "); fgets(buffer, BUFSIZE, stdin); switch(buffer[0]) { case 0: case ' ': case '\r': case '\n': strcpy(buffer,"atmega_ee.bin"); break; default: break; } fp=fopen(buffer,"wb"); if(!fp) { printf("\nError opening file %s !!!\n",buffer); return; } add=gDeviceData.eeprom; printf("Reading %ld bytes from device %s EEPROM\n",add,gDeviceData.name); ReadEepromBlock(0,add,gEEPROMBuffer); /* Read whole device */ printf("\nWriting binary file %s",buffer); fwrite(gEEPROMBuffer,add,1,fp); fclose(fp); AVR_Prog_Disable(); printf(" done\n"); } unsigned gEepromDisplayStart=(~0)-512; void ReadEepromDisplay(struct MENU_ITEM *ptr) { char buffer[BUFSIZE],tmp; int i,j,tmp1; unsigned add,length; AVR_Prog_Enable(); ptr=ptr; printf("\nStart Address ? "); fgets(buffer, BUFSIZE, stdin); switch(buffer[0]) { case 0: case ' ': case '\r': case '\n': gEepromDisplayStart+=256; break; default: sscanf(buffer,"%i",&gEepromDisplayStart); /* Read Octal, Decimal or Hex */ break; } if((unsigned)gEepromDisplayStart>(unsigned)(gDeviceData.eeprom-16)) gEepromDisplayStart=0; add=gEepromDisplayStart; add>>=4; add<<=4; length=256; if((add+length)>gDeviceData.eeprom) { length=gDeviceData.eeprom-add; } for(i=0;i<(int)length;) { ReadEepromPage((add>>4),(unsigned char*)buffer); printf("%4.4X: ",add); add+=16; for(j=0;j<8;j++,i++) { tmp1=buffer[j]; tmp1&=0xFF; printf("%2.2X",tmp1); } printf(" "); for(j=8;j<16;j++,i++) { tmp1=buffer[j]; tmp1&=0xFF; printf("%2.2X",tmp1); } printf(" : "); for(j=0;j<8;j++) { tmp=buffer[j]; if(isprint(tmp)) putchar(tmp); else putchar('.'); } printf(" "); for(j=8;j<16;j++) { tmp=buffer[j]; if(isprint(tmp)) putchar(tmp); else putchar('.'); } printf("\n"); } printf("\n"); AVR_Prog_Disable(); fgets(buffer, BUFSIZE, stdin); } xc3sprog-0+svn795+dfsg/javr/menu.h000066400000000000000000000035031337255630200170370ustar00rootroot00000000000000/*************************************************************************\ * Copyright (C) <2001> * antone@sentechsa.com * * 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 * \*************************************************************************/ /********************************************************************\ * $Id: menu.h,v 1.3 2005/03/23 21:03:49 anton Exp $ * $Log: menu.h,v $ * Revision 1.3 2005/03/23 21:03:49 anton * Added GPL License to source files * * Revision 1.2 2003/09/28 14:31:04 anton * Added --help command, display GPL * * Revision 1.1.1.1 2003/09/24 15:35:57 anton * Initial import into CVS * \********************************************************************/ struct MENU_ITEM { char selection; const char *title; void(*function)(struct MENU_ITEM *ptr); }; #ifdef MENU_M char gExitMenu; #else #endif void DisplayMenu(void); void ReadFuseBits(struct MENU_ITEM *ptr); void WriteFuseBits(struct MENU_ITEM *ptr); void EraseDevice(struct MENU_ITEM *ptr); void ReadFlashDisplay(struct MENU_ITEM *ptr); void ReadFlashWriteFile(struct MENU_ITEM *ptr); void ReadEEPROMWriteFile(struct MENU_ITEM *ptr); void ReadEepromDisplay(struct MENU_ITEM *ptr); xc3sprog-0+svn795+dfsg/javr/parse.cpp000066400000000000000000000244651337255630200175520ustar00rootroot00000000000000/*************************************************************************\ * Copyright (C) <2001> * antone@sentechsa.com * * 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 * \*************************************************************************/ /********************************************************************\ * $Id: parse.c,v 1.3 2005/03/23 21:03:49 anton Exp $ * $Log: parse.c,v $ * Revision 1.3 2005/03/23 21:03:49 anton * Added GPL License to source files * * Revision 1.2 2003/09/27 19:21:59 anton * Added support for Linux compile * * Revision 1.1.1.1 2003/09/24 15:35:57 anton * Initial import into CVS * \********************************************************************/ #include #include #include #include #include "fuse.h" #define PARSE_M #include "parse.h" #undef PARSE_M const char *gToken[]={ "M103C:", "WDTON:", "OCDEN:", "JTAGEN:", "SPIEN:", "CKOPT:", "EESAVE:", "BOOTSIZE:", "BOOTRST:", "BODLEVEL:", "BODEN:", "SUT:", "CKSEL:", "BLB0:", "BLB1:", "LB:", "M161C:", "CKDIV8:", "CKOUT:", "HWBE:", "RESETDIS:", NULL }; #define TokenM103C 0 #define TokenWDTON 1 #define TokenOCDEN 2 #define TokenJTAGEN 3 #define TokenSPIEN 4 #define TokenCKOPT 5 #define TokenEESAVE 6 #define TokenBOOTSIZE 7 #define TokenBOOTRST 8 #define TokenBODLEVEL 9 #define TokenBODEN 10 #define TokenSUT 11 #define TokenCKSEL 12 #define TokenBLB0 13 #define TokenBLB1 14 #define TokenLB 15 #define TokenM161C 16 #define TokenCKDIV8 17 #define TokenCKOUT 18 #define TokenHWBE 19 #define TokenRESETDIS 20 #define TokenNone 21 /********************************************************************\ * * * Returns 0 on Failure * * * \********************************************************************/ int GetParamInfo(void) { unsigned char c; unsigned char Buffer[40]; char restart=1; unsigned char EventNum=0,Index=0; int Token,TokenOld; unsigned long DataCount; int tmp; char fname[256]; strncpy(fname,gFuseName,250); gFuseFile=fopen(fname,"rb"); if(gFuseFile==NULL) { strcat(fname,".fus"); gFuseFile=fopen(fname,"rb"); if (!gFuseFile) { printf("Error Opening Fuse File: %s or %s\n",gFuseName, fname); return(0); /* Failure */ } } printf("Reading Fuse Data from %s\n",fname); gLockByteUpdated=0; DataCount=0; TokenOld=TokenNone; do { if(!feof(gFuseFile)) { switch(EventNum) { case 0: /* Start */ restart=1; Index=0; EventNum=1; break; case 1: /* Looking for token */ c=fgetc(gFuseFile); if(!isspace(c)) { if(c==';') /* Start of comment */ { EventNum=4; } else { Buffer[Index++]=c; EventNum=2; } } break; case 2: /* Reading Token */ c=fgetc(gFuseFile); if(isspace(c)) { if(c!=' ') { EventNum=3; Buffer[Index]=0; } else { Buffer[Index++]=c; } } else { Buffer[Index++]=c; if(c==':') /* End of Token char */ { EventNum=3; Buffer[Index]=0; } if(Index>30) restart=0; } break; case 3: /* Token in Buffer */ Token=Tokenize(Buffer); DataCount++; switch(Token) { case TokenM103C: break; case TokenWDTON: break; case TokenOCDEN: break; case TokenJTAGEN: break; case TokenSPIEN: break; case TokenCKOPT: break; case TokenEESAVE: break; case TokenBOOTSIZE: break; case TokenBOOTRST: break; case TokenBODLEVEL: break; case TokenBODEN: break; case TokenSUT: break; case TokenCKSEL: break; case TokenM161C: break; case TokenCKDIV8: break; case TokenCKOUT: break; case TokenHWBE: break; case TokenRESETDIS: break; case TokenNone: /* printf("%s >>%s<<\n",gToken[TokenOld],Buffer); */ switch(TokenOld) { case TokenM103C: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.M103C=tmp; break; case TokenWDTON: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.WDTON=tmp; break; case TokenOCDEN: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.OCDEN=tmp; break; case TokenJTAGEN: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.JTAGEN=tmp; break; case TokenSPIEN: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.SPIEN=tmp; break; case TokenCKOPT: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.CKOPT=tmp; break; case TokenEESAVE: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.EESAVE=tmp; break; case TokenBOOTSIZE: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.BOOTSIZE=tmp; break; case TokenBOOTRST: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.BOOTRST=tmp; break; case TokenBODLEVEL: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.BODLEVEL=tmp; break; case TokenBODEN: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.BODEN=tmp; break; case TokenSUT: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.SUT=tmp; break; case TokenCKSEL: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.CKSEL=tmp; break; case TokenBLB0: sscanf((const char*)Buffer,"%i",&tmp); gLockBitsAll.BLB0=tmp; gLockByteUpdated=1; break; case TokenBLB1: sscanf((const char*)Buffer,"%i",&tmp); gLockBitsAll.BLB1=tmp; gLockByteUpdated=1; break; case TokenLB: sscanf((const char*)Buffer,"%i",&tmp); gLockBitsAll.LB=tmp; gLockByteUpdated=1; break; case TokenM161C: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.M161C=tmp; break; case TokenCKDIV8: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.CKDIV8=tmp; break; case TokenCKOUT: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.CKOUT=tmp; break; case TokenHWBE: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.HWBE=tmp; break; case TokenRESETDIS: sscanf((const char*)Buffer,"%i",&tmp); gFuseBitsAll.RESETDIS=tmp; break; } break; } EventNum=1; Index=0; TokenOld=Token; break; case 4: /* Skipping Comment */ c=fgetc(gFuseFile); if((c=='\r') || (c=='\n')) /* End of comment */ { Index=0; EventNum=1; } break; } } else { restart=0; } } while(restart); fclose(gFuseFile); return(DataCount); } #if defined(__unix__) || defined(__MACH__) #define stricmp strcasecmp #endif int Tokenize(unsigned char *buffer) { int i; i=0; while(gToken[i]) { if(!stricmp((const char*)gToken[i],(const char*)buffer)) return(i); i++; } return(i); } xc3sprog-0+svn795+dfsg/javr/parse.h000066400000000000000000000027611337255630200172120ustar00rootroot00000000000000/*************************************************************************\ * Copyright (C) <2001> * antone@sentechsa.com * * 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 * \*************************************************************************/ /********************************************************************\ * $Id: parse.h,v 1.3 2005/03/23 21:03:50 anton Exp $ * $Log: parse.h,v $ * Revision 1.3 2005/03/23 21:03:50 anton * Added GPL License to source files * * Revision 1.2 2003/09/27 19:21:59 anton * Added support for Linux compile * * Revision 1.1.1.1 2003/09/24 15:35:57 anton * Initial import into CVS * \********************************************************************/ #ifdef PARSE_M FILE *gFuseFile; char *gFuseName; #else extern char *gFuseName; #endif int GetParamInfo(void); int Tokenize(unsigned char *buffer); xc3sprog-0+svn795+dfsg/javr/srecdec.cpp000066400000000000000000000144751337255630200200500ustar00rootroot00000000000000/*************************************************************************\ * Copyright (C) <2001> * antone@sentechsa.com * * 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 * \*************************************************************************/ /********************************************************************\ * Code to Read in S Record File to buffer * * $Id: srecdec.c,v 1.3 2005/03/23 21:03:50 anton Exp $ * $Log: srecdec.c,v $ * Revision 1.3 2005/03/23 21:03:50 anton * Added GPL License to source files * * Revision 1.2 2003/09/27 19:21:59 anton * Added support for Linux compile * * Revision 1.1.1.1 2003/09/24 15:35:57 anton * Initial import into CVS * \********************************************************************/ #include #include #include #include "srecdec.h" long Hex2Bin(char *ptr); char RecordType(char Type); S_Record DecodeSRecordLine(char *source, unsigned char *dest) { S_Record SRec; char buffer[16]; int i,l; if(*source!='S') { printf("\n%s\n",source); SRec.Type= INVALID_REC; return SRec; } source++; SRec.Type=*source++-'0'; for(i=0;i<2;i++) { buffer[i]=*source++; } buffer[i]=0; SRec.Length=(char)Hex2Bin(buffer); switch(SRec.Type) { case 0: /* Start Record */ for(i=0;i<4;i++) { buffer[i]=*source++; } buffer[i]=0; SRec.Address=Hex2Bin(buffer); l=SRec.Length-3; /* 2 Address Bytes + 1 Checksum Bytes */ for(i=0;i 0x800000) /* for new avr-obj setting the ARAM section 081202*/ break; if (Address >= (unsigned long)MaxLen) { fprintf(stderr,"\n Address: 0x%lx",Address); Rslt.Bytes_Read = 0; fprintf(stderr, "\n Buffer too small, Number of bytes read = %lu \n ",NumberOfBytes); return Rslt; } Data[(size_t)Address] = LBuf[i]; NumberOfBytes++; if(Address>MaxA) { MaxA=Address; } i++; } } } Rslt.StartAddr = StartAddress; Rslt.Bytes_Read = NumberOfBytes; Rslt.EndAddr = MaxA; return Rslt; } xc3sprog-0+svn795+dfsg/javr/srecdec.h000066400000000000000000000034501337255630200175040ustar00rootroot00000000000000/*************************************************************************\ * Copyright (C) <2001> * antone@sentechsa.com * * 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 * \*************************************************************************/ /********************************************************************\ * $Id: srecdec.h,v 1.3 2005/03/23 21:03:50 anton Exp $ * $Log: srecdec.h,v $ * Revision 1.3 2005/03/23 21:03:50 anton * Added GPL License to source files * * Revision 1.2 2003/09/27 19:21:59 anton * Added support for Linux compile * * Revision 1.1.1.1 2003/09/24 15:35:57 anton * Initial import into CVS * \********************************************************************/ typedef struct { int Type; /* S-Record Type */ long Address; /* Block Address */ int Length; /* S-Record Length */ int DataLength; /* Actual Number of Data Bytes */ }S_Record; #define STARTRECORD 0 #define DATARECORD 1 #define ENDRECORD 2 #define INVALID_REC -1 typedef struct { long StartAddr; /* Info for block binary */ long EndAddr; long Bytes_Read; } SrecRd; SrecRd ReadData(FILE *fp,unsigned char *Data,long MaxAddress); xc3sprog-0+svn795+dfsg/jedecfile.cpp000066400000000000000000000311461337255630200174020ustar00rootroot00000000000000/* Jedec .jed file parser Copyright (C) Uwe Bonnes 2009 bon@elektron.ikp.physik.tu-darmstadt.de 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 */ /* * Using a slightly corrected version from IPAL libjedec * Copyright (c) 2000 Stephen Williams (steve@icarus.com) */ #include #include #include #include #include #include #include "jedecfile.h" #include "io_exception.h" static unsigned char*allocate_fusemap(unsigned size) { unsigned char*ptr = (unsigned char*) calloc(size/8 + ((size%8)?1:0), 1); return ptr; } int jedec_get_fuse(jedec_data_t jed, unsigned idx) { unsigned int bval, bit; if(idx >= jed->fuse_count) throw io_exception(std::string("jedec_get_fuse")); bval = idx / 8; bit = idx % 8; return (jed->fuse_list[bval] & (1 << bit))? 1 : 0; } void jedec_set_fuse(jedec_data_t jed, unsigned idx, int blow) { unsigned int bval, bit; if(idx >= jed->fuse_count) throw io_exception(std::string("jedec_set_fuse")); bval = idx / 8; bit = idx % 8; if (blow) jed->fuse_list[bval] |= (1 << bit); else jed->fuse_list[bval] &= ~(1 << bit); } struct state_mach { jedec_data_t jed; void (*state)(int ch, struct state_mach*m); unsigned int checksum; union { struct { unsigned cur_fuse; } l; } m; }; static void m_startup(int ch, struct state_mach*m); static void m_header(int ch, struct state_mach*m); static void m_base(int ch, struct state_mach*m); static void m_C(int ch, struct state_mach*m); static void m_L(int ch, struct state_mach*m); static void m_Lfuse(int ch, struct state_mach*m); static void m_Q(int ch, struct state_mach*m); static void m_QF(int ch, struct state_mach*m); static void m_QP(int ch, struct state_mach*m); static void m_skip(int ch, struct state_mach*m); static void m_N(int ch, struct state_mach*m); int m_N_item; int m_N_pos; int m_H_pos = 0; char m_H_string[MAX_SIZE]; char m_N_strings[MAX_ITEM][MAX_SIZE]; static void m_startup(int ch, struct state_mach*m) { switch (ch) { case '\002': m->state = m_base; break; case 'D': m->state = m_header; break; default: break; } } static void m_header(int ch, struct state_mach*m) { switch (ch) { case '\n': case '\r': if (m_H_pos) { char * ptr = strchr( m_H_string, ':'); if (ptr) strncpy(m->jed->date, ptr, MAX_SIZE); } m->state = m_startup; break; default: m_H_string[m_H_pos] = ch; m_H_pos++; } } static void m_base(int ch, struct state_mach*m) { if (isspace(ch)) return; switch (ch) { case 'L': m->state = m_L; m->m.l.cur_fuse = 0; break; case 'Q': m->state = m_Q; break; case 'C': m->state = m_C; m->jed->checksum = 0; break; case 'N': m->state = m_N; m_N_item = -1; break; default: m->state = m_skip; break; } } static void m_C(int ch, struct state_mach*m) { if (isspace(ch)) return; if (ch == '*') { m->state = m_base; return; } if(ch >='0' && ch <='9') { m->jed->checksum <<=4; m->jed->checksum += ch - '0'; return; } ch &= 0x5f; if(ch >='A' && ch <= 'F') { m->jed->checksum <<=4; m->jed->checksum += ch - '7'; return; } fprintf(stderr, "m_C: Dangling '%c' 0x%02x\n", ch, ch); fflush(stderr); throw io_exception(std::string("m_C")); } static void m_L(int ch, struct state_mach*m) { if (isdigit(ch)) { m->m.l.cur_fuse *= 10; m->m.l.cur_fuse += ch - '0'; return; } if (isspace(ch)) { m->state = m_Lfuse; return; } if (ch == '*') { m->state = m_base; return; } fprintf(stderr, "m_L: Dangling '%c' 0x%02x\n", ch, ch); fflush(stderr); m->state = 0; } static void m_Lfuse(int ch, struct state_mach*m) { switch (ch) { case '*': m->state = m_base; break; case '0': jedec_set_fuse(m->jed, m->m.l.cur_fuse, 0); m->m.l.cur_fuse += 1; break; case '1': jedec_set_fuse(m->jed, m->m.l.cur_fuse, 1); m->m.l.cur_fuse += 1; break; case ' ': case '\n': case '\r': break; default: fprintf(stderr, "m_LFuse: Dangling '%c' 0x%02x\n", ch, ch); fflush(stderr); m->state = 0; break; } } #if defined(__unix__) || defined(__MACH__) #define stricmp strcasecmp #define strnicmp strncasecmp #endif static void m_N(int ch, struct state_mach*m) { switch (ch) { case '*': if ((stricmp(m_N_strings[0], "DEVICE")) == 0) { m_N_strings[m_N_item][m_N_pos] = 0; strncpy(m->jed->device, m_N_strings[1], MAX_SIZE); } if ((stricmp(m_N_strings[0], "VERSION")) == 0) { m_N_strings[m_N_item][m_N_pos] = 0; strncpy(m->jed->version, m_N_strings[1], MAX_SIZE); } m->state = m_base; m_N_item= -1; break; case ' ': if(m_N_item >=0) m_N_strings[m_N_item][m_N_pos] = 0; if (m_N_item < MAX_ITEM) { /* Don't stumble on too many items like in ISE XC2C Jedecfiles */ m_N_item++; } m_N_pos = 0; case '\n': case '\r': break; default: if((m_N_item >=0) && (m_N_item jed->fuse_count != 0) { m->state = 0; return; } m->state = m_QF; m->jed->fuse_count = 0; break; case 'P': if (m->jed->pin_count != 0) { m->state = 0; return; } m->state = m_QP; m->jed->pin_count = 0; break; default: m->state = m_skip; break; } } static void m_QF(int ch, struct state_mach*m) { if (isspace(ch)) return; if (isdigit(ch)) { m->jed->fuse_count *= 10; m->jed->fuse_count += ch - '0'; return; } if (ch == '*') { m->state = m_base; m->jed->fuse_list = allocate_fusemap(m->jed->fuse_count); return; } throw io_exception(std::string("m_QF")); } static void m_QP(int ch, struct state_mach*m) { if (isspace(ch)) return; if (isdigit(ch)) { m->jed->pin_count *= 10; m->jed->pin_count += ch - '0'; return; } if (ch == '*') { m->state = m_base; return; } throw io_exception(std::string("m_QP")); } static void m_skip(int ch, struct state_mach*m) { switch (ch) { case '*': m->state = m_base; break; default: break; } } JedecFile::JedecFile(void) : Error(false), logfile(stderr) { jed.checksum = 0; jed.fuse_count = 0; jed.pin_count = 0; jed.fuse_list = 0; jed.device[0] = 0; jed.version[0] = 0; jed.date[0] = 0; } JedecFile::~JedecFile(void) { if(jed.fuse_list) free(jed.fuse_list); } int JedecFile::readFile(FILE *fp) { int ch; struct state_mach m; if(!fp) return 1; //jed = (jedec_data_t)calloc(1, sizeof(struct jedec_data)); m.jed = &jed; m.state = m_startup; while ((ch = fgetc(fp)) != EOF) { m.state(ch, &m); if (m.state == 0) { /* Some sort of error happened. */ return 2; } } if (!jed.fuse_count) return 3; return 0; } void JedecFile::saveAsJed(const char *device, FILE *fp) { unsigned int i, b=0, l=0 ,w=0; unsigned short chksum=0; unsigned int DRegLength; int type=-1; if (!fp) return; if (strnicmp("XC9536",device, sizeof("XC9536X")-1) == 0) { type = JED_XC95; } else if (strnicmp("XC9572",device, sizeof("XC9572X")-1) == 0) { type = JED_XC95; } else if (strnicmp("XC95108",device, sizeof("XC95144X")-1) == 0) { type = JED_XC95; } else if (strnicmp("XC95144",device, sizeof("XC95288X")-1) == 0) { type = JED_XC95; } else if (strnicmp("XC95216",device, sizeof("XC95288X")-1) == 0) { type = JED_XC95; } else if (strnicmp("XC95288",device, sizeof("XC95288X")-1) == 0) { type = JED_XC95; } else if (strnicmp("XC9536X",device, sizeof("XC9536X")-1) == 0) { type = JED_XC95X; DRegLength=2; } else if (strnicmp("XC9572X",device, sizeof("XC9572X")-1) == 0) { type = JED_XC95X; DRegLength=4; } else if (strnicmp("XC95144X",device, sizeof("XC95144X")-1) == 0) { type = JED_XC95X; DRegLength=8; } else if (strnicmp("XC95288X",device, sizeof("XC95288X")-1) == 0) { type = JED_XC95X; DRegLength=16; } else if (strnicmp("XC2C",device, sizeof("XC2C")-1) == 0) { type = JED_XC2C; } if (strlen(jed.date) == 0) { time_t t; struct tm *tmp; char outstr[200]; t = time(NULL); tmp = localtime(&t); if (tmp != NULL) { if (strftime(outstr, sizeof(outstr), "%a %b %d %T %Y", tmp)) fprintf(fp, "Date Extracted: %s\n\n", outstr); } } else fprintf(fp, "Date Extracted%s\n\n",jed.date); fprintf(fp, "\2QF%d*\nQV0*\nF0*\nX0*\nJ0 0*\n",jed.fuse_count); if (strlen(jed.version) == 0) fprintf(fp, "N VERSION XC3SPROG*\n"); else fprintf(fp, "N VERSION %s*\n",jed.version); fprintf(fp, "N DEVICE %s*\n", device); if(type == JED_XC95X) { /* Xilinx Impact (10.1) needs following additional items to recognizes as a valid Jedec File * the 4 Digits as total Checksum * N DEVICE */ for (i=0; i jed.fuse_count) { if (jed.fuse_list) free(jed.fuse_list); jed.fuse_list = new byte[f_count/8 + ((f_count%8)?1:0)]; memset(jed.fuse_list, 0xff, f_count/8 + ((f_count%8)?1:0)); } else { for (unsigned int i = f_count; i < jed.fuse_count; i++) set_fuse(i, 0); } jed.fuse_count = f_count; } void JedecFile::set_fuse(unsigned int idx, int blow) { jedec_set_fuse(&jed, idx,blow); } int JedecFile::get_fuse(unsigned int idx) { return jedec_get_fuse(&jed, idx); } unsigned short JedecFile::calcChecksum() { unsigned int i; unsigned short cc=0; for(i=0; i<(jed.fuse_count/8 + ((jed.fuse_count%8)?1:0)); i++) cc += jed.fuse_list[i]; return cc; } xc3sprog-0+svn795+dfsg/jedecfile.h000066400000000000000000000040301337255630200170370ustar00rootroot00000000000000/* Jedec .jed file parser Copyright (C) Uwe Bonnes 2009 bon@elektron.ikp.physik.tu-darmstadt.de 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 */ /* * Using a slightly corrected version from IPAL libjedec * Copyright (c) 2000 Stephen Williams (steve@icarus.com) */ #ifndef JEDECFILE_H #define JEDECFILE_H #include #define MAX_ITEM 8 #define MAX_SIZE 256 typedef unsigned char byte; struct jedec_data { char device[MAX_SIZE]; char version[MAX_SIZE]; char date[MAX_SIZE]; unsigned fuse_count; unsigned pin_count; unsigned vector_count; unsigned checksum; unsigned char fuse_default; unsigned char*fuse_list; }; typedef struct jedec_data *jedec_data_t; #define JED_XC95X 0 #define JED_XC2C 1 #define JED_XC95 2 class JedecFile { private: struct jedec_data jed; bool Error; std::string errorStr; FILE *logfile; public: JedecFile(void); ~JedecFile(); public: int readFile(FILE *fp); inline unsigned int getLength(){return jed.fuse_count;} inline unsigned short getChecksum(){return jed.checksum;} char *getDevice(){return jed.device;} char *getVersion(){return jed.version;} char *getDate(){return jed.date;} unsigned short calcChecksum(); void setLength(unsigned int fuse_count); int get_fuse(unsigned int idx); void set_fuse(unsigned int idx, int blow); void saveAsJed(const char * device, FILE *fp); }; #endif //JEDECFILE_H xc3sprog-0+svn795+dfsg/jedecparse.cpp000066400000000000000000000041011337255630200175640ustar00rootroot00000000000000/* Jedec .jed file parser Copyright (C) 2009 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de Copyright (C) 2004 Andrew Rogers 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 Changes: Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: Code cleanup for clean -Wall compile. */ #include #include #include #include "jedecfile.h" #include "io_exception.h" int main(int argc, char**args) { if(argc < 2) { fprintf(stderr,"Usage: %s infile.jed\n",args[0]); } else { try { JedecFile file; FILE *fp; if (*args[1] == '-') fp = stdin; else { fp=fopen(args[1],"rb"); if(!fp) { fprintf(stderr, "Can't open datafile %s: %s\n", args[1], strerror(errno)); return 1; } } file.readFile(fp); fp = NULL; if(args[2]) { if (*args[2] == '-') fp = stdout; fp = fopen(args[2], "wb"); if (!fp) fprintf(stderr," Can't open %s: %s \n", args[2], strerror(errno)); } fprintf(stderr, "Device %s: %d Fuses\n" "Checksum calculated: 0x%04x," "Checksum from file 0x%04x\n", file.getDevice(), file.getLength(), file.calcChecksum(), file.getChecksum()); fprintf(stderr, "Version : %s Date %s\n", file.getVersion(), file.getDate()); file.saveAsJed(file.getDevice(), fp); } catch(io_exception& e) { fprintf(stderr, "IOException: %s", e.getMessage().c_str()); return 1; } } } xc3sprog-0+svn795+dfsg/jtag.cpp000066400000000000000000000240761337255630200164210ustar00rootroot00000000000000/* JTAG routines Copyright (C) 2004 Andrew Rogers Copyright (C) 2005-2009 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 "jtag.h" #include Jtag::Jtag(IOBase *iob) { verbose = false; io=iob; current_state = UNKNOWN; postDRState = RUN_TEST_IDLE; postIRState = RUN_TEST_IDLE; deviceIndex = -1; numDevices = -1; shiftDRincomplete=false; char *fname = getenv("JTAG_DEBUG"); if (fname) fp_dbg = fopen(fname,"wb"); else fp_dbg = NULL; } Jtag::~Jtag(void) { if(fp_dbg) fclose(fp_dbg); } /* Detect chain length on first start, return chain length else*/ int Jtag::getChain(bool detect) { if(numDevices == -1 || detect) { tapTestLogicReset(); setTapState(SHIFT_DR); byte idx[4]; byte zero[4]; numDevices=0; for(int i=0; i<4; i++)zero[i]=0; do{ io->shiftTDITDO(zero,idx,32,false); unsigned long id=byteArrayToLong(idx); if(id!=0 && id !=0xffffffff){ numDevices++; chainParam_t dev; dev.idcode=id; devices.insert(devices.begin(),dev); } else{ if (id == 0xffffffff && numDevices >0) { fprintf(stderr,"Probably a broken Atmel device in your chain!\n"); fprintf(stderr,"No succeeding device can be identified\n"); } break; } }while(numDevices=numDevices)deviceIndex=-1; else deviceIndex=dev; if(fp_dbg) fprintf(fp_dbg,"selectDevices %d\n", deviceIndex); return deviceIndex; } void Jtag::cycleTCK(int n, bool tdi) { if(current_state==TEST_LOGIC_RESET) fprintf(stderr, "cycleTCK in TEST_LOGIC_RESET\n"); if(fp_dbg) fprintf(fp_dbg, "cycleTCK %d TDI %s\n", n, (tdi)?"TRUE":"FALSE"); io->shift(tdi, n, false); } int Jtag::setDeviceIRLength(int dev, int len) { if(dev>=numDevices||dev<0)return -1; devices[dev].irlen=len; return dev; } void Jtag::shiftDR(const byte *tdi, byte *tdo, int length, int align, bool exit) { if(deviceIndex<0)return; int post=deviceIndex; if(!shiftDRincomplete){ int pre=numDevices-deviceIndex-1; if(align){ pre=-post; while(pre<=0)pre+=align; } /* We can combine the pre bits to reach the target device with the TMS bits to reach the SHIFT-DR state, as the pre bit can be '0'*/ setTapState(SHIFT_DR,pre); } if(fp_dbg) { fprintf(fp_dbg, "shiftDR len %d\n", length); if (tdi) { int i; fprintf(fp_dbg, "In:\n" ); for (i=0; i< (length+7)>>3; i++) { fprintf(fp_dbg, " %02x", tdi[i]); if (i % 26== 25) fprintf(fp_dbg, "\n"); } fprintf(fp_dbg, "\n"); } } if(tdi!=0&&tdo!=0)io->shiftTDITDO(tdi,tdo,length,post==0&&exit); else if(tdi!=0&&tdo==0)io->shiftTDI(tdi,length,post==0&&exit); else if(tdi==0&&tdo!=0)io->shiftTDO(tdo,length,post==0&&exit); else io->shift(false,length,post==0&&exit); if(fp_dbg) { if (tdo) { int i; fprintf(fp_dbg, "Out:\n" ); for (i=0; i< (length+7)>>3; i++) { fprintf(fp_dbg, " %02x", tdo[i]); if (i % 26 == 25) fprintf(fp_dbg, "\n"); } fprintf(fp_dbg, "\n"); } } nextTapState(post==0&&exit); // If TMS is set the the state of the tap changes if(exit){ io->shift(false,post); if (!(post==0&&exit)) nextTapState(true); setTapState(postDRState); shiftDRincomplete=false; } else shiftDRincomplete=true; } void Jtag::shiftIR(const byte *tdi, byte *tdo) { if(deviceIndex<0)return; setTapState(SHIFT_IR); if(fp_dbg) { fprintf(fp_dbg, "shiftIR "); if (tdi) fprintf(fp_dbg, "In: %02x", *tdi ); } int pre=0; for(int dev=deviceIndex+1; devshift(true,pre,false); if(tdo!=0)io->shiftTDITDO(tdi,tdo,devices[deviceIndex].irlen,post==0); else if(tdo==0)io->shiftTDI(tdi,devices[deviceIndex].irlen,post==0); io->shift(true,post); if(fp_dbg) { if (tdo) fprintf(fp_dbg, "Out: %02x", *tdo); fprintf(fp_dbg, "\n"); } nextTapState(true); setTapState(postIRState); } void Jtag::setTapState(tapState_t state, int pre) { bool tms; while(current_state!=state){ switch(current_state){ case TEST_LOGIC_RESET: switch(state){ case TEST_LOGIC_RESET: tms=true; break; default: tms=false; current_state=RUN_TEST_IDLE; }; break; case RUN_TEST_IDLE: switch(state){ case RUN_TEST_IDLE: tms=false; break; default: tms=true; current_state=SELECT_DR_SCAN; }; break; case SELECT_DR_SCAN: switch(state){ case CAPTURE_DR: case SHIFT_DR: case EXIT1_DR: case PAUSE_DR: case EXIT2_DR: case UPDATE_DR: tms=false; current_state=CAPTURE_DR; break; default: tms=true; current_state=SELECT_IR_SCAN; }; break; case CAPTURE_DR: switch(state){ case SHIFT_DR: tms=false; current_state=SHIFT_DR; break; default: tms=true; current_state=EXIT1_DR; }; break; case SHIFT_DR: switch(state){ case SHIFT_DR: tms=false; break; default: tms=true; current_state=EXIT1_DR; }; break; case EXIT1_DR: switch(state){ case PAUSE_DR: case EXIT2_DR: case SHIFT_DR: case EXIT1_DR: tms=false; current_state=PAUSE_DR; break; default: tms=true; current_state=UPDATE_DR; }; break; case PAUSE_DR: switch(state){ case PAUSE_DR: tms=false; break; default: tms=true; current_state=EXIT2_DR; }; break; case EXIT2_DR: switch(state){ case SHIFT_DR: case EXIT1_DR: case PAUSE_DR: tms=false; current_state=SHIFT_DR; break; default: tms=true; current_state=UPDATE_DR; }; break; case UPDATE_DR: switch(state){ case RUN_TEST_IDLE: tms=false; current_state=RUN_TEST_IDLE; break; default: tms=true; current_state=SELECT_DR_SCAN; }; break; case SELECT_IR_SCAN: switch(state){ case CAPTURE_IR: case SHIFT_IR: case EXIT1_IR: case PAUSE_IR: case EXIT2_IR: case UPDATE_IR: tms=false; current_state=CAPTURE_IR; break; default: tms=true; current_state=TEST_LOGIC_RESET; }; break; case CAPTURE_IR: switch(state){ case SHIFT_IR: tms=false; current_state=SHIFT_IR; break; default: tms=true; current_state=EXIT1_IR; }; break; case SHIFT_IR: switch(state){ case SHIFT_IR: tms=false; break; default: tms=true; current_state=EXIT1_IR; }; break; case EXIT1_IR: switch(state){ case PAUSE_IR: case EXIT2_IR: case SHIFT_IR: case EXIT1_IR: tms=false; current_state=PAUSE_IR; break; default: tms=true; current_state=UPDATE_IR; }; break; case PAUSE_IR: switch(state){ case PAUSE_IR: tms=false; break; default: tms=true; current_state=EXIT2_IR; }; break; case EXIT2_IR: switch(state){ case SHIFT_IR: case EXIT1_IR: case PAUSE_IR: tms=false; current_state=SHIFT_IR; break; default: tms=true; current_state=UPDATE_IR; }; break; case UPDATE_IR: switch(state){ case RUN_TEST_IDLE: tms=false; current_state=RUN_TEST_IDLE; break; default: tms=true; current_state=SELECT_DR_SCAN; }; break; default: tapTestLogicReset(); tms=true; }; if(fp_dbg) fprintf(fp_dbg,"TMS %d: %s\n", tms, getStateName(current_state)); io->set_tms(tms); } for(int i=0; iset_tms(false); } // After shift data into the DR or IR we goto the next state // This function should only be called from the end of a shift function void Jtag::nextTapState(bool tms) { if(current_state==SHIFT_DR){ if(tms)current_state=EXIT1_DR; // If TMS was set then goto next state } else if(current_state==SHIFT_IR){ if(tms)current_state=EXIT1_IR; // If TMS was set then goto next state } else { fprintf(stderr,"Unexpected state %d\n",current_state); tapTestLogicReset(); // We were in an unexpected state } } void Jtag::tapTestLogicReset() { int i; for(i=0; i<5; i++) io->set_tms(true); current_state=TEST_LOGIC_RESET; io->flush_tms(true); } xc3sprog-0+svn795+dfsg/jtag.h000066400000000000000000000074511337255630200160640ustar00rootroot00000000000000/* JTAG routines Copyright (C) 2004 Andrew Rogers 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 Changes: Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: Code cleanup for clean -Wall compile. */ #ifndef JTAG_H #define JTAG_H #include #include #include #include "iobase.h" #include "bitrev.h" #ifdef __WIN32__ #include #endif typedef unsigned char byte; typedef uint32_t DeviceID; class Jtag { public: enum tapState_t{ TEST_LOGIC_RESET=0, RUN_TEST_IDLE=1, SELECT_DR_SCAN=2, CAPTURE_DR=3, SHIFT_DR=4, EXIT1_DR=5, PAUSE_DR=6, EXIT2_DR=7, UPDATE_DR=8, SELECT_IR_SCAN=9, CAPTURE_IR=10, SHIFT_IR=11, EXIT1_IR=12, PAUSE_IR=13, EXIT2_IR=14, UPDATE_IR=15, UNKNOWN=999 }; private: bool verbose; tapState_t current_state; static const int MAXNUMDEVICES=1000; protected: struct chainParam_t { DeviceID idcode; // Store IDCODE //byte bypass[4]; // The bypass instruction. Most instruction register lengths are a lot less than 32 bits. int irlen; // instruction register length. }; std::vector devices; IOBase *io; int numDevices; tapState_t postDRState; tapState_t postIRState; int deviceIndex; FILE *fp_svf; bool shiftDRincomplete; FILE *fp_dbg; const char* getStateName(tapState_t s); public: Jtag(IOBase *iob); ~Jtag(); void setVerbose(bool v) { verbose = v; } bool getVerbose(void) { return verbose; } int getChain(bool detect = false); // Shift IDCODEs from devices inline void setPostDRState(tapState_t s){postDRState=s;} inline void setPostIRState(tapState_t s){postIRState=s;} void setTapState(tapState_t state, int pre=0); void tapTestLogicReset(void); void nextTapState(bool tms); void cycleTCK(int n, bool tdi=1); tapState_t getTapState(void); int setDeviceIRLength(int dev, int len); DeviceID getDeviceID(unsigned int dev){ if(dev>=devices.size())return 0; return devices[dev].idcode; } void Usleep(unsigned int usec) {io->Usleep(usec);} int selectDevice(int dev); void shiftDR(const byte *tdi, byte *tdo, int length, int align=0, bool exit=true);// Some devices use TCK for aligning data, for example, Xilinx FPGAs for configuration data. void shiftIR(const byte *tdi, byte *tdo=0); // No length argumant required as IR length specified in chainParam_t inline void longToByteArray(unsigned long l, byte *b){ b[0]=(byte)(l&0xff); b[1]=(byte)((l>>8)&0xff); b[2]=(byte)((l>>16)&0xff); b[3]=(byte)((l>>24)&0xff); } inline void longToByteArrayRev(unsigned long l, byte *b){ b[0]=bitRevTable[ l & 0xff]; b[1]=bitRevTable[(l>> 8) & 0xff]; b[2]=bitRevTable[(l>>16) & 0xff]; b[3]=bitRevTable[(l>>24) & 0xff]; } inline void shortToByteArray(const unsigned short l, byte *b){ b[0]=(byte)(l&0xff); b[1]=(byte)((l>>8)&0xff); } inline unsigned long byteArrayToLong(const byte *b){ return ((unsigned long)b[3]<<24)+((unsigned long)b[2]<<16)+ ((unsigned long)b[1]<<8)+(unsigned long)b[0]; } static inline uint16_t byteArrayToShort(const byte *b) { return ((uint16_t)b[0]) | (((uint16_t)b[1]) << 8); } }; #endif //JTAG_H xc3sprog-0+svn795+dfsg/libusb0/000077500000000000000000000000001337255630200163175ustar00rootroot00000000000000xc3sprog-0+svn795+dfsg/libusb0/usb.h000066400000000000000000000246411337255630200172700ustar00rootroot00000000000000#ifndef __USB_H__ #define __USB_H__ #include #include /* * 'interface' is defined somewhere in the Windows header files. This macro * is deleted here to avoid conflicts and compile errors. */ #ifdef interface #undef interface #endif /* * PATH_MAX from limits.h can't be used on Windows if the dll and * import libraries are build/used by different compilers */ #define LIBUSB_PATH_MAX 512 /* * USB spec information * * This is all stuff grabbed from various USB specs and is pretty much * not subject to change */ /* * Device and/or Interface Class codes */ #define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */ #define USB_CLASS_AUDIO 1 #define USB_CLASS_COMM 2 #define USB_CLASS_HID 3 #define USB_CLASS_PRINTER 7 #define USB_CLASS_MASS_STORAGE 8 #define USB_CLASS_HUB 9 #define USB_CLASS_DATA 10 #define USB_CLASS_VENDOR_SPEC 0xff /* * Descriptor types */ #define USB_DT_DEVICE 0x01 #define USB_DT_CONFIG 0x02 #define USB_DT_STRING 0x03 #define USB_DT_INTERFACE 0x04 #define USB_DT_ENDPOINT 0x05 #define USB_DT_HID 0x21 #define USB_DT_REPORT 0x22 #define USB_DT_PHYSICAL 0x23 #define USB_DT_HUB 0x29 /* * Descriptor sizes per descriptor type */ #define USB_DT_DEVICE_SIZE 18 #define USB_DT_CONFIG_SIZE 9 #define USB_DT_INTERFACE_SIZE 9 #define USB_DT_ENDPOINT_SIZE 7 #define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ #define USB_DT_HUB_NONVAR_SIZE 7 /* ensure byte-packed structures */ #include /* All standard descriptors have these 2 fields in common */ struct usb_descriptor_header { unsigned char bLength; unsigned char bDescriptorType; }; /* String descriptor */ struct usb_string_descriptor { unsigned char bLength; unsigned char bDescriptorType; unsigned short wData[1]; }; /* HID descriptor */ struct usb_hid_descriptor { unsigned char bLength; unsigned char bDescriptorType; unsigned short bcdHID; unsigned char bCountryCode; unsigned char bNumDescriptors; }; /* Endpoint descriptor */ #define USB_MAXENDPOINTS 32 struct usb_endpoint_descriptor { unsigned char bLength; unsigned char bDescriptorType; unsigned char bEndpointAddress; unsigned char bmAttributes; unsigned short wMaxPacketSize; unsigned char bInterval; unsigned char bRefresh; unsigned char bSynchAddress; unsigned char *extra; /* Extra descriptors */ int extralen; }; #define USB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */ #define USB_ENDPOINT_DIR_MASK 0x80 #define USB_ENDPOINT_TYPE_MASK 0x03 /* in bmAttributes */ #define USB_ENDPOINT_TYPE_CONTROL 0 #define USB_ENDPOINT_TYPE_ISOCHRONOUS 1 #define USB_ENDPOINT_TYPE_BULK 2 #define USB_ENDPOINT_TYPE_INTERRUPT 3 /* Interface descriptor */ #define USB_MAXINTERFACES 32 struct usb_interface_descriptor { unsigned char bLength; unsigned char bDescriptorType; unsigned char bInterfaceNumber; unsigned char bAlternateSetting; unsigned char bNumEndpoints; unsigned char bInterfaceClass; unsigned char bInterfaceSubClass; unsigned char bInterfaceProtocol; unsigned char iInterface; struct usb_endpoint_descriptor *endpoint; unsigned char *extra; /* Extra descriptors */ int extralen; }; #define USB_MAXALTSETTING 128 /* Hard limit */ struct usb_interface { struct usb_interface_descriptor *altsetting; int num_altsetting; }; /* Configuration descriptor information.. */ #define USB_MAXCONFIG 8 struct usb_config_descriptor { unsigned char bLength; unsigned char bDescriptorType; unsigned short wTotalLength; unsigned char bNumInterfaces; unsigned char bConfigurationValue; unsigned char iConfiguration; unsigned char bmAttributes; unsigned char MaxPower; struct usb_interface *interface; unsigned char *extra; /* Extra descriptors */ int extralen; }; /* Device descriptor */ struct usb_device_descriptor { unsigned char bLength; unsigned char bDescriptorType; unsigned short bcdUSB; unsigned char bDeviceClass; unsigned char bDeviceSubClass; unsigned char bDeviceProtocol; unsigned char bMaxPacketSize0; unsigned short idVendor; unsigned short idProduct; unsigned short bcdDevice; unsigned char iManufacturer; unsigned char iProduct; unsigned char iSerialNumber; unsigned char bNumConfigurations; }; struct usb_ctrl_setup { unsigned char bRequestType; unsigned char bRequest; unsigned short wValue; unsigned short wIndex; unsigned short wLength; }; /* * Standard requests */ #define USB_REQ_GET_STATUS 0x00 #define USB_REQ_CLEAR_FEATURE 0x01 /* 0x02 is reserved */ #define USB_REQ_SET_FEATURE 0x03 /* 0x04 is reserved */ #define USB_REQ_SET_ADDRESS 0x05 #define USB_REQ_GET_DESCRIPTOR 0x06 #define USB_REQ_SET_DESCRIPTOR 0x07 #define USB_REQ_GET_CONFIGURATION 0x08 #define USB_REQ_SET_CONFIGURATION 0x09 #define USB_REQ_GET_INTERFACE 0x0A #define USB_REQ_SET_INTERFACE 0x0B #define USB_REQ_SYNCH_FRAME 0x0C #define USB_TYPE_STANDARD (0x00 << 5) #define USB_TYPE_CLASS (0x01 << 5) #define USB_TYPE_VENDOR (0x02 << 5) #define USB_TYPE_RESERVED (0x03 << 5) #define USB_RECIP_DEVICE 0x00 #define USB_RECIP_INTERFACE 0x01 #define USB_RECIP_ENDPOINT 0x02 #define USB_RECIP_OTHER 0x03 /* * Various libusb API related stuff */ #define USB_ENDPOINT_IN 0x80 #define USB_ENDPOINT_OUT 0x00 /* Error codes */ #define USB_ERROR_BEGIN 500000 /* * This is supposed to look weird. This file is generated from autoconf * and I didn't want to make this too complicated. */ #define USB_LE16_TO_CPU(x) /* Data types */ /* struct usb_device; */ /* struct usb_bus; */ struct usb_device { struct usb_device *next, *prev; char filename[LIBUSB_PATH_MAX]; struct usb_bus *bus; struct usb_device_descriptor descriptor; struct usb_config_descriptor *config; void *dev; /* Darwin support */ unsigned char devnum; unsigned char num_children; struct usb_device **children; }; struct usb_bus { struct usb_bus *next, *prev; char dirname[LIBUSB_PATH_MAX]; struct usb_device *devices; unsigned long location; struct usb_device *root_dev; }; /* Version information, Windows specific */ struct usb_version { struct { int major; int minor; int micro; int nano; } dll; struct { int major; int minor; int micro; int nano; } driver; }; struct usb_dev_handle; typedef struct usb_dev_handle usb_dev_handle; /* Variables */ #ifndef __USB_C__ #define usb_busses usb_get_busses() #endif #include #ifdef __cplusplus extern "C" { #endif /* Function prototypes */ /* usb.c */ usb_dev_handle *usb_open(struct usb_device *dev); int usb_close(usb_dev_handle *dev); int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, size_t buflen); int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, size_t buflen); /* descriptors.c */ int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep, unsigned char type, unsigned char index, void *buf, int size); int usb_get_descriptor(usb_dev_handle *udev, unsigned char type, unsigned char index, void *buf, int size); /* .c */ int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout); int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout); int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout); int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout); int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout); int usb_set_configuration(usb_dev_handle *dev, int configuration); int usb_claim_interface(usb_dev_handle *dev, int interface); int usb_release_interface(usb_dev_handle *dev, int interface); int usb_set_altinterface(usb_dev_handle *dev, int alternate); int usb_resetep(usb_dev_handle *dev, unsigned int ep); int usb_clear_halt(usb_dev_handle *dev, unsigned int ep); int usb_reset(usb_dev_handle *dev); char *usb_strerror(void); void usb_init(void); void usb_set_debug(int level); int usb_find_busses(void); int usb_find_devices(void); struct usb_device *usb_device(usb_dev_handle *dev); struct usb_bus *usb_get_busses(void); /* Windows specific functions */ #define LIBUSB_HAS_INSTALL_SERVICE_NP 1 int usb_install_service_np(void); void CALLBACK usb_install_service_np_rundll(HWND wnd, HINSTANCE instance, LPSTR cmd_line, int cmd_show); #define LIBUSB_HAS_UNINSTALL_SERVICE_NP 1 int usb_uninstall_service_np(void); void CALLBACK usb_uninstall_service_np_rundll(HWND wnd, HINSTANCE instance, LPSTR cmd_line, int cmd_show); #define LIBUSB_HAS_INSTALL_DRIVER_NP 1 int usb_install_driver_np(const char *inf_file); void CALLBACK usb_install_driver_np_rundll(HWND wnd, HINSTANCE instance, LPSTR cmd_line, int cmd_show); #define LIBUSB_HAS_TOUCH_INF_FILE_NP 1 int usb_touch_inf_file_np(const char *inf_file); void CALLBACK usb_touch_inf_file_np_rundll(HWND wnd, HINSTANCE instance, LPSTR cmd_line, int cmd_show); #define LIBUSB_HAS_INSTALL_NEEDS_RESTART_NP 1 int usb_install_needs_restart_np(void); const struct usb_version *usb_get_version(void); int usb_isochronous_setup_async(usb_dev_handle *dev, void **context, unsigned char ep, int pktsize); int usb_bulk_setup_async(usb_dev_handle *dev, void **context, unsigned char ep); int usb_interrupt_setup_async(usb_dev_handle *dev, void **context, unsigned char ep); int usb_submit_async(void *context, char *bytes, int size); int usb_reap_async(void *context, int timeout); int usb_reap_async_nocancel(void *context, int timeout); int usb_cancel_async(void *context); int usb_free_async(void **context); #ifdef __cplusplus } #endif #endif /* __USB_H__ */ xc3sprog-0+svn795+dfsg/libusb_dyn.c000066400000000000000000000401601337255630200172560ustar00rootroot00000000000000/* LIBUSB-WIN32, Generic Windows USB Library * Copyright (c) 2002-2005 Stephan Meyer * * 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifdef __WIN32__ #include #define LIBUSB_DLL_NAME "libusb0.dll" #else #include #endif #include #include #include typedef usb_dev_handle * (*usb_open_t)(struct usb_device *dev); typedef int (*usb_close_t)(usb_dev_handle *dev); typedef int (*usb_get_string_t)(usb_dev_handle *dev, int index, int langid, char *buf, size_t buflen); typedef int (*usb_get_string_simple_t)(usb_dev_handle *dev, int index, char *buf, size_t buflen); typedef int (*usb_get_descriptor_by_endpoint_t)(usb_dev_handle *udev, int ep, unsigned char type, unsigned char index, void *buf, int size); typedef int (*usb_get_descriptor_t)(usb_dev_handle *udev, unsigned char type, unsigned char index, void *buf, int size); typedef int (*usb_bulk_write_t)(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout); typedef int (*usb_bulk_read_t)(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout); typedef int (*usb_interrupt_write_t)(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout); typedef int (*usb_interrupt_read_t)(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout); typedef int (*usb_control_msg_t)(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout); typedef int (*usb_set_configuration_t)(usb_dev_handle *dev, int configuration); typedef int (*usb_claim_interface_t)(usb_dev_handle *dev, int interface); typedef int (*usb_release_interface_t)(usb_dev_handle *dev, int interface); typedef int (*usb_set_altinterface_t)(usb_dev_handle *dev, int alternate); typedef int (*usb_resetep_t)(usb_dev_handle *dev, unsigned int ep); typedef int (*usb_clear_halt_t)(usb_dev_handle *dev, unsigned int ep); typedef int (*usb_reset_t)(usb_dev_handle *dev); typedef char * (*usb_strerror_t)(void); typedef void (*usb_init_t)(void); typedef void (*usb_set_debug_t)(int level); typedef int (*usb_find_busses_t)(void); typedef int (*usb_find_devices_t)(void); typedef struct usb_device * (*usb_device_t)(usb_dev_handle *dev); typedef struct usb_bus * (*usb_get_busses_t)(void); typedef int (*usb_install_service_np_t)(void); typedef int (*usb_uninstall_service_np_t)(void); typedef int (*usb_install_driver_np_t)(const char *inf_file); typedef const struct usb_version * (*usb_get_version_t)(void); typedef int (*usb_isochronous_setup_async_t)(usb_dev_handle *dev, void **context, unsigned char ep, int pktsize); typedef int (*usb_bulk_setup_async_t)(usb_dev_handle *dev, void **context, unsigned char ep); typedef int (*usb_interrupt_setup_async_t)(usb_dev_handle *dev, void **context, unsigned char ep); typedef int (*usb_submit_async_t)(void *context, char *bytes, int size); typedef int (*usb_reap_async_t)(void *context, int timeout); typedef int (*usb_free_async_t)(void **context); static usb_open_t _usb_open = NULL; static usb_close_t _usb_close = NULL; static usb_get_string_t _usb_get_string = NULL; static usb_get_string_simple_t _usb_get_string_simple = NULL; static usb_get_descriptor_by_endpoint_t _usb_get_descriptor_by_endpoint = NULL; static usb_get_descriptor_t _usb_get_descriptor = NULL; static usb_bulk_write_t _usb_bulk_write = NULL; static usb_bulk_read_t _usb_bulk_read = NULL; static usb_interrupt_write_t _usb_interrupt_write = NULL; static usb_interrupt_read_t _usb_interrupt_read = NULL; static usb_control_msg_t _usb_control_msg = NULL; static usb_set_configuration_t _usb_set_configuration = NULL; static usb_claim_interface_t _usb_claim_interface = NULL; static usb_release_interface_t _usb_release_interface = NULL; static usb_set_altinterface_t _usb_set_altinterface = NULL; static usb_resetep_t _usb_resetep = NULL; static usb_clear_halt_t _usb_clear_halt = NULL; static usb_reset_t _usb_reset = NULL; static usb_strerror_t _usb_strerror = NULL; static usb_init_t _usb_init = NULL; static usb_set_debug_t _usb_set_debug = NULL; static usb_find_busses_t _usb_find_busses = NULL; static usb_find_devices_t _usb_find_devices = NULL; static usb_device_t _usb_device = NULL; static usb_get_busses_t _usb_get_busses = NULL; static usb_install_service_np_t _usb_install_service_np = NULL; static usb_uninstall_service_np_t _usb_uninstall_service_np = NULL; static usb_install_driver_np_t _usb_install_driver_np = NULL; static usb_get_version_t _usb_get_version = NULL; static usb_isochronous_setup_async_t _usb_isochronous_setup_async = NULL; static usb_bulk_setup_async_t _usb_bulk_setup_async = NULL; static usb_interrupt_setup_async_t _usb_interrupt_setup_async = NULL; static usb_submit_async_t _usb_submit_async = NULL; static usb_reap_async_t _usb_reap_async = NULL; static usb_free_async_t _usb_free_async = NULL; #ifdef __WIN32__ #else typedef int (*usb_detach_kernel_driver_np_t)(usb_dev_handle *dev, int interface); static usb_detach_kernel_driver_np_t _usb_detach_kernel_driver_np = NULL; #endif void usb_init(void) { #ifdef __WIN32__ HINSTANCE libusb_dll = LoadLibrary(LIBUSB_DLL_NAME); #else void *libusb_dll = dlopen("libusb.so", RTLD_LAZY); #define GetProcAddress(x,y) dlsym(x,y) #define ENOFILE ENOENT #endif if(!libusb_dll) { fprintf(stderr, "Libusb not found, expect failure\n"); return; } _usb_open = (usb_open_t) GetProcAddress(libusb_dll, "usb_open"); _usb_close = (usb_close_t) GetProcAddress(libusb_dll, "usb_close"); _usb_get_string = (usb_get_string_t) GetProcAddress(libusb_dll, "usb_get_string"); _usb_get_string_simple = (usb_get_string_simple_t) GetProcAddress(libusb_dll, "usb_get_string_simple"); _usb_get_descriptor_by_endpoint = (usb_get_descriptor_by_endpoint_t) GetProcAddress(libusb_dll, "usb_get_descriptor_by_endpoint"); _usb_get_descriptor = (usb_get_descriptor_t) GetProcAddress(libusb_dll, "usb_get_descriptor"); _usb_bulk_write = (usb_bulk_write_t) GetProcAddress(libusb_dll, "usb_bulk_write"); _usb_bulk_read = (usb_bulk_read_t) GetProcAddress(libusb_dll, "usb_bulk_read"); _usb_interrupt_write = (usb_interrupt_write_t) GetProcAddress(libusb_dll, "usb_interrupt_write"); _usb_interrupt_read = (usb_interrupt_read_t) GetProcAddress(libusb_dll, "usb_interrupt_read"); _usb_control_msg = (usb_control_msg_t) GetProcAddress(libusb_dll, "usb_control_msg"); _usb_set_configuration = (usb_set_configuration_t) GetProcAddress(libusb_dll, "usb_set_configuration"); _usb_claim_interface = (usb_claim_interface_t) GetProcAddress(libusb_dll, "usb_claim_interface"); _usb_release_interface = (usb_release_interface_t) GetProcAddress(libusb_dll, "usb_release_interface"); _usb_set_altinterface = (usb_set_altinterface_t) GetProcAddress(libusb_dll, "usb_set_altinterface"); _usb_resetep = (usb_resetep_t) GetProcAddress(libusb_dll, "usb_resetep"); _usb_clear_halt = (usb_clear_halt_t) GetProcAddress(libusb_dll, "usb_clear_halt"); _usb_reset = (usb_reset_t) GetProcAddress(libusb_dll, "usb_reset"); _usb_strerror = (usb_strerror_t) GetProcAddress(libusb_dll, "usb_strerror"); _usb_init = (usb_init_t) GetProcAddress(libusb_dll, "usb_init"); _usb_set_debug = (usb_set_debug_t) GetProcAddress(libusb_dll, "usb_set_debug"); _usb_find_busses = (usb_find_busses_t) GetProcAddress(libusb_dll, "usb_find_busses"); _usb_find_devices = (usb_find_devices_t) GetProcAddress(libusb_dll, "usb_find_devices"); _usb_device = (usb_device_t) GetProcAddress(libusb_dll, "usb_device"); _usb_get_busses = (usb_get_busses_t) GetProcAddress(libusb_dll, "usb_get_busses"); _usb_install_service_np = (usb_install_service_np_t) GetProcAddress(libusb_dll, "usb_install_service_np"); _usb_uninstall_service_np = (usb_uninstall_service_np_t) GetProcAddress(libusb_dll, "usb_uninstall_service_np"); _usb_install_driver_np = (usb_install_driver_np_t) GetProcAddress(libusb_dll, "usb_install_driver_np"); _usb_get_version = (usb_get_version_t) GetProcAddress(libusb_dll, "usb_get_version"); _usb_isochronous_setup_async = (usb_isochronous_setup_async_t) GetProcAddress(libusb_dll, "usb_isochronous_setup_async"); _usb_bulk_setup_async = (usb_bulk_setup_async_t) GetProcAddress(libusb_dll, "usb_bulk_setup_async"); _usb_interrupt_setup_async = (usb_interrupt_setup_async_t) GetProcAddress(libusb_dll, "usb_interrupt_setup_async"); _usb_submit_async = (usb_submit_async_t) GetProcAddress(libusb_dll, "usb_submit_async"); _usb_reap_async = (usb_reap_async_t) GetProcAddress(libusb_dll, "usb_reap_async"); _usb_free_async = (usb_free_async_t) GetProcAddress(libusb_dll, "usb_free_async"); #ifdef __WIN32__ #else _usb_detach_kernel_driver_np = ( usb_detach_kernel_driver_np_t) GetProcAddress(libusb_dll, "usb_detach_kernel_driver_np"); #endif if(_usb_init) _usb_init(); } usb_dev_handle *usb_open(struct usb_device *dev) { if(_usb_open) return _usb_open(dev); else return NULL; } int usb_close(usb_dev_handle *dev) { if(_usb_close) return _usb_close(dev); else return -ENOFILE; } int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, size_t buflen) { if(_usb_get_string) return _usb_get_string(dev, index, langid, buf, buflen); else return -ENOFILE; } int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, size_t buflen) { if(_usb_get_string_simple) return _usb_get_string_simple(dev, index, buf, buflen); else return -ENOFILE; } int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep, unsigned char type, unsigned char index, void *buf, int size) { if(_usb_get_descriptor_by_endpoint) return _usb_get_descriptor_by_endpoint(udev, ep, type, index, buf, size); else return -ENOFILE; } int usb_get_descriptor(usb_dev_handle *udev, unsigned char type, unsigned char index, void *buf, int size) { if(_usb_get_descriptor) return _usb_get_descriptor(udev, type, index, buf, size); else return -ENOFILE; } int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout) { if(_usb_bulk_write) return _usb_bulk_write(dev, ep, bytes, size, timeout); else return -ENOFILE; } int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout) { if(_usb_bulk_read) return _usb_bulk_read(dev, ep, bytes, size, timeout); else return -ENOFILE; } int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout) { if(_usb_interrupt_write) return _usb_interrupt_write(dev, ep, bytes, size, timeout); else return -ENOFILE; } int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout) { if(_usb_interrupt_read) return _usb_interrupt_read(dev, ep, bytes, size, timeout); else return -ENOFILE; } int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout) { if(_usb_control_msg) return _usb_control_msg(dev, requesttype, request, value, index, bytes, size, timeout); else return -ENOFILE; } int usb_set_configuration(usb_dev_handle *dev, int configuration) { if(_usb_set_configuration) return _usb_set_configuration(dev, configuration); else return -ENOFILE; } int usb_claim_interface(usb_dev_handle *dev, int interface) { if(_usb_claim_interface) return _usb_claim_interface(dev, interface); else return -ENOFILE; } int usb_release_interface(usb_dev_handle *dev, int interface) { if(_usb_release_interface) return _usb_release_interface(dev, interface); else return -ENOFILE; } int usb_set_altinterface(usb_dev_handle *dev, int alternate) { if(_usb_set_altinterface) return _usb_set_altinterface(dev, alternate); else return -ENOFILE; } int usb_resetep(usb_dev_handle *dev, unsigned int ep) { if(_usb_resetep) return _usb_resetep(dev, ep); else return -ENOFILE; } int usb_clear_halt(usb_dev_handle *dev, unsigned int ep) { if(_usb_clear_halt) return _usb_clear_halt(dev, ep); else return -ENOFILE; } int usb_reset(usb_dev_handle *dev) { if(_usb_reset) return _usb_reset(dev); else return -ENOFILE; } char *usb_strerror(void) { if(_usb_strerror) return _usb_strerror(); else return NULL; } void usb_set_debug(int level) { if(_usb_set_debug) return _usb_set_debug(level); } int usb_find_busses(void) { if(_usb_find_busses) return _usb_find_busses(); else return -ENOFILE; } int usb_find_devices(void) { if(_usb_find_devices) return _usb_find_devices(); else return -ENOFILE; } struct usb_device *usb_device(usb_dev_handle *dev) { if(_usb_device) return _usb_device(dev); else return NULL; } struct usb_bus *usb_get_busses(void) { if(_usb_get_busses) return _usb_get_busses(); else return NULL; } int usb_install_service_np(void) { if(_usb_install_service_np) return _usb_install_service_np(); else return -ENOFILE; } int usb_uninstall_service_np(void) { if(_usb_uninstall_service_np) return _usb_uninstall_service_np(); else return -ENOFILE; } int usb_install_driver_np(const char *inf_file) { if(_usb_install_driver_np) return _usb_install_driver_np(inf_file); else return -ENOFILE; } const struct usb_version *usb_get_version(void) { if(_usb_get_version) return _usb_get_version(); else return NULL; } int usb_isochronous_setup_async(usb_dev_handle *dev, void **context, unsigned char ep, int pktsize) { if(_usb_isochronous_setup_async) return _usb_isochronous_setup_async(dev, context, ep, pktsize); else return -ENOFILE; } int usb_bulk_setup_async(usb_dev_handle *dev, void **context, unsigned char ep) { if(_usb_bulk_setup_async) return _usb_bulk_setup_async(dev, context, ep); else return -ENOFILE; } int usb_interrupt_setup_async(usb_dev_handle *dev, void **context, unsigned char ep) { if(_usb_interrupt_setup_async) return _usb_interrupt_setup_async(dev, context, ep); else return -ENOFILE; } int usb_submit_async(void *context, char *bytes, int size) { if(_usb_submit_async) return _usb_submit_async(context, bytes, size); else return -ENOFILE; } int usb_reap_async(void *context, int timeout) { if(_usb_reap_async) return _usb_reap_async(context, timeout); else return -ENOFILE; } int usb_free_async(void **context) { if(_usb_free_async) return _usb_free_async(context); else return -ENOFILE; } #ifdef __WIN32__ #else int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface) { if(_usb_detach_kernel_driver_np) return _usb_detach_kernel_driver_np(dev, interface); else return -ENOFILE; } #endif xc3sprog-0+svn795+dfsg/mapfile_xc2c.cpp000066400000000000000000000125671337255630200200320ustar00rootroot00000000000000/* * Warp Coolrunner II Jedecfile to Bitfiles suitable for programming * and vice- versa * * Needs access to the Xilinx supplied .map files for transformation * * Copyright Uwe Bonnes 2009 bon@elektron.ikp.physik.tu-darmstadt.de * */ #include #include #include #include #include "mapfile_xc2c.h" #ifndef MAPDIR #if defined (__linux__) || defined(__FreeBSD__) || defined(__MACH__) #define MAPDIR "/opt/Xilinx/12.4/ISE_DS/ISE/xbr/data" #elif defined(__WIN32__) #define MAPDIR "c:" #endif #endif #define MAP_ZERO -1 #define MAP_ONE -2 #define MAP_SPARE -3 #define MAP_SEC -10 /* sec_0 = -10, ... , sec_6 = -4 */ #define MAP_DONE -12 /* done_0 = -12, done_1 = -11 */ #define MAP_USER -44 /* user_0 = -44, ..., user_31 = -13 */ MapFile_XC2C::MapFile_XC2C() { map = 0; } MapFile_XC2C::~MapFile_XC2C() { if (map) free(map); } int MapFile_XC2C::readmap(FILE *fp) { unsigned int i=0, j=0, k=0; int num = 0; char buffer[8]; int x; int empty = 2; while ((x = fgetc(fp)) != EOF) { switch (x) { case 0x09: case '\n': /* Lines with all TABs mark transfer bits and those bits should be set 0 other empty places should be set 1 */ if (empty == 2) num = MAP_ZERO; /* Empty line (for now) */ else if(empty == 1) num = MAP_ONE; /* Empty place */ else empty = 1; /* If not empty reset the value for next token */ if(k > 0) /* String value */ { if (strncmp(buffer, "spare", k) == 0) num = MAP_SPARE; else if(strncmp(buffer, "sec_", k) == 0) num += MAP_SEC; else if(strncmp(buffer, "done_", k) == 0) num += MAP_DONE; else if(strncmp(buffer, "user_", k) == 0) num += MAP_USER; k = 0; } /* Store value */ map[i*block_num+j] = num; num = 0; j++; if(x == '\n') { j = 0; i++; empty = 2; } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': num = 10 * num + (x-'0'); empty = 0; break; case '\r': break; case '_': case 'a' ... 'z': if(k < sizeof(buffer)) buffer[k++] = x; empty = 0; break; } } return 0; } int MapFile_XC2C::loadmapfile(const char *mapdir, const char *device) { FILE *fp; const char * mapfile; if (strncasecmp(device, "XC2C32", 6) == 0) { block_size = 260; block_num = 48; if (strncasecmp(device, "XC2C32A", 7) == 0) mapfile = "xc2c32a"; else mapfile = "xc2c32"; } else if (strncasecmp(device, "XC2C64", 6) == 0) { block_size = 274; block_num = 96; if (strncasecmp(device, "XC2C64A", 7) == 0) mapfile = "xc2c64a"; else mapfile = "xc2c64"; } else if (strncasecmp(device, "XC2C128", 7) == 0) { block_size = 752; block_num = 80; mapfile = "xc2c128"; } else if (strncasecmp(device, "XC2C256", 7) == 0) { block_size = 1364; block_num = 96; mapfile = "xc2c256"; } else if (strncasecmp(device, "XC2C384", 7) == 0) { block_size = 1868; block_num = 120; mapfile = "xc2c384"; } else if (strncasecmp(device, "XC2C512", 7) == 0) { block_size = 1980; block_num = 160; mapfile = "xc2c512"; } /* There are two extra rows for security/done and usercode bits*/ block_num += 2; if (!mapdir) if(!(mapdir = getenv("XC_MAPDIR"))) mapdir = MAPDIR; mapfilename = (char *) malloc(strlen(mapdir)+strlen(mapfile)+6); if (mapfilename) { strcpy(mapfilename, mapdir); strcat(mapfilename, "/"); strcat(mapfilename, mapfile); strcat(mapfilename, ".map"); } fp = fopen(mapfilename, "rb"); free(mapfilename); if (fp == NULL) { fprintf(stderr,"Mapfile %s/%s.map not found: %s\n", mapdir, mapfile, strerror(errno)); return 1; } if(map) free (map); map = (int *) malloc(block_size * (block_num) * sizeof(unsigned int)); if (map == NULL) return 2; memset(map, 0, block_size * (block_num) * sizeof(unsigned int)); readmap(fp); fclose(fp); return 0; } void MapFile_XC2C::jedecfile2bitfile(uint32_t usercode, JedecFile *fuses, BitFile *bits) { int i, j; bits->setLength(block_size*block_num); for (i=0; i> (fuse_idx-MAP_USER) & 1; break; default: /* xc2c32a.map from 10.1 contain 0 .. 12278 versus 0..12277 */ if (fuse_idx < (int)fuses->getLength()) fuse = fuses->get_fuse(fuse_idx); } bits->set_bit(bitnum, fuse); } } } void MapFile_XC2C::bitfile2jedecfile(BitFile *bits, JedecFile *fuses) { int i, j; fuses->setLength(block_size*block_num); int maxnum =0; for (i=0; iget_bit(bitnum); if (fuse_idx>= 0) { if (fuse_idx > maxnum) maxnum = fuse_idx; fuses->set_fuse(fuse_idx, bit); } } } fuses->setLength(maxnum+1); } xc3sprog-0+svn795+dfsg/mapfile_xc2c.h000066400000000000000000000011021337255630200174560ustar00rootroot00000000000000#ifndef MAPFILE_XC2C_H #define MAPFILE_XC2C_H #include "jedecfile.h" #include "bitfile.h" class MapFile_XC2C { private: char *mapfilename; int block_size; int block_num; int post; int *map; int readmap(FILE *); public: MapFile_XC2C(void); ~MapFile_XC2C(void); int loadmapfile(const char *mapdir, const char *mapfile); void jedecfile2bitfile(uint32_t usercode, JedecFile *fuses, BitFile *bits); void bitfile2jedecfile(BitFile *bits, JedecFile *fuses); const char *GetFilename(){return (mapfilename)?mapfilename:"";}; }; #endif /* MAPFILE_XC2C_H */ xc3sprog-0+svn795+dfsg/multiboot/000077500000000000000000000000001337255630200167755ustar00rootroot00000000000000xc3sprog-0+svn795+dfsg/multiboot/README000066400000000000000000000011741337255630200176600ustar00rootroot00000000000000Adapt the example from Xilinx SP601 XTP038.pdf for your setup. Generate BIT File: ../build/bitparse -i hexraw .bit Generate BIN File: ../build/bitparse -i hexraw -o bin -O .bin Spartan6: ======== At least the Multiboot Image should be generated with the bitgen Options " -g next_config_register_write:Disable" " -g Reset_on_err:Yes" so that booting a partial written or corrupted multiboot image will result in the golden image to be booted. Otherwise only a Flash pattern with no valid sync pattern at the multiboot address (and up bitgen option TIMER_CFG = 0x10000 bytes) will use the golden image. xc3sprog-0+svn795+dfsg/multiboot/mb_xc6_spi_0x01_0x19.bin000066400000000000000000000000701337255630200230460ustar00rootroot00000000000000ÿÿÿÿª™Uf1áÿÿ2a22¡2Á2á0¡3!20¡ xc3sprog-0+svn795+dfsg/multiboot/mb_xc6_spi_0x01_0x19.bit000066400000000000000000000001641337255630200230600ustar00rootroot00000000000000 ðððða XC3SPROGbc 2011/02/03d 14:22:38e8ÿÿÿÿª™Uf1áÿÿ2a22¡2Á2á0¡3!20¡ xc3sprog-0+svn795+dfsg/multiboot/mb_xc6_spi_0x01_0x19.hex000066400000000000000000000007561337255630200230750ustar00rootroot00000000000000FFFFFFFF // DUMMYWORD, DUMMYWORD AA995566 // SYNCWORD 31E1FFFF 32610000 // 32A1=GENERAL1 0x0000=address[15:0] MultiBoot image location 32810319 // 3281=GENERAL2 0x03=SPIx1 read command, 0x40=address[23:16] MultiBoot image address 32A10000 // 32A1=GENERAL3 0x0000=address[15:0] Golden image address location 32C10301 // 32C1=GENERAL4 0x03=SPIx1 read command, 0x01=address[23:16] of Golden image address 32E10000 30A10000 33012100 3201001F 30A1000E 20002000 // NOOP, NOOP 20002000 // NOOP, NOOP xc3sprog-0+svn795+dfsg/multiboot/xtp038.bit000066400000000000000000000001641337255630200205440ustar00rootroot00000000000000 ðððða XC3SPROGbc 2011/02/04d 13:00:08e8ÿÿÿÿª™Uf1áÿÿ2a2@2¡2Á2á0¡3!20¡ xc3sprog-0+svn795+dfsg/multiboot/xtp038.hex000066400000000000000000000007561337255630200205610ustar00rootroot00000000000000FFFFFFFF // DUMMYWORD, DUMMYWORD AA995566 // SYNCWORD 31E1FFFF 32610000 // 32A1=GENERAL1 0x0000=address[15:0] MultiBoot image location 32810340 // 3281=GENERAL2 0x03=SPIx1 read command, 0x40=address[23:16] MultiBoot image address 32A10000 // 32A1=GENERAL3 0x0000=address[15:0] Golden image address location 32C10301 // 32C1=GENERAL4 0x03=SPIx1 read command, 0x01=address[23:16] of Golden image address 32E10000 30A10000 33012100 3201001F 30A1000E 20002000 // NOOP, NOOP 20002000 // NOOP, NOOP xc3sprog-0+svn795+dfsg/packages/000077500000000000000000000000001337255630200165355ustar00rootroot00000000000000xc3sprog-0+svn795+dfsg/packages/CMakeLists.txt000066400000000000000000000010521337255630200212730ustar00rootroot00000000000000# Debian if("${PACKAGE}" STREQUAL "Debian") # Settings set(REVISION 0) set(CPACK_GENERATOR "DEB" PARENT_SCOPE) set(CPACK_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION}-${REVISION} PARENT_SCOPE) # Dependencies set(CPACK_DEBIAN_PACKAGE_DEPENDS "libusb-0.1-4" PARENT_SCOPE) set(DEBIAN_PACKAGE_BUILDS_DEPENDS "cmake, libusb-dev" PARENT_SCOPE) endif("${PACKAGE}" STREQUAL "Debian") # General RPM rules set(CPACK_RPM_PACKAGE_DEPENDS "libusb" "libftdi" PARENT_SCOPE) xc3sprog-0+svn795+dfsg/par_nt.h000066400000000000000000000025411337255630200164150ustar00rootroot00000000000000/* NT Parport Access stuff - Matthew Duggan (2002) */ /* * ParallelVdm Device (0x2C) is mostly undocumented, used by VDM for parallel * port compatibility. */ /* * Different from CTL_CODE in DDK, limited to ParallelVdm but makes this * code cleaner. */ #ifndef _PAR_NT_H #define _PAR_NT_H #define NT_CTL_CODE( Function ) ( (FILE_DEVICE_VDM<<16) | ((Function) << 2) ) /* IOCTL codes */ #define NT_IOCTL_DATA NT_CTL_CODE(1) /* Write Only */ #define NT_IOCTL_CONTROL NT_CTL_CODE(2) /* Read/Write */ #define NT_IOCTL_STATUS NT_CTL_CODE(3) /* Read Only */ /* * Raw port access (PC-style port registers but within inversions) * Functions returning int may fail. */ /* The status pin functions operate in terms of these bits: */ enum ieee1284_status_bits { S1284_NFAULT = 0x08, S1284_SELECT = 0x10, S1284_PERROR = 0x20, S1284_NACK = 0x40, S1284_BUSY = 0x80, /* To convert those values into PC-style register values, use this: */ S1284_INVERTED = S1284_BUSY }; /* The control pin functions operate in terms of these bits: */ enum ieee1284_control_bits { C1284_NSTROBE = 0x01, C1284_NAUTOFD = 0x02, C1284_NINIT = 0x04, C1284_NSELECTIN = 0x08, /* To convert those values into PC-style register values, use this: */ C1284_INVERTED = (C1284_NSTROBE| C1284_NAUTOFD| C1284_NSELECTIN) }; #endif /* _PAR_NT_H */ xc3sprog-0+svn795+dfsg/pdibase.h000066400000000000000000000017571337255630200165510ustar00rootroot00000000000000#ifndef PDIBASE_H #define PDIBASE_H enum PDI_STATUS_CODE { STATUS_OK = 0, //!< Success ERR_IO_ERROR = -1, //!< I/O error ERR_FLUSHED = -2, //!< Request flushed from queue ERR_TIMEOUT = -3, //!< Operation timed out ERR_BAD_DATA = -4, //!< Data integrity check failed ERR_PROTOCOL = -5, //!< Protocol error ERR_UNSUPPORTED_DEV = -6, //!< Unsupported device ERR_NO_MEMORY = -7, //!< Insufficient memory ERR_INVALID_ARG = -8, //!< Invalid argument ERR_BAD_ADDRESS = -9, //!< Bad address ERR_BUSY = -10, //!< Resource is busy ERR_BAD_FORMAT = -11, //!< Data format not recognized }; class PDIBase { protected: virtual enum PDI_STATUS_CODE pdi_write(const uint8_t *data, uint16_t length) =0; virtual uint32_t pdi_read(uint8_t *data, uint32_t length, uint32_t retries) = 0; }; #endif //PDIBASE_H xc3sprog-0+svn795+dfsg/pdioverjtag.cpp000066400000000000000000000063001337255630200200000ustar00rootroot00000000000000/* AVR XMEGA programming algorithms Copyright (C) 2011 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de With Infos from AVR1612 and vsprog/src/target/avrxmega 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 "pdioverjtag.h" PDIoverJTAG::PDIoverJTAG(Jtag *j, uint8_t pdicom) { char *fname = getenv("PDI_DEBUG"); if (fname) pdi_dbg = fopen(fname,"wb"); else pdi_dbg = NULL; jtag=j; pdicmd = pdicom; } PDIoverJTAG::~PDIoverJTAG(void) { if(pdi_dbg) fclose(pdi_dbg); } enum PDI_STATUS_CODE PDIoverJTAG::pdi_write(const uint8_t *data, uint16_t length) { int i; if (pdi_dbg) { fprintf(pdi_dbg, "pdi_write len %d:", length); for (i = 0; i < length; i++ ) fprintf(pdi_dbg, " %02x", data[i]); fprintf(pdi_dbg, "\n"); } jtag->shiftIR(&pdicmd); for (i = 0; i < length; i++) { uint8_t parity_data = get_parity(data[i]); uint8_t sd[2]; sd[0]= data[i]; sd[1] = parity_data; jtag->shiftDR(sd, NULL, 9); } return STATUS_OK; } uint32_t PDIoverJTAG::pdi_read(uint8_t *data, uint32_t length, int retries) { uint32_t i; int j = 0; jtag->shiftIR(&pdicmd); for (i = 0 ; i shiftDR(0, rev, 9); rev[2] = get_parity( rev[0]); while((rev[2] != rev[1]) && (rev[0] == 0xeb) && (j shiftDR(0, rev, 9); rev[2] = get_parity( rev[0]); j++; if (pdi_dbg) fprintf(pdi_dbg, " %02x", rev[0]); } if (j>0 && pdi_dbg) fprintf(pdi_dbg, "\n"); if (j == retries) { if (pdi_dbg) fprintf(pdi_dbg," Read time out\n"); return 0; } if ( rev[2] != rev[1]) { if (pdi_dbg) { uint32_t j; fprintf(pdi_dbg, "\npdi_read parity error at pos %d/%d :", i, length); fprintf(pdi_dbg, " %02x %02x\n", rev[1], rev[0]); for (j = 0; j < i; j++ ) fprintf(pdi_dbg, " %02x", data[j]); fprintf(pdi_dbg, "\n"); } return 0; } data[i] = rev[0]; } if (pdi_dbg) { fprintf(pdi_dbg, "pdi_read:\n"); for (i = 0; i < length; i++ ) { if ((i & 0xf) == 0) fprintf(pdi_dbg, "%04x",i); fprintf(pdi_dbg, "%02x", data[i]); if ((i & 0xf) == 0xf) fprintf(pdi_dbg, "\n"); } fprintf(pdi_dbg, "\n"); } return length; } uint8_t PDIoverJTAG::get_parity(uint8_t data) { int i; uint8_t p = 0; for (i = 0; i < 8; i++) if (data & (1 << i)) p ^= 1; return p; } xc3sprog-0+svn795+dfsg/pdioverjtag.h000066400000000000000000000007311337255630200174470ustar00rootroot00000000000000#ifndef PDIOVERJTAG_H #define PDIOVERJTAG_H #include #include "jtag.h" #include "pdibase.h" class PDIoverJTAG { private: Jtag *jtag; uint8_t pdicmd; uint8_t get_parity(uint8_t data); FILE *pdi_dbg; public: PDIoverJTAG(Jtag *j, uint8_t pdicom); ~PDIoverJTAG(void); uint32_t pdi_read(uint8_t *data, uint32_t length, int retries); enum PDI_STATUS_CODE pdi_write (const uint8_t *data, uint16_t length); }; #endif //PDIOVERJTAG_H xc3sprog-0+svn795+dfsg/progalg.h000066400000000000000000000007141337255630200165650ustar00rootroot00000000000000/* Base class for programming algorithms */ #ifndef PROGALG_H #define PROGALG_H #include "bitfile.h" class ProgAlg { protected: ProgAlg() { } public: virtual ~ProgAlg() { } virtual unsigned int getSize() const = 0; virtual int erase() = 0; virtual int program(BitFile &file) = 0; virtual int verify(BitFile &file) = 0; virtual int read(BitFile &file) = 0; virtual void reconfig() = 0; virtual void disable() = 0; }; #endif //PROGALG_H xc3sprog-0+svn795+dfsg/progalgavr.cpp000066400000000000000000000243611337255630200176350ustar00rootroot00000000000000/* AVR programming algorithms Copyright (C) 2009 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de Copyright (C) <2001> antone@sentechsa.com 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 "progalgavr.h" const byte ProgAlgAVR::EXTEST = 0x0; const byte ProgAlgAVR::IDCODE = 0x1; const byte ProgAlgAVR::SAMPLE_PRELOAD = 0x2; const byte ProgAlgAVR::PROG_ENABLE = 0x4; const byte ProgAlgAVR::PROG_COMMANDS = 0x5; const byte ProgAlgAVR::PROG_PAGELOAD = 0x6; const byte ProgAlgAVR::PROG_PAGEREAD = 0x7; const byte ProgAlgAVR::AVR_RESET = 0xc; const byte ProgAlgAVR::BYPASS = 0xf; #define DO_ENABLE 0xA370 #define PROG_NOP1 0x2300 #define PROG_NOP2 0x3300 #define CHIP_ERASE_A 0x2380 #define CHIP_ERASE_B 0x3180 #define POLL_CHIP_ERASE 0x3380 #define ENT_FLASH_READ 0x2302 #define LOAD_ADDR_EXT_HIGH 0x0b #define LOAD_ADDR_HIGH 0x07 #define LOAD_ADDR_LOW 0x03 #define REPEAT_ADDR_LOW 0x33 #define EN_FLASH_READ 0x3200 #define RD_FLASH_HIGH 0x3600 #define RD_FLASH_LOW 0x3700 #define ENT_FLASH_WRITE 0x2310 #define WRITE_PAGE 0x3500 #define POLL_WRITE_PAGE 0x3700 #define ENT_FUSE_READ 0x2304 #define EN_FUSE_READ 0x3a00 #define RD_FUSE_EXT 0x3e00 #define RD_FUSE_HIGH 0x3200 #define RD_FUSE_LOW 0x3600 #define RD_FUSE_LOCK 0x3700 #define ENT_FUSE_WRITE 0x2340 #define LOAD_DATA_LOW_BYTE 0x13 #define ENT_FUSE_WRITE 0x2340 #define WRITE_FUSE_EXT 0x3900 #define POLL_FUSE_EXT 0x3b00 #define WRITE_FUSE_HIGH 0x3500 #define POLL_FUSE_HIGH 0x3700 #define WRITE_FUSE_LOW 0x3100 #define POLL_FUSE_LOW 0x3300 #define ENT_EEPROM_READ 0x2303 #define READ_EEPROM_DUMMY 0x3200 #define READ_EEPROM_BYTE 0x3300 ProgAlgAVR::ProgAlgAVR(Jtag &j, unsigned int flashpagesize) { jtag=&j; fp_size = flashpagesize; progmode(true); } ProgAlgAVR::~ProgAlgAVR() { progmode(false); /* in case we forgot*/ } void ProgAlgAVR::progmode(bool enter) { byte rstval[2]={0, 0}; if(enter) {/* Enter Programming */ rstval[0] = 1; jtag->shiftIR(&AVR_RESET); jtag->shiftDR(rstval, 0, 1); jtag->shortToByteArray(DO_ENABLE, rstval); jtag->shiftIR(&PROG_ENABLE); jtag->shiftDR(rstval, 0, 16); } else { jtag->shiftIR(&PROG_COMMANDS); jtag->shortToByteArray(PROG_NOP1, rstval); jtag->shiftDR(rstval, 0, 15); jtag->shortToByteArray(PROG_NOP2, rstval); jtag->shiftDR(rstval, 0, 15); jtag->shortToByteArray(0, rstval); jtag->shiftIR(&PROG_ENABLE); jtag->shiftDR(rstval, 0, 16); jtag->shiftIR(&AVR_RESET); jtag->shiftDR(rstval, 0, 1); } } int ProgAlgAVR::erase(void) { byte cookies[2]; byte o_data[2]; int i; jtag->shiftIR(&PROG_COMMANDS); jtag->shortToByteArray(CHIP_ERASE_A , cookies); jtag->shiftDR(cookies,0, 15); jtag->shortToByteArray(CHIP_ERASE_B , cookies); jtag->shiftDR(cookies,0, 15); jtag->shortToByteArray(POLL_CHIP_ERASE , cookies); jtag->shiftDR(cookies,0, 15); jtag->shiftDR(cookies,0, 15); for (i=0; i<10; i++) { jtag->Usleep(1000); jtag->shiftDR(cookies,o_data, 15); if(o_data[1] & 0x02) break; } if (1 == 10) { fprintf(stderr, "Problem Writing Fuse Extended Byte!!!\r\n"); return 1; } return 0; } void ProgAlgAVR::read_fuses(byte * fuses) { byte cookies[2]; byte o_data[2]; jtag->shiftIR(&PROG_COMMANDS); jtag->shortToByteArray(ENT_FUSE_READ, cookies); jtag->shiftDR(cookies,0, 15); jtag->shortToByteArray(EN_FUSE_READ, cookies); jtag->shiftDR(cookies,0, 15); jtag->shortToByteArray(RD_FUSE_EXT, cookies); jtag->shiftDR(cookies,o_data, 15); fuses[FUSE_EXT]= o_data[0]; jtag->shortToByteArray(RD_FUSE_HIGH, cookies); jtag->shiftDR(cookies,o_data, 15); fuses[FUSE_HIGH]= o_data[0]; jtag->shortToByteArray(RD_FUSE_LOW, cookies); jtag->shiftDR(cookies,o_data, 15); fuses[FUSE_LOW]= o_data[0]; jtag->shortToByteArray(RD_FUSE_LOCK, cookies); jtag->shiftDR(cookies,o_data, 15); fuses[FUSE_LOCK]= o_data[0]; } int ProgAlgAVR::write_fuses(byte * fuses) { byte cookies[2]; byte o_data[2]; int i; jtag->shiftIR(&PROG_COMMANDS); jtag->shortToByteArray(ENT_FUSE_WRITE, cookies); jtag->shiftDR(cookies,0, 15); if (fuses[FUSE_EXT] != 0xff) { cookies[0] = fuses[FUSE_EXT]; cookies[1] = LOAD_DATA_LOW_BYTE; jtag->shiftDR(cookies,0, 15); jtag->shortToByteArray(POLL_FUSE_EXT , cookies); jtag->shiftDR(cookies,0, 15); jtag->shortToByteArray(WRITE_FUSE_EXT , cookies); jtag->shiftDR(cookies,0, 15); jtag->shortToByteArray(POLL_FUSE_EXT , cookies); jtag->shiftDR(cookies,0, 15); jtag->shiftDR(cookies,0, 15); for (i=0; i<10; i++) { jtag->Usleep(1000); jtag->shiftDR(cookies,o_data, 15); if(o_data[1] & 0x02) break; } if (1 == 10) { fprintf(stderr, "Problem Writing Fuse Extended Byte!!!\r\n"); return 1; } } if (fuses[FUSE_HIGH] != 0xff) { cookies[0] = fuses[FUSE_HIGH]; cookies[1] = LOAD_DATA_LOW_BYTE; jtag->shiftDR(cookies,0, 15); jtag->shortToByteArray(POLL_FUSE_HIGH, cookies); jtag->shiftDR(cookies,0, 15); jtag->shortToByteArray(WRITE_FUSE_HIGH, cookies); jtag->shiftDR(cookies,0, 15); jtag->shortToByteArray(POLL_FUSE_HIGH, cookies); jtag->shiftDR(cookies,0, 15); jtag->shiftDR(cookies,0, 15); for (i=0; i<10; i++) { jtag->Usleep(1000); jtag->shiftDR(cookies,o_data, 15); if(o_data[1] & 0x02) break; } if (1 == 10) { fprintf(stderr, "Problem Writing Fuse HIGH Byte!!!\r\n"); return 1; } } if (fuses[FUSE_LOW] != 0xff) { cookies[0] = fuses[FUSE_LOW]; cookies[1] = LOAD_DATA_LOW_BYTE; jtag->shiftDR(cookies,0, 15); jtag->shortToByteArray(POLL_FUSE_LOW, cookies); jtag->shiftDR(cookies,0, 15); jtag->shortToByteArray(WRITE_FUSE_LOW, cookies); jtag->shiftDR(cookies,0, 15); jtag->shortToByteArray(POLL_FUSE_LOW, cookies); jtag->shiftDR(cookies,0, 15); jtag->shiftDR(cookies,0, 15); for (i=0; i<10; i++) { jtag->Usleep(1000); jtag->shiftDR(cookies,o_data, 15); if(o_data[1] & 0x02) break; } if (1 == 10) { fprintf(stderr, "Problem Writing Fuse LOW Byte!!!\r\n"); return 1; } } return 0; } void ProgAlgAVR::pageread_flash(unsigned int address, byte * buffer, unsigned int size) { byte cookies[2]; jtag->shiftIR(&PROG_COMMANDS); jtag->shortToByteArray(ENT_FLASH_READ, cookies); jtag->shiftDR(cookies,0, 15); if(address & (fp_size -1) ) fprintf(stderr, "Unalied read access to address 0x%08x\n", address); if (address >> 17) { cookies[0] = (address >> 17) & 0xff; cookies[1] = LOAD_ADDR_EXT_HIGH; jtag->shiftDR(cookies,0, 15); } cookies[0] = (address >> 9) & 0xff; cookies[1] = LOAD_ADDR_HIGH; jtag->shiftDR(cookies,0, 15); cookies[0] = (address >> 1) & 0xff;; cookies[1] = LOAD_ADDR_LOW; jtag->shiftDR(cookies,0, 15); jtag->shiftIR(&PROG_PAGEREAD); for(unsigned int i = 0; ishiftDR(buffer+i, buffer+i, 8, 0, 1); } jtag->shiftIR(&PROG_COMMANDS); jtag->shiftIR(&PROG_COMMANDS); } /* Caller is responsible to write whole pages*/ int ProgAlgAVR::pagewrite_flash(unsigned int address, byte * buffer, unsigned int size) { byte cookies[2]; byte o_data[2]; int i; if(address & (fp_size -1)) fprintf(stderr, "Unalied write access to address 0x%08x\n", address); if(size != fp_size) fprintf(stderr, "Size is too small for a full page\n"); jtag->shiftIR(&PROG_COMMANDS); jtag->shortToByteArray(ENT_FLASH_WRITE, cookies); jtag->shiftDR(cookies,0, 15); if (address >> 17) { cookies[0] = (address >> 17) & 0xff; cookies[1] = LOAD_ADDR_EXT_HIGH; jtag->shiftDR(cookies,0, 15); } cookies[0] = (address >> 9) & 0xff; cookies[1] = LOAD_ADDR_HIGH; jtag->shiftDR(cookies,0, 15); cookies[0] = (address >> 1) & 0xff;; cookies[1] = LOAD_ADDR_LOW; jtag->shiftDR(cookies,0, 15); jtag->shiftIR(&PROG_PAGELOAD); for(unsigned int i = 0; ishiftDR(buffer+i, 0, 8); } jtag->shiftIR(&PROG_COMMANDS); jtag->shortToByteArray( POLL_WRITE_PAGE, cookies); jtag->shiftDR(cookies,0, 15); jtag->shortToByteArray( WRITE_PAGE, cookies); jtag->shiftDR(cookies,0, 15); jtag->shortToByteArray( POLL_WRITE_PAGE, cookies); for (i=0; i<10; i++) { jtag->shiftDR(cookies,o_data, 15); if(o_data[1] & 0x02) break; fprintf(stdout,"."); fflush(stderr); jtag->Usleep(1000); } if (1 == 10) { fprintf(stderr, "Problem Writing Fuse LOW Byte!!!\r\n"); return 1; } return 0; } void ProgAlgAVR::read_eeprom(unsigned int address, byte * buffer, unsigned int size) { byte cookies[2]; byte o_data[2]; unsigned int i; jtag->shiftIR(&PROG_COMMANDS); jtag->shortToByteArray( ENT_EEPROM_READ, cookies); jtag->shiftDR(cookies,0, 15); for(i=0; i< size; i++) { cookies[0] = ((address+i) >> 8) & 0xff; cookies[1] = LOAD_ADDR_HIGH; jtag->shiftDR(cookies,0, 15); cookies[0] = ((address+i) ) & 0xff; cookies[1] = LOAD_ADDR_LOW; jtag->shiftDR(cookies,0, 15); cookies[0] = ((address+i) ) & 0xff; cookies[1] = REPEAT_ADDR_LOW; jtag->shiftDR(cookies,0, 15); jtag->shortToByteArray( READ_EEPROM_DUMMY, cookies); jtag->shiftDR(cookies,0, 15); jtag->shortToByteArray( READ_EEPROM_BYTE, cookies); jtag->shiftDR(cookies, o_data, 15); buffer[i] = o_data[0]; } } xc3sprog-0+svn795+dfsg/progalgavr.h000066400000000000000000000035311337255630200172760ustar00rootroot00000000000000/* AVR programming algorithms Copyright (C) 2009 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de Copyright (C) <2001> antone@sentechsa.com 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 PROGALGAVR_H #define PROGALGAVR_H #include #include "jtag.h" #include "iobase.h" #include "srecfile.h" typedef unsigned char byte; #define FUSE_EXT 3 #define FUSE_HIGH 2 #define FUSE_LOW 1 #define FUSE_LOCK 0 class ProgAlgAVR { private: static const byte EXTEST; static const byte IDCODE; static const byte SAMPLE_PRELOAD; static const byte PROG_ENABLE; static const byte PROG_COMMANDS; static const byte PROG_PAGELOAD; static const byte PROG_PAGEREAD; static const byte AVR_RESET; static const byte BYPASS; Jtag *jtag; unsigned int fp_size; void progmode(bool enter); public: ProgAlgAVR(Jtag &j, unsigned int FlashpageSize); ~ProgAlgAVR(); void read_fuses(byte * fuses); int write_fuses(byte * fuses); int erase(void); int pagewrite_flash(unsigned int address, byte * buffer, unsigned int size); void pageread_flash(unsigned int address, byte * buffer, unsigned int size); void read_eeprom(unsigned int address, byte * buffer, unsigned int size); }; #endif //PROGALGAVR_H xc3sprog-0+svn795+dfsg/progalgnvm.h000066400000000000000000000156311337255630200173120ustar00rootroot00000000000000#ifndef PROGALGNVM_H #define PROGALGNVM_H #include #include #define XNVM_PDI_LDS_INSTR 0x00 //!< LDS instruction. #define XNVM_PDI_STS_INSTR 0x40 //!< STS instruction. #define XNVM_PDI_LD_INSTR 0x20 //!< LD instruction. #define XNVM_PDI_ST_INSTR 0x60 //!< ST instruction. #define XNVM_PDI_LDCS_INSTR 0x80 //!< LDCS instruction. #define XNVM_PDI_STCS_INSTR 0xC0 //!< STCS instruction. #define XNVM_PDI_REPEAT_INSTR 0xA0 //!< REPEAT instruction. #define XNVM_PDI_KEY_INSTR 0xE0 //!< KEY instruction. /** Byte size address mask for LDS and STS instruction */ #define XNVM_PDI_BYTE_ADDRESS_MASK 0x00 /** Word size address mask for LDS and STS instruction */ #define XNVM_PDI_WORD_ADDRESS_MASK 0x04 /** 3 bytes size address mask for LDS and STS instruction */ #define XNVM_PDI_3BYTES_ADDRESS_MASK 0x08 /** Long size address mask for LDS and STS instruction */ #define XNVM_PDI_LONG_ADDRESS_MASK 0x0C /** Byte size data mask for LDS and STS instruction */ #define XNVM_PDI_BYTE_DATA_MASK 0x00 /** Word size data mask for LDS and STS instruction */ #define XNVM_PDI_WORD_DATA_MASK 0x01 /** 3 bytes size data mask for LDS and STS instruction */ #define XNVM_PDI_3BYTES_DATA_MASK 0x02 /** Long size data mask for LDS and STS instruction */ #define XNVM_PDI_LONG_DATA_MASK 0x03 /** Byte size address mask for LDS and STS instruction */ #define XNVM_PDI_LD_PTR_STAR_MASK 0x00 /** Word size address mask for LDS and STS instruction */ #define XNVM_PDI_LD_PTR_STAR_INC_MASK 0x04 /** 3 bytes size address mask for LDS and STS instruction */ #define XNVM_PDI_LD_PTR_ADDRESS_MASK 0x08 #define XNVM_CMD_NOP 0x00 //!< No Operation. #define XNVM_CMD_CHIP_ERASE 0x40 //!< Chip Erase. #define XNVM_CMD_READ_NVM_PDI 0x43 //!< Read NVM PDI. #define XNVM_CMD_LOAD_FLASH_PAGE_BUFFER 0x23 //!< Load Flash Page Buffer. #define XNVM_CMD_ERASE_FLASH_PAGE_BUFFER 0x26 //!< Erase Flash Page Buffer. #define XNVM_CMD_ERASE_FLASH_PAGE 0x2B //!< Erase Flash Page. #define XNVM_CMD_WRITE_FLASH_PAGE 0x2E //!< Flash Page Write. #define XNVM_CMD_ERASE_AND_WRITE_FLASH_PAGE 0x2F //!< Erase & Write Flash Page. #define XNVM_CMD_CALC_CRC_ON_FLASH 0x78 //!< Flash CRC. #define XNVM_CMD_ERASE_APP_SECTION 0x20 //!< Erase Application Section. #define XNVM_CMD_ERASE_APP_PAGE 0x22 //!< Erase Application Section. #define XNVM_CMD_WRITE_APP_SECTION 0x24 //!< Write Application Section. #define XNVM_CMD_ERASE_AND_WRITE_APP_SECTION 0x25 //!< Erase & Write Application Section Page. #define XNVM_CMD_CALC_CRC_APP_SECTION 0x38 //!< Application Section CRC. #define XNVM_CMD_ERASE_BOOT_SECTION 0x68 //!< Erase Boot Section. #define XNVM_CMD_ERASE_BOOT_PAGE 0x2A //!< Erase Boot Loader Section Page. #define XNVM_CMD_WRITE_BOOT_PAGE 0x2C //!< Write Boot Loader Section Page. #define XNVM_CMD_ERASE_AND_WRITE_BOOT_PAGE 0x2D //!< Erase & Write Boot Loader Section Page. #define XNVM_CMD_CALC_CRC_BOOT_SECTION 0x39 //!< Boot Loader Section CRC. #define XNVM_CMD_READ_USER_SIGN 0x03 //!< Read User Signature Row. #define XNVM_CMD_ERASE_USER_SIGN 0x18 //!< Erase User Signature Row. #define XNVM_CMD_WRITE_USER_SIGN 0x1A //!< Write User Signature Row. #define XNVM_CMD_READ_CALIB_ROW 0x02 //!< Read Calibration Row. #define XNVM_CMD_READ_FUSE 0x07 //!< Read Fuse. #define XNVM_CMD_WRITE_FUSE 0x4C //!< Write Fuse. #define XNVM_CMD_WRITE_LOCK_BITS 0x08 //!< Write Lock Bits. #define XNVM_CMD_LOAD_EEPROM_PAGE_BUFFER 0x33 //!< Load EEPROM Page Buffer. #define XNVM_CMD_ERASE_EEPROM_PAGE_BUFFER 0x36 //!< Erase EEPROM Page Buffer. #define XNVM_CMD_ERASE_EEPROM 0x30 //!< Erase EEPROM. #define XNVM_CMD_ERASE_EEPROM_PAGE 0x32 //!< Erase EEPROM Page. #define XNVM_CMD_WRITE_EEPROM_PAGE 0x34 //!< Write EEPROM Page. #define XNVM_CMD_ERASE_AND_WRITE_EEPROM 0x35 //!< Erase & Write EEPROM Page. #define XNVM_CMD_READ_EEPROM 0x06 //!< Read EEPROM. /** * \brief Key used to enable the NVM interface. */ #define NVM_KEY_BYTE0 0xFF #define NVM_KEY_BYTE1 0x88 #define NVM_KEY_BYTE2 0xD8 #define NVM_KEY_BYTE3 0xCD #define NVM_KEY_BYTE4 0x45 #define NVM_KEY_BYTE5 0xAB #define NVM_KEY_BYTE6 0x89 #define NVM_KEY_BYTE7 0x12 class ProgAlgNVM { private: PDIoverJTAG *prot; int initialized; enum PDI_STATUS_CODE xnvm_read_pdi_status(uint8_t *status); enum PDI_STATUS_CODE xnvm_wait_for_nvmen(uint32_t retries); enum PDI_STATUS_CODE xnvm_ctrl_read_reg(uint16_t reg, uint8_t *value); enum PDI_STATUS_CODE xnvm_ctrl_write_reg(uint16_t reg, uint8_t value); enum PDI_STATUS_CODE xnvm_ctrl_cmd_write(uint8_t cmd_id); enum PDI_STATUS_CODE xnvm_ctrl_read_status(uint8_t *value); enum PDI_STATUS_CODE xnvm_erase_application_flash_page (uint32_t address, uint8_t *dat_buf, uint16_t length); enum PDI_STATUS_CODE xnvm_erase_flash_buffer(uint32_t retries); enum PDI_STATUS_CODE xnvm_load_flash_page_buffer (uint32_t addr, uint8_t *buf, uint16_t len); enum PDI_STATUS_CODE xnvm_st_ptr(uint32_t address); enum PDI_STATUS_CODE xnvm_st_star_ptr_postinc(uint8_t value); enum PDI_STATUS_CODE xnvm_write_repeat(uint32_t count); enum PDI_STATUS_CODE xnvm_ctrl_wait_nvmbusy(uint32_t retries); enum PDI_STATUS_CODE xnvm_ctrl_cmdex_write(void); enum PDI_STATUS_CODE xnvm_erase_eeprom_buffer(uint32_t retries); enum PDI_STATUS_CODE xnvm_load_eeprom_page_buffer (uint32_t addr, uint8_t *buf, uint16_t len); public: uint8_t cmd_buffer[20]; ProgAlgNVM(PDIoverJTAG *protocoll); ~ProgAlgNVM(void); enum PDI_STATUS_CODE xnvm_init (void); enum PDI_STATUS_CODE xnvm_ioread_byte(uint16_t address, uint8_t *value); enum PDI_STATUS_CODE xnvm_iowrite_byte(uint16_t address, uint8_t value); enum PDI_STATUS_CODE xnvm_chip_erase(void); enum PDI_STATUS_CODE xnvm_application_erase(void); enum PDI_STATUS_CODE xnvm_boot_erase(uint32_t address); enum PDI_STATUS_CODE xnvm_erase_eeprom(void); uint16_t xnvm_read_memory(uint32_t address, uint8_t *data, uint32_t length); enum PDI_STATUS_CODE xnvm_erase_program_flash_page (uint32_t address, uint8_t *dat_buf, uint16_t length); enum PDI_STATUS_CODE xnvm_program_flash_page (uint32_t address, uint8_t *dat_buf, uint16_t length); enum PDI_STATUS_CODE xnvm_put_dev_in_reset (void); enum PDI_STATUS_CODE xnvm_pull_dev_out_of_reset(void); enum PDI_STATUS_CODE xnvm_erase_program_eeprom_page (uint32_t address, uint8_t *dat_buf, uint16_t length); enum PDI_STATUS_CODE xnvm_erase_user_sign(void); enum PDI_STATUS_CODE xnvm_erase_program_user_sign (uint32_t address, uint8_t *dat_buf, uint16_t length); enum PDI_STATUS_CODE xnvm_write_fuse_byte (uint32_t address, uint8_t value); enum PDI_STATUS_CODE xnvm_write_lock_byte(uint8_t value); }; #endif //PROGALGNVM_H xc3sprog-0+svn795+dfsg/progalgspiflash.cpp000066400000000000000000001066071337255630200206620ustar00rootroot00000000000000/* SPI Flash PROM JTAG programming algorithms Copyright (C) 2009, 2010, 2011 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 Code based on http://code.google.com/p/xilprg-hunz/ */ #include #include "progalgspiflash.h" #include #include #include #include "bitrev.h" const byte ProgAlgSPIFlash::USER1=0x02; const byte ProgAlgSPIFlash::USER2=0x03; const byte ProgAlgSPIFlash::JSTART=0x0c; const byte ProgAlgSPIFlash::JSHUTDOWN=0x0d; const byte ProgAlgSPIFlash::CFG_IN=0x05; const byte ProgAlgSPIFlash::CONFIG=0xee; const byte ProgAlgSPIFlash::BYPASS=0xff; #define PAGE_PROGRAM 0x02 #define PAGE_READ 0x03 #define READ_STATUS_REGISTER 0x05 #define WRITE_ENABLE 0x06 #define SECTOR_ERASE 0xD8 #define READ_IDENTIFICATION 0x9F #define BULK_ERASE 0xC7 #define WRITE_BUSY 0x80 /* AT45 specific*/ #define AT45_SECTOR_ERASE 0x7C #define SECTOR_LOCKDOWN_READ 0x35 #define AT45_READ_STATUS 0xD7 #define AT45_READY 0x01 /* Block protect bits */ #define BP0 0x04 #define BP1 0x08 #define BP2 0x10 ProgAlgSPIFlash::ProgAlgSPIFlash(Jtag &j) { char *fname = getenv("SPI_DEBUG"); if (fname) fp_dbg = fopen(fname,"wb"); else fp_dbg = NULL; jtag=&j; buf = 0; miso_buf = new byte[5010]; mosi_buf = new byte[5010]; sector_size = 65536; /* Many devices have 64 kiByte sectors*/ sector_erase_cmd = 0xD8; /* default erase command */ } ProgAlgSPIFlash::~ProgAlgSPIFlash(void) { delete[] miso_buf; delete[] mosi_buf; if(buf) delete[] buf; if(fp_dbg) fclose(fp_dbg); } int ProgAlgSPIFlash::spi_flashinfo_spansion(unsigned char *buf){ fprintf(stderr, "Found Spansion Device, Device ID %02x, memory type %02x, capacity %02x\n", buf[1], buf[2], buf[3]); switch (buf[3]){ case 0x01: pages = 4096; } pgsize = 256; return 1; } int ProgAlgSPIFlash::spi_flashinfo_s33(unsigned char *buf) { fprintf(stderr, "Found Intel Device, Device ID 0x%02x%02x\n", buf[1], buf[2]); if (buf[1] != 0x89) { fprintf(stderr,"S33: Unexpected RDID upper Device ID 0x%02x\n", buf[1]); return -1; } switch (buf[2]) { case 0x11: pages = 8192; break; case 0x12: pages = 16364; break; case 0x13: pages = 32768; break; default: fprintf(stderr,"Unexpected S33 size ID 0x%02x\n", buf[2]); return -1; } pgsize = 256; /* try to read the OTP Number */ buf[0]=0x4B; buf[1]=0x00; buf[2]=0x01; buf[3]=0x02; spi_xfer_user1(NULL,0,0,buf,8, 4); spi_xfer_user1(buf, 8,4,NULL,0, 0); fprintf(stderr,"Unique number: "); for (int i= 0; i<8 ; i++) fprintf(stderr,"%02x", buf[i]); fprintf(stderr, " \n"); return 1; } int ProgAlgSPIFlash::spi_flashinfo_amic(unsigned char *buf) { fprintf(stderr, "Found AMIC Device, Device ID 0x%02x%02x\n", buf[1], buf[2]); switch (buf[2]) { case 0x10: pages = 256; break; case 0x11: pages = 512; break; case 0x12: pages = 1024; break; case 0x13: pages = 2048; break; case 0x14: pages = 4096; break; case 0x15: pages = 8192; break; case 0x16: pages = 16384; break; default: fprintf(stderr,"Unexpected AMIC size ID 0x%02x\n", buf[2]); return -1; } pgsize = 256; fprintf(stderr, " \n"); return 1; } int ProgAlgSPIFlash::spi_flashinfo_amic_quad(unsigned char *buf) { fprintf(stderr, "Found AMIC Quad Device, Device ID 0x%02x%02x\n", buf[1], buf[2]); switch (buf[2]) { case 0x16: pages = 16384; break; default: fprintf(stderr,"Unexpected AMIC Quad size ID 0x%02x\n", buf[2]); return -1; } pgsize = 256; fprintf(stderr, " \n"); return 1; } int ProgAlgSPIFlash::spi_flashinfo_w25(unsigned char *buf) { fprintf(stderr, "Found Winbond Device, Device ID 0x%02x%02x\n", buf[1], buf[2]); if ((buf[1] != 0x30) && (buf[1] != 0x40)) { fprintf(stderr,"W25: Unexpected RDID upper Device ID 0x%02x\n", buf[1]); return -1; } switch (buf[2]) { case 0x11: pages = 512; break; case 0x12: pages = 1024; break; case 0x13: pages = 2048; break; case 0x14: pages = 4096; break; case 0x15: pages = 8192; break; case 0x16: pages = 16384; break; case 0x17: pages = 32768; break; case 0x18: pages = 65536; break; case 0x19: pages = 2*65536; break; default: fprintf(stderr,"Unexpected W25 size ID 0x%02x\n", buf[2]); return -1; } pgsize = 256; sector_size = 4096; /* Bytes = 32 kiBits*/ sector_erase_cmd = 0x20; if (buf[1] == 0x40) { /* try to read the OTP Number */ buf[0]=0x4B; buf[1]=0x00; buf[2]=0x01; buf[3]=0x02; spi_xfer_user1(NULL,0,0,buf,8, 4); spi_xfer_user1(buf, 8,4,NULL,0, 0); fprintf(stderr,"Unique number: "); for (int i= 0; i<8 ; i++) fprintf(stderr,"%02x", buf[i]); fprintf(stderr, " \n"); } return 1; } struct at45_t { unsigned int id; int pgsize; int alt_pagesize; int pages; int pages_per_sector; char chipname[12]; }; int ProgAlgSPIFlash::spi_flashinfo_at45(unsigned char *buf) { byte fbuf[128]; int idx; #define NUM_AT45 7 struct at45_t at45chips[NUM_AT45] = { { 3, 264, 256, 512, 128, "AT45DB011"}, { 7, 264, 256, 2048, 256, "AT45DB041"}, { 9, 264, 256, 4096, 256, "AT45DB801"}, { 0x0b, 528, 512, 4096, 256, "AT45DB161"}, { 0x0d, 528, 512, 8192, 256, "AT45DB321"}, { 0x0f, 1056, 1024, 8192, 256, "AT45DB641"}, { 0xff, 0, 0, 0, 0, "UNKNOWN" } }; // read result fbuf[0]= AT45_READ_STATUS; spi_xfer_user1(NULL,0,0,fbuf, 2, 1); // get status spi_xfer_user1(fbuf,2,1, NULL, 0, 0); fbuf[0] = bitRevTable[fbuf[0]]; fbuf[1] = bitRevTable[fbuf[1]]; fprintf(stderr, "status: %02x\n",fbuf[1]); for(idx=0; idx < NUM_AT45;idx++) { if(at45chips[idx].id == ((fbuf[0]>>2)&0x0f)) break; } if(idx == NUM_AT45) { fprintf(stderr, "don't know that flash or status b0rken!\n"); return -1; } fprintf(stderr, "Found Atmel Device, Device ID 0x%02x%02x: %s\n", buf[1], buf[2], at45chips[idx].chipname); pgsize=at45chips[idx].pgsize; pages=at45chips[idx].pages; pages_per_sector = at45chips[idx].pages_per_sector; pages_per_block = 8; /* try to read the OTP Number */ fbuf[0]=0x77; fbuf[3]=fbuf[2]=fbuf[1]=0; spi_xfer_user1(NULL,0,0,fbuf,128, 4); spi_xfer_user1(fbuf, 128,4,NULL,0, 0); fprintf(stderr,"Unique number:\n"); for (int i= 64; i< 128; i++) { fprintf(stderr,"%02x", fbuf[i]); if ((i & 0x1f) == 0x1f) fprintf(stderr,"\n"); } return 1; } int ProgAlgSPIFlash::spi_flashinfo_sst(unsigned char *buf) { fprintf(stderr, "Found SST device, Device ID 0x%02x%02x\n", buf[1], buf[2]); if (buf[1]!=0x25) { fprintf(stderr,"Does not look like this is a SST SPI flash device\n"); return false; } pgsize = 256; sector_size = 4096; switch(buf[2]) { case 0x8d: /* SST25VF040B */ pages = 2048; break; case 0x8e: /* SST25VF080B */ pages = 4096; break; case 0x41: /* SST25VF016B */ pages = 8192; break; default: printf("Unknown SST Flash Size (0x%.2x)\n", buf[2]); return false; } return true; } int ProgAlgSPIFlash::spi_flashinfo_m25p_mx25l(unsigned char *buf, int is_mx25l) { byte fbuf[21]= {READ_IDENTIFICATION}; int i, j = 0; spi_xfer_user1(NULL,0,0,fbuf,20,1); spi_xfer_user1(fbuf, 20, 1, NULL,0, 0); fbuf[0] = bitRevTable[fbuf[0]]; fbuf[1] = bitRevTable[fbuf[1]]; fbuf[2] = bitRevTable[fbuf[2]]; fbuf[3] = bitRevTable[fbuf[3]]; if(is_mx25l) { switch (fbuf[1]) { case 0x20: fprintf(stderr, "Found Macronix MX25L Device, Device ID 0x%02x%02x\n", fbuf[1], fbuf[2]); switch (fbuf[2]) { case 0x17: pages = 262144; sector_size = 65536; break; default: fprintf(stderr,"Unexpected MX25L size ID 0x%02x\n", buf[2]); return -1; } break; default: fprintf(stderr,"MX25L: Unexpected RDID upper Device ID 0x%02x\n", fbuf[1]); return -1; } } else { switch (fbuf[1]) { case 0x20: fprintf(stderr, "Found Numonyx M25P Device, Device ID 0x%02x%02x\n", fbuf[1], fbuf[2]); switch (fbuf[2]) { case 0x11: pages = 512; sector_size = 32768; /* Bytes = 262144 bits*/ break; case 0x12: pages = 1024; break; case 0x13: pages = 2048; break; case 0x14: pages = 4096; break; case 0x15: pages = 8192; break; case 0x16: pages = 16384; break; case 0x17: pages = 32768; sector_size = 131072; /* Bytes = 1 Mi Bit*/ break; case 0x18: pages = 65536; sector_size = 262144; /* Bytes = 2 Mi Bit*/ break; default: fprintf(stderr,"Unexpected M25P size ID 0x%02x\n", buf[2]); return -1; } break; case 0x80: fprintf(stderr, "Found Micron M25PE Device, Device ID 0x%02x%02x\n", fbuf[1], fbuf[2]); switch (fbuf[2]) { case 0x15: pages = 65536; sector_size = 65536; break; default: fprintf(stderr,"Unexpected M25PE size ID 0x%02x\n", buf[2]); return -1; } break; case 0x71: fprintf(stderr, "Found Numonyx M25PX Device, Device ID 0x%02x%02x\n", fbuf[1], fbuf[2]); switch (fbuf[2]) { case 0x14: pages = 4096; sector_size = 65536; break; default: fprintf(stderr,"Unexpected M25Px size ID 0x%02x\n", buf[2]); return -1; } break; case 0xba: fprintf(stderr, "Found Numonyx N25Q Device, Device ID 0x%02x%02x\n", fbuf[1], fbuf[2]); switch (fbuf[2]) { case 0x17: pages = 32768; sector_size = 65536; break; case 0x18: pages = 65536; sector_size = 65536; break; case 0x20: pages = 524288; sector_size = 65536; break; default: fprintf(stderr,"Unexpected N25Q size ID 0x%02x\n", buf[2]); return -1; } break; default: fprintf(stderr,"M25P: Unexpected RDID upper Device ID 0x%02x\n", fbuf[1]); return -1; } } pgsize = 256; if (fbuf[3] == 0x10) { for (i= 4; i<20 ; i++) j+=fbuf[i]; if (j != 0) { fprintf(stderr,"CFI: "); for (i= 5; i<21 ; i++) fprintf(stderr,"%02x", fbuf[i]); fprintf(stderr, " \n"); } } return 1; } int ProgAlgSPIFlash::spi_flashinfo(void) { byte fbuf[8]={READ_IDENTIFICATION, 0, 0, 0, 0, 0, 0, 0}; int res; // send JEDEC info spi_xfer_user1(NULL,0,0,fbuf,4,1); /* FIXME: for some reason on the FT2232test board with XC3S200 and AT45DB321 the commands need to be repeated*/ spi_xfer_user1(NULL,0,0,fbuf,4,1); // read result spi_xfer_user1(fbuf,4,1,NULL, 0, 0); fbuf[0] = bitRevTable[fbuf[0]]; fbuf[1] = bitRevTable[fbuf[1]]; fbuf[2] = bitRevTable[fbuf[2]]; fbuf[3] = bitRevTable[fbuf[3]]; fprintf(stderr, "JEDEC: %02x %02x 0x%02x 0x%02x\n", fbuf[0],fbuf[1], fbuf[2], fbuf[3]); manf_id = fbuf[0]; prod_id = fbuf[1]<<8 | fbuf[2]; switch (fbuf[0]) { case 0x01: res = spi_flashinfo_spansion(fbuf); break; case 0x1f: { switch (fbuf[1]>> 5) /* Family code*/ { case 1: res = spi_flashinfo_at45(fbuf); break; case 2: fprintf(stderr, "Unhandled AT25 device\n"); return -1; default: fprintf(stderr, "Unhandled Adesto device\n"); return -1; } break; } case 0x30: res = spi_flashinfo_amic(fbuf); break; case 0x40: res = spi_flashinfo_amic_quad(fbuf); break; case 0x20: res = spi_flashinfo_m25p_mx25l(fbuf, 0); break; case 0xc2: res = spi_flashinfo_m25p_mx25l(fbuf, 1); break; case 0x89: res = spi_flashinfo_s33(fbuf); break; case 0xef: res = spi_flashinfo_w25(fbuf); break; case 0xbf: res = spi_flashinfo_sst(fbuf); break; default: fprintf(stderr, "unknown JEDEC manufacturer: %02x\n",fbuf[0]); return -1; } if (res == 1) { fprintf(stderr, "%d bytes/page, %d pages = %d bytes total \n", pgsize, pages, pgsize * pages); buf = new byte[pgsize+16]; } if (!buf) return -1; return res; } void ProgAlgSPIFlash::test(int test_count) { int i; fprintf(stderr, "Running %d times\n", test_count); for(i=0; i maxlen) maxlen = mosi_len + preamble + 4 + 2; // SPI magic mosi_buf[0]=0x59; mosi_buf[1]=0xa6; mosi_buf[2]=0x59; mosi_buf[3]=0xa6; // SPI len (bits) mosi_buf[4]=((mosi_len + preamble)*8)>>8; mosi_buf[5]=((mosi_len + preamble)*8)&0xff; // bit-reverse header for(cnt=0;cnt<6;cnt++) mosi_buf[cnt]=bitRevTable[mosi_buf[cnt]]; // bit-reverse preamble for(cnt=6;cnt<6+preamble;cnt++) mosi_buf[cnt]=bitRevTable[mosi[cnt-6]]; memcpy(mosi_buf+6+preamble, mosi+preamble, mosi_len); } rc=xc_user((mosi)?mosi_buf:NULL,(last_miso)?miso_buf:NULL, maxlen*8); if(last_miso && miso_len) { memcpy(last_miso, miso_buf+miso_skip, miso_len); } if(fp_dbg) { if (mosi && (preamble || mosi_len)) { int i; fprintf(fp_dbg,"In "); for (i=0; i< preamble; i++) fprintf(fp_dbg," %02x", mosi[i]); if ( mosi_len) { fprintf(fp_dbg,":"); for (i=preamble; i<(preamble +mosi_len) && i< 32; i++) fprintf(fp_dbg," %02x", mosi[i]); if((preamble +mosi_len)> 32) fprintf(fp_dbg,"..."); } fprintf(fp_dbg,"\n"); } if(last_miso && miso_len) { int i; fprintf(fp_dbg,"OUT:"); if ( miso_len) { for (i=0; i 32) fprintf(fp_dbg,"..."); } fprintf(fp_dbg,"\n"); } } return rc; } int ProgAlgSPIFlash::xc_user(byte *in, byte *out, int len) { jtag->shiftIR(&USER1); jtag->shiftDR(in, out, len); return 0; } void page2padd(byte *buf, int page, int pgsize) { if (buf == NULL) return; // see UG333 page 19 if(pgsize>512) page<<=2; else if (pgsize > 256) page<<=1; buf[1] = page >> 8; buf[2] = page & 0xff; buf[3] = 0; } /* read full pages * Writing of bitfile will delete trailing 0xff's */ int ProgAlgSPIFlash::read(BitFile &rfile) { unsigned int offset, len , data_end, i, rc=0; unsigned int rlen; int l; byte buf[4]= {PAGE_READ, 0, 0, 0}; offset = (rfile.getOffset()/pgsize) * pgsize; if (offset > pages * pgsize) { fprintf(stderr,"Offset greater than PROM\n"); return -1; } if (rfile.getRLength() != 0) { data_end = offset + rfile.getRLength(); len = rfile.getRLength(); } else { data_end = pages * pgsize; len = data_end - offset; } if (len > pages * pgsize) { fprintf(stderr,"Read outside PROM arearequested, clipping\n"); data_end = pages* pgsize; } rfile.setLength(len * 8); l = -pgsize; for(i = offset; i < data_end+pgsize; i+= pgsize) { if (i < data_end) /* Read last page */ rlen = ((data_end - i) > pgsize)? pgsize: data_end - i; if(jtag->getVerbose()) { fprintf(stderr, "\rReading page %6d/%6d at flash page %6d", (l+ 2*pgsize -1)/pgsize , (len+pgsize -1)/pgsize, (i+pgsize -1)/pgsize); fflush(stderr); } page2padd(buf, i/pgsize, pgsize); if (l < 0) /* don't write when sending first page*/ spi_xfer_user1(NULL, 0, 0, buf, rlen, 4); else if (i >= data_end) spi_xfer_user1(rfile.getData()+l, rlen, 4, NULL, 0, 0); else spi_xfer_user1(rfile.getData()+l, pgsize, 4, buf, rlen, 4); l+= pgsize; } fprintf(stderr, "\n"); return rc; } /* return 0 on success, anything else on failure */ int ProgAlgSPIFlash::verify(BitFile &vfile) { unsigned int i, offset, data_end, res, k=0; unsigned int rlen; int l, len = vfile.getLength()/8; byte *data = new byte[pgsize]; byte buf[4] = {PAGE_READ, 0,0,0}; if (data == 0 || len == 0) { fprintf(stderr,"Program start outside PROM area, aborting\n"); return -1; } offset = (vfile.getOffset()/pgsize)*pgsize; if (offset > pages* pgsize) { fprintf(stderr,"Verify start outside PROM area, aborting\n"); k = 1; goto v_cleanup; } if (vfile.getRLength() != 0 && (vfile.getRLength() < vfile.getLength()/8)) { data_end = offset + vfile.getRLength(); len = vfile.getRLength(); } else { data_end = offset + vfile.getLength()/8; len = vfile.getLength()/8; } if( data_end > pages * pgsize) { fprintf(stderr,"Verify outside PROM areas requested, clipping\n"); data_end = pages * pgsize; len = data_end - offset; } l = -pgsize; for(i = offset; i < data_end+pgsize; i+= pgsize) { if (i < data_end) /* Read last page */ rlen = ((data_end - i) > pgsize)? pgsize: data_end - i; page2padd(buf, i/pgsize, pgsize); // get: flash_page n-1, send: read flashpage n res=spi_xfer_user1(data, pgsize, 4, buf, rlen, 4); if (l >= 0) /* don't compare when sending first page*/ { if(jtag->getVerbose()) { fprintf(stderr, "\rVerifying page %6d/%6d at flash page %6d", (i - offset +pgsize-1)/pgsize, (len +pgsize -1)/pgsize, (i + pgsize -1)/pgsize ); fflush(stderr); } res=memcmp(data, vfile.getData()+ l, rlen); if (res) { unsigned int j; fprintf(stderr, "\nVerify failed at flash_page %6d\nread:", i/pgsize + 1); k++; for(j =0; j5) { goto v_cleanup; } } } l+= pgsize; } if(jtag->getVerbose()) fprintf(stderr, "\n"); if (k) { fprintf(stderr, "Verify: Failure!\n"); } else fprintf(stderr, "Verify: Success!\n"); v_cleanup: delete[] data; return k; } #define deltaT(tvp1, tvp2) (((tvp2)->tv_sec-(tvp1)->tv_sec)*1000000 + \ (tvp2)->tv_usec - (tvp1)->tv_usec) /* Wait at maximum "limit" Milliseconds and report a '.' every "report" * Milliseconds and report used time as "delta" by issuing a * READ_STATUS_REGISTER command every Millisecond while waiting for * WRITE_BUSY to deassert * retval = 0 : All fine * else Error */ int ProgAlgSPIFlash::wait(byte command, int report, int limit, double *delta) { int j = 0; int done = 0; byte fbuf[4]; byte rbuf[1]; struct timeval tv[2]; fbuf[0] = command; spi_xfer_user1(NULL,0,0,fbuf, 1, 1); gettimeofday(tv, NULL); /* wait for command complete */ do { jtag->Usleep(1000); spi_xfer_user1(rbuf,1,1,fbuf, 1, 1); j++; if ((jtag->getVerbose()) &&((j%report) == (report -1))) { /* one tick every report mS wait time */ fprintf(stderr,"."); fflush(stderr); } if (command == AT45_READ_STATUS) done = (rbuf[0] & AT45_READY)?1:0; else done = (rbuf[0] & WRITE_BUSY)?0:1; } while (!done && (j < limit)); gettimeofday(tv+1, NULL); *delta = deltaT(tv, tv + 1); return (jUsleep(1000); spi_xfer_user1(rbuf,1,1,fbuf, 1, 1); j++; if ((jtag->getVerbose()) &&((j%report) == (report -1))) { /* one tick every report mS wait time */ fprintf(stderr,"."); fflush(stderr); } done = (rbuf[0] & mask)==mask; } while (!done && (j < limit)); gettimeofday(tv+1, NULL); *delta = deltaT(tv, tv + 1); return (j pages *pgsize) { fprintf(stderr,"Program start outside PROM area, aborting\n"); return -1; } if (pfile.getRLength() != 0) { data_end = offset + pfile.getRLength(); len = pfile.getRLength(); } else { data_end = offset + pfile.getLength()/8; len = pfile.getLength()/8; } if( data_end > pages * pgsize) { fprintf(stderr,"Program outside PROM areas requested, clipping\n"); data_end = pages * pgsize; } for(i = offset ; i < data_end; i+= pgsize) { unsigned int rlen = ((data_end -i) > pgsize) ? pgsize : (data_end -i); /* Find out if sector needs to be erased*/ if (sector_nr <= i/sector_size) { sector_nr = i/sector_size +1; /* Enable Write */ fbuf[0] = WRITE_ENABLE; spi_xfer_user1(NULL,0,0,fbuf, 0, 1); /* Erase selected page */ fbuf[0] = sector_erase_cmd; page2padd(fbuf, i/pgsize, pgsize); spi_xfer_user1(NULL,0,0,fbuf, 0, 4); if(jtag->getVerbose()) fprintf(stderr,"\rErasing sector %2d/%2d", sector_nr, (data_end + sector_size + 1)/sector_size); j = wait(READ_STATUS_REGISTER, 100, 3000, &delta); if(j != 0) { fprintf(stderr,"\nErase failed for sector %2d\n", sector_nr); return -1; } else { if (delta > max_sector_erase) max_sector_erase= delta; } } if(jtag->getVerbose()) { fprintf(stderr, "\r\t\t\tWriting data page %6d/%6d", (i - offset + pgsize -1)/pgsize, (len + pgsize -1)/pgsize); fprintf(stderr, " at flash page %6d", (i + pgsize -1)/pgsize); fflush(stderr); } /* Enable Write */ fbuf[0] = WRITE_ENABLE; spi_xfer_user1(NULL,0,0,fbuf, 0, 1); buf[0] = PAGE_PROGRAM; page2padd(buf, i/pgsize, pgsize); memcpy(buf+4,&pfile.getData()[i-offset], rlen); spi_xfer_user1(NULL,0,0,buf, rlen, 4); j = wait(READ_STATUS_REGISTER, 1, 50, &delta); if(j != 0) { fprintf(stderr,"\nPage Program failed for flashpage %6d\n", i/pgsize +1); return -1; } else { if (delta > max_page_program) max_page_program= delta; } data_page++; } if(jtag->getVerbose()) { fprintf(stderr, "\nMaximum erase time %.1f ms, Max PP time %.0f us\n", max_sector_erase/1.0e3, max_sector_erase/1e1); } return 0; } void ProgAlgSPIFlash::sst_disable_write_protect() { byte fbuf[2]; const byte tCE=10; fbuf[0] = 0x50; // EWSR spi_xfer_user1(NULL,0,0,fbuf,0,1); jtag->Usleep(tCE); fbuf[0] = 0x01; fbuf[1] = 0x00; // WRSR spi_xfer_user1(NULL,0,0,fbuf,0,2); jtag->Usleep(tCE); } int ProgAlgSPIFlash::program_sst(BitFile &pfile) { byte fbuf[4]; byte AAIP_Cmd[6]={0xad,0x00,0x00,0x00,0xaa,0xaa}; double delta; const unsigned long tCE=50; const unsigned long tBP=10; bool inAAImode; unsigned int i, offset, data_end= 0; offset = (pfile.getOffset()/pgsize)*pgsize; if (offset > pages *pgsize) { fprintf(stderr,"Program start outside PROM area, aborting\n"); return -1; } if (pfile.getRLength() != 0) { data_end = offset + pfile.getRLength(); } else { data_end = offset + pfile.getLength()/8; } if( data_end > pages * pgsize) { fprintf(stderr,"Program outside PROM areas requested, clipping\n"); data_end = pages * pgsize; } fbuf[0] = 0x06; // WREN spi_xfer_user1(NULL,0,0,fbuf,0,1); jtag->Usleep(tCE); fbuf[0] = 0x80; // DBSY spi_xfer_user1(NULL,0,0,fbuf,0,1); jtag->Usleep(tCE); sst_disable_write_protect(); fbuf[0] = 0x06; // WREN spi_xfer_user1(NULL,0,0,fbuf,0,1); jtag->Usleep(tCE); if (wait( READ_STATUS_REGISTER, 0x40, 0x40, tCE>>2, tCE, &delta)!=0) { fprintf(stderr,"Error waiting for flash\n"); return -1; } // TODO: Check enough bytes and /2 alignment /* if (wait(READ_STATUS_REGISTER, 0x1f, 0x2, tCE>>2, tCE, &delta)<0) { fprintf(stderr, "Timeout\n"); return -1; } */ unsigned int sector_nr = 0; int j; /* Sector erasing */ for(i = offset ; i < data_end; i+= sector_size) { if (sector_nr <= i/sector_size) { sector_nr = i/sector_size +1; /* Enable Write */ fbuf[0] = WRITE_ENABLE; spi_xfer_user1(NULL,0,0,fbuf, 0, 1); /* Erase selected page */ fbuf[0] = sector_erase_cmd; page2padd(fbuf, i/pgsize, pgsize); spi_xfer_user1(NULL,0,0,fbuf, 0, 4); if(jtag->getVerbose()) fprintf(stderr,"\rErasing sector %2d/%2d", sector_nr, (data_end + sector_size + 1)/sector_size); j = wait(READ_STATUS_REGISTER, 100, 3000, &delta); if(j != 0) { fprintf(stderr,"\nErase failed for sector %2d\n", sector_nr); return -1; } else { // if (delta > max_sector_erase) // max_sector_erase= delta; } } } fprintf(stderr,"\n"); inAAImode = false; fbuf[0] = 0x06; // WREN spi_xfer_user1(NULL,0,0,fbuf,0,1); jtag->Usleep(tCE); if (wait( READ_STATUS_REGISTER, 0x40, 0x40, tCE>>2, tCE, &delta)!=0) { fprintf(stderr,"Error waiting for flash\n"); return -1; } for(i = offset ; i < data_end; i+= 2) { if (inAAImode) { AAIP_Cmd[1] = bitRevTable[ pfile.getData()[i-offset] ]; AAIP_Cmd[2] = bitRevTable[ pfile.getData()[i-offset+1] ]; } else { AAIP_Cmd[1] = (offset>>16)&0xff; AAIP_Cmd[2] = (offset>>8)&0xff; AAIP_Cmd[3] = (offset)&0xff; AAIP_Cmd[4] = bitRevTable[ pfile.getData()[i-offset] ]; AAIP_Cmd[5] = bitRevTable[ pfile.getData()[i-offset+1] ]; } spi_xfer_user1(NULL,0,0,&AAIP_Cmd[0], 0, inAAImode ? 3 : 6); inAAImode=true; } printf("Programming done\n"); fbuf[0] = 0x04; // WRDI spi_xfer_user1(NULL,0,0,fbuf, 0, 1); if (wait(READ_STATUS_REGISTER, 0x01, 0x0, tBP>>2, tBP, &delta)<0) { fprintf(stderr,"Timeout\n"); return -1; } return 0; } int ProgAlgSPIFlash::erase_sst() { sst_disable_write_protect(); return erase_bulk(); } int ProgAlgSPIFlash::program(BitFile &pfile) { unsigned int len = pfile.getLength()/8; if( len >(pgsize*pages)) { fprintf(stderr, "dude, that file is larger than the flash!\n"); return -1; } switch (manf_id) { case 0x1f: /* Atmel */ return program_at45(pfile); case 0x01: /* Spansion */ case 0x20: /* Numonyx */ case 0xc2: /* Macronix */ case 0x30: /* AMIC */ case 0x40: /* AMIC Quad */ case 0xef: /* Winbond */ case 0x89: /* Intel S33 */ return sectorerase_and_program(pfile); case 0xbf: return program_sst(pfile); default: fprintf(stderr,"Programming not yet implemented\n"); } return -1; } int ProgAlgSPIFlash::program_at45(BitFile &pfile) { int len = pfile.getLength()/8; unsigned int i, offset, data_end, data_page= 0; double max_page_program = 0.0; double delta; offset = (pfile.getOffset()/pgsize)*pgsize; if (offset > pages *pgsize) { fprintf(stderr,"Program start outside PROM area, aborting\n"); return -1; } if (pfile.getRLength() != 0) { data_end = offset + pfile.getRLength(); len = pfile.getRLength(); } else { data_end = offset + pfile.getLength()/8; len = pfile.getLength()/8; } if( data_end > pages * pgsize) { fprintf(stderr,"Program outside PROM areas requested, clipping\n"); data_end = pages * pgsize; } buf[0] = 0x82;/* page program with builtin erase */ for(i = offset ; i < data_end; i+= pgsize) { unsigned int j; unsigned int rlen = ((data_end -i) > pgsize) ? pgsize : (data_end -i); if(jtag->getVerbose()) { fprintf(stderr, "\r\t\t\tWriting data page %6d/%6d", (i - offset + pgsize -1)/pgsize, (len + pgsize -1)/pgsize); fprintf(stderr, " at flash page %6d", (i + pgsize -1)/pgsize); fflush(stderr); } page2padd(buf, i/pgsize, pgsize); memcpy(buf+4,&pfile.getData()[i-offset], rlen); spi_xfer_user1(NULL,0,0,buf, rlen, 4); /* Page Erase/Program takes up to 35 ms (t_pep, UG333.pdf page 43)*/ j = wait(AT45_READ_STATUS, 1, 35, &delta); if(j != 0) { fprintf(stderr,"\nPage Program failed for flashpage %6d\n", i/pgsize +1); return -1; } else { if (delta > max_page_program) max_page_program= delta; } data_page++; } return 0; } int ProgAlgSPIFlash::erase_bulk(void) { byte fbuf[3] = {READ_STATUS_REGISTER, 0, 0}; /* Read Status*/ int i; double delta; // get status spi_xfer_user1(fbuf,2,1, NULL, 0, 0); fbuf[0] = bitRevTable[fbuf[0]]; fbuf[1] = bitRevTable[fbuf[1]]; if (fbuf[1] & (BP0 | BP1 | BP2)) { fprintf(stderr, "Can't erase, device has block protection%s%s%s\n", (fbuf[1]& BP0)? " BP0":"", (fbuf[1]& BP1)? " BP1":"", (fbuf[1]& BP2)? " BP2":""); return -1; } if(jtag->getVerbose()) { fprintf(stderr,"Bulk erase "); } fbuf[0] = WRITE_ENABLE; spi_xfer_user1(NULL,0,0,fbuf, 0, 1); fbuf[0] = BULK_ERASE; spi_xfer_user1(NULL,0,0,fbuf, 0, 1); i = wait(READ_STATUS_REGISTER, 1000, 80000, &delta); if (i != 0) { fprintf(stderr,"\nBulk erase failed\n"); return -1; } if(jtag->getVerbose()) { fprintf(stderr," took %.3f s\n", delta/1.0e6); } return 0; } int ProgAlgSPIFlash::erase_at45(void) { byte fbuf[24] = {SECTOR_LOCKDOWN_READ}; byte rbuf[20]; unsigned int page; double max_sector_erase = 0.0; double delta = 0; unsigned int i; spi_xfer_user1(NULL,0,0, fbuf, 0, 32); spi_xfer_user1(rbuf,4,28, NULL, 0, 0); for (i = 0; i < pages/pages_per_sector; i++) { if (rbuf[i] != 0x00) { fprintf(stderr,"Sector %d is locked (0x%02x)\n", i, rbuf[i]); return -1; } } for(page = 0; page < pages;) { byte fbuf[4]; fbuf[0] = AT45_SECTOR_ERASE; fbuf[3] = 0; page2padd(fbuf, page, pgsize); if(jtag->getVerbose()) fprintf(stderr,"\rErasing sector %2d%c", page/pages_per_sector, (page == 0)?'a':(page ==pages_per_block)?'b':' ' ); spi_xfer_user1(NULL,0,0, fbuf, 0, 4); fbuf[0] = AT45_READ_STATUS; /*Treat 50AN with limit 2.5s as other devices*/ i = wait(AT45_READ_STATUS, 100, 5000, &delta); if (i != 0) { fprintf(stderr,"\nSector 0x%06x erase failed\n", page); return -1; } if (delta > max_sector_erase) max_sector_erase = delta; if (page == 0) page = pages_per_block; else if (page == pages_per_block) page = pages_per_sector; else page += pages_per_sector; } fprintf(stderr, "\nMaximum Sector erase time %.3f s\n", max_sector_erase/1.0e6); return 0; // get status // spi_xfer_user1(fbuf,2,1, NULL, 0, 0); // fbuf[0] = bitRevTable[fbuf[0]); // fbuf[1] = bitRevTable[fbuf[1]); // fprintf(stderr, "status: %02x\n",fbuf[1]); return -1; } int ProgAlgSPIFlash::erase(void) { switch (manf_id) { case 0x1f: /* Atmel */ return erase_at45(); case 0x20: /* Numonyx */ case 0xc2: /* Macronix */ case 0x30: /* AMIC */ case 0x40: /* AMIC Quad */ case 0x89: /* Intel */ case 0xef: /* Winbond */ return erase_bulk(); case 0xbf: /* SST */ return erase_sst(); default: fprintf(stderr,"Programming not yet implemented\n"); } return -1; } xc3sprog-0+svn795+dfsg/progalgspiflash.h000066400000000000000000000052611337255630200203210ustar00rootroot00000000000000/* SPI Flash PROM JTAG programming algorithms Copyright (C) 2009 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 Code based on http://code.google.com/p/xilprg-hunz/ */ #ifndef PROGALGSPIFLASH_H #define PROGALGSPIFLASH_H #include #include #include #include "bitfile.h" #include "jtag.h" typedef unsigned char byte; class ProgAlgSPIFlash { private: static const byte USER1; static const byte USER2; static const byte CFG_IN; static const byte JSHUTDOWN; static const byte JSTART; static const byte CONFIG; static const byte BYPASS; Jtag *jtag; FILE *fp_dbg; unsigned int pgsize; unsigned int pages; unsigned int pages_per_sector; unsigned int pages_per_block; int sector_size; int sector_erase_cmd; int manf_id; int prod_id; byte *miso_buf; byte *mosi_buf; byte *buf; int xc_user(byte *in, byte *out, int len); int spi_xfer_user1(uint8_t *last_miso, int miso_len, int miso_skip, uint8_t *mosi, int mosi_len, int preamble); int spi_flashinfo_spansion (unsigned char * fbuf); int spi_flashinfo_s33 (unsigned char * fbuf); int spi_flashinfo_amic (unsigned char * fbuf); int spi_flashinfo_amic_quad (unsigned char * fbuf); int spi_flashinfo_w25 (unsigned char * fbuf); int spi_flashinfo_at45(unsigned char * fbuf); int spi_flashinfo_m25p_mx25l(unsigned char * fbuf, int is_mx25l); int spi_flashinfo_sst(unsigned char * fbuf); int wait(byte command, int report, int limit, double *delta); int wait(byte command, byte mask, byte value, int report, int limit, double *delta); int program_at45(BitFile &file); int program_sst(BitFile &pfile); void sst_disable_write_protect(); int sectorerase_and_program(BitFile &file); int erase_at45(); int erase_bulk(); int erase_sst(); int sst_has_completed(); public: ProgAlgSPIFlash(Jtag &j); ~ProgAlgSPIFlash(void); int spi_flashinfo(void); int erase(void); int program(BitFile &file); int verify(BitFile &file); int read(BitFile &file); void disable(){}; void test(int test_count); }; #endif /*PROGALGSPIFLASH_H */ xc3sprog-0+svn795+dfsg/progalgxc2c.cpp000066400000000000000000000211321337255630200176750ustar00rootroot00000000000000/* XC2C Flash PROM JTAG programming algorithms Copyright (C) 2004 Andrew Rogers 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 Changes: Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: Code cleanup for clean -Wall compile. */ #include #include #include #include #include "progalgxc2c.h" const byte ProgAlgXC2C::IDCODE = 0x01; const byte ProgAlgXC2C::ISC_ENABLE_OTF= 0xe4; const byte ProgAlgXC2C::ISC_ENABLE = 0xe8; const byte ProgAlgXC2C::ISC_SRAM_READ = 0xe7; const byte ProgAlgXC2C::ISC_WRITE = 0xe6; const byte ProgAlgXC2C::ISC_ERASE = 0xed; const byte ProgAlgXC2C::ISC_PROGRAM = 0xea; const byte ProgAlgXC2C::ISC_READ = 0xee; const byte ProgAlgXC2C::ISC_INIT = 0xf0; const byte ProgAlgXC2C::ISC_DISABLE = 0xc0; const byte ProgAlgXC2C::USERCODE = 0xfd; const byte ProgAlgXC2C::BYPASS = 0xff; static byte reverse_gray_code_table[256]; static byte gray_code_table[256]; void init_bin2rev_gray(void) { int i, j; unsigned char c; for (i=0; i<0x100; i++) { c= 0; if(i & 0x80) c |= 1; for (j=6; j>=0; j--) { int pat0 = 1<< j; int pat1 = 1<<(1+j); if (!(i & pat0 ) && (i & pat1)) c |= (1<<(7-j)); if ( (i & pat0 ) && !(i & pat1)) c |= (1<<(7-j)); } reverse_gray_code_table[i] = c; } } void init_bin2gray(void) { int i, j; unsigned char c; for (i=0; i<0x100; i++) { c= 0; if(i & 0x80) c |= 0x80; for (j=6; j>=0; j--) { int pat0 = 1<< j; int pat1 = 1<<(1+j); if (!(i & pat0 ) && (i & pat1)) c |= (1<shiftIR(&ISC_ENABLE_OTF); jtag->cycleTCK(1); } void ProgAlgXC2C::flow_disable() { jtag->shiftIR(&ISC_DISABLE); jtag->cycleTCK(1); jtag->Usleep(100); } void ProgAlgXC2C::flow_reinit() { jtag->shiftIR(&ISC_INIT); jtag->cycleTCK(1); jtag->Usleep(20); jtag->shiftIR(&ISC_INIT); jtag->cycleTCK(1); jtag->Usleep(100); } void ProgAlgXC2C::erase(void) { jtag->shiftIR(&ISC_ENABLE_OTF); jtag->shiftIR(&ISC_ERASE); jtag->Usleep(100000); jtag->shiftIR(&ISC_DISABLE); } /* Blank check by OTF Verification */ int ProgAlgXC2C::blank_check(void) { int i, j; byte i_data[1]; byte o_data[MAXSIZE]; byte preamble[1]={0}; byte ircap[1]; jtag->shiftIR(&BYPASS, ircap); jtag->shiftIR(&ISC_ENABLE_OTF); jtag->shiftIR(&ISC_READ); i_data[0] = reverse_gray_code_table[0]>>(8-post); jtag->shiftDR(i_data, NULL, post); for (i=1; i<=block_num; i++) { jtag->cycleTCK(20); i_data[0] = reverse_gray_code_table[i]>>(8-post); jtag->shiftDR(NULL, o_data, block_size, 0, false); jtag->shiftDR(i_data, preamble, post); for(j =0; j < block_size%8; j ++) o_data[block_size/8] |= 1<<(7-j); for(j = 0; j*8shiftIR(&ISC_DISABLE); return 0; } void ProgAlgXC2C::array_program(BitFile &file) { int i, j, k=0; byte a_data[1]; byte i_data[MAXSIZE]; byte preamble[1]={0}; byte ircap[1]; jtag->shiftIR(&ISC_ENABLE_OTF, ircap); jtag->shiftIR(&ISC_PROGRAM, ircap); a_data[0] = reverse_gray_code_table[0]>>(8-post); jtag->shiftDR(i_data, NULL, post); for(k = 0; k < block_size; k++) if (file.get_bit(k)) i_data[k/8] |= (1 <<(k%8)); else i_data[k/8] &= ~(1 <<(k%8)); jtag->shiftDR(i_data, NULL, block_size, 0, false); jtag->shiftDR(a_data, preamble, post); jtag->Usleep(10000); for (i=1; i>(8-post); for(j = 0; j < block_size; j++) { if (file.get_bit(k)) i_data[j/8] |= (1 <<(j%8)); else i_data[j/8] &= ~(1 <<(j%8)); k++; } jtag->shiftDR(i_data, NULL, block_size, 0, false); jtag->shiftDR(a_data, preamble, post); jtag->Usleep(10000); } fprintf(stderr, "\n"); jtag->shiftIR(&ISC_DISABLE, ircap); } int ProgAlgXC2C::array_verify(BitFile &file) { int i, j, k=0; int res = 0; byte a_data[1]; byte o_data[MAXSIZE]; byte preamble[1]={0}; byte data; byte ircap[1]; jtag->shiftIR(&BYPASS, ircap); jtag->shiftIR(&ISC_ENABLE_OTF, ircap); jtag->shiftIR(&ISC_READ, ircap); a_data[0] = reverse_gray_code_table[0]>>(8-post); jtag->shiftDR(a_data, NULL, post); /* Do not verify the Program Done and Usercode Row. */ for (i=1; i<=block_num-2; i++) { fprintf(stderr, " \r" "Verify: Row %3d", i); fflush(stderr); jtag->Usleep(20); a_data[0] = reverse_gray_code_table[i]>>(8-post); jtag->shiftDR(NULL, o_data, block_size, 0, false); jtag->shiftDR(a_data, preamble, post); for(j = 0; j>3]; } if (file.get_bit(k) != ((data & (1<<(j%8)))?1:0)) { fprintf(stderr, "\n" "Verify mismatch row %d byte %d cal file %d device %d\n", i, j, file.get_bit(k), (data & (1<<(j%8)))?1:0); res = 1; i = block_size +1; break; } k++; } } jtag->shiftIR(&ISC_DISABLE, ircap); fprintf(stderr, " \r" "Verify: %s\n",(res)?"Failure":"Success"); return res; } void ProgAlgXC2C::done_program(void) { byte a_data[1]; byte i_data[MAXSIZE]; byte preamble[1]={0}; byte ircap[1]; /* Program Done Bits are yet in BitFile like the usercode too. */ jtag->shiftIR(&ISC_ENABLE_OTF); jtag->shiftIR(&ISC_INIT); jtag->Usleep(20); jtag->shiftIR(&ISC_INIT); jtag->shiftDR(i_data, NULL, 8, 0, false); jtag->Usleep(800); jtag->shiftIR(&ISC_DISABLE); jtag->shiftIR(&BYPASS); } void ProgAlgXC2C::array_read(BitFile &rbfile) { int i, j, k=0; byte a_data[1]; byte o_data[MAXSIZE]; byte preamble[1]={0}; byte data; byte ircap[1]; rbfile.setLength(block_num *block_size); jtag->shiftIR(&BYPASS, ircap); jtag->shiftIR(&ISC_ENABLE_OTF, ircap); jtag->shiftIR(&ISC_READ, ircap); a_data[0] = reverse_gray_code_table[0]>>(8-post); jtag->shiftDR(a_data, NULL, post); jtag->Usleep(20); for (i=1; i<=block_num; i++) { a_data[0] = reverse_gray_code_table[i]>>(8-post); jtag->shiftDR(NULL, o_data, block_size, 0, false); jtag->shiftDR(a_data, preamble, post); jtag->Usleep(20); for(j = 0; j>3]; } rbfile.set_bit(k, data & (1<<(j%8))); k++; } } jtag->shiftIR(&ISC_DISABLE); } void ProgAlgXC2C::read_usercode(void) { byte o_data[4]; jtag->shiftIR(&ISC_ENABLE_OTF); jtag->shiftIR(&USERCODE); jtag->shiftDR(NULL, o_data, 32); printf("Usercode: 0x%02X%02X%02X%02X\n", o_data[3],o_data[2],o_data[1],o_data[0]); jtag->shiftIR(&ISC_DISABLE); } xc3sprog-0+svn795+dfsg/progalgxc2c.h000066400000000000000000000034651337255630200173530ustar00rootroot00000000000000/* XC2X Flash PROM JTAG programming algorithms Copyright (C) 2009 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de 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 PROGALGXC2_H #define PROGALGXC2_H #include "jtag.h" #include "bitfile.h" #define MAXSIZE 256 class ProgAlgXC2C { private: static const byte IDCODE; static const byte ISC_ENABLE_OTF; static const byte ISC_ENABLE; static const byte ISC_SRAM_READ; static const byte ISC_WRITE; static const byte ISC_ERASE; static const byte ISC_PROGRAM; static const byte ISC_READ; static const byte ISC_INIT; static const byte ISC_DISABLE; static const byte CONFIG; static const byte USERCODE; static const byte BYPASS; Jtag *jtag; int block_size; int block_num; int post; void flow_disable(); void flow_reinit(); void flow_error_exit(){}; void flow_array_read(BitFile &file){}; void flow_erase(){}; void flow_enable_highz(); public: ProgAlgXC2C(Jtag &j, int si); int blank_check(void); void erase(void); int array_verify(BitFile &file); void array_read(BitFile &file); void array_program(BitFile &file); void done_program(void); void read_usercode(void); }; #endif //PROGALGXC2C_H xc3sprog-0+svn795+dfsg/progalgxc3s.cpp000066400000000000000000000206321337255630200177220ustar00rootroot00000000000000/* Spartan3 JTAG programming algorithms Copyright (C) 2004 Andrew Rogers 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 Changes: Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: Code cleanup for clean -Wall compile. Added programming time measurements. */ #include "progalgxc3s.h" #include "utilities.h" /* * Note: instruction lengths differ: * Spartan-3 has length 5; * Virtex-5 has length 10 or 14. * The LSB parts of the codes are identical, so one set fits all. */ static const byte JPROGRAM[2] = { 0xcb, 0xff }; static const byte CFG_IN[2] = { 0xc5, 0xff }; static const byte JSHUTDOWN[2] = { 0xcd, 0xff }; static const byte JSTART[2] = { 0xcc, 0xff }; static const byte ISC_PROGRAM[2] = { 0xd1, 0xff }; static const byte ISC_ENABLE[2] = { 0xd0, 0xff }; static const byte ISC_DISABLE[2] = { 0xd6, 0xff }; static const byte BYPASS[2] = { 0xff, 0xff }; static const byte ISC_DNA[1] = { 0x31 }; ProgAlgXC3S::ProgAlgXC3S(Jtag &j, int fam) { jtag=&j; family = fam; switch(family) { case FAMILY_XC3SE: case FAMILY_XC3SA: case FAMILY_XC3SAN: case FAMILY_XC3SD: tck_len = 16; array_transfer_len = 16; break; case FAMILY_XC5VLX: case FAMILY_XC5VLXT: case FAMILY_XC5VSXT: case FAMILY_XC5VFXT: case FAMILY_XC5VTXT: case FAMILY_XC7: tck_len = 12; array_transfer_len = 32; break; default: tck_len = 12; array_transfer_len = 64; } } void ProgAlgXC3S::flow_enable() { byte data[1]; jtag->shiftIR(ISC_ENABLE); data[0]=0x0; jtag->shiftDR(data,0,5); jtag->cycleTCK(tck_len); } void ProgAlgXC3S::flow_disable() { byte data[1]; jtag->shiftIR(ISC_DISABLE); jtag->cycleTCK(tck_len); jtag->shiftIR(BYPASS); data[0]=0x0; jtag->shiftDR(data,0,1); jtag->cycleTCK(1); } void ProgAlgXC3S::flow_array_program(BitFile &file) { Timer timer; unsigned int i; for(i=0; ishiftIR(ISC_PROGRAM); jtag->shiftDR(&(file.getData())[i/8],0,array_transfer_len); jtag->cycleTCK(1); if((i % (10000*array_transfer_len)) == 0) { fprintf(stderr,"."); fflush(stderr); } } // Print the timing summary if (jtag->getVerbose()) fprintf(stderr, " done. Programming time %.1f ms\n", timer.elapsed() * 1000); } void ProgAlgXC3S::flow_program_xc2s(BitFile &file) { byte data[2]; byte xc2sbuf0[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x99, 0xaa, 0x66, 0x0c, 0x80, 0x04, 0x80, /*Header: Write to COR*/ 0x00, 0x05, 0xfd, 0xbc, /* OR data sets SHUTDOWN = 1 */ 0x0c, 0x00, 0x01, 0x80, /*-> Header: Write to CMD*/ 0x00, 0x00, 0x00, 0xa0, /*Start Shutdown*/ 0x0c, 0x00, 0x01, 0x80, /* Header: Write to CMD*/ 0x00, 0x00, 0x00, 0xe0, /*RCRC command*/ 0x00, 0x00, 0x00, 0x00 }; byte xc2sbuf1[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x99, 0xaa, 0x66, 0x0c, 0x00, 0x01, 0x80, /* Header: Write to CMD*/ 0x00, 0x00, 0x00, 0x10, /* Assert GHIGH */ 0x0c, 0x80, 0x04, 0x80, /*Header: Write to COR*/ 0x00, 0x05, 0xfc, 0xff, /* OR data sets SHUTDOWN = 0 */ 0x0c, 0x00, 0x01, 0x80, /* Header: Write to CMD*/ 0x00, 0x00, 0x00, 0xa0, /*Start command*/ 0x0c, 0x00, 0x01, 0x80, /* Header: Write to CMD*/ 0x00, 0x00, 0x00, 0xe0, /*RCRC command*/ 0x00, 0x00, 0x00, 0x00 }; jtag->shiftIR(CFG_IN); jtag->shiftDR(xc2sbuf0,0, sizeof(xc2sbuf0) *8); jtag->shiftIR(JSTART); jtag->cycleTCK(13); jtag->shiftIR(CFG_IN); jtag->shiftDR(xc2sbuf1,0, sizeof(xc2sbuf1) *8); jtag->shiftIR(JSTART); jtag->cycleTCK(13); jtag->shiftIR(CFG_IN); jtag->shiftDR(xc2sbuf0,0, sizeof(xc2sbuf0) *8); jtag->shiftIR(JSTART); jtag->cycleTCK(13); jtag->shiftIR(CFG_IN); jtag->shiftDR((file.getData()),0,file.getLength()); jtag->cycleTCK(1); jtag->shiftIR(JSTART); jtag->cycleTCK(13); jtag->shiftIR(BYPASS); jtag->shiftDR(data,0,1); jtag->cycleTCK(1); return; } void ProgAlgXC3S::flow_program_legacy(BitFile &file) { Timer timer; byte data[2]; jtag->shiftIR(JSHUTDOWN); jtag->cycleTCK(tck_len); jtag->shiftIR(CFG_IN); jtag->shiftDR((file.getData()),0,file.getLength()); jtag->cycleTCK(1); jtag->shiftIR(JSTART); jtag->cycleTCK(2*tck_len); jtag->shiftIR(BYPASS); data[0]=0x0; jtag->shiftDR(data,0,1); jtag->cycleTCK(1); // Print the timing summary if (jtag->getVerbose()) { fprintf(stderr, "done. Programming time %.1f ms\n", timer.elapsed() * 1000); } } void ProgAlgXC3S::array_program(BitFile &file) { unsigned char buf[1] = {0}; int i = 0; if (family == FAMILY_XC2S || family == FAMILY_XC2SE) return flow_program_xc2s(file); flow_enable(); /* JPROGAM: Triger reconfiguration, not explained in ug332, but DS099 Figure 28: Boundary-Scan Configuration Flow Diagram (p.49) */ jtag->shiftIR(JPROGRAM); do jtag->shiftIR(CFG_IN, buf); while (! (buf[0] & 0x10)); /* wait until configuration cleared */ /* As ISC_DNA only works on a unconfigured device, see AR #29977*/ switch(family) { case 0x11: /* XC3SA*/ case 0x13: /* XC3SAN*/ case 0x1c: /* SC3SADSP*/ case 0x20: /* SC3SADSP*/ { byte data[8]; jtag->shiftIR(ISC_ENABLE); jtag->shiftIR(ISC_DNA); jtag->shiftDR(0, data, 64); jtag->cycleTCK(1); if (*(long long*)data != -1LL) /* ISC_DNA only works on a unconfigured device, see AR #29977*/ fprintf(stderr, "DNA is 0x%02x%02x%02x%02x%02x%02x%02x%02x\n", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); break; } } /* use legacy, as large USB transfers are faster then chunks */ flow_program_legacy(file); /*flow_array_program(file);*/ flow_disable(); /* NOTE: Virtex7 devices do not support flow_program_legacy according to the Xilinx IEEE 1532 files. However, my tests with flow_array_program failed, while flow_program_legacy appears to work just fine on XC7VX690T. (jorisvr) */ /* Wait until device comes up */ while ((( buf[0] & 0x23) != 0x21) && (i <50)) { jtag->shiftIR(BYPASS, buf); jtag->Usleep(1000); i++; } if (i == 50) fprintf(stderr, "Device failed to configure, INSTRUCTION_CAPTURE is 0x%02x\n", buf[0]); } void ProgAlgXC3S::reconfig(void) { switch(family) { case FAMILY_XC2V: case FAMILY_XC3S: case FAMILY_XC3SE: case FAMILY_XC3SA: case FAMILY_XC3SAN: case FAMILY_XC3SD: case FAMILY_XC6S: break; default: fprintf(stderr, "Device does not support reconfiguration.\n"); // TODO : return error code return; } /* Sequence is from AR #31913 FFFF Dummy Word 9955 SYNC 850c Type 1 Write to CMD 7000 REBOOT command 0004 NOOP 0004 NOOP */ byte xc3sbuf[12]= {0xff, 0xff, 0x55, 0x99, 0x0c, 0x85, 0x00, 0x70, 0x04, 0x00, 0x04, 0x00}; /* xtp038.pdf FFFF Dummy Word AA99 Sync Word 5566 Sync Word 30A1 Type 1 Write 1 Word to CMD 000E IPROG Command 2000 Type 1 NO OP */ byte xc6sbuf[12]= {0xff, 0xff, 0x55, 0x99, 0xaa, 0x66, 0x0c, 0x85, 0x00, 0x70, 0x04, 0x00}; jtag->shiftIR(JSHUTDOWN); jtag->cycleTCK(16); jtag->shiftIR(CFG_IN); if(jtag->getVerbose()) fprintf(stderr, "Trying reconfigure\n"); if(family == 0x20) /*XC6S*/ jtag->shiftDR(xc6sbuf, NULL, 12*8 ); else jtag->shiftDR(xc3sbuf, NULL, 12*8 ); jtag->shiftIR(JSTART); jtag->cycleTCK(32); jtag->shiftIR(BYPASS); jtag->cycleTCK(1); jtag->setTapState(Jtag::TEST_LOGIC_RESET); } xc3sprog-0+svn795+dfsg/progalgxc3s.h000066400000000000000000000035171337255630200173720ustar00rootroot00000000000000/* Spartan3 JTAG programming algorithms Copyright (C) 2004 Andrew Rogers 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 Changes: Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: Code cleanup for clean -Wall compile. */ #ifndef PROGALGXC3S_H #define PROGALGXC3S_H #include "bitfile.h" #include "jtag.h" #define FAMILY_XC2S 0x03 #define FAMILY_XC2SE 0x05 #define FAMILY_XC2V 0x08 #define FAMILY_XC3S 0x0a #define FAMILY_XC4VLX 0x0b #define FAMILY_XC3SE 0x0e #define FAMILY_XC4VFX 0x0f #define FAMILY_XC4VSX 0x10 #define FAMILY_XC3SA 0x11 #define FAMILY_XC3SAN 0x13 #define FAMILY_XC5VLX 0x14 #define FAMILY_XC5VLXT 0x15 #define FAMILY_XC5VSXT 0x17 #define FAMILY_XC5VFXT 0x19 #define FAMILY_XC7 0x1b #define FAMILY_XC3SD 0x1c #define FAMILY_XC6S 0x20 #define FAMILY_XC5VTXT 0x22 class ProgAlgXC3S { private: Jtag *jtag; int family; int tck_len; int array_transfer_len; void flow_enable(); void flow_disable(); void flow_program_xc2s(BitFile &file); void flow_array_program(BitFile &file); void flow_program_legacy(BitFile &file); public: ProgAlgXC3S(Jtag &j, int family); void array_program(BitFile &file); void reconfig(); }; #endif xc3sprog-0+svn795+dfsg/progalgxc95x.cpp000066400000000000000000000204771337255630200200310ustar00rootroot00000000000000/* XC95 CPLD JTAG programming algorithms Copyright (C) 2008-2009 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de (C) Copyright 2001 Nahitafu,Naitou Ryuji 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 "progalgxc95x.h" const byte ProgAlgXC95X::ISC_NOOP=0xff; const byte ProgAlgXC95X::ISC_DISABLE=0xf0; const byte ProgAlgXC95X::ISC_ERASE=0xed; const byte ProgAlgXC95X::ISC_PROGRAM=0xea; const byte ProgAlgXC95X::ISC_READ=0xee; const byte ProgAlgXC95X::ISC_ENABLE=0xe9; const byte ProgAlgXC95X::XSC_BLANK_CHECK=0xe5; const byte ProgAlgXC95X::BYPASS=0xff; #define deltaT(tvp1, tvp2) (((tvp2)->tv_sec-(tvp1)->tv_sec)*1000000 + \ (tvp2)->tv_usec - (tvp1)->tv_usec) ProgAlgXC95X::ProgAlgXC95X(Jtag &j, int s) { jtag=&j; switch (s) { case 1: DRegLength = 2; break; case 2: DRegLength = 4; break; case 4: DRegLength = 8; break; case 11: DRegLength = 16; break; default: fprintf(stderr, "Unknown device\n"); } } void ProgAlgXC95X::flow_enable() { byte data[1]; jtag->shiftIR(&ISC_ENABLE); data[0]=0x15; jtag->shiftDR(data,0,6); jtag->cycleTCK(1); } void ProgAlgXC95X::flow_disable() { jtag->shiftIR(&ISC_DISABLE); jtag->Usleep(100); jtag->shiftIR(&BYPASS); jtag->cycleTCK(1); } void ProgAlgXC95X::flow_error_exit() { jtag->shiftIR(&ISC_NOOP); jtag->cycleTCK(1); } int ProgAlgXC95X::flow_blank_check() { byte i_data[3]={0x3,0,0}; byte o_data[3]; jtag->shiftIR(&XSC_BLANK_CHECK); jtag->shiftDR(i_data, 0,18); jtag->cycleTCK(500); jtag->shiftDR(0,o_data,18); if(jtag->getVerbose()) { if ((o_data[0] & 0x03) == 0x01) fprintf(stderr, "Device is blank\n"); else fprintf(stderr, "Device is not blank\n"); } return ((o_data[0] & 0x03) == 0x01); } void ProgAlgXC95X::flow_erase() { byte data[3] = {0x03, 0, 0}; jtag->shiftIR(&ISC_ERASE); jtag->shiftDR(data,0,18); jtag->Usleep(500000); jtag->shiftDR(0,data,18); if((data[0]& 0x03) != 0x01) fprintf(stderr, "Erase still running %02x\n", data[0]); } #define MaxSector 108 #define MaxDRegLength 16 int ProgAlgXC95X::flow_array_program(JedecFile &file) { byte preamble[1]= {0x01}; byte i_data[MaxDRegLength+2]; byte o_data[MaxDRegLength+3]; struct timeval tv[2]; unsigned long Addr=0; int bitlen; int k, sec,l,m; unsigned char data; unsigned int idx=0; gettimeofday(tv, NULL); for(sec=0;sec < MaxSector;sec++) { if(jtag->getVerbose()) fprintf(stderr, " \r" "Programming Sector %3d", sec); preamble[0]= 0x01; for(l=0;l<3;l++){ for(m=0;m<5;m++){ Addr = sec*0x20 + l*0x08 + m; i_data[DRegLength] = (byte) (Addr &0xff); i_data[DRegLength+1] = (byte) ((Addr>>8) &0xff); if(l*5+m >= 9){ bitlen=6; } else{ bitlen=8; } for(int j=0;jUsleep(1000); /*FIXME: IOFTDI Buffer causes abort with high rate on some board otherwise*/ jtag->shiftIR(&ISC_PROGRAM); jtag->shiftDR(preamble,0,2,0,false); jtag->shiftDR(i_data,0,(DRegLength+2)*8); if((l == 2) && (m == 4)) jtag->Usleep(50000); else jtag->cycleTCK(1); if ((l == 2) && (m == 4)) { preamble[0]= 0x00; for(k=0; k< 32; k++) { jtag->shiftIR(&ISC_PROGRAM); jtag->shiftDR(preamble, 0,2,0,false); jtag->shiftDR(i_data, 0,(DRegLength+2)*8); jtag->Usleep(50000); jtag->shiftDR(0,o_data, ((DRegLength+2)*8)+2); if(jtag->getVerbose()) { fprintf(stderr, "."); fflush(stderr); } if ((o_data[0] & 0x03) == 0x01) break; } if (k == 32) { fprintf(stderr, "failed\n"); return 1; } } } } } gettimeofday(tv+1, NULL); if(jtag->getVerbose()) fprintf(stderr, "\nProgramming time %.1f ms\n", (double)deltaT(tv, tv + 1)/1.0e3); return 0; } void ProgAlgXC95X::flow_array_read(JedecFile &rbfile) { byte preamble[1]= {0x03}; byte i_data[MaxDRegLength+2]; byte o_data[MaxDRegLength+2]; struct timeval tv[2]; unsigned long Addr=0; int bitlen; int sec,l,m; unsigned char data; unsigned int idx=0; gettimeofday(tv, NULL); for(sec=0;sec < MaxSector;sec++) { if(jtag->getVerbose()) { fprintf(stderr, "\rReading Sector %3d", sec); fflush(stderr); } for(l=0;l<3;l++){ for(m=0;m<5;m++){ Addr = sec*0x20 + l*0x08 + m; i_data[DRegLength] = (byte) (Addr &0xff); i_data[DRegLength+1] = (byte) ((Addr>>8) &0xff); jtag->shiftIR(&ISC_READ); jtag->shiftDR(preamble,0,2,0,false); jtag->shiftDR(i_data,o_data,(DRegLength+2)*8); jtag->cycleTCK(1); if(sec | l | m ) { for(int j=0;j> 1; } } } if(l*5+m >= 9){ bitlen=6; } else{ bitlen=8; } } } } /* Now read the security fuses*/ jtag->shiftIR(&ISC_READ); jtag->shiftDR(preamble,0,2,0,false); jtag->shiftDR(i_data,o_data,(DRegLength+2)*8); for(int j=0;j> 1; } } gettimeofday(tv+1, NULL); if(jtag->getVerbose()) fprintf(stderr, "\nReadback time %.1f ms\n", (double)deltaT(tv, tv + 1)/1.0e3); } int ProgAlgXC95X::flow_array_verify(JedecFile &file) { byte preamble[1]= {0x03}; byte i_data[MaxDRegLength+2]; byte o_data[MaxDRegLength+2]; struct timeval tv[2]; unsigned long Addr=0; int bitlen; int sec,l,m; unsigned char data; unsigned int idx=0; gettimeofday(tv, NULL); for(sec=0;sec < MaxSector;sec++) { if(jtag->getVerbose()) { fprintf(stderr, "\rVerify Sector %3d", sec); fflush(stderr); } for(l=0;l<3;l++){ for(m=0;m<5;m++){ Addr = sec*0x20 + l*0x08 + m; i_data[DRegLength] = (byte) (Addr &0xff); i_data[DRegLength+1] = (byte) ((Addr>>8) &0xff); jtag->shiftIR(&ISC_READ); jtag->shiftDR(preamble,0,2,0,false); jtag->shiftDR(i_data,o_data,(DRegLength+2)*8); jtag->cycleTCK(1); if(sec | l | m ) { for(int j=0;j> 1; idx++; } } } if(l*5+m >= 9){ bitlen=6; } else{ bitlen=8; } } } } /* Now read the security fuses*/ jtag->shiftIR(&ISC_READ); jtag->shiftDR(preamble,0,2,0,false); jtag->shiftDR(i_data,o_data,(DRegLength+2)*8); for(int j=0;j> 1; } } gettimeofday(tv+1, NULL); if(jtag->getVerbose()) fprintf(stderr, "\nSuccess! Verify time %.1f ms\n", (double)deltaT(tv, tv + 1)/1.0e3); return 0; } void ProgAlgXC95X::array_read(JedecFile &file) { file.setLength(108*108* DRegLength); flow_enable(); flow_array_read(file); flow_disable(); } void ProgAlgXC95X::array_program(JedecFile &file) { flow_array_program(file); } int ProgAlgXC95X::array_verify(JedecFile &file) { int ret; flow_enable(); ret = flow_array_verify(file); flow_disable(); return ret; } xc3sprog-0+svn795+dfsg/progalgxc95x.h000066400000000000000000000035151337255630200174700ustar00rootroot00000000000000/* XC95 CPLD JTAG programming algorithms Copyright (C) 2008 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de 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 */ /* * Based on the Xilinx 1532 BSDL Files and alg95??.cpp for naxjp */ #ifndef PROGALGXC95X_H #define PROGALGXC95X_H #include "jtag.h" #include "jedecfile.h" class ProgAlgXC95X { private: static const byte ISC_NOOP; static const byte ISC_DISABLE; static const byte ISC_ERASE; static const byte ISC_PROGRAM; static const byte ISC_READ; static const byte ISC_ENABLE; static const byte XSC_BLANK_CHECK; static const byte BYPASS; Jtag *jtag; int DRegLength; void flow_enable(); void flow_disable(); void flow_error_exit(); void flow_array_read(JedecFile &file); int flow_array_program(JedecFile &file); int flow_array_verify(JedecFile &file); int flow_blank_check(); void flow_erase(); public: ProgAlgXC95X(Jtag &j, int s); int blank_check(){flow_enable(); int ret= flow_blank_check(); flow_disable(); return ret;}; int erase(){flow_enable(); flow_erase(); return flow_blank_check();}; int array_verify(JedecFile &file); void array_read(JedecFile &file); void array_program(JedecFile &file); }; #endif //PROGALGXC95X_H xc3sprog-0+svn795+dfsg/progalgxcf.cpp000066400000000000000000000262751337255630200176330ustar00rootroot00000000000000/* XCF Flash PROM JTAG programming algorithms Copyright (C) 2004-2011 Andrew Rogers 2009 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 Changes: Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: Code cleanup for clean -Wall compile. */ #include #include #include "progalgxcf.h" #include "utilities.h" const byte ProgAlgXCF::SERASE=0x0a; const byte ProgAlgXCF::ISCTESTSTATUS=0xe3; const byte ProgAlgXCF::ISC_ENABLE=0xe8; const byte ProgAlgXCF::ISC_PROGRAM=0xea; const byte ProgAlgXCF::ISC_ADDRESS_SHIFT=0xeb; const byte ProgAlgXCF::ISC_ERASE=0xec; const byte ProgAlgXCF::ISC_DATA_SHIFT=0xed; const byte ProgAlgXCF::CONFIG=0xee; const byte ProgAlgXCF::ISC_READ=0xef; const byte ProgAlgXCF::ISC_DISABLE=0xf0; const byte ProgAlgXCF::IDCODE=0xfe; const byte ProgAlgXCF::BYPASS=0xff; const byte ProgAlgXCF::BIT3=0x08; const byte ProgAlgXCF::BIT4=0x10; static const unsigned int MAX_BLOCK_SIZE = 4096; static const unsigned int FRAMES_PER_BLOCK = 32; ProgAlgXCF::ProgAlgXCF(Jtag &j, int size_ind) { use_optimized_algs = false; switch (size_ind & 0xfffffef) /* part number of XC18V has X in bitmask */ { case 0x23: size = 1<<19; block_size = 2048; break; case 0x24: size = 1<<20; block_size = 2048; break; case 0x25: size = 2<<20; block_size = 4096; break; case 0x26: size = 4<<20; block_size = 4096; break; case 0x44: size = 1<<20; block_size = 2048; use_optimized_algs = true; break; case 0x45: size = 2<<20; block_size = 4096; use_optimized_algs = true; break; case 0x46: size = 4<<20; block_size = 4096; use_optimized_algs = true; break; default: fprintf(stderr,"Unknown XCF device size code %x\n", size_ind); throw std::invalid_argument("Unknown XCF device size code"); } jtag=&j; } /* For XCF, implement "xflow_erase_optimized" for the serial devices * from the XCF..1532.bsd" files * and for XC18V flow_erase */ int ProgAlgXCF::erase() { byte data[4]; int i; byte ircap[1]; Timer timer; jtag->shiftIR(&ISC_DISABLE); jtag->Usleep(110000); jtag->shiftIR(&BYPASS,ircap); if((ircap[0]&BIT3)==BIT3){ fprintf(stderr,"Device is write protected! Aborting\n"); return 1; } jtag->shiftIR(&ISC_ENABLE); if (! use_optimized_algs) data[0]=0x34; else data[0]=0x37; jtag->shiftDR(data,0,6); jtag->shiftIR(&ISC_ADDRESS_SHIFT); jtag->longToByteArray(1,data); jtag->shiftDR(data,0,16); jtag->cycleTCK(1); if(jtag->getVerbose()) { fprintf(stderr, "Erasing"); fflush(stderr); } jtag->shiftIR(&ISC_ERASE); for(i=0; i<32;i++) { byte xcstatus[1]; if(jtag->getVerbose()) { fprintf(stderr, "."); fflush(stderr); } jtag->Usleep(500000); if (! use_optimized_algs) { if (i == 31) break; } else { jtag->shiftIR(&ISCTESTSTATUS); jtag->shiftDR(0,xcstatus,8); if (xcstatus[0] & 0x04) break; } } if (i > 31) { fprintf(stderr,"\nErased failed! Aborting\n"); return 1; } if (jtag->getVerbose()) fprintf(stderr, "done\nErase time %.1f ms\n", timer.elapsed() * 1.0e3); return 0; } int ProgAlgXCF::program(BitFile &file) { byte data[MAX_BLOCK_SIZE/8]; unsigned int skipbits, nbits; skipbits = file.getOffset() * 8; if (skipbits % block_size != 0) { fprintf(stderr, "Programming does not start at block boundary (offset = %u bits), aborting\n", skipbits); return -1; } if (skipbits > size) { fprintf(stderr,"Program start outside PROM area (offset = %u bits), aborting\n", skipbits); return -1; } if (file.getRLength() != 0) nbits = file.getRLength() * 8; else nbits = file.getLength(); if (nbits > size - skipbits) { fprintf(stderr,"Program outside PROM areas requested, clipping\n"); nbits = size - skipbits; } if (nbits % block_size != 0) fprintf(stderr, "Programming does not end at block boundary (nbits = %u), padding\n", nbits); unsigned int skipblocks = skipbits / block_size; unsigned int nblocks = (nbits + block_size - 1) / block_size; Timer timer; jtag->shiftIR(&ISC_DISABLE); jtag->Usleep(1000); jtag->setTapState(Jtag::TEST_LOGIC_RESET); jtag->shiftIR(&ISC_ENABLE); if (! use_optimized_algs) data[0]=0x34; else data[0]=0x37; jtag->shiftDR(data,0,6); for (unsigned int i = 0; i < nblocks; i++) { unsigned int frame = (skipblocks + i) * FRAMES_PER_BLOCK; int j; if (jtag->getVerbose()) { fprintf(stderr, "\rProgramming block %6u/%6u at XCF frame 0x%04x", i, nblocks, frame); fflush(stderr); } jtag->shiftIR(&ISC_DATA_SHIFT); if ((i+1) * block_size <= nbits) { jtag->shiftDR(&(file.getData())[i*block_size/8], 0, block_size); } else { unsigned int rembytes = (nbits - (i * block_size) + 7) / 8; unsigned int padbytes = block_size / 8 - rembytes; memset(data, 0xff, padbytes); jtag->shiftDR(&(file.getData())[i*block_size/8], 0, rembytes*8, 0, false); jtag->shiftDR(data, 0, padbytes*8); } jtag->longToByteArray(frame, data); jtag->shiftIR(&ISC_ADDRESS_SHIFT); jtag->cycleTCK(1); jtag->shiftDR(data,0,16); jtag->cycleTCK(1); jtag->shiftIR(&ISC_PROGRAM); if (! use_optimized_algs) { jtag->Usleep(14000); } else { for (j = 0; j < 28; j++) { byte xcstatus[1]; jtag->Usleep(500); jtag->shiftIR(&ISCTESTSTATUS); jtag->shiftDR(0,xcstatus,8); if (xcstatus[0] & 0x04) break; else if(jtag->getVerbose()) { fprintf(stderr, "."); fflush(stderr); } } if (j == 28) { fprintf(stderr,"\nProgramming block %u (frame 0x%04x) failed! Aborting\n", i, frame); return 1; } } } if (! use_optimized_algs) /* only on XC18V*/ { jtag->shiftIR(&ISC_ADDRESS_SHIFT); jtag->cycleTCK(1); jtag->longToByteArray(1,data); jtag->shiftDR(data, 0, 16); jtag->cycleTCK(1); jtag->shiftIR(&SERASE); jtag->Usleep(37000); } if (jtag->getVerbose()) fprintf(stderr, "done\nProgramming time %.1f ms\n", timer.elapsed() * 1.0e3); jtag->shiftIR(&BYPASS); jtag->cycleTCK(1); jtag->tapTestLogicReset(); return 0; } int ProgAlgXCF::verify(BitFile &file) { byte data[MAX_BLOCK_SIZE/8]; unsigned int skipbits, nbits; skipbits = file.getOffset() * 8; if (skipbits % block_size != 0) { fprintf(stderr, "Verify does not start at block boundary (offset = %u bits), aborting\n", skipbits); return 1; } if (skipbits > size) { fprintf(stderr,"Verify start outside PROM area (offset = %u bits), aborting\n", skipbits); return -1; } if (file.getRLength() != 0) nbits = file.getRLength() * 8; else nbits = file.getLength(); if (nbits > size - skipbits) { fprintf(stderr,"Verify outside PROM areas requested, clipping\n"); nbits = size - skipbits; } unsigned int skipblocks = skipbits / block_size; unsigned int nblocks = (nbits + block_size - 1) / block_size; Timer timer; jtag->setTapState(Jtag::TEST_LOGIC_RESET); jtag->shiftIR(&ISC_ENABLE); data[0]=0x34; jtag->shiftDR(data,0,6); for (unsigned int i = 0; i < nblocks; i++) { unsigned int frame = (skipblocks + i) * FRAMES_PER_BLOCK; int res; if(jtag->getVerbose()) { fprintf(stderr, "\rVerify block %6u/%6u at XCF frame 0x%04x", i, nblocks, frame); fflush(stderr); } jtag->longToByteArray(frame,data); jtag->shiftIR(&ISC_ADDRESS_SHIFT); jtag->shiftDR(data,0,16); jtag->cycleTCK(1); jtag->shiftIR(&ISC_READ); jtag->Usleep(50); jtag->shiftDR(0,data,block_size); unsigned int blkbytes = block_size / 8; if ((i + 1) * block_size > nbits) blkbytes = (nbits - (i * block_size) + 7) / 8; res = memcmp(data, &(file.getData())[i*block_size/8], blkbytes); if (res) { fprintf(stderr, "\nVerify failed at block %u (frame 0x%04x)\n", i, frame); return res; } } if (jtag->getVerbose()) fprintf(stderr, "\nSuccess! Verify time %.1f ms\n", timer.elapsed() * 1.0e3); jtag->tapTestLogicReset(); return 0; } int ProgAlgXCF::read(BitFile &file) { byte data[MAX_BLOCK_SIZE/8]; unsigned int skipbits, nbits; skipbits = file.getOffset() * 8; if (skipbits % block_size != 0) { fprintf(stderr, "Read does not start at block boundary (offset = %u bits), aborting\n", skipbits); return -1; } if (skipbits > size) { fprintf(stderr,"Read start outside PROM area (offset = %u bits), aborting\n", skipbits); return -1; } if (file.getRLength() != 0) nbits = file.getRLength() * 8; else nbits = size - skipbits; if (nbits > size - skipbits) { fprintf(stderr,"Read outside PROM areas requested, clipping\n"); nbits = size - skipbits; } unsigned int skipblocks = skipbits / block_size; unsigned int nblocks = (nbits + block_size - 1) / block_size; file.setLength(nbits); Timer timer; jtag->setTapState(Jtag::TEST_LOGIC_RESET); jtag->shiftIR(&ISC_ENABLE); data[0]=0x34; jtag->shiftDR(data,0,6); for (unsigned int i = 0; i < nblocks; i++) { unsigned int frame = (skipblocks + i) * FRAMES_PER_BLOCK; if(jtag->getVerbose()) { fprintf(stderr, "\rReading block %6u/%6u at XCF frame 0x%04x", i, nblocks, frame); fflush(stderr); } jtag->longToByteArray(frame,data); jtag->shiftIR(&ISC_ADDRESS_SHIFT); jtag->shiftDR(data,0,16); jtag->cycleTCK(1); jtag->shiftIR(&ISC_READ); jtag->Usleep(50); jtag->shiftDR(0,data,block_size); unsigned int blkbytes = block_size / 8; if ((i + 1) * block_size > nbits) blkbytes = (nbits - (i * block_size) + 7) / 8; memcpy(&(file.getData())[i*block_size/8], data, blkbytes); } if (jtag->getVerbose()) fprintf(stderr, "\nSuccess! Read time %.1f ms\n", timer.elapsed() * 1.0e3); jtag->tapTestLogicReset(); return 0; } void ProgAlgXCF::disable() { jtag->shiftIR(&ISC_DISABLE); jtag->Usleep(110000); jtag->shiftIR(&BYPASS); jtag->cycleTCK(1); jtag->tapTestLogicReset(); } void ProgAlgXCF::reconfig(void) { jtag->shiftIR(&CONFIG); jtag->cycleTCK(1); jtag->shiftIR(&BYPASS); jtag->cycleTCK(1); jtag->tapTestLogicReset(); } xc3sprog-0+svn795+dfsg/progalgxcf.h000066400000000000000000000035621337255630200172720ustar00rootroot00000000000000/* XCF Flash PROM JTAG programming algorithms Copyright (C) 2004 Andrew Rogers 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 PROGALGXCF_H #define PROGALGXCF_H #include "bitfile.h" #include "jtag.h" #include "iobase.h" #include "progalg.h" #define FAMILY_XCF 0x28 class ProgAlgXCF : public ProgAlg { private: static const byte SERASE; static const byte ISC_ENABLE; static const byte ISC_PROGRAM; static const byte ISC_ADDRESS_SHIFT; static const byte ISC_ERASE; static const byte ISC_DATA_SHIFT; static const byte ISC_READ; static const byte ISC_DISABLE; static const byte IDCODE; static const byte CONFIG; static const byte BYPASS; static const byte FVFY1; static const byte FVFY3; static const byte ISCTESTSTATUS; static const byte USERCODE; static const byte BIT3; static const byte BIT4; Jtag *jtag; unsigned int block_size; unsigned int size; bool use_optimized_algs; public: ProgAlgXCF(Jtag &j, int si); virtual ~ProgAlgXCF() { } virtual unsigned int getSize() const { return size; } virtual int erase(); virtual int program(BitFile &file); virtual int verify(BitFile &file); virtual int read(BitFile &file); virtual void disable(); virtual void reconfig(); }; #endif //PROGALGXCF_H xc3sprog-0+svn795+dfsg/progalgxcfp.cpp000066400000000000000000000421331337255630200200020ustar00rootroot00000000000000/* * XCFxxP Flash PROM JTAG programming algorithms * * Copyright (C) 2010 Joris van Rantwijk * * 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. * * Programming sequences are based on the Xilinx 1532 BSDL files. * * Note: Some XCFP features are not supported (such as multiple revisions). * The special PROM registers are written to always select revision 00. * The default is slave serial mode (FPGA in master serial mode). * A few other configuration modes may be selected by calling * setXxxMode() before programming. */ #include #include #include #include "jtag.h" #include "progalgxcfp.h" #include "utilities.h" /* Device identification */ #define IDCODE_IS_XCF08P(id) (((id) & 0x0FFFFFFF) == 0x05057093) #define IDCODE_IS_XCF16P(id) (((id) & 0x0FFFFFFF) == 0x05058093) #define IDCODE_IS_XCF32P(id) (((id) & 0x0FFFFFFF) == 0x05059093) /* Note: XCFxxP devices have instruction_length == 16 */ static const byte BYPASS[2] = { 0xff, 0xff }; static const byte IDCODE[2] = { 0xfe, 0x00 }; static const byte ISC_ENABLE[2] = { 0xe8, 0x00 }; static const byte ISC_DISABLE[2] = { 0xf0, 0x00 }; static const byte ISC_PROGRAM[2] = { 0xea, 0x00 }; static const byte ISC_READ[2] = { 0xf8, 0x00 }; static const byte ISC_ERASE[2] = { 0xec, 0x00 }; static const byte ISC_ADDRESS_SHIFT[2] = { 0xeb, 0x00 }; static const byte ISC_DATA_SHIFT[2] = { 0xed, 0x00 }; static const byte XSC_CONFIG[2] = { 0xee, 0x00 }; static const byte XSC_OP_STATUS[2] = { 0xe3, 0x00 }; static const byte XSC_UNLOCK[2] = { 0x55, 0xaa }; static const byte XSC_DATA_BTC[2] = { 0xf2, 0x00 }; static const byte XSC_DATA_CCB[2] = { 0x0c, 0x00 }; static const byte XSC_DATA_SUCR[2] = { 0x0e, 0x00 }; static const byte XSC_DATA_DONE[2] = { 0x09, 0x00 }; ProgAlgXCFP::ProgAlgXCFP(Jtag &j, unsigned long id) { jtag = &j; idcode = id; // size of one array in bytes block_size = 0x100000; if (IDCODE_IS_XCF08P(idcode)) narray = 1; else if (IDCODE_IS_XCF16P(idcode)) narray = 2; else if (IDCODE_IS_XCF32P(idcode)) narray = 4; else { fprintf(stderr, "Unknown XCF device ID 0x%08lx\n", idcode); throw std::invalid_argument("Unknown XCF device"); } // default to slave serial mode (FPGA running in master serial mode) ccbParallelMode = false; ccbMasterMode = false; ccbFastClock = true; ccbExternalClock = true; fprintf(stderr, "ProgAlgXCFP $Rev$\n"); } unsigned int ProgAlgXCFP::getSize() const { // return storage capacity in bits return narray * block_size * 8; } int ProgAlgXCFP::erase() { return erase((1<tapTestLogicReset(); jtag->Usleep(1000); ret = verify_idcode(); if (ret) return ret; enable(); data[0] = 0x30 | array_mask; data[1] = 0x00; data[2] = 0x00; jtag->shiftIR(XSC_UNLOCK); jtag->shiftDR(data, 0, 24); jtag->cycleTCK(1); if(jtag->getVerbose()) { fprintf(stderr, "Erasing"); fflush(stderr); } // The ERASE command fails when state goes through READY-TEST-IDLE between // instruction and data. jtag->setPostIRState(Jtag::EXIT1_IR); jtag->shiftIR(ISC_ERASE); jtag->shiftDR(data, 0, 24); jtag->Usleep(10000); // restore default jtag->setPostIRState(Jtag::RUN_TEST_IDLE); for (int i = 0; i < 280; i++) { // we use 280 loops of 500 ms instead of 14000 loops of 10 ms jtag->Usleep(490000); if (jtag->getVerbose()) { fprintf(stderr, "."); fflush(stderr); } jtag->shiftIR(XSC_OP_STATUS); jtag->Usleep(10000); jtag->shiftDR(0, xcstatus, 8); if (xcstatus[0] & 0x04) break; } if (xcstatus[0] == 0x36) { if (jtag->getVerbose()) fprintf(stderr, "done!"); } else { ret = 1; fprintf(stderr, "\nErase failed (status=0x%02x)! Aborting\n", xcstatus[0]); } disable(); if (jtag->getVerbose()) fprintf(stderr, "Erase time %.3f s\n", timer.elapsed()); return ret; } int ProgAlgXCFP::program(BitFile &file) { Timer timer; byte data[32]; byte xcstatus[1]; int ret = 0; if (file.getOffset() != 0 || (file.getRLength() != 0 && file.getRLength() != file.getLengthBytes())) throw std::invalid_argument("XCFP does not yet support bitfile subranges"); jtag->tapTestLogicReset(); jtag->Usleep(1000); ret = verify_idcode(); if (ret) return ret; enable(); unsigned int used_blocks = (file.getLengthBytes() + block_size - 1) / block_size; if (used_blocks == 0) used_blocks = 1; if (used_blocks > narray) { fprintf(stderr, "Program does not fit in PROM, clipping\n"); used_blocks = narray; } for (unsigned int k = 0; k < used_blocks; k++) { for (unsigned int i = 0; i < 32768; i++) { unsigned int p = k * block_size + i * 32; // no need to program after end of bitfile if (p >= file.getLengthBytes()) break; if (jtag->getVerbose()) { fprintf(stderr, "\rProgramming frames 0x%06x to 0x%06x ", p, p+31); fflush(stderr); } jtag->shiftIR(ISC_DATA_SHIFT); if (p + 32 <= file.getLengthBytes()) { jtag->shiftDR(file.getData() + p, 0, 256); } else { memset(data, 0xff, 32); if (p < file.getLengthBytes()) memcpy(data, file.getData() + p, file.getLengthBytes() - p); jtag->shiftDR(data, 0, 256); } jtag->cycleTCK(1); if (i == 0) { jtag->longToByteArray(p, data); jtag->shiftIR(ISC_ADDRESS_SHIFT); jtag->shiftDR(data, 0, 24); jtag->cycleTCK(1); } jtag->shiftIR(ISC_PROGRAM); jtag->Usleep((i == 0) ? 1000 : 25); for (int t = 0; t < 100; t++) { jtag->shiftIR(XSC_OP_STATUS); jtag->shiftDR(0, xcstatus, 8); if (xcstatus[0] & 0x04) break; } if (xcstatus[0] != 0x36) { ret = 1; fprintf(stderr,"\nProgramming failed! Aborting\n"); break; } } } if (ret == 0) { unsigned long btc_data = 0xffffffe0 | ((used_blocks-1) << 2); if (jtag->getVerbose()) fprintf(stderr, "\nProgramming BTC=0x%08lx\n", btc_data); jtag->longToByteArray(btc_data, data); jtag->shiftIR(XSC_DATA_BTC); jtag->shiftDR(data, 0, 32); jtag->cycleTCK(1); jtag->shiftIR(ISC_PROGRAM); jtag->Usleep(1000); jtag->shiftIR(XSC_DATA_BTC); jtag->cycleTCK(1); jtag->shiftDR(0, data, 32); if (jtag->byteArrayToLong(data) != btc_data) { fprintf(stderr,"Programming BTC failed! Aborting\n"); ret = 1; } } if (ret == 0) { uint16_t ccb_data = encodeCCB(); if (jtag->getVerbose()) fprintf(stderr, "Programming CCB=0x%04x\n", ccb_data); jtag->shortToByteArray(ccb_data, data); jtag->shiftIR(XSC_DATA_CCB); jtag->shiftDR(data, 0, 16); jtag->cycleTCK(1); jtag->shiftIR(ISC_PROGRAM); jtag->Usleep(1000); jtag->shiftIR(XSC_DATA_CCB); jtag->cycleTCK(1); jtag->shiftDR(0, data, 16); if (jtag->byteArrayToShort(data) != ccb_data) { fprintf(stderr,"Programming CCB failed! Aborting\n"); ret = 1; } } if (ret == 0) { uint16_t sucr_data = 0xfffc; if (jtag->getVerbose()) fprintf(stderr, "Programming SUCR=0x%04x\n", sucr_data); jtag->shortToByteArray(sucr_data, data); jtag->shiftIR(XSC_DATA_SUCR); jtag->shiftDR(data, 0, 16); jtag->cycleTCK(1); jtag->shiftIR(ISC_PROGRAM); jtag->Usleep(1000); jtag->shiftIR(XSC_DATA_SUCR); jtag->cycleTCK(1); jtag->shiftDR(0, data, 16); if (jtag->byteArrayToShort(data) != sucr_data) { fprintf(stderr,"Programming SUCR failed! Aborting\n"); ret = 1; } } if (ret == 0) { byte done_data = 0xc0 | (0x0f & (0x0f << narray)); if (jtag->getVerbose()) fprintf(stderr, "Programming DONE=0x%02x\n", done_data); data[0] = done_data; jtag->shiftIR(XSC_DATA_DONE); jtag->shiftDR(data, 0, 8); jtag->cycleTCK(1); jtag->shiftIR(ISC_PROGRAM); jtag->Usleep(1000); jtag->shiftIR(XSC_DATA_DONE); jtag->cycleTCK(1); jtag->shiftDR(0, data, 8); if (data[0] != done_data) { fprintf(stderr,"Programming DONE failed! Aborting\n"); ret = 1; } else { if (jtag->getVerbose()) fprintf(stderr, "finished\n"); } } disable(); if (jtag->getVerbose()) fprintf(stderr, "Programming time %.3f s\n", timer.elapsed()); return ret; } int ProgAlgXCFP::verify(BitFile &file) { Timer timer; byte data[32]; int ret = 0; if (file.getOffset() != 0 || (file.getRLength() != 0 && file.getRLength() != file.getLengthBytes())) throw std::invalid_argument("XCFP does not yet support bitfile subranges"); jtag->tapTestLogicReset(); jtag->Usleep(1000); ret = verify_idcode(); if (ret) return ret; enable(); unsigned int used_blocks = (file.getLengthBytes() + block_size - 1) / block_size; if (used_blocks == 0) used_blocks = 1; if (used_blocks > narray) { fprintf(stderr, "Program does not fit in PROM, clipping\n"); used_blocks = narray; } for (unsigned int k = 0; k < used_blocks; k++) { jtag->longToByteArray(k * block_size, data); jtag->shiftIR(ISC_ADDRESS_SHIFT); jtag->shiftDR(data, 0, 24); jtag->cycleTCK(1); for (unsigned int i = 0; i < 32768; i++) { unsigned int p = k * block_size + i * 32; unsigned int n = 32; if (p >= file.getLengthBytes()) break; if (p + n > file.getLengthBytes()) n = file.getLengthBytes() - p; if (jtag->getVerbose()) { fprintf(stderr, "\rVerifying frames 0x%06x to 0x%06x ", p, p+n-1); fflush(stderr); } jtag->shiftIR(ISC_READ); jtag->Usleep(25); jtag->shiftIR(ISC_DATA_SHIFT); jtag->cycleTCK(1); jtag->shiftDR(0, data, 256); if (memcmp(data, file.getData() + p, n)) { ret = 1; fprintf(stderr, "\nVerify failed at frame 0x%06x to 0x%06x\n", p, p+n-1); break; } } if (ret) break; } if (jtag->getVerbose()) fprintf(stderr, "\nVerifying BTC "); unsigned long btc_data = 0xffffffe0 | ((used_blocks-1) << 2); jtag->shiftIR(XSC_DATA_BTC); jtag->cycleTCK(1); jtag->shiftDR(0, data, 32); if (jtag->getVerbose()) fprintf(stderr, "= 0x%08lx\n", jtag->byteArrayToLong(data)); if (jtag->byteArrayToLong(data) != btc_data) { fprintf(stderr, "Unexpected value in BTC register\n"); ret = 1; } if (jtag->getVerbose()) fprintf(stderr, "Verifying CCB "); jtag->shiftIR(XSC_DATA_CCB); jtag->cycleTCK(1); jtag->shiftDR(0, data, 16); if (jtag->getVerbose()) fprintf(stderr, "= 0x%04x\n", jtag->byteArrayToShort(data)); if (jtag->byteArrayToShort(data) != encodeCCB()) { fprintf(stderr, "Unexpected value in CCB register\n"); ret = 1; } if (jtag->getVerbose()) fprintf(stderr, "Verifying SUCR "); jtag->shiftIR(XSC_DATA_SUCR); jtag->cycleTCK(1); jtag->shiftDR(0, data, 16); if (jtag->getVerbose()) fprintf(stderr, "= 0x%02x%02x\n", data[1], data[0]); if (data[0] != 0xfc || data[1] != 0xff) { fprintf(stderr, "Unexpected value in SUCR register\n"); ret = 1; } if (jtag->getVerbose()) fprintf(stderr, "Verifying DONE "); byte done_data = 0xc0 | (0x0f & (0x0f << narray)); jtag->shiftIR(XSC_DATA_DONE); jtag->cycleTCK(1); jtag->shiftDR(0, data, 8); if (jtag->getVerbose()) fprintf(stderr, "= 0x%02x\n", data[0]); if (data[0] != done_data) { fprintf(stderr, "Unexpected value in DONE register\n"); ret = 1; } disable(); if (jtag->getVerbose() && ret == 0) fprintf(stderr, "Success!\n"); if (jtag->getVerbose()) fprintf(stderr, "Verify time %.3f s\n", timer.elapsed()); return ret; } int ProgAlgXCFP::read(BitFile &file) { Timer timer; byte data[32]; int ret = 0; if (file.getOffset() != 0 || (file.getRLength() != 0 && file.getRLength() != getSize() / 8)) throw std::invalid_argument("XCFP does not yet support bitfile subranges"); timer.start(); jtag->tapTestLogicReset(); jtag->Usleep(1000); ret = verify_idcode(); if (ret) return ret; enable(); jtag->shiftIR(XSC_DATA_BTC); jtag->cycleTCK(1); jtag->shiftDR(0, data, 32); unsigned long btc_data = jtag->byteArrayToLong(data); if (jtag->getVerbose()) fprintf(stderr, "BTC = 0x%08lx\n", btc_data); unsigned int first_block = btc_data & 0x03; unsigned int last_block = (btc_data & 0x0c) >> 2; if (jtag->getVerbose()) fprintf(stderr, "BTC: first_block=%u, last_block=%u, content_len=%u bytes\n", first_block, last_block, (last_block + 1 - first_block) * block_size); if (first_block > last_block || last_block >= narray) { fprintf(stderr, "Invalid data in BTC register: first_block=%u, last_block=%u\n", first_block, last_block); fprintf(stderr, "Reading failed.\n"); return 1; } file.setLength((last_block - first_block + 1) * 32768 * 256); for (unsigned int k = first_block; k <= last_block; k++) { jtag->longToByteArray(k * block_size, data); jtag->shiftIR(ISC_ADDRESS_SHIFT); jtag->shiftDR(data, 0, 24); jtag->cycleTCK(1); for (unsigned int i = 0; i < 32768; i++) { if (jtag->getVerbose()) { fprintf(stderr, "\rReading frames 0x%06x to 0x%06x ", k*block_size+i*32,k*block_size+i*32+31); fflush(stderr); } jtag->shiftIR(ISC_READ); jtag->Usleep(25); unsigned int p = (k - first_block) * block_size + i * 32; jtag->shiftIR(ISC_DATA_SHIFT); jtag->cycleTCK(1); jtag->shiftDR(0, file.getData() + p, 256); } } if (jtag->getVerbose()) fprintf(stderr, "done\n"); jtag->shiftIR(XSC_DATA_CCB); jtag->cycleTCK(1); jtag->shiftDR(0, data, 16); if (jtag->getVerbose()) fprintf(stderr, "CCB = 0x%04x\n", jtag->byteArrayToShort(data)); decodeCCB(jtag->byteArrayToShort(data)); if (jtag->getVerbose()) fprintf(stderr, "CCB: %s, %s, %s, %s\n", ccbMasterMode ? "master" : "slave", ccbParallelMode ? "parallel" : "serial", ccbExternalClock ? "extclk" : "intclk", ccbFastClock ? "fastclk" : "slowclk" ); jtag->shiftIR(XSC_DATA_DONE); jtag->cycleTCK(1); jtag->shiftDR(0, data, 8); if (jtag->getVerbose()) fprintf(stderr, "DONE = 0x%02x\n", data[0]); jtag->shiftIR(XSC_DATA_SUCR); jtag->cycleTCK(1); jtag->shiftDR(0, data, 16); if (jtag->getVerbose()) fprintf(stderr, "SUCR = 0x%02x%02x\n", data[1], data[0]); disable(); if (jtag->getVerbose()) fprintf(stderr, "Read time %.3f s\n", timer.elapsed()); return ret; } void ProgAlgXCFP::reconfig(void) { jtag->shiftIR(XSC_CONFIG); jtag->cycleTCK(1); jtag->shiftIR(BYPASS); jtag->cycleTCK(1); jtag->tapTestLogicReset(); } int ProgAlgXCFP::verify_idcode() { byte data[4]; jtag->shiftIR(IDCODE); jtag->cycleTCK(1); jtag->shiftDR(0, data, 32); unsigned long devid = jtag->byteArrayToLong(data); if ((devid & 0x0fffffff) != (idcode & 0x0fffffff)) { fprintf(stderr, "Failed to verify ID code, got 0x%08lx expected 0x%08lx\n", devid, idcode); return 1; } return 0; } void ProgAlgXCFP::enable() { byte data[1] = { 0x00 }; jtag->shiftIR(ISC_ENABLE); jtag->shiftDR(data, 0, 8); jtag->cycleTCK(1); } void ProgAlgXCFP::disable() { jtag->shiftIR(ISC_DISABLE); jtag->Usleep(1000); jtag->shiftIR(BYPASS); jtag->cycleTCK(1); jtag->tapTestLogicReset(); } uint16_t ProgAlgXCFP::encodeCCB() const { // The CCB register in the XCFnnP PROM deteremines the FPGA configuration // mode, i.e. parallel or serial, master or slave, config clock, etc. // See xcf32p_1532.bsd. uint16_t ccb = 0xffc0; ccb |= ccbParallelMode ? 0x00 : 0x06; ccb |= ccbMasterMode ? 0x00 : 0x08; ccb |= ccbFastClock ? 0x30 : 0x10; ccb |= ccbExternalClock ? 0x01 : 0x00; return ccb; } void ProgAlgXCFP::decodeCCB(uint16_t ccb) { ccbParallelMode = ((ccb & 0x06) == 0x00); ccbMasterMode = ((ccb & 0x08) == 0x00); ccbFastClock = ((ccb & 0x20) == 0x20); ccbExternalClock = ((ccb & 0x01) == 0x01); } xc3sprog-0+svn795+dfsg/progalgxcfp.h000066400000000000000000000032031337255630200174420ustar00rootroot00000000000000/* XCFxxP Flash PROM JTAG programming algorithms * * Copyright (C) 2010 Joris van Rantwijk * * 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. * */ #ifndef PROGALGXCFP_H #define PROGALGXCFP_H #include "bitfile.h" #include "jtag.h" #include "progalg.h" class ProgAlgXCFP : public ProgAlg { private: Jtag *jtag; unsigned long idcode; unsigned int narray; unsigned int block_size; bool ccbParallelMode; bool ccbMasterMode; bool ccbFastClock; bool ccbExternalClock; public: ProgAlgXCFP(Jtag &j, unsigned long id); virtual ~ProgAlgXCFP() { } virtual unsigned int getSize() const; virtual int erase(); virtual int program(BitFile &file); virtual int verify(BitFile &file); virtual int read(BitFile &file); virtual void reconfig(); virtual void disable(); void setParallelMode(bool v) { ccbParallelMode = v; } bool getParallelMode() const { return ccbParallelMode; } void setMasterMode(bool v) { ccbMasterMode = v; } bool getMasterMode() const { return ccbMasterMode; } void setFastClock(bool v) { ccbFastClock = v; } bool getFastClock() const { return ccbFastClock; } void setExternalClock(bool v) { ccbExternalClock = v; } bool getExternalClock() const { return ccbExternalClock; } private: int verify_idcode(); void enable(); int erase(int array_mask); uint16_t encodeCCB() const; void decodeCCB(uint16_t ccb); }; #endif //PROGALGXCFP_H xc3sprog-0+svn795+dfsg/readdna.cpp000066400000000000000000000143601337255630200170650ustar00rootroot00000000000000/* JTAG chain detection Copyright (C) 2004 Andrew Rogers 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 Changes: Sandro Amato [sdroamt@netscape.net] 26 Jun 2006 [applied 13 Jul 2006]: Print also the location of the devices found in the jtag chain to be used from jtagProgram.sh script... Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: Code cleanup for clean -Wall compile. Added support for FT2232 driver. */ #include #include #include #include #include "io_exception.h" #include "ioparport.h" #include "iofx2.h" #include "ioxpc.h" #include "ioftdi.h" #include "iodebug.h" #include "jtag.h" #include "devicedb.h" #include "utilities.h" extern char *optarg; void usage(void) { fprintf(stderr, "\nUsage: readdna [-c cable_type] [-v]\n" " -v\tverbose output\n" " -J val\tRun at max with given JTAG Frequency, 0(default) means max. Rate of device\n" " \tOnly used for FTDI cables for now\n\n" " Supported cable types: pp, ftdi, fx2, xpc\n" " \tOptional pp arguments:\n" " \t\t[-d device] (e.g. /dev/parport0)\n" " \tOptional fx2/ftdi/xpc arguments:\n" " \t\t[-V vendor] (idVendor)\n" " \t\t[-P product] (idProduct)\n" " \t\t[-S description] (Product string)\n" " \t\t[-s serial] (SerialNumber string)\n" " \tOptional ftdi arguments:\n" " \t\t[-t subtype]\n" " \t\t\t(NONE\t\t(0x0403:0x0610) or\n" " \t\t\t IKDA\t\t(0x0403:0x0610, EN_N on ACBUS2) or\n" " \t\t\t OLIMEX\t\t(0x15b1:0x0003, JTAG_EN_N on ADBUS4, LED on ACBUS3))\n" " \t\t\t AMONTEC\t(0x0403:0xcff8, JTAG_EN_N on ADBUS4)\n" " \tOptional xpc arguments:\n" " \t\t[-t subtype] (NONE or INT (Internal Chain on XPC, doesn't work for now on DLC10))\n"); exit(255); } unsigned int get_id(Jtag &jtag, DeviceDB &db, int chainpos, bool verbose) { int num=jtag.getChain(); DeviceID id; if (num == 0) { fprintf(stderr,"No JTAG Chain found\n"); return 0; } // Synchronise database with chain of devices. for(int i=0; i 0) jtag.setDeviceIRLength(i, length); else { fprintf(stderr,"Cannot find device having IDCODE=%08lx\n", (unsigned long)id); return 0; } } if(jtag.selectDevice(chainpos)<0){ fprintf(stderr,"Invalid chain position %d, position must be less than %d (but not less than 0).\n",chainpos,num); return 0; } id = jtag.getDeviceID(chainpos); if (verbose) { printf("JTAG chainpos: %d Device IDCODE = 0x%08lx Desc: %s\nProgramming: ", chainpos, (unsigned long)id, db.idToDescription(id)); fflush(stdout); } return id; } int main(int argc, char **args) { bool verbose = false; bool use_ftd2xx = false; struct cable_t cable; char const *dev = 0; char const *serial = 0; char const *cablename = 0; unsigned int jtag_freq = 0; byte idata[8]; byte odata[8]; int chainpos =0; char *devicedb = NULL; std::auto_ptr io; DeviceDB db(devicedb); int res; // Start from parsing command line arguments while(true) { switch(getopt(argc, args, "?hvc:d:J:L")) { case -1: goto args_done; case 'v': verbose = true; break; case 'J': jtag_freq = atoi(optarg); break; case 'L': use_ftd2xx = true; break; case 'c': cablename = optarg; break; case 'd': dev = optarg; break; case 's': serial = optarg; break; case '?': case 'h': default: usage(); } } args_done: // Get rid of options //printf("argc: %d\n", argc); argc -= optind; args += optind; //printf("argc: %d\n", argc); if((argc != 0) || (cablename == 0)) usage(); if (verbose) fprintf(stderr, "Using %s\n", db.getFile().c_str()); CableDB cabledb(0); res = cabledb.getCable(cablename, &cable); res = getIO( &io, &cable, dev, serial, verbose, use_ftd2xx, jtag_freq); if (res) /* some error happend*/ { if (res == 1) exit(1); else usage(); } io.get()->setVerbose(verbose); Jtag jtag(io.get()); jtag.setVerbose(verbose); get_id (jtag, db, chainpos, verbose); if (verbose) fprintf(stderr, "Using %s\n", db.getFile().c_str()); #define CFG_IN 0x05 #define ISC_ENABLE 0x10 #define ISC_DISABLE 0x16 #define JPROGRAM 0x0b #define ISC_DNA 0x31 #define BYPASS 0x3f jtag.selectDevice(chainpos); idata[0] = JPROGRAM; jtag.shiftIR(idata); idata[0] = CFG_IN; do jtag.shiftIR(idata, odata); while (! (odata[0] & 0x10)); /* wait until configuration cleared */ /* As ISC_DNA only works on a unconfigured device, see AR #29977*/ idata[0] = ISC_ENABLE; jtag.shiftIR(idata); idata[0] = ISC_DNA; jtag.shiftIR(idata); jtag.shiftDR(0, odata, 64); if (*(long long*)odata != -1LL) printf("DNA is 0x%02x%02x%02x%02x%02x%02x%02x%02x\n", odata[0], odata[1], odata[2], odata[3], odata[4], odata[5], odata[6], odata[7]); idata[0] = ISC_DISABLE; jtag.shiftIR(idata); /* Release JTAG control over configuration (AR 16829)*/ jtag.tapTestLogicReset(); idata[0] = JPROGRAM; jtag.shiftIR(idata); /* Now device will reconfigure from standard configuration source */ idata[0] = BYPASS; fprintf(stderr, "Will wait up to 10 seconds for device to reconfigure."); fflush(stderr); int i = 0; do { jtag.Usleep(1000); jtag.shiftIR(idata, odata); if(i%250 == 249) { fprintf(stderr, "."); fflush(stderr); } i++; } while ((( odata[0] & 0x23) != 0x21) && (i <10000)); fprintf(stderr, "\n"); return 0; } xc3sprog-0+svn795+dfsg/srecfile.cpp000066400000000000000000000147431337255630200172700ustar00rootroot00000000000000/* SREC .rom file parser Copyright (C) Uwe Bonnes 2009 bon@elektron.ikp.physik.tu-darmstadt.de 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 Modifyied from srecdec * Copyright (C) <2001> * antone@sentechsa.com */ #include "srecfile.h" #include "io_exception.h" #include #include using namespace std; int SrecFile::DecodeSRecordLine(char *source, unsigned char *dest, S_Record *SRec) { char buffer[16]; int i,l; if(*source!='S') { fprintf(stderr, "\r\n%s\r\n",source); if(*source != 'S') { fprintf(stderr, "DecodeSRecordLine: unexpected char 0x%02x", *source); if (isprint(*source)) fprintf(stderr," \"%c\"", *source); fprintf(stderr, "\n"); return -1; } } source++; SRec->Type=*source++-'0'; for(i=0;i<2;i++) { buffer[i]=*source++; } buffer[i]=0; SRec->Length=(char)Hex2Bin(buffer); switch(SRec->Type) { case 0: /* Start Record */ for(i=0;i<4;i++) { buffer[i]=*source++; } buffer[i]=0; SRec->Address=Hex2Bin(buffer); l=SRec->Length-3; /* 2 Address Bytes + 1 Checksum Bytes */ for(i=0;iDataLength=l; /* Actual Number of Data Bytes */ break; case 1: /* Data Record 16 bit address */ for(i=0;i<4;i++) { buffer[i]=*source++; } buffer[i]=0; SRec->Address=Hex2Bin(buffer); l=SRec->Length-3; /* 2 Address Bytes + 1 Checksum Bytes */ for(i=0;iDataLength=l; /* Actual Number of Data Bytes */ break; case 2: /* Data Record 24 bit address */ for(i=0;i<6;i++) { buffer[i]=*source++; } buffer[i]=0; SRec->Address=Hex2Bin(buffer); l=SRec->Length-4; /* 3 Address Bytes + 1 Checksum Bytes */ for(i=0;iDataLength=l; /* Actual Number of Data Bytes */ break; case 3: /* Data Record 32 bit address */ for(i=0;i<8;i++) { buffer[i]=*source++; } buffer[i]=0; SRec->Address=Hex2Bin(buffer); l=SRec->Length-5; /* 4 Address Bytes + 1 Checksum Bytes */ for(i=0;iDataLength=l; /* Actual Number of Data Bytes */ break; case 9: /* End Record 16 bit address */ for(i=0;i<4;i++) { buffer[i]=*source++; } buffer[i]=0; SRec->Address=Hex2Bin(buffer); SRec->DataLength=0; break; case 8: /* End Record 24 bit address */ for(i=0;i<6;i++) { buffer[i]=*source++; } buffer[i]=0; SRec->Address=Hex2Bin(buffer); SRec->DataLength=0; break; case 7: /* End Record 32 bit address */ for(i=0;i<8;i++) { buffer[i]=*source++; } buffer[i]=0; SRec->Address=Hex2Bin(buffer); SRec->DataLength=0; break; default: SRec->Type=255; SRec->Address=0; SRec->Length=0; SRec->DataLength=0; break; } return -1; } long SrecFile::Hex2Bin(char *ptr) { long tmp; sscanf(ptr,"%lX",&tmp); return((long)tmp); } char SrecFile::RecordType(char Type) { char tmp=3; switch(Type) { case 0: tmp=STARTRECORD; break; case 1: case 2: case 3: tmp=DATARECORD; break; case 7: case 8: case 9: tmp=ENDRECORD; break; } return(tmp); } int SrecFile::ReadOneLine(FILE *fp,char *dest, int len) { char c; int count=0; while((!feof(fp)) && (count = bufsize) { fprintf(stderr,"\n Address: 0x%lx",Address); Bytes_Read = 0; fprintf(stderr, "\n Buffer too small, " "Number of bytes read = %lu \n ",NumberOfBytes); return -3; } buffer[(size_t)Address] = LBuf[i]; NumberOfBytes++; if(Address>MaxA) { MaxA=Address; } i++; } } } StartAddr = StartAddress; Bytes_Read = NumberOfBytes; EndAddr = MaxA; return 0; } xc3sprog-0+svn795+dfsg/srecfile.h000066400000000000000000000035051337255630200167270ustar00rootroot00000000000000/* SREC .rom file parser Copyright (C) Uwe Bonnes 2009 bon@elektron.ikp.physik.tu-darmstadt.de 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 Modifyied from sreddec * Copyright (C) <2001> * antone@sentechsa.com */ #ifndef SRECFILE_H #define SRECFILE_H #include #include typedef unsigned char byte; typedef struct { int Type; /* S-Record Type */ long Address; /* Block Address */ int Length; /* S-Record Length */ int DataLength; /* Actual Number of Data Bytes */ }S_Record; #define STARTRECORD 0 #define DATARECORD 1 #define ENDRECORD 2 class SrecFile { private: unsigned int StartAddr; unsigned int EndAddr; unsigned int Bytes_Read; byte *buffer; int ReadOneLine(FILE *fp,char *dest, int len); int DecodeSRecordLine(char *source, unsigned char *dest, S_Record *SRec); long Hex2Bin(char *ptr); char RecordType(char Type); public: SrecFile(void); ~SrecFile(void); int readSrecFile(char const * fname, unsigned int bufsize); inline byte *getData(){return buffer;} inline unsigned int getStart(){return StartAddr;} inline unsigned int getEnd(){return EndAddr;} inline unsigned int getLength(){return Bytes_Read;} }; #endif //SRECFILE_H xc3sprog-0+svn795+dfsg/srecparse.cpp000066400000000000000000000024561337255630200174610ustar00rootroot00000000000000/* Srec .rom file parser Copyright (C) 2009 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de 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 "srecfile.h" #include "io_exception.h" int main(int argc, char**args) { if(argc < 2) { fprintf(stderr,"Usage: %s infile.rom\n",args[0]); } else { try { SrecFile file; if (file.readSrecFile(args[1], 0)<0) fprintf(stderr, "no valid file given\n"); else fprintf(stderr, "start 0x%08x end 0x%08x len 0x%08x\n", file.getStart(), file.getEnd(), file.getLength()); } catch(io_exception& e) { fprintf(stderr, "IOException: %s", e.getMessage().c_str()); return 1; } } } xc3sprog-0+svn795+dfsg/utilities.cpp000066400000000000000000000101261337255630200174760ustar00rootroot00000000000000#ifndef WIN32 #include #endif #include #include #include #include #include "ioparport.h" #include "iofx2.h" #include "ioftdi.h" #include "ioxpc.h" #include "utilities.h" extern char *optarg; void detect_chain(Jtag *jtag, DeviceDB *db) { int num=jtag->getChain(); for(int i=0; igetDeviceID(i); fprintf(stderr,"JTAG loc.: %3d IDCODE: 0x%08lx ", i, (unsigned long)id); int length = db->idToIRLength(id); if (length > 0) { jtag->setDeviceIRLength(i,length); fprintf(stderr,"Desc: %30s Rev: %c IR length: %2d\n", db->idToDescription(id), (int)(id >> 28) | 'A', length); } else { fprintf(stderr,"not found in '%s'.\n", db->getFile().c_str()); } } } int getIO( std::auto_ptr *io, struct cable_t * cable, char const *dev, char const *serial, bool verbose, bool use_ftd2xx, unsigned int freq) { int res = 1; unsigned int use_freq; if (!cable) { fprintf(stderr, "No cable selected. You must use -c option." " See xc3sprog -h for more help\n"); return 1; } if ((freq == 0) || ((cable->freq != 0) && (freq > cable->freq))) use_freq = cable->freq; else use_freq = freq; if (cable->cabletype == CABLE_PP) { #ifdef __MACH__ fprintf(stderr, "Parallel port cables are not supported on OS X.\n"); return 1; #else io->reset(new IOParport()); io->get()->setVerbose(verbose); res = io->get()->Init(cable, dev, use_freq); #endif } else if(cable->cabletype == CABLE_FTDI) { io->reset(new IOFtdi(use_ftd2xx)); io->get()->setVerbose(verbose); res = io->get()->Init(cable, serial, use_freq); } else if(cable->cabletype == CABLE_FX2) { io->reset(new IOFX2()); io->get()->setVerbose(verbose); res = io->get()->Init(cable, serial, use_freq); } else if(cable->cabletype == CABLE_XPC) { io->reset(new IOXPC()); io->get()->setVerbose(verbose); res = io->get()->Init(cable, serial, use_freq); } else { fprintf(stderr, "Unknown Cable \"%s\" \n", getCableName(cable->cabletype)); } return res; } const char *getCableName(int type) { switch (type) { case CABLE_PP: return "pp"; break; case CABLE_FTDI: return "ftdi"; break; case CABLE_FX2: return "fx2"; break; case CABLE_XPC: return "xpc"; break; case CABLE_UNKNOWN: return "unknown"; break; default: return "Unknown"; } } void get_os_name(char *buf, int buflen) { memset(buf, 0, buflen); #ifdef WIN32 snprintf(buf, buflen - 1, "Windows"); #else struct utsname uts; int ret; // Obtain information about current system. memset(&uts, 0, sizeof(uts)); ret = uname(&uts); if (ret < 0) snprintf(buf, buflen - 1, ""); snprintf(buf, buflen - 1, "%s", uts.sysname); #endif } void xc3sprog_Usleep(unsigned int usec) { #if defined(__WIN32__) /* Busy wait, as scheduler prolongs all waits for to least 10 ms http://sourceforge.net/apps/trac/scummvm/browser/vendor/freesci/ \ glutton/src/win32/usleep.c?rev=38187 */ LARGE_INTEGER lFrequency; LARGE_INTEGER lEndTime; LARGE_INTEGER lCurTime; QueryPerformanceFrequency (&lFrequency); if (lFrequency.QuadPart) { QueryPerformanceCounter (&lEndTime); lEndTime.QuadPart += (LONGLONG) usec * lFrequency.QuadPart / 1000000; do { QueryPerformanceCounter (&lCurTime); if (usec > 11000) Sleep(0); } while (lCurTime.QuadPart < lEndTime.QuadPart); } #else usleep(usec); #endif } /* Split string on delimiting character. */ std::vector splitString(const std::string& s, char delim) { std::vector res; for (std::string::size_type i = 0, n = s.size(); i < n; ) { std::string::size_type k = s.find(delim, i); if (k == std::string::npos) k = n; res.push_back(s.substr(i, k - i)); i = k + 1; } return res; } xc3sprog-0+svn795+dfsg/utilities.h000066400000000000000000000021301337255630200171370ustar00rootroot00000000000000#include #include #include #include "bitfile.h" #include "devicedb.h" #include "jtag.h" #include "cabledb.h" class DeviceDB; void detect_chain(Jtag *jtag, DeviceDB *db); int getIO(std::auto_ptr *io, struct cable_t*, char const *dev, const char *serial, bool verbose, bool ftd2xx, unsigned int freq); const char *getCableName(int type); void xc3sprog_Usleep(unsigned int usec); #define OSNAME_LEN 64 void get_os_name(char *buf, int buflen); /* Split string on delimiting character. */ std::vector splitString(const std::string& s, char delim); /* Utility class for measuring execution times. */ class Timer { private: struct timeval m_tv; public: // Construct and start timer. Timer() { start(); } // Restart timer from zero. void start() { gettimeofday(&m_tv, NULL); } // Return number of seconds elapsed since starting the timer. double elapsed() const { struct timeval t; gettimeofday(&t, NULL); return t.tv_sec + 1.0e-6 * t.tv_usec - m_tv.tv_sec - 1.0e-6 * m_tv.tv_usec; } }; xc3sprog-0+svn795+dfsg/xc2c_warp.cpp000066400000000000000000000067421337255630200173640ustar00rootroot00000000000000#include #include #include #include "unistd.h" #include "mapfile_xc2c.h" #include "jedecfile.h" #include "bitfile.h" void usage() { fprintf(stderr, "\nUsage:xc2c_warp [-v] [-m Mapfile Directory] infile [-o outfile]\n" " -h\t\tprint this help\n" " -v\t\tverbose output\n" " -m\t\tDirectory containg Map files\n" " -O\t\toutput file (parse input file only if not given\n" " -i\t\tintput file format (BIT|BIN|BPI|HEX)\n" " -o\t\toutput file format (BIT|BIN|BPI|HEX)\n"); exit(255); } int main(int argc, char**args) { bool verbose = false; bool revert = false; const char * outfile = NULL; FILE_STYLE in_style = STYLE_BIT; FILE_STYLE out_style = STYLE_BIT; char device[256]= ""; FILE *fp = NULL; const char * mapdir = NULL; fprintf(stderr, "Release $Rev: 237 $\n" "Please provide feedback on success/failure/enhancement requests!\n" "Check Sourceforge SVN for updates!\n"); while(true) { switch(getopt(argc, args, "?m:i:vo:O:")) { case -1: goto args_done; case 'v': verbose = true; break; case 'i': if (BitFile::styleFromString(optarg, &in_style)) { fprintf(stderr, "Unknown format \"%s\"\n", optarg); usage(); } break; case 'o': if (BitFile::styleFromString(optarg, &out_style)) { fprintf(stderr, "Unknown format \"%s\"\n", optarg); usage(); } break; case 'm': mapdir = optarg; break; case 'O': outfile = optarg; break; case '?': case 'h': default: usage(); } } args_done: argc -= optind; args += optind; if(argc < 1) usage(); MapFile_XC2C map; JedecFile fuses; BitFile bits; if (*args[0] == '-') fp = stdin; else { fp=fopen(args[0],"rb"); if(!fp) { fprintf(stderr, "Can't open datafile %s: %s\n", args[0], strerror(errno)); return 1; } } if (fuses.readFile(fp) == 0) { if (verbose) fprintf(stderr,"Jedecfile %s for %s: %d Fuses, Checksum: 0x%04x\n", args[0], fuses.getDevice(), fuses.getLength(), fuses.getChecksum()); strncpy(device, fuses.getDevice(), 255); } else { if (*args[0] == '-') fp = stdin; else { fp=fopen(args[0],"rb"); if(!fp) { fprintf(stderr, "Can't open datafile %s: %s\n", args[0], strerror(errno)); return 1; } } if (bits.readFile(fp, in_style) == 0 ) { if (verbose) fprintf(stderr,"Got Bitfile for Device %s: %d Fuses\n", bits.getPartName(), bits.getLength()); revert = true; strncpy(device, bits.getPartName(), 255); } else { fprintf(stderr, "File %s not recognized as Bit- or Jedecfile\n", args[0]); return 3; } } if (map.loadmapfile(mapdir, device)) { fprintf(stderr, "failed to load Mapfile %s, aborting\n", map.GetFilename()); return 2; } if(outfile) { fp = fopen(outfile,"wb"); if (!fp) { fprintf(stderr, "failed to open %s: %s\n", outfile, strerror(errno)); return 1; } } else return 0; if (revert) { map.bitfile2jedecfile(&bits, &fuses); fprintf(stderr, "Device %s: %d Fuses, Checksum calculated: 0x%04x," " Checksum from file 0x%04x\n", fuses.getDevice(), fuses.getLength(), fuses.calcChecksum(), fuses.getChecksum()); fuses.saveAsJed( device, fp); } else { map.jedecfile2bitfile(0xFFFFFFFF, &fuses, &bits); bits.saveAs(out_style, device, fp); } return 0; } xc3sprog-0+svn795+dfsg/xc3sprog.1000066400000000000000000000300231337255630200166070ustar00rootroot00000000000000'\" t .\" ** The above line should force tbl to be a preprocessor ** .\" .\" Man page for XC3Sprog .\" .\" Copyright (C) 2011 Joris van Rantwijk, ... .\" .\" This manpage 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. .\" .TH XC3SPROG 1 "2011-09-04" .nh .SH NAME xc3sprog \- JTAG programming utility for Xilinx FPGAs and PROMs .SH SYNOPSIS .B xc3sprog .B \-c .I cable .RI [\| options \|] .I file1spec .RI [\| file2spec \ ...\|] .br .B xc3sprog .B \-c .I cable .RI [\| options \|] .B \-j .SH DESCRIPTION .B xc3sprog is a command-line tool for programming FPGAs, microcontrollers and PROMs via JTAG. In a typical application, \fBxc3sprog\fR reads a .BIT file generated by an FPGA design tool, and programs it into the PROM chip on an FPGA board for persistent storage or the configuration RAM of a FPGA for temporary storage. For other use cases, see the section \fBEXAMPLES\fR below. As its name indicates, \fBxc3sprog\fR was originally designed for Xilinx Spartan-3 FPGAs. However, it has been extended to handle several other types of devices including Xilinx FPGAs, CPLDs, XCF flash PROMs, Atmel AVRs and SPI flash chips. \fBxc3sprog\fR supports several JTAG cables, including parallel port cables and USB programmers. .SH OPTIONS .TP \fB\-c\fR \fIcable\fR Specify the type of JTAG cable. The specified type, \fIcable\fR refers to a label in the cable database. .br Common cable types are \fBpp\fR (parallel port cable), \fBxpc\fR (Xilinx USB programmer), and \fBftdi\fR (FTDI-based USB programmer). .TP .B \-j Detect the JTAG chain and print a list of attached devices. This is the default if no other action is specified. .TP \fB\-p\fR \fIval\fR[,\fIval\fR,...] Use device at JTAG chain position \fIval\fR, default is position 0, the device connected to the TDO pin of the JTAG cable. Use this option to select a device from a multi-device JTAG chain. If multiple chain positions are specified, the data file will be split, programming the first part of the file into the first specified device and so on. This is useful for boards which a chain of multiple XCF chips to configure a single FPGA. .TP \fB\-T\fR\fIn\fR Test the JTAG chain \fIn\fR times. When running in ISF mode, test the SPI connection. .br If \fIn\fR is not specified, the default is to test 10000 times. .br If \fIn\fR = 0, keep testing forever. .TP \fB\-J\fR \fIfreq\fR Run at the specified JTAG clock frequency (\fIfreq\fR in Hz). If not specified, or if \fIfreq\fR = 0, the default is to run at the maximum frequency supported by the cable. .br Currently only supported for FTDI-based cables. .TP .B \-e Erase the entire device. .TP \fB\-I\fR[\fIfile\fR] Work in ISF mode to program an internal serial flash memory. The flash memory is attached to the primary JTAG target, but not directly accessible via the JTAG chain. The primary JTAG target is used as a proxy to forward SPI transactions to the flash memory. If \fIfile\fR is specified, start by programming the specified bitfile into the primary JTAG target (typically an FPGA). .TP .B \-R Send a reconfiguration command to the target device (XCV, XCF, XCFP for reconfiguration of the connected FPGA device or XC3S, XC6S, XC2V direct) .TP \fB\-m\fR \fImapdir\fR Search for XC2C map files in the specified directory. Map files are required to handle JEDEC files during CPLD programming. If not specified, defaults to the value of \fB$XC_MAPDIR\fR. .TP \fB\-d\fR \fI/dev/parportN\fR Specify the parallel port device to be used. If not specified, defaults to the value of \fB$XCPORT\fR or \fI/dev/parport0\fR. .br Only used for cable type \fBpp\fR. .TP \fB\-s\fR \fIserialnum\fR Use the USB device with the specified serial number string. Needed if several adapters of the same type are connected at the same time. .TP .B \-L Use libFTD2XX instead of libftdi to access FTDI-based cables. .TP .B \-D Dump the device database and cable database to files \fIdevlist.txt\fR and \fIcablelist.txt\fR in the current directory. If a file already exists, xc3sprog tries to generate a unique name by appending an increasing number. .TP \fB\-X\fR \fIopt\fR[,\fIopt\fR...] Set configuration mode for XCFnnP PROM devices. Configuration from XCFnnP PROM may be done in several modes, depending on the wiring between XCFnnP and FPGA. By default, xc3sprog prepares XCFnnP devices for slave serial mode (FPGA running in master serial mode). To override the defaults, specify a comma-separated list of options. The following options are accepted: .br .TS tab (@); l l. \fBmaster\fR@XCFnnP is master (FPGA is slave) \fBslave\fR@XCFnnP is slave (FPGA is master, this is default) \fBparallel\fR@Parallel configuration data bus \fBserial\fR@Serial configuration data line (default) \fBextclk\fR@Use external clock in master mode \fBintclk\fR@Use internal clock in master mode \fBfastclk\fR@Use fast internal clock \fBslowclk\fR@Use slow internal clock .TE .TP .B \-v Enable verbose output. .TP .B \-h Print a help text. .SH "ACTION SPECIFICATION" One or more programming actions may be specified. Each action consists of a filename, optionally followed by attributes in the form <\fIfilename\fR:\fIaction\fR:\fIoffset\fR:\fIstyle\fR:\fIlength\fR>. .TP 4 .I filename The file to be written to the device, or the file in which to store data after reading from the device. On windows systems, a colon on position 2 is considered as filename part and not as an action separator. .TP .I action One letter indicating whether to write, read, or verify the device. If not specified, the default action is 'w'. .TS tab (@); l l. w@Erase, then write data from file to device and verify. W@Write with auto-sector erase, then verify. v@Verify device against file. r@Read from device and write to file (no overwriting). R@Read from device and write to file, overwriting existing files. .TE .TP .I offset The byte offset inside the device where programming/reading should start. Only supported for SPI, XCFnnS devices and XMEGA. .TP .I style The format of the specified file. .TS tab (@); l lw(56). BIT@T{ Xilinx \.BIT file format. Default for FPGA, XCF and SPI devices. T} BIN@Raw binary file. BPI@Raw binary file not bit reversed. MCS@Xilinx .MCS file format. IHEX@T{ Intel HEX format. Also used by Xilinx PROMGEN when writing MCS files. Default for XMEGA devices. T} HEXRAW@Raw sequence of hexadecimal digits. JEDEC@Default for CPLD devices. .TE .TP .I length The number of bytes to program/read. Only supported for SPI, XCFnnS and XMEGA devices. .SH "DEVICE DATABASE" The device database contains a list of supported JTAG devices. When \fBxc3sprog\fR starts, it scans the JTAG chain to discover all attached devices. A device database is used to map the 32-bit ID codes of the devices to descriptive names and get basic knowledge how to handle the part, at minimum how to skip it. A default device database is compiled into the \fBxc3sprog\fR executable. The database is tried to be loaded from a file at run time. If the environment variable \fB$XCDB\fR is defined, it specifies the name of the device database file, otherwise the file \fIdevlist.txt\fR is read from the current directory. If a database file is not found at all, the internal compile-time database will be used. If a device is not yet know, the builtin list can be dumped, the information on the unknown part added and on the next run the new list will be read and used. .SH "CABLE DATABASE" The cable database contains a list of supported JTAG cables. Each cable type is identified by a short label, such as \fBpp\fR, \fBftdijtag\fR, or \fBxpc\fR. The database maps the label to parameters to be used to access the hardware of the cable. A default cable database is compiled into the \fBxc3sprog\fR executable. The database is tried to be loaded from a file at run time. If the environment variable \fB$CABLEDB\fR is defined, it specifies the name of the cable database file, otherwise the file \fIcablelist.txt\fR is read from the current directory. If a database file is not found at all, the internal compile-time database will be used. If a cable subtype (e.g. different VID/PID) is not yet know, the builtin list can be dumped, the information on the new cable added and on the next run the new list will be read and used. The database contains a line for each nown cable. The line consists of the alias for that cable to used with the \-c option, the basic type of the cable, the maximum allowed JTAG frequency of the cable and an optional option string. For FTDI devices the option string contains the USB vendor ID (VID), USB product ID (PID), the USB device description string, the FTDI channel of the JTAG interface and eventual commands for setting other pins beside the JTAG pins. e.g. to switch on some buffers. If the JTAG device uses a FTDI default VID/PID, the USB device description string is important to destinguish your JTAG device from other eventual connected FTDI devices with the same VID/PID .SH EXAMPLES .TP 4 .B xc3sprog \-c pp \-j Show a list of JTAG devices attached to the parallel port JTAG cable. .TP \fBxc3sprog\fR \fB\-c\fR \fBftdijtag\fR \fB\-v\fR \fB\-p\fR 0 \fIdesign.bit\fR Program the specified bitfile into the first device (position 0) in the JTAG chain. Use an FTDI-based USB JTAG cable. Show detailed progress information. .TP .B xc3sprog \-c ftidjtag \-T Test the integrity of the JTAG chain. .TP \fBxc3sprog\fR \fB\-c\fR \fBxpc\fR \fB\-p\fR 1 \fIdump.bit\fR\fB:r\fR Read the contents from the JTAG device in position 1 in the chain, and write the data as a Xilinx .BIT file. Use a Xilinx USB programmer. .TP \fBxc3sprog\fR \fB\-c\fR \fIcable\fR \fB\-I\fR\fIbscan_spi/xc3s50an.bit\fR \fIdesign.bit\fR Load \fIxc3s50an.bit\fR into the FPGA in position 0 in the JTAG chain. Then, program \fIdesign.bit\fR into the ISF memory in the FPGA. .TP \fBxc3sprog\fR \fB\-c\fR \fIcable\fR \fB\-I\fR \fIimage.bit\fR\fB:w:\fR0x10000 Program the image file into the SPI memory attached to the FPGA, starting at byte offset 0x10000. An appropriate bscan_spi file must already be loaded in the FPGA, so that it will act as a bridge between the JTAG cable and SPI bus. .SH ENVIRONMENT .TP .B XCDB Name of the file to use as device database. The default is \fIdevlist.txt\fR in the current directory. .TP .B CABLEDB Name of the file to use as cable database. The default is \fIcablelist.txt\fR in the current directory. .TP .B XCPORT Parallel port device to be used for JTAG cable type \fBpp\fR. The default is \fI/dev/parport0\fR. This setting may be overridden by command-line option \fB\-d\fR. .TP .B XC_MAPDIR Default directory to search for XC2C map files. This setting may be overridden by command-line option \fB\-m\fR. .TP .B JTAG_DEBUG If specified, a log of JTAG operations is written to a file with this name. .TP .B FTDI_DEBUG If specified, a log of interactions with the FTDI device is written to a file with this name. Only used for FTDI-based cable types. .TP .B XPC_DEBUG If specified, a log of interactions with the XPC programmer is written to a file with this name. Only used for XPC-based cable types. .TP .B SPI_DEBUG If specified, a log of SPI operations is written to a file with this name. Only used in ISF mode. .TP .B PDI_DEBUG If specified, a log of PDI operations is written to a file with this name. Only used when programming an Atmel XMega device. .SH FILES .TP .I devlist.txt The device database, containing a list of known JTAG target devices. This file is read from the current directory by default, or from the location indicated by the \fIXCDB\fR environment variable. If not found, an internal compile-time version of the device database is used. .TP .I cablelist.txt The cable database, containing a list of known JTAG cable types. This file is read from the current directory by default, or from the location indicated by the \fICABLEDB\fR environment variable. If not found, an internal compile-time version of the cable database is used. .SH "SEE ALSO" http://sourceforge.net/projects/xc3sprog/ .SH "Contribute back" Feedback on success/failure/enhancement requests: http://sourceforge.net/mail/?group_id=170565 xc3sprog-0+svn795+dfsg/xc3sprog.cpp000066400000000000000000001526761337255630200172540ustar00rootroot00000000000000/* Spartan3 JTAG programmer Copyright (C) 2004 Andrew Rogers 2005-2011 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de 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 Changes: Dmitry Teytelman [dimtey@gmail.com] 14 Jun 2006 [applied 13 Aug 2006]: Code cleanup for clean -Wall compile. Added support for FT2232 driver. Verbose support added. Installable device database location. */ #include #include #include #include #include #include #include #include #include #include #include #include "io_exception.h" #include "ioparport.h" #include "iofx2.h" #include "ioftdi.h" #include "ioxpc.h" #include "bitfile.h" #include "jtag.h" #include "devicedb.h" #include "cabledb.h" #include "progalgxcf.h" #include "progalgxcfp.h" #include "javr.h" #include "progalgxc3s.h" #include "jedecfile.h" #include "mapfile_xc2c.h" #include "progalgxc95x.h" #include "progalgxc2c.h" #include "progalgavr.h" #include "progalgspiflash.h" #include "progalgnvm.h" #include "utilities.h" using namespace std; #define MAXPOSITIONS 8 #define IDCODE_TO_FAMILY(id) ((id>>21) & 0x7f) #define IDCODE_TO_MANUFACTURER(id) ((id>>1) & 0x3ff) #define MANUFACTURER_ATMEL 0x01f #define MANUFACTURER_XILINX 0x049 int do_exit = 0; void ctrl_c(int sig) { do_exit = 1; } int programXC3S(Jtag &g, int argc, char **args, bool verbose, bool reconfig, int family); int programXCF(Jtag &jtag, DeviceDB &db, int argc, char **args, bool verbose, bool erase, bool reconfigure, const char *device, int *chainpositions, int nchainpos, const vector& xcfopts); int programXC95X(Jtag &jtag, unsigned long id, int argc, char **args, bool verbose, bool erase, const char *device); int programXC2C(Jtag &jtag, unsigned int id, int argc, char ** args, bool verbose, bool erase, bool rUsercode, uint32_t wUsercode, const char *mapdir, const char *device); int programSPI(Jtag &jtag, int argc, char ** args, bool verbose, bool erase, bool reconfig, int test_count, char *bscanfile,int family, const char *device); int programXMega(Jtag *jtag, unsigned long id, int argc, char **args, bool verbose, bool erase, bool reconfigure, const char *device); /* Excercise the IR Chain for at least 10000 Times If we read a different pattern, print the pattern for for optical comparision and read for at least 100000 times more If we found no chain, simple rerun the chain detection This may result in an endless loop to facilitate debugging with a scope etc */ void test_IRChain(Jtag *jtag, IOBase *io,DeviceDB &db , int test_count) { int num=jtag->getChain(); int failed = 0; int len = 0; int i, j, k; unsigned char ir_in[256]; unsigned char ir_out[256]; unsigned char din[256]; unsigned char dout[256]; unsigned char dcmp[256]; memset(din, 0xaa, 256); int run_irtest = 0; if(num == 0) /* the chain is not functional and we have no idea * what parts to look for */ { fprintf(stderr, "Running getChain %d times\n", test_count); k=0; for(i=0; igetChain(true)> 0) { if(k%1000 == 1) { fprintf(stderr,"."); fflush(stderr); } k++; } } return; } if(num >8) fprintf(stderr, "Found %d devices\n", num); /* Read the IDCODE via the IDCODE command */ (void) signal (SIGINT, ctrl_c); for(i=0; isetTapState(Jtag::TEST_LOGIC_RESET); jtag->selectDevice(i); DeviceID id = jtag->getDeviceID(i); int irlen = db.idToIRLength(id); if (irlen == 0) { run_irtest++; break; } uint32_t idcmd = db.idToIDCmd(id); for (j = 0; j < irlen; j = j+8) ir_in[j>>3] = (idcmd>>j) & 0xff; jtag->shiftIR(ir_in, ir_out); jtag->cycleTCK(1); jtag->shiftDR(NULL, &dout[i*4], 32); if (jtag->byteArrayToLong(dout+i*4) != id) { fprintf(stderr, "IDCODE mismatch pos %d Read 0x%08lx vs 0x%08lx\n", i, jtag->byteArrayToLong(dout+i*4), (unsigned long)id); run_irtest++; } } if(run_irtest) { /* ID Code did fail, to simple shift the IR chain */ fprintf(stderr, "Running IR_TEST %d times\n", test_count); /* exercise the chain */ for(i=0; igetDeviceID(i)); fprintf(stderr, "IR len = %d\n", len); jtag->setTapState(Jtag::TEST_LOGIC_RESET); jtag->setTapState(Jtag::SHIFT_IR); io->shiftTDITDO(din,dout,len,true); jtag->nextTapState(true); fprintf(stderr, "0x"); for(i=0; i >3; i++) fprintf(stderr, "%02x", dout[i]); fprintf(stderr, " binary "); k=len-1; for(i = 0; igetDeviceID(i)); for(j=0; j>3]>>(k&0x7)) &0x01) == 0x01)?'1':'0'); k--; } fprintf(stderr, " "); } fflush(stderr); for(i=0; isetTapState(Jtag::SELECT_DR_SCAN); jtag->setTapState(Jtag::SHIFT_IR); io->shiftTDITDO(din,dcmp,len,true); jtag->nextTapState(true); if (memcmp(dout, dcmp, (len+1)>>3) !=0) { fprintf(stderr, "mismatch run %d\n", i); failed++; for(j=0; j >3; j++) fprintf(stderr, "%02x", dcmp[j]); fprintf(stderr, " "); k=len-1; for(i = 0; igetDeviceID(i)); for(j=0; j>3]>>(k&0x7)) &0x01) == 0x01)?'1':'0'); k--; } fprintf(stderr, " "); } } fflush(stderr); if(i%1000 == 999) { fprintf(stderr, "."); fflush(stderr); } } fprintf(stderr, "\n"); } else { fprintf(stderr, "Reading ID_CODE %d times\n", test_count); memset(ir_in, 0, 256); /* exercise the chain */ for(i=num-1; i>=0 && !do_exit; i--) { int irlen = db.idToIRLength(jtag->getDeviceID(i)); uint32_t idcmd = db.idToIDCmd(jtag->getDeviceID(i)); for(j=0; j>3] |= ((l)?(1<<(len & 0x7)):0); len++; jtag->longToByteArray(jtag->getDeviceID(i), dcmp+((num -1 -i)*4)); } } fprintf(stderr, "Sending %d bits IDCODE Commands: 0x", len); for(i=0; i >3]); fprintf(stderr, "\n"); fprintf(stderr, "Expecting %d IDCODES :", num); for(i=num-1; i >= 0; i--) fprintf(stderr, " 0x%08lx", (unsigned long) jtag->getDeviceID(i)); jtag->tapTestLogicReset(); for(i=0; isetTapState(Jtag::SHIFT_IR); io->shiftTDI(ir_in,len,true); jtag->nextTapState(true); jtag->setTapState(Jtag::SHIFT_DR); io->shiftTDITDO(NULL,dout,num*32,true); jtag->nextTapState(true); jtag->setTapState(Jtag::TEST_LOGIC_RESET); if(memcmp(dout, dcmp, num*4) !=0) { fprintf(stderr, "\nMismatch run %8d:", i+1); failed++; for(j=num-1; j>=0; j--) fprintf(stderr," 0x%08lx", jtag->byteArrayToLong(dout+j*4)); fflush(stderr); } if(i%1000 == 999) { fprintf(stderr, "."); fflush(stderr); } } fprintf(stderr, "\n"); } if (failed) fprintf(stderr, "Failed %8d/%8d\n", failed, i); signal (SIGINT, SIG_DFL); } int init_chain(Jtag &jtag, DeviceDB &db) { int num = jtag.getChain(); if (num == 0) { fprintf(stderr,"No JTAG Chain found\n"); return 0; } // Synchronise database with chain of devices. for (int i=0; i 0) jtag.setDeviceIRLength(i,length); else { fprintf(stderr,"Cannot find device having IDCODE=%07lx Revision %c\n", id & 0x0fffffff, (int)(id >>28) + 'A'); return 0; } } return num; } static int last_pos = -1; unsigned long get_id(Jtag &jtag, DeviceDB &db, int chainpos) { bool verbose = jtag.getVerbose(); int num = jtag.getChain(); if (jtag.selectDevice(chainpos)<0) { fprintf(stderr, "Invalid chain position %d, must be >= 0 and < %d\n", chainpos, num); return 0; } unsigned long id = jtag.getDeviceID(chainpos); if (verbose && (last_pos != chainpos)) { fprintf(stderr, "JTAG chainpos: %d Device IDCODE = 0x%08lx\tDesc: %s\n", chainpos, id, db.idToDescription(id)); fflush(stderr); last_pos = chainpos; } return id; } void usage(bool all_options) { fprintf(stderr, "usage:\txc3sprog -c cable [options] ...\n"); fprintf(stderr, "\tList of known cables is given with -c follow by no or invalid cablename\n"); fprintf(stderr, "\tfilespec is filename:action:offset:style:length\n"); fprintf(stderr, "\taction on of 'w|W|v|r|R'\n"); fprintf(stderr, "\tw: erase whole area, write and verify\n"); fprintf(stderr, "\tW: Write with auto-sector erase and verify\n"); fprintf(stderr, "\tv: Verify device against filename\n"); fprintf(stderr, "\tr: Read from device,write to file, don't overwrite existing file\n"); fprintf(stderr, "\tR: Read from device and write to file, overwrite existing file\n"); fprintf(stderr, "\tDefault action is 'w'\n\n"); fprintf(stderr, "\tDefault offset is 0\n\n"); fprintf(stderr, "\tstyle: One of BIT|BIN|BPI|MCS|IHEX|HEX\n"); fprintf(stderr, "\tBIT: Xilinx .bit format\n"); fprintf(stderr, "\tBIN: Binary format\n"); fprintf(stderr, "\tBPI: Binary format not bit reversed\n"); fprintf(stderr, "\tMCS: Intel Hex File, LSB first\n"); fprintf(stderr, "\tIHEX: INTEL Hex format, MSB first (Use for Xilinx .mcs files!)\n"); fprintf(stderr, "\tHEX: Hex dump format\n"); fprintf(stderr, "\tDefault for FPGA|SPI|XCF is BIT\n"); fprintf(stderr, "\tDefault for CPLD is JED\n"); fprintf(stderr, "\tDefault for XMEGA is IHEX\n"); fprintf(stderr, "\tDefault length is whole device\n"); if (!all_options) exit(255); fprintf(stderr, "\nPossible options:\n"); #define OPT(arg, desc) \ fprintf(stderr, " %-8s %s\n", (arg), (desc)) OPT("-p val[,val...]", "Use device at JTAG Chain position ."); OPT("", "Default (0) is device connected to JTAG Adapter TDO."); OPT("-e", "Erase whole device."); OPT("-h", "Print this help."); OPT("-I[file]", "Work on connected SPI Flash (ISF Mode),"); OPT("" , "after loading 'bscan_spi' bitfile if given."); OPT("-j", "Detect JTAG chain, nothing else (default action)."); OPT("-l", "Program lockbits if defined in fusefile."); OPT("-m ", "Directory with XC2C mapfiles."); OPT("-u", "Read usercode form XC2C devices."); OPT("-U val", "Set usercode when writing a JED file to XC2C devices."); OPT("-R", "Try to reconfigure device(No other action!)."); OPT("-T val", "Test chain 'val' times (0 = forever) or 10000 times" " default."); OPT("-J val", "Run at max with given JTAG Frequency, 0(default) means max. Rate of device"); OPT("", "Only used for FTDI cables for now"); OPT("-D", "Dump internal devlist and cablelist to files"); OPT("" , "In ISF Mode, test the SPI connection."); OPT("-X opts", "Set options for XCFxxP programming"); OPT("-v", "Verbose output."); fprintf(stderr, "\nProgrammer specific options:\n"); /* Parallel cable */ OPT("-d", "(pp only ) Parallel port device."); /* USB devices */ OPT("-s num" , "(usb devices only) Serial number string."); OPT("-L ", "(ftdi only ) Don't use LibUSB."); fprintf(stderr, "\nDevice specific options:\n"); OPT("-E file", "(AVR only) EEPROM file."); OPT("-F file", "(AVR only) File with fuse bits."); #undef OPT exit(255); } /* Parse a filename in the form * aaaa.bb:action:0x10000|section:0x10000:rawhex:0x1000 * for name, action, offset|area, style, length * * return the Open File * * possible action * w: erase whole area, write and verify * W: Write with auto-sector erase and verify * v: Verify device against filename * r: Read from device and write to file, don't overwrite exixting file * R: Read from device and write to file, overwrite exixting file * * possible sections: * f: Flash * a: * */ FILE *getFile_and_Attribute_from_name( char *name, char * action, char * section, unsigned int *offset, FILE_STYLE *style, unsigned int *length) { FILE *ret; char filename[256]; char *p = name, *q; int len; char localaction = 'w'; char localsection = 'a'; unsigned int localoffset = 0; FILE_STYLE localstyle=STYLE_BIT; unsigned int locallength = 0; if(!p) return NULL; else { q = strchr(p,':'); #if defined(__WIN32__) if (p[1] == ':') { /* Assume we have a DOS path. * Look for next colon or end-of-string. */ q = strchr(p + 2, ':'); } #endif if (q) len = q-p; else len = strlen(p); if (len>0) { int num = (len>255)?255:len; strncpy(filename, p, num); filename[num] = 0; } else return NULL; p = q; if(p) p ++; } /* Action*/ if(p) { q = strchr(p,':'); if (q) len = q-p; else len = strlen(p); if (len == 1) localaction = *p; else localaction = 'w'; if (action) { if(localaction == 'W') *action = localaction; else *action = tolower(localaction); } p = q; if(p) p ++; } /*Offset/Area*/ if(p) { q = strchr(p,':'); if (q) len = q-p; else len = strlen(p); if (!isdigit(*p)) { localsection = *p; if (section) *section = localsection; p++; } localoffset = strtol(p, NULL, 0); if (offset) *offset = localoffset; p = q; if(p) p ++; } /*Style*/ if(p ) { int res = 0; q = strchr(p,':'); if (q) len = q-p; else len = strlen(p); if (len) res = BitFile::styleFromString(p, &localstyle); if(res) { fprintf(stderr, "\nUnknown format \"%*s\"\n", len, p); return 0; } if (len && style) *style = localstyle; p = q; if(p) p ++; } /*Length*/ if(p) { locallength = strtol(p, NULL, 0); p = strchr(p,':'); if (length) *length = locallength; if(p) p ++; } if (tolower(localaction) == 'r') { if (!(strcasecmp(filename,"stdout"))) ret= stdout; else { int res; struct stat stats; res = stat(filename, &stats); if ((res == 0) && (localaction == 'r') && stats.st_size !=0) { fprintf(stderr, "File %s already exists. Aborting\n", filename); return NULL; } ret=fopen(filename,"wb"); if(!ret) fprintf(stderr, "Unable to open File %s. Aborting\n", filename); } } else { #if 0 if (!(strcasecmp(filename,"stdin"))) ret = stdin; else #endif { ret = fopen(filename,"rb"); if(!ret) fprintf(stderr, "Can't open datafile %s: %s\n", filename, strerror(errno)); } } return ret; } void dump_lists(CableDB *cabledb, DeviceDB *db) { int fd; FILE *fp_out; char outname[17] = "cablelist.txt"; fd = open(outname, O_WRONLY|O_CREAT|O_EXCL, 0644); if (fd <0 ) { sprintf(outname,"cablelist.txt.1"); fd = open(outname, O_WRONLY|O_CREAT, 0644); } if (fd <0 ) { fprintf(stderr, "Error creating file\n"); } else { fprintf(stderr, "Dumping internal cablelist to %s\n", outname); fp_out = fdopen(fd, "w"); if (fp_out) { fprintf(fp_out, "%-20s%-8s%-10sOptString\n", "#Alias", "Type", "Frequency"); cabledb->dumpCables(fp_out); fclose(fp_out); } } sprintf(outname,"devlist.txt"); fd = open(outname, O_WRONLY|O_CREAT|O_EXCL, 0644); if (fd <0 ) { sprintf(outname,"devlist.txt.1"); fd = open(outname, O_WRONLY|O_CREAT, 0644); } if (fd <0 ) { fprintf(stderr, "Error creating file\n"); } else { fprintf(stderr, "Dumping internal devicelist to %s\n", outname); fp_out = fdopen(fd, "w"); if (fp_out) { fprintf(fp_out, "# IDCODE IR_len ID_Cmd Text\n"); db->dumpDevices(fp_out); fclose(fp_out); } } exit(0); } int main(int argc, char **args) { bool verbose = false; bool dump = false; bool verify = false; bool lock = false; bool detectchain = false; bool chaintest = false; bool spiflash = false; bool reconfigure = false; bool erase = false; bool rUsercode = false; uint32_t wUsercode = 0xFFFFFFFF; bool use_ftd2xx = false; unsigned int jtag_freq= 0; unsigned long id; struct cable_t cable; char const *dev = 0; char const *eepromfile= 0; char const *fusefile = 0; char const *mapdir = 0; FILE_STYLE in_style = STYLE_BIT; FILE_STYLE out_style = STYLE_BIT; int chainpos = 0; int nchainpos = 1; int chainpositions[MAXPOSITIONS] = {0}; vector xcfopts; int test_count = 0; char const *serial = 0; char *bscanfile = 0; char *cablename = 0; char osname[OSNAME_LEN]; DeviceDB db(NULL); CableDB cabledb(NULL); std::auto_ptr io; int res; get_os_name(osname, sizeof(osname)); // Produce release info from SVN tags fprintf(stderr, "XC3SPROG (c) 2004-2011 xc3sprog project $Rev$ OS: %s\n" "Free software: If you contribute nothing, expect nothing!\n" "Feedback on success/failure/enhancement requests:\n" "\thttp://sourceforge.net/mail/?group_id=170565 \n" "Check Sourceforge for updates:\n" "\thttp://sourceforge.net/projects/xc3sprog/develop\n\n", osname); // Start from parsing command line arguments while(true) { int c = getopt(argc, args, "?hCLc:d:DeE:F:i:I::jJ:Lm:o:p:Rs:S:T::uU:vX:"); switch(c) { case -1: goto args_done; case 'v': verbose = true; break; case 'C': verify = true; break; case 'I': spiflash = true; bscanfile = optarg; break; case 'j': detectchain = true; break; case 'L': use_ftd2xx = true; break; case 'R': reconfigure = true; break; case 'T': chaintest = true; if(optarg == 0) test_count = 10000; else test_count = atoi(optarg); if (test_count == 0) test_count = INT_MAX; break; case 'J': jtag_freq = atoi(optarg); break; case 'l': lock = true; break; case 'c': cablename = optarg; break; case 'm': mapdir = optarg; break; case 'e': erase = true; break; case 'u': rUsercode = true; break; case 'U': wUsercode = strtoul(optarg, NULL, 0); break; case 'D': dump = true; break; case 'E': eepromfile = optarg; break; case 'F': fusefile = optarg; break; case 'o': if (BitFile::styleFromString(optarg, &out_style) != 0) { fprintf(stderr, "\nUnknown format \"%s\"\n", optarg); usage(false); } break; case 'i': if (BitFile::styleFromString(optarg, &in_style) != 0) { fprintf(stderr, "\nUnknown format \"%s\"\n", optarg); usage(false); } break; case 'd': dev = optarg; break; case 'p': { char *p = optarg, *q; for (nchainpos = 0; nchainpos <= MAXPOSITIONS; ) { chainpositions[nchainpos] = strtoul(p, &q, 10); if (p == q) break; p = q; nchainpos++; if (*p == ',') p++; else break; } if (*p != '\0') { fprintf(stderr, "Invalid position specification \"%s\"\n", optarg); usage(false); } } chainpos = chainpositions[0]; break; case 's': serial = optarg; break; case 'X': { vector new_opts = splitString(string(optarg), ','); xcfopts.insert(xcfopts.end(), new_opts.begin(), new_opts.end()); break; } case '?': case 'h': default: if (optopt == 'c') { fprintf(stdout, "Known Cables\n"); cabledb.dumpCables(stderr); exit(1); } fprintf(stderr, "Unknown option -%c\n", c); usage(true); } } args_done: argc -= optind; args += optind; if (dump) dump_lists(&cabledb, &db); if((argc < 0) || (cablename == 0)) usage(true); if(argc < 1 && !reconfigure && !erase && !rUsercode) detectchain = true; if (verbose) { fprintf(stderr, "Using %s\n", db.getFile().c_str()); fprintf(stderr, "Using %s\n", cabledb.getFile().c_str()); } res = cabledb.getCable(cablename, &cable); if(res) { fprintf(stderr,"Can't find description for a cable named %s\n", cablename); fprintf(stdout, "Known Cables\n"); cabledb.dumpCables(stderr); exit(1); } res = getIO( &io, &cable, dev, serial, verbose, use_ftd2xx, jtag_freq); if (res) /* some error happend*/ { if (res == 1) exit(1); else usage(false); } Jtag jtag = Jtag(io.get()); jtag.setVerbose(verbose); if (init_chain(jtag, db)) id = get_id (jtag, db, chainpos); else id = 0; if(chaintest && !spiflash) test_IRChain(&jtag, io.get(), db, test_count); if (detectchain && !spiflash) { detect_chain(&jtag, &db); return 0; } if (id == 0) return 2; unsigned int family = IDCODE_TO_FAMILY(id); unsigned int manufacturer = IDCODE_TO_MANUFACTURER(id); if (nchainpos != 1 && (manufacturer != MANUFACTURER_XILINX || family != FAMILY_XCF)) { fprintf(stderr, "Multiple positions only supported in case of XCF\n"); usage(false); } if(spiflash) return programSPI(jtag, argc, args, verbose, erase, reconfigure, test_count, bscanfile, family, db.idToDescription(id)); else if (manufacturer == MANUFACTURER_XILINX) { /* Probably XC4V and XC5V should work too. No devices to test at IKDA */ if( (family == FAMILY_XC2S) || (family == FAMILY_XC2SE) || (family == FAMILY_XC4VLX) || (family == FAMILY_XC4VFX) || (family == FAMILY_XC4VSX) || (family == FAMILY_XC3S) || (family == FAMILY_XC3SE) || (family == FAMILY_XC3SA) || (family == FAMILY_XC3SAN) || (family == FAMILY_XC3SD) || (family == FAMILY_XC6S) || (family == FAMILY_XC2V) || (family == FAMILY_XC5VLX) || (family == FAMILY_XC5VLXT) || (family == FAMILY_XC5VSXT) || (family == FAMILY_XC5VFXT) || (family == FAMILY_XC5VTXT) || (family == FAMILY_XC7) ) return programXC3S(jtag, argc, args, verbose, reconfigure, family); else if (family == FAMILY_XCF) { return programXCF(jtag, db, argc, args, verbose, erase, reconfigure, db.idToDescription(id), chainpositions, nchainpos, xcfopts); } else if( family == 0x4b) /* XC95XL XC95XV*/ { return programXC95X(jtag, id, argc,args, verbose, erase, db.idToDescription(id)); } else if ((family & 0x7e) == 0x36) /* XC2C */ { return programXC2C(jtag, id, argc, args, verbose, erase, rUsercode, wUsercode, mapdir, db.idToDescription(id)); } else { fprintf(stderr, "Sorry, can't program Xilinx device '%s' from family 0x%02x " "A more recent release may be able to.\n", db.idToDescription(id), family); return 1; } } else if ( manufacturer == MANUFACTURER_ATMEL) { switch(db.idToIDCmd(id)) { case 3: return programXMega(&jtag, id, argc, args, verbose, erase, reconfigure, db.idToDescription(id)); default: return jAVR (jtag, id, args[0],verify, lock, eepromfile, fusefile); } } else fprintf(stderr, "Sorry, can't program device '%s' from manufacturer 0x%02x " "A more recent release may be able to.\n", db.idToDescription(id), manufacturer); return 1; } ProgAlg * makeProgAlg(Jtag &jtag, unsigned long id, const vector& xcfopts, bool checkopts) { if ((id & 0x000f0000) == 0x00050000) { // XCFxxP ProgAlgXCFP *alg = new ProgAlgXCFP(jtag, id); for (size_t i = 0; i < xcfopts.size(); i++) { const char *opt = xcfopts[i].c_str(); if (strcasecmp(opt, "parallel") == 0) alg->setParallelMode(true); else if (strcasecmp(opt, "serial") == 0) alg->setParallelMode(false); else if (strcasecmp(opt, "master") == 0) alg->setMasterMode(true); else if (strcasecmp(opt, "slave") == 0) alg->setMasterMode(false); else if (strcasecmp(opt, "fastclk") == 0) alg->setFastClock(true); else if (strcasecmp(opt, "slowclk") == 0) alg->setFastClock(false); else if (strcasecmp(opt, "extclk") == 0) alg->setExternalClock(true); else if (strcasecmp(opt, "intclk") == 0) alg->setExternalClock(false); else if (checkopts) fprintf(stderr, "Ignoring unknown option '%s' for XCFxxP device\n", xcfopts[i].c_str()); } return alg; } else { // XCFxxS if (checkopts) { for (size_t i = 0; i < xcfopts.size(); i++) fprintf(stderr, "Ignoring unknown option '%s' for XCFxxS device\n", xcfopts[i].c_str()); } return new ProgAlgXCF(jtag, (id & 0x000ff000) >> 12); } } int programXC3S(Jtag &jtag, int argc, char** args, bool verbose, bool reconfig, int family) { ProgAlgXC3S alg(jtag, family); int i; if(reconfig) alg.reconfig(); else { for(i=0; i< argc; i++) { int res; unsigned int bitfile_offset = 0; unsigned int bitfile_length = 0; char action = 'w'; FILE_STYLE bitfile_style = STYLE_BIT; FILE *fp; BitFile bitfile; fp = getFile_and_Attribute_from_name (args[i], &action, NULL, &bitfile_offset, &bitfile_style, &bitfile_length); if (tolower(action) != 'w') { if (verbose) { fprintf(stderr,"Action %c not supported for XC3S\n", action); } continue; } if( bitfile_offset != 0) { if (verbose) { fprintf(stderr,"Offset %d not supported for XC3S\n", bitfile_offset); } continue; } if( bitfile_length != 0) { if (verbose) { fprintf(stderr,"Length %d not supported for XC3S\n", bitfile_length); } continue; } res = bitfile.readFile(fp, bitfile_style); if (res != 0) { if (verbose) { fprintf(stderr,"Reading Bitfile %s failed\n", args[i]); } continue; } if(verbose) { fprintf(stderr, "Created from NCD file: %s\n", bitfile.getNCDFilename()); fprintf(stderr, "Target device: %s\n", bitfile.getPartName()); fprintf(stderr, "Created: %s %s\n", bitfile.getDate(), bitfile.getTime()); fprintf(stderr, "Bitstream length: %u bits\n", bitfile.getLength()); } alg.array_program(bitfile); } } return 0; } int programXCF(Jtag &jtag, DeviceDB &db, int argc, char **args, bool verbose, bool erase, bool reconfigure, const char *device, int *chainpositions, int nchainpos, const vector& xcfopts) { // identify all specified devices unsigned int total_size = 0; for (int k = 0; k < nchainpos; k++) { unsigned long id = get_id(jtag, db, chainpositions[k]); if (IDCODE_TO_MANUFACTURER(id) != MANUFACTURER_XILINX || IDCODE_TO_FAMILY(id) != FAMILY_XCF) { fprintf(stderr, "Multiple positions only supported in case of XCF\n"); usage(false); } std::auto_ptr alg(makeProgAlg(jtag, id, xcfopts, true)); total_size += alg->getSize(); } if (erase) { for (int k = 0; k < nchainpos; k++) { unsigned long id = get_id(jtag, db, chainpositions[k]); std::auto_ptr alg(makeProgAlg(jtag, id, xcfopts, false)); alg->erase(); } } for (int i = 0; i < argc; i++) { unsigned int promfile_offset = 0; /* Where to start in the XCF space */ unsigned int promfile_rlength = 0;/* How many bytes to process */ unsigned int prom_pos = 0; /* Current byte position in XCF space */ char action = 'w'; BitFile promfile; FILE_STYLE promfile_style = STYLE_BIT; FILE *promfile_fp = getFile_and_Attribute_from_name (args[i], &action, NULL, &promfile_offset, &promfile_style, &promfile_rlength); if (!promfile_fp) continue; promfile.setOffset(promfile_offset); promfile.setRLength(promfile_rlength); if (action == 'v' || tolower(action) == 'w') { promfile.readFile(promfile_fp, promfile_style); // If no explicit length requested, default to complete file. if (promfile_rlength == 0) promfile_rlength = promfile.getLength() / 8; } else if(action == 'r') { // If no length requested, default to complete PROM space. if (promfile_rlength == 0) promfile_rlength = total_size / 8 - promfile_offset; promfile.setLength(promfile_rlength * 8); } if (promfile_rlength > promfile.getLength() / 8) { fprintf(stderr, "Requested length (%u bytes) exceeds bitfile size (%u bytes)\n", promfile_rlength, promfile.getLength() / 8); continue; } if (promfile_offset > total_size / 8 || promfile_rlength > total_size / 8 - promfile_offset) { fprintf(stderr, "Requested operation (offset %u, length %u bytes) exceeds PROM space (%u bits)\n", promfile_offset, promfile_rlength, total_size); continue; } for (int k = 0; k < nchainpos; k++) { unsigned long id = get_id(jtag, db, chainpositions[k]); std::auto_ptr alg(makeProgAlg(jtag, id, xcfopts, false)); BitFile tmp_bitfile; BitFile &cur_bitfile = (nchainpos == 1) ? promfile : tmp_bitfile; unsigned int current_promlen = alg->getSize() / 8; unsigned int current_offset = 0; unsigned int current_rlength = 0; if (prom_pos + current_promlen <= promfile_offset) { // current PROM falls before requested range prom_pos += current_promlen; continue; } else if (prom_pos < promfile_offset) { // requested range starts inside current PROM current_offset = promfile_offset - prom_pos; } if (prom_pos >= promfile_offset + promfile_rlength) { // current PROM falls behind the requested range break; } else if (prom_pos + current_promlen > promfile_offset + promfile_rlength) { // requested range ends inside current PROM current_rlength = promfile_offset + promfile_rlength - prom_pos - current_offset; } cur_bitfile.setOffset(current_offset); if (current_rlength * 8 != cur_bitfile.getLength()) cur_bitfile.setRLength(current_rlength); else cur_bitfile.setRLength(0); if (action == 'r') { alg->read(cur_bitfile); if (nchainpos != 1) { // copy temp data to selected part of output file assert(cur_bitfile.getLength() % 8 == 0); assert(prom_pos - promfile_offset + tmp_bitfile.getLength() / 8 <= promfile.getLength() / 8); memcpy(promfile.getData() + prom_pos - promfile_offset, tmp_bitfile.getData(), tmp_bitfile.getLength() / 8); } } else { if (nchainpos != 1) { // copy selected part of input file to temp object unsigned int n = current_rlength ? current_rlength : (current_promlen - current_offset); assert(prom_pos - promfile_offset + n <= promfile.getLength() / 8); tmp_bitfile.setLength(n * 8); memcpy(tmp_bitfile.getData(), promfile.getData() + prom_pos - promfile_offset, n); } if (tolower(action) == 'w') { int res; if (action == 'w') { res = alg->erase(); if (res) return res; } res = alg->program(cur_bitfile); if (res) { alg->disable(); return res; } } int res = alg->verify(cur_bitfile); alg->disable(); if (res) { return res; } } prom_pos += current_promlen; } // write output file if (action == 'r') promfile.saveAs(promfile_style, device, promfile_fp); } // send reconfiguration cmd to first device if (reconfigure) { unsigned long id = get_id(jtag, db, chainpositions[0]); std::auto_ptr alg(makeProgAlg(jtag, id, xcfopts, false)); alg->reconfig(); } return 0; } int programSPI(Jtag &jtag, int argc, char ** args, bool verbose, bool erase, bool reconfig, int test_count, char *bscanfile, int family, const char *device) { int i; ProgAlgSPIFlash alg(jtag); if (bscanfile) { programXC3S(jtag, 1, &bscanfile, verbose, 0, family); } if (alg.spi_flashinfo() != 1 && !reconfig) { fprintf(stderr,"ISF Bitfile probably not loaded\n"); return 2; } if (test_count) { alg.test(test_count); goto test_reconf; } if(erase) { alg.erase(); } for(i=0; i< argc; i++) { unsigned int spifile_offset = 0; unsigned int spifile_rlength = 0; int ret = 0; char action = 'w'; BitFile spifile; FILE_STYLE spifile_style = STYLE_BIT; FILE *spifile_fp = getFile_and_Attribute_from_name (args[i], &action, NULL, &spifile_offset, &spifile_style, &spifile_rlength); if(!spifile_fp) continue; spifile.setOffset(spifile_offset); spifile.setRLength(spifile_rlength); if (action == 'r') { alg.read(spifile); spifile.saveAs(spifile_style, device, spifile_fp); } else if (action == 'v') { spifile.readFile(spifile_fp, spifile_style); ret = alg.verify(spifile); } else { spifile.readFile(spifile_fp, spifile_style); fclose(spifile_fp); spifile_fp = NULL; if(verbose) { fprintf(stderr, "Created from NCD file: %s\n", spifile.getNCDFilename()); fprintf(stderr, "Target device: %s\n", spifile.getPartName()); fprintf(stderr, "Created: %s %s\n", spifile.getDate(),spifile.getTime()); fprintf(stderr, "Bitstream length: %u bits\n", spifile.getLength()); } ret = alg.program(spifile); if (ret == 0 ) ret = alg.verify(spifile); } if (spifile_fp) fclose(spifile_fp); if (ret != 0) return ret; } test_reconf: if(reconfig) { ProgAlgXC3S fpga(jtag, family); fpga.reconfig(); } return 0; } int programXC95X(Jtag &jtag, unsigned long id, int argc, char **args, bool verbose, bool erase, const char *device) { int i, size = (id & 0x000ff000)>>13; ProgAlgXC95X alg(jtag, size); if (erase) { alg.erase(); } for (i = 0; i< argc; i++) { int ret = 0; unsigned int jedecfile_offset = 0; unsigned int jedecfile_rlength = 0; char action = 'w'; JedecFile jedecfile; FILE_STYLE jedecfile_style= STYLE_JEDEC; if (i>1) { fprintf(stderr, "Multiple arguments not supported: %s\n", args[i]); continue; } FILE *jedecfile_fp = getFile_and_Attribute_from_name (args[i], &action, NULL, &jedecfile_offset, &jedecfile_style, &jedecfile_rlength); if (jedecfile_offset != 0) { fprintf(stderr, "Offset %d not supported, Using 0\n", jedecfile_offset); jedecfile_offset = 0; } if (jedecfile_rlength != 0) { fprintf(stderr, "Readlength %d not supported, Using 0\n", jedecfile_rlength); jedecfile_rlength = 0; } if(jedecfile_style != STYLE_JEDEC) { fprintf(stderr, "Style %s not supported, skipping\n", BitFile::styleToString(jedecfile_style)); } if (action == 'r') { alg.array_read(jedecfile); jedecfile.saveAsJed(device, jedecfile_fp); } else if (action == 'v' || tolower(action) == 'w') { jedecfile.readFile(jedecfile_fp); if (action == 'w') { if (!erase) { ret = alg.erase(); } } if(tolower(action) == 'w') alg.array_program(jedecfile); ret = alg.array_verify(jedecfile); } if(ret) return ret; } return 0; } int programXC2C( Jtag &jtag, unsigned int id, int argc, char ** args, bool verbose, bool erase, bool rUsercode, uint32_t wUsercode, const char *mapdir, const char *device) { int i, ret; int size_ind = (id & 0x001f0000)>>16; bool map_available = false; MapFile_XC2C map; if (map.loadmapfile(mapdir, device)) { // map.GetFilename() isn't defined if loadmapfile fails(). // (It will also output its own error message.) fprintf(stderr, "No mapfile available -- only bitfile (not JEDEC) " "operations will be supported.\n"); } else map_available = true; if (rUsercode) { ProgAlgXC2C alg(jtag, size_ind); alg.read_usercode(); } if (erase) { ProgAlgXC2C alg(jtag, size_ind); alg.erase(); ret = alg.blank_check(); if (ret != 0) { fprintf(stderr,"Erase failed\n"); return ret; } } for (i = 0; i< argc; i++) { int ret = 0; unsigned int file_offset = 0; unsigned int file_rlength = 0; char action = 'w'; BitFile file; JedecFile fuses; FILE_STYLE file_style= (map_available)?STYLE_JEDEC:STYLE_BIT; FILE *fp = getFile_and_Attribute_from_name (args[i], &action, NULL, &file_offset, &file_style, &file_rlength); if (i>1) { fprintf(stderr, "Multiple arguments not supported: %s\n", args[i]); continue; } if (file_offset != 0) { fprintf(stderr, "Offset %d not supported, Using 0\n", file_offset); file_offset = 0; } if (file_rlength != 0) { fprintf(stderr, "Readlength %d not supported, Using 0\n", file_rlength); file_rlength = 0; } if(action == 'r') /* Readback requested*/ { ProgAlgXC2C alg(jtag, size_ind); alg.array_read(file); if (map_available && file_style == STYLE_JEDEC) { map.bitfile2jedecfile(&file, &fuses); fuses.saveAsJed( device, fp); } else file.saveAs(file_style, device, fp); ret = 0; } else if (action == 'v' || tolower(action) == 'w') { /* Load file */ if (map_available && file_style == STYLE_JEDEC) { ret = fuses.readFile(fp); if (ret) fprintf(stderr, "Probably no JEDEC File, aborting\n"); else /*FIXME ret = */ map.jedecfile2bitfile(wUsercode, &fuses, &file); } else { fprintf(stderr,"Reading style %s\n", file.styleToString(file_style)); file.readFile(fp, file_style); if (file.getLength() == 0) { fprintf(stderr, "Probably no Bitfile, aborting\n"); return 2; } } if(strncmp(device, (map_available)?fuses.getDevice():file.getPartName(), sizeof("XC2CXX")) !=0) { fprintf(stderr, "Incompatible File for Device %s\n" "Actual device in Chain is %s\n", (map_available)?fuses.getDevice(): file.getPartName(), device); ret = 3; } if (ret == 0) { ProgAlgXC2C alg(jtag, size_ind); if(tolower(action) == 'w') { if (!erase && (action == 'w')) { alg.erase(); ret = alg.blank_check(); } if (ret == 0) { alg.array_program(file); } } ret = alg.array_verify(file); alg.done_program(); } } if(fp) fclose(fp); if (ret) return ret; } return 0; } int programXMega(Jtag *jtag, unsigned long id, int argc, char **args, bool verbose, bool erase, bool reconfigure, const char *device) { int i,ret = 0; enum PDI_STATUS_CODE res; uint32_t appl_size, boot_size, eeprom_size, eeprom_page = 0x20; uint32_t flash_page = 0x200; uint8_t bypass = 0; PDIoverJTAG protocol (jtag, 0x7); ProgAlgNVM alg(&protocol); switch((id >>12)& 0xffff) { case 0x9642: case 0x964c: case 0x964e: appl_size = 0x10000; boot_size = 0x01000; eeprom_size = 0x00800; flash_page = 0x100; break; case 0x974a: case 0x974c: appl_size = 0x20000; boot_size = 0x02000; eeprom_size = 0x00800; break; case 0x9842: case 0x9843: appl_size = 0x40000; boot_size = 0x02000; eeprom_size = 0x01000; break; default: fprintf(stderr,"Unknown/Unhandled XMega device 0x%08lx\n", id); return 1; } res = alg.xnvm_init(); if(res != STATUS_OK) { fprintf(stderr, "Init Xmega PDI programming failed\n"); return 1; } if (verbose) { uint8_t device_id[5]; uint8_t fuses[8]; uint8_t row[200]; alg.xnvm_read_memory(0x1000090, device_id, 5); fprintf(stderr,"DeviceID from MCU_CONTROL 0x%02x%02x%02x Rev %c" " JTAGUID %02x\n", device_id[0],device_id[1], device_id[2],'A'+ device_id[3], device_id[4] ); alg.xnvm_read_memory(0x08f0020, fuses, 8); fprintf(stderr,"Fuses U:%02x W:%02x R:%02x S:%02x V:%02x L:%02x\n", fuses[0], fuses[1], fuses[2], fuses[4], fuses[5], fuses[7]); alg.xnvm_read_memory(0x08e0200, row, 200); fprintf(stderr,"Lot:%02x%02x%02x%02x%02x%02x Wafer:%02x " "X:%02x%02x Y:%02x%02x\n", row[0xd], row[0xc], row[0xb], row[0xa], row[9], row[8], row[0x10], row[0x13], row[0x12], row[0x15], row[0x14]); } if(erase) { res = alg.xnvm_chip_erase(); if (res != STATUS_OK) { fprintf(stderr, "Xmega PDI chip erase failed\n"); ret = 1; goto xmega_release; } } for (i = 0; i< argc; i++) { char section = 'a'; unsigned int file_offset = 0; unsigned int file_rlength = 0; char action = 'w'; BitFile file; FILE_STYLE file_style= STYLE_IHEX; uint32_t base = 0x800000; unsigned int length; FILE *fp = getFile_and_Attribute_from_name (args[i], &action, §ion, &file_offset, &file_style, &file_rlength); if((action != 'e') && !fp) continue; switch (section) { case 'a': length = appl_size; break; case 'b': base += appl_size; length = boot_size; break; case 'e': base = 0x8c0000; length = eeprom_size; break; case 'p': base = 0x8e0200; length = 0x40; break; case 'u': base = 0x8e0400; length = flash_page; break; case 'f': base = 0x8f0020; length = 8; break; case 'l': base = 0x8f0027; length = 1; break; default: fprintf(stderr,"Unknown section %c\n", section); continue; } if (file_rlength != 0) { length = file_rlength; } if (file_offset != 0) file.setOffset(file_offset); else file.setOffset(length); if (action == 'r') { uint32_t res; file.setLength(length *8); /* Inhibit clipping of trailing 0xff's for fuses and lock*/ if ((section == 'f') || (section == 'l')) file.setRLength(length); res = alg.xnvm_read_memory(base + file_offset, file.getData(), length); if(res != length) { fprintf(stderr, "Xmega PDI Reading Section %c failed:" " read 0x%06x vs requested 0x%06x\n", section, res, length); res = 1; goto xmega_release; } file.saveAs(file_style, device, fp); } else if (action == 'v') { uint32_t j, res; BitFile vfile; vfile.readFile(fp, file_style); length = vfile.getLength()/8; file.setLength(length *8); res = alg.xnvm_read_memory(base, file.getData(), length); if(res != length) { fprintf(stderr, "Xmega PDI Verify Section %c failed:" " 0x%06x read vs 0x%06x req\n", section, res, length); ret = 1; goto xmega_release; } for(j=0; jshiftIR(&bypass); return ret; } xc3sprog-0+svn795+dfsg/xmega_pdi_nvm.cpp000066400000000000000000000547221337255630200203120ustar00rootroot00000000000000/** * \file * * \brief XMEGA PDI NVM command driver * * Copyright (C) 2009 Atmel Corporation. All rights reserved. * * \page License * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. The name of Atmel may not be used to endorse or promote products derived * from this software without specific prior written permission. * * 4. This software may only be redistributed and used in connection with an * Atmel AVR product. * * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ /* Adaptation to xc3sprog Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de 2011 */ #include #include "progalgnvm.h" #include "atxmega128a1_nvm_regs.h" ProgAlgNVM::ProgAlgNVM(PDIoverJTAG *protocoll) { prot = protocoll; initialized = 0; } ProgAlgNVM::~ProgAlgNVM(void) { prot = 0; initialized = 0; } /** * \brief Initiliazation function for the PDI interface * * This function initializes the PDI interface agains * the connected target device. * * \retval STATUS_OK init ok * \retval ERR_TIMEOUT the init timed out */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_init(void) { PDI_STATUS_CODE retval; if(initialized == 0){ /* Put the device in reset mode */ xnvm_put_dev_in_reset(); /* Create the key command */ cmd_buffer[0] = XNVM_PDI_KEY_INSTR; cmd_buffer[1] = NVM_KEY_BYTE0; cmd_buffer[2] = NVM_KEY_BYTE1; cmd_buffer[3] = NVM_KEY_BYTE2; cmd_buffer[4] = NVM_KEY_BYTE3; cmd_buffer[5] = NVM_KEY_BYTE4; cmd_buffer[6] = NVM_KEY_BYTE5; cmd_buffer[7] = NVM_KEY_BYTE6; cmd_buffer[8] = NVM_KEY_BYTE7; prot->pdi_write(cmd_buffer, 9); retval = xnvm_ctrl_wait_nvmbusy(WAIT_RETRIES_NUM); initialized = 1; } return retval; } /** * \brief Function for putting the device into reset * * \retval STATUS_OK if all went well * \retval ERR_IO_ERROR if the pdi write failed */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_put_dev_in_reset (void) { /* Reset the device */ cmd_buffer[0] = XNVM_PDI_STCS_INSTR | XOCD_RESET_REGISTER_ADDRESS; cmd_buffer[1] = XOCD_RESET_SIGNATURE; if(prot->pdi_write(cmd_buffer, 2)){ return ERR_IO_ERROR; } return STATUS_OK; } /** * \brief Function for releasing the reset of the device * * \retval STATUS_OK if all went well * \retval ERR_IO_ERROR if the pdi write failed */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_pull_dev_out_of_reset (void) { /* Pull device out of reset */ cmd_buffer[0] = XNVM_PDI_STCS_INSTR | XOCD_RESET_REGISTER_ADDRESS; cmd_buffer[1] = 0; if(prot->pdi_write(cmd_buffer, 2)){ return ERR_IO_ERROR; } return STATUS_OK; } /** * \internal * \brief Wait until the NVM module has completed initialization * * \param retries the retry count. * \retval STATUS_OK the NVMEN was set successfully. * \retval ERR_BAD_DATA One of the bytes sent was corrupted during transmission. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_wait_for_nvmen(uint32_t retries) { uint8_t pdi_status; while (retries != 0) { if (xnvm_read_pdi_status(&pdi_status) != STATUS_OK) { fprintf(stderr,"xnvm_wait_for_nvmen failed retries %d\n", retries); return ERR_BAD_DATA; } if ((pdi_status & XNVM_NVMEN) != 0) { return STATUS_OK; } --retries; } return ERR_TIMEOUT; } /** * \internal * \brief Read the PDI Controller's STATUS register * * \param status the status buffer pointer. * \retval STATUS_OK read successfully. * \retval ERR_BAD_DATA One of the bytes sent was corrupted during transmission. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_read_pdi_status(uint8_t *status) { enum PDI_STATUS_CODE ret = STATUS_OK; cmd_buffer[0] = XNVM_PDI_LDCS_INSTR; if (STATUS_OK != prot->pdi_write(cmd_buffer, 1)) { ret = ERR_BAD_DATA; } if (prot->pdi_read(status, 1, WAIT_RETRIES_NUM) == 0) { ret = ERR_TIMEOUT; } return ret; } /** * \brief Read the IO space register with NVM controller * * \param address the register address in the IO space. * \param value the value buffer pointer. * \retval STATUS_OK read successfully. * \retval ERR_BAD_DATA One of the bytes sent was corrupted during transmission. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_ioread_byte(uint16_t address, uint8_t *value) { enum PDI_STATUS_CODE ret = STATUS_OK; uint32_t register_address; int res; cmd_buffer[0] = XNVM_PDI_LDS_INSTR | XNVM_PDI_LONG_ADDRESS_MASK | XNVM_PDI_BYTE_DATA_MASK; register_address = XNVM_DATA_BASE + address; memmove((cmd_buffer + 1), (uint8_t*)®ister_address, 4); ret = prot->pdi_write(cmd_buffer, 5); if( ret == STATUS_OK) { res = prot->pdi_read(value, 1, WAIT_RETRIES_NUM); if (res != 0) ret = ERR_BAD_DATA; } return ret; } /** * \brief Write the IO space register with NVM controller * * \param address the register address in the IO space. * \param value the value which should be write into the address. * \retval STATUS_OK write successfully. * \retval ERR_BAD_DATA One of the bytes sent was corrupted during transmission. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_iowrite_byte(uint16_t address, uint8_t value) { uint32_t register_address = XNVM_DATA_BASE + address; cmd_buffer[0] = XNVM_PDI_STS_INSTR | XNVM_PDI_LONG_ADDRESS_MASK | XNVM_PDI_BYTE_DATA_MASK; memmove((cmd_buffer + 1), (uint8_t*)®ister_address, 4); cmd_buffer[5] = value; return (prot->pdi_write(cmd_buffer, 6)); } /** * \internal * \brief Read the NVM Controller's status register * * \param value the NVM Controller's status buffer pointer. * \retval STATUS_OK read successfully. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_ctrl_read_status(uint8_t *value) { return xnvm_ctrl_read_reg(XNVM_CONTROLLER_STATUS_REG_OFFSET, value); } /** * \internal * \brief Read the NVM Controller's register * * \param reg the offset of the NVM Controller register. * \param value the pointer of the value buffer. * \retval STATUS_OK read succussfully. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_ctrl_read_reg(uint16_t reg, uint8_t *value) { uint16_t address; address = XNVM_CONTROLLER_BASE + reg; return xnvm_ioread_byte(address, value); } /** * \internal * \brief Write the NVM Controller's register * * \param reg the offset of the NVM Controller register. * \param value the value which should be write into the register. * \retval STATUS_OK write succussfully. * \retval ERR_BAD_DATA One of the bytes sent was corrupted during transmission. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_ctrl_write_reg(uint16_t reg, uint8_t value) { uint16_t address; address = XNVM_CONTROLLER_BASE + reg; return xnvm_iowrite_byte(address, value); } /** * \internal * \brief Write the NVM CTRLA register CMDEX * * \retval STATUS_OK write successful. * \retval STATUS_OK write successfully. * \retval ERR_BAD_DATA One of the bytes sent was corrupted during transmission. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_ctrl_cmdex_write(void) { return xnvm_ctrl_write_reg(XNVM_CONTROLLER_CTRLA_REG_OFFSET, XNVM_CTRLA_CMDEX); } /** * \internal * \brief Write NVM command register * * \param cmd_id the command code which should be write into the NVM command register. * \retval STATUS_OK write successfully. * \retval ERR_BAD_DATA One of the bytes sent was corrupted during transmission. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_ctrl_cmd_write(uint8_t cmd_id) { return xnvm_ctrl_write_reg(XNVM_CONTROLLER_CMD_REG_OFFSET, cmd_id); } /** * \brief Erase the whole chip * * \retval STATUS_OK erase chip succussfully. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_chip_erase(void) { /* Write the chip erase command to the NVM command reg */ xnvm_ctrl_cmd_write(XNVM_CMD_CHIP_ERASE); /* Write the CMDEX to execute command */ xnvm_ctrl_cmdex_write(); return xnvm_wait_for_nvmen(WAIT_RETRIES_NUM); } /** * \brief Erase the application section chip * * \retval STATUS_OK erase chip succussfully. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_application_erase(void) { /* Write the chip erase command to the NVM command reg */ xnvm_ctrl_cmd_write(XNVM_CMD_ERASE_APP_SECTION); /* Write the CMDEX to execute command */ xnvm_st_ptr(XNVM_FLASH_BASE); xnvm_st_star_ptr_postinc(DUMMY_BYTE); return xnvm_wait_for_nvmen(WAIT_RETRIES_NUM); } /** * \brief Erase the boot section chip * * \retval STATUS_OK erase chip succussfully. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_boot_erase(uint32_t address) { /* Write the chip erase command to the NVM command reg */ xnvm_ctrl_cmd_write(XNVM_CMD_ERASE_BOOT_SECTION); /* Write the CMDEX to execute command */ xnvm_st_ptr(address); xnvm_st_star_ptr_postinc(DUMMY_BYTE); return xnvm_ctrl_wait_nvmbusy(WAIT_RETRIES_NUM); } /** * \brief Erase the eeprom section chip * * \retval STATUS_OK erase chip succussfully. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_erase_eeprom(void) { /* Write the chip erase command to the NVM command reg */ xnvm_ctrl_cmd_write(XNVM_CMD_ERASE_EEPROM); /* Write the CMDEX to execute command */ xnvm_st_ptr(XNVM_EEPROM_BASE); xnvm_st_star_ptr_postinc(DUMMY_BYTE); return xnvm_ctrl_wait_nvmbusy(WAIT_RETRIES_NUM); } /** * \internal * \brief Load the flash page buffer * * \param addr the flash address. * \param buf the pointer which points to the data buffer. * \param len the length of data. * \retval STATUS_OK write succussfully. * \retval ERR_BAD_DATA One of the bytes sent was corrupted during transmission. * \retval ERR_INVALID_ARG Invalid argument. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_load_flash_page_buffer(uint32_t addr, uint8_t *buf, uint16_t len) { if (buf == NULL || len == 0) { return ERR_INVALID_ARG; } xnvm_ctrl_cmd_write(XNVM_CMD_LOAD_FLASH_PAGE_BUFFER); xnvm_st_ptr(addr); if (len > 1) { xnvm_write_repeat(len); } else { return xnvm_st_star_ptr_postinc(*buf); } cmd_buffer[0] = XNVM_PDI_ST_INSTR | XNVM_PDI_LD_PTR_STAR_INC_MASK | XNVM_PDI_BYTE_DATA_MASK; prot->pdi_write(cmd_buffer, 1); return prot->pdi_write(buf, len); } /** * \internal * \brief Erase the flash buffer with NVM controller. * * \param retries the time out delay number. * \retval STATUS_OK erase successfully. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_erase_flash_buffer(uint32_t retries) { xnvm_st_ptr(0); xnvm_ctrl_cmd_write(XNVM_CMD_ERASE_FLASH_PAGE_BUFFER); xnvm_ctrl_cmdex_write(); return xnvm_ctrl_wait_nvmbusy(retries); } /** * \internal * \brief Program the flash page buffer with NVM controller. * * \param address the address of the flash IN PDI address space * \param dat_buf the pointer which points to the data buffer. * \param length the data length. * \retval STATUS_OK program succussfully. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_program_flash_page( uint32_t address, uint8_t *dat_buf, uint16_t length) { xnvm_erase_flash_buffer(WAIT_RETRIES_NUM); xnvm_load_flash_page_buffer(address, dat_buf, length); xnvm_ctrl_cmd_write(XNVM_CMD_WRITE_FLASH_PAGE); /* Dummy write for starting the erase and write command */ xnvm_st_ptr(address); xnvm_st_star_ptr_postinc(DUMMY_BYTE); return xnvm_ctrl_wait_nvmbusy(WAIT_RETRIES_NUM); } /** * \internal * \brief Erase and program the flash page buffer with NVM controller. * * \param address the address of the flash. * \param dat_buf the pointer which points to the data buffer. * \param length the data length. * \retval STATUS_OK program succussfully. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_erase_program_flash_page( uint32_t address, uint8_t *dat_buf, uint16_t length) { xnvm_erase_flash_buffer(WAIT_RETRIES_NUM); xnvm_load_flash_page_buffer(address, dat_buf, length); xnvm_ctrl_cmd_write(XNVM_CMD_ERASE_AND_WRITE_FLASH_PAGE); /* Dummy write for starting the erase and write command */ xnvm_st_ptr(address); xnvm_st_star_ptr_postinc(DUMMY_BYTE); return xnvm_ctrl_wait_nvmbusy(WAIT_RETRIES_NUM); } /** * \internal * \brief Erase and program the flash page buffer with NVM controller. * * \param address the address of the flash. * \param dat_buf the pointer which points to the data buffer. * \param length the data length. * \retval STATUS_OK program succussfully. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_erase_application_flash_page(uint32_t address, uint8_t *dat_buf, uint16_t length) { address = address + XNVM_FLASH_BASE; xnvm_erase_flash_buffer(WAIT_RETRIES_NUM); xnvm_load_flash_page_buffer(address, dat_buf, length); xnvm_ctrl_cmd_write(XNVM_CMD_ERASE_AND_WRITE_APP_SECTION); /* Dummy write for starting the erase and write command */ xnvm_st_ptr(address); xnvm_st_star_ptr_postinc(DUMMY_BYTE); return xnvm_ctrl_wait_nvmbusy(WAIT_RETRIES_NUM); } /** * \internal * \brief Write the repeating number with PDI port * * \param count the repeating number. * \retval STATUS_OK write succussfully. * \retval ERR_BAD_DATA One of the bytes sent was corrupted during transmission. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_write_repeat(uint32_t count) { uint8_t cmd_len; --count; if (count < (1 << 8)) { cmd_buffer[0] = XNVM_PDI_REPEAT_INSTR | XNVM_PDI_BYTE_DATA_MASK; cmd_buffer[1] = count; cmd_len = 2; } else if (count < ((uint32_t)(1) << 16)) { cmd_buffer[0] = XNVM_PDI_REPEAT_INSTR | XNVM_PDI_WORD_DATA_MASK; memmove((cmd_buffer + 1), (uint8_t*)&count, 2); cmd_len = 3; } else if (count < ((uint32_t)(1) << 24)) { cmd_buffer[0] = XNVM_PDI_REPEAT_INSTR | XNVM_PDI_3BYTES_DATA_MASK; memmove((cmd_buffer + 1), (uint8_t*)&count, 3); cmd_len = 4; } else { cmd_buffer[0] = XNVM_PDI_REPEAT_INSTR | XNVM_PDI_LONG_DATA_MASK; memmove((cmd_buffer + 1), (uint8_t*)&count, 4); cmd_len = 5; } return prot->pdi_write(cmd_buffer, cmd_len); } /** * \internal * \brief Write a value to a address with *(ptr++) instruction through the PDI Controller. * * \param value the value should be write into the *ptr. * \retval STATUS_OK write succussfully. * \retval ERR_BAD_DATA One of the bytes sent was corrupted during transmission. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_st_star_ptr_postinc(uint8_t value) { cmd_buffer[0] = XNVM_PDI_ST_INSTR | XNVM_PDI_LD_PTR_STAR_INC_MASK | XNVM_PDI_BYTE_DATA_MASK; cmd_buffer[1] = value; return prot->pdi_write(cmd_buffer, 2); } /** * \internal * \brief Write a address in PDI Controller's pointer. * * \param address the address which should be written into the ptr. * \retval STATUS_OK write successfully. * \retval ERR_BAD_DATA One of the bytes sent was corrupted during transmission. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_st_ptr(uint32_t address) { cmd_buffer[0] = XNVM_PDI_ST_INSTR | XNVM_PDI_LD_PTR_ADDRESS_MASK | XNVM_PDI_LONG_DATA_MASK; memmove((cmd_buffer + 1), (uint8_t*)&address, 4); return prot->pdi_write(cmd_buffer, 5); } /** * \brief Read the memory (include flash, eeprom, user signature, fuse bits)with NVM controller. * * \param address the address of the memory. * \param data the pointer which points to the data buffer. * \param length the data length. * \retval non-zero the read byte length. * \retval zero read fail. */ uint16_t ProgAlgNVM::xnvm_read_memory (uint32_t address, uint8_t *data, uint32_t length) { xnvm_ctrl_cmd_write(XNVM_CMD_READ_NVM_PDI); xnvm_st_ptr(address); if (length > 1) { xnvm_write_repeat(length); } cmd_buffer[0] = XNVM_PDI_LD_INSTR | XNVM_PDI_LD_PTR_STAR_INC_MASK | XNVM_PDI_BYTE_DATA_MASK; prot->pdi_write(cmd_buffer, 1); return prot->pdi_read(data, length, WAIT_RETRIES_NUM); } /** * \internal * \brief Erase and program the eeprom page buffer with NVM controller. * * \param address the address of the eeprom. * \param dat_buf the pointer which points to the data buffer. * \param length the data length. * \retval STATUS_OK program succussfully. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_erase_program_eeprom_page(uint32_t address, uint8_t *dat_buf, uint16_t length) { address = address + XNVM_EEPROM_BASE; xnvm_erase_eeprom_buffer(WAIT_RETRIES_NUM); xnvm_load_eeprom_page_buffer(address, dat_buf, length); xnvm_ctrl_cmd_write(XNVM_CMD_ERASE_AND_WRITE_EEPROM); /* Dummy write for starting the erase and write command */ xnvm_st_ptr(address); xnvm_st_star_ptr_postinc(DUMMY_BYTE); return xnvm_ctrl_wait_nvmbusy(WAIT_RETRIES_NUM); } /** * \internal * \brief Erase the eeprom buffer with NVM controller. * * \param retries the time out delay number. * \retval STATUS_OK erase succussfully. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_erase_eeprom_buffer(uint32_t retries) { xnvm_st_ptr(0); xnvm_ctrl_cmd_write(XNVM_CMD_ERASE_EEPROM_PAGE_BUFFER); /* Execute command by setting CMDEX */ xnvm_ctrl_cmdex_write(); return xnvm_ctrl_wait_nvmbusy(retries); } /** * \internal * \brief Load the eeprom page buffer * * \param addr the eeprom address. * \param buf the pointer which points to the data buffer. * \param len the length of data. * \retval STATUS_OK load succussfully. * \retval ERR_BAD_DATA One of the bytes sent was corrupted during transmission. * \retval ERR_INVALID_ARG Invalid argument. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_load_eeprom_page_buffer(uint32_t addr, uint8_t *buf, uint16_t len) { if (buf == NULL || len == 0) { return ERR_INVALID_ARG; } xnvm_ctrl_cmd_write(XNVM_CMD_LOAD_EEPROM_PAGE_BUFFER); xnvm_st_ptr(addr); if (len > 1) { xnvm_write_repeat(len); } else { xnvm_st_star_ptr_postinc(*buf); return STATUS_OK; } cmd_buffer[0] = XNVM_PDI_ST_INSTR | XNVM_PDI_LD_PTR_STAR_INC_MASK | XNVM_PDI_BYTE_DATA_MASK; prot->pdi_write(cmd_buffer, 1); return prot->pdi_write(buf, len); } /** * \internal * \brief Erase the user signature with NVM controller. * * \retval STATUS_OK erase succussfully. * \retval ERR_TIMEOUT time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_erase_user_sign(void) { xnvm_ctrl_cmd_write(XNVM_CMD_ERASE_USER_SIGN); /* Dummy write for starting the erase command */ xnvm_st_ptr(XNVM_SIGNATURE_BASE); xnvm_st_star_ptr_postinc(DUMMY_BYTE); return xnvm_ctrl_wait_nvmbusy(WAIT_RETRIES_NUM); } /** * \internal * \brief Erase and program the user signature with NVM controller. * * \param address the address of the user signature. * \param dat_buf the pointer which points to the data buffer. * \param length the data length. * \retval STATUS_OK program succussfully. * \retval ERR_TIMEOUT time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_erase_program_user_sign (uint32_t address, uint8_t *dat_buf, uint16_t length) { address = address + XNVM_SIGNATURE_BASE; xnvm_erase_flash_buffer(WAIT_RETRIES_NUM); xnvm_load_flash_page_buffer(address, dat_buf, length); xnvm_erase_user_sign(); xnvm_ctrl_cmd_write(XNVM_CMD_WRITE_USER_SIGN); /* Dummy write for starting the write command. */ xnvm_st_ptr(address); xnvm_st_star_ptr_postinc(DUMMY_BYTE); return xnvm_ctrl_wait_nvmbusy(WAIT_RETRIES_NUM); } /** * \brief Write a single fuse byte with NVM controller * * \param address the fuse bit address. * \param value which should be write into the fuse bit. * \retval STATUS_OK write succussfully. * \retval ERR_TIMEOUT time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_write_fuse_byte(uint32_t address, uint8_t value) { uint32_t register_address; xnvm_ctrl_cmd_write(XNVM_CMD_WRITE_FUSE); cmd_buffer[0] = XNVM_PDI_STS_INSTR | XNVM_PDI_LONG_ADDRESS_MASK | XNVM_PDI_BYTE_DATA_MASK; register_address = XNVM_FUSE_BASE + address; memmove((cmd_buffer + 1), (uint8_t*)®ister_address, 4); cmd_buffer[5] = value; prot->pdi_write(cmd_buffer, 6); return xnvm_ctrl_wait_nvmbusy(WAIT_RETRIES_NUM); } /** * \brief Write the lock byte with NVM controller * * \param value which should be write into the lock byte. * \retval STATUS_OK write succussfully. * \retval ERR_TIMEOUT time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_write_lock_byte(uint8_t value) { uint32_t register_address; xnvm_ctrl_cmd_write(XNVM_CMD_WRITE_LOCK_BITS); cmd_buffer[0] = XNVM_PDI_STS_INSTR | XNVM_PDI_LONG_ADDRESS_MASK | XNVM_PDI_BYTE_DATA_MASK; register_address = XNVM_FUSE_BASE + NVM_LOCKBIT_ADDR; memmove((cmd_buffer + 1), (uint8_t*)®ister_address, 4); cmd_buffer[5] = value; prot->pdi_write(cmd_buffer, 6); return xnvm_ctrl_wait_nvmbusy(WAIT_RETRIES_NUM); } /** * \internal * \brief Wait until the NVM Controller is ready. * * \param retries the retry count. * \retval STATUS_OK BUSY bit was set. * \retval ERR_TIMEOUT Time out. */ enum PDI_STATUS_CODE ProgAlgNVM::xnvm_ctrl_wait_nvmbusy(uint32_t retries) { uint8_t status; while (retries != 0) { xnvm_ctrl_read_status(&status); /* Check if the NVMBUSY bit is clear in the NVM_STATUS register. */ if ((status & XNVM_NVM_BUSY) == 0) { return STATUS_OK; } --retries; } return ERR_TIMEOUT; }