pax_global_header00006660000000000000000000000064143315345400014514gustar00rootroot0000000000000052 comment=82aa68a2148a0ac0326b4c1fff1a6c57e3278b05 mesaflash-3.4.6/000077500000000000000000000000001433153454000134715ustar00rootroot00000000000000mesaflash-3.4.6/.gitattributes000066400000000000000000000002361433153454000163650ustar00rootroot00000000000000WinIo32.* export-ignore libpci.dll export-ignore libpci/** export-ignore libpci export-ignore winio32/** export-ignore winio32 export-ignore mesaflash-3.4.6/.github/000077500000000000000000000000001433153454000150315ustar00rootroot00000000000000mesaflash-3.4.6/.github/workflows/000077500000000000000000000000001433153454000170665ustar00rootroot00000000000000mesaflash-3.4.6/.github/workflows/ci.yml000066400000000000000000000040611433153454000202050ustar00rootroot00000000000000on: push: pull_request: release: types: [published] check_suite: types: [rerequested] jobs: test: runs-on: ubuntu-20.04 steps: - name: Dump GitHub context env: GITHUB_CONTEXT: ${{ toJson(github) }} run: echo "$GITHUB_CONTEXT" - uses: actions/checkout@v2 - name: Install deps run: | sudo apt-get update sudo apt-get install -y eatmydata sudo eatmydata apt-get install -y --no-install-suggests --no-install-recommends build-essential devscripts equivs mk-build-deps -irs sudo -t "apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends -y" - name: Build run: | make -j$(nproc) - name: Clean run: | make clean - name: Build (package) run: | dch -l+`git rev-parse --short HEAD` "actions package build" debuild -b test-package: strategy: matrix: os: ["buster", "bullseye", "testing", "unstable"] cpu: ["i386", "amd64", "armhf", "aarch64"] runs-on: ubuntu-20.04 steps: - name: Install deps run: | sudo apt-get update sudo apt install -y --no-install-suggests --no-install-recommends devscripts - uses: actions/checkout@v2 with: fetch-depth: 0 - name: Update debian changelog env: OS_RELEASE: ${{ matrix.os }} run: | git checkout HEAD -- debian/changelog git fetch --tags https://github.com/LinuxCNC/mesaflash ref=`git describe --tags --always | sed -e 's/^release\///;s/^v//;s/-/+/g'` DEBEMAIL=noreply@github.com dch -v "${ref}+${OS_RELEASE}-1" "Build from github actions" head debian/changelog - name: Build Debian package uses: dawidd6/action-debian-package@v1 with: source_directory: . artifacts_directory: output os_distribution: ${{ matrix.os }} cpu_architecture: ${{ matrix.cpu }} - name: Upload artifact uses: actions/upload-artifact@v2 with: path: output name: debs-${{ matrix.os }}-${{ matrix.cpu }} mesaflash-3.4.6/.gitignore000066400000000000000000000001101433153454000154510ustar00rootroot00000000000000*.o libanyio* mesaflash mesaflash.exe pci_encoder_read pci_analog_write mesaflash-3.4.6/COPYING000066400000000000000000000432541433153454000145340ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser General Public License instead of this License. mesaflash-3.4.6/Makefile000066400000000000000000000143261433153454000151370ustar00rootroot00000000000000# # Copyright (C) 2013-2014 Michael Geszkiewicz # # 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # target (linux, windows) TARGET = linux LIBNAME = libanyio LIBANYIO = $(LIBNAME).a CC = gcc RM = rm -f AR = ar RANLIB = ranlib OWNERSHIP ?= --owner root --group root # default CFLAGS CFLAGS ?= -O0 -g -Wall -Wextra -Werror # mesaflash needs at least C99 to compile. # # The oldest distros we support are Debian Wheezy (EOL 2018-05-31) # and Ubuntu Precise (EOL 2017-04-28): # # Debian Wheezy has gcc 4.7.2, which defaults to C90 but supports C11. # # Ubuntu Precise has gcc 4.6.3, which defaults to C90 but supports # C99 (but does not support C11). # # So we explicitly select the newest ancient C standard that we have to # support here. CFLAGS += -std=c99 ifeq ($(TARGET),linux) $(shell which pkg-config > /dev/null) ifeq ($(.SHELLSTATUS), 1) $(error "can't find pkg-config") endif $(shell pkg-config --exists libpci > /dev/null) ifeq ($(.SHELLSTATUS), 1) $(error "pkg-config can't find libpci") endif $(shell pkg-config --exists libmd > /dev/null) ifeq ($(.SHELLSTATUS), 1) $(error "pkg-config can't find libmd") endif LIBPCI_CFLAGS := $(shell pkg-config --cflags libpci) LIBPCI_LDFLAGS := $(shell pkg-config --libs libpci) LIBMD_CFLAGS := $(shell pkg-config --cflags libmd) LIBMD_LDFLAGS := $(shell pkg-config --libs libmd) BIN = mesaflash LDFLAGS = -lm $(LIBPCI_LDFLAGS) $(LIBMD_LDFLAGS) CFLAGS += -D_GNU_SOURCE $(LIBPCI_CFLAGS) $(LIBMD_CFLAGS) -D_FILE_OFFSET_BITS=64 UNAME_M := $(shell uname -m) # # A bunch of platforms lack `sys/io.h`, which means mesaflash builds # without support for EPP or PCI cards. # ifeq ($(UNAME_M),aarch64) MESAFLASH_IO ?= 0 endif ifeq ($(patsubst arm%,arm,$(UNAME_M)),arm) ifeq ($(wildcard /usr/include/arm-linux-gnueabihf/asm/io.h),) MESAFLASH_IO ?= 0 endif endif ifeq ($(UNAME_M),parisc) MESAFLASH_IO ?= 0 endif ifeq ($(UNAME_M),m68k) MESAFLASH_IO ?= 0 endif ifeq ($(patsubst mips%,mips,$(UNAME_M)),mips) MESAFLASH_IO ?= 0 endif ifeq ($(patsubst ppc%,ppc,$(UNAME_M)),ppc) MESAFLASH_IO ?= 0 endif ifeq ($(UNAME_M),riscv64) MESAFLASH_IO ?= 0 endif ifeq ($(patsubst s390%,s390,$(UNAME_M)),s390) MESAFLASH_IO ?= 0 endif ifeq ($(UNAME_M),sh) MESAFLASH_IO ?= 0 endif ifeq ($(UNAME_M),sparc64) MESAFLASH_IO ?= 0 endif endif ifeq ($(TARGET),windows) MINGW = c:/MinGW CFLAGS += -I$(MINGW)/include BIN = mesaflash.exe LDFLAGS = -lwsock32 -lws2_32 libpci.dll winio32.dll CFLAGS += -mno-ms-bitfields endif MESAFLASH_IO ?= 1 CFLAGS += -DMESAFLASH_IO=$(MESAFLASH_IO) objects = common.o lbp.o lbp16.o bitfile.o hostmot2.o eeprom.o anyio.o eth_boards.o epp_boards.o usb_boards.o pci_boards.o objects += sserial_module.o encoder_module.o eeprom_local.o eeprom_remote.o spi_boards.o serial_boards.o headers = eth_boards.h pci_boards.h epp_boards.h usb_boards.h spi_boards.h serial_boards.h anyio.h hostmot2.h lbp16.h types.h headers += common.h eeprom.h lbp.h eeprom_local.h eeprom_remote.h bitfile.h sserial_module.h hostmot2_def.h boards.h headers += encoder_module.h all: $(LIBANYIO) $(BIN) pci_encoder_read pci_analog_write $(LIBANYIO) : $(objects) $(RM) $(LIBANYIO) $(BIN) $(AR) rcs $(LIBANYIO) $(objects) $(RANLIB) $(LIBANYIO) mesaflash.o : mesaflash.c $(headers) $(CC) $(CFLAGS) -c mesaflash.c $(BIN): mesaflash.o anyio.h $(LIBANYIO) $(CC) $(CFLAGS) -o $(BIN) mesaflash.o $(LIBANYIO) $(LDFLAGS) anyio.o : anyio.c $(headers) $(CC) $(CFLAGS) -c anyio.c eth_boards.o : eth_boards.c $(headers) $(CC) $(CFLAGS) -c eth_boards.c pci_boards.o : pci_boards.c $(headers) $(CC) $(CFLAGS) -c pci_boards.c epp_boards.o : epp_boards.c $(headers) $(CC) $(CFLAGS) -c epp_boards.c usb_boards.o : usb_boards.c $(headers) $(CC) $(CFLAGS) -c usb_boards.c spi_boards.o : spi_boards.c $(headers) $(CC) $(CFLAGS) -c spi_boards.c serial_boards.o : serial_boards.c $(headers) $(CC) $(CFLAGS) -c serial_boards.c sserial_module.o : sserial_module.c $(headers) $(CC) $(CFLAGS) -c sserial_module.c encoder_module.o : encoder_module.c $(headers) $(CC) $(CFLAGS) -c encoder_module.c eeprom_local.o : eeprom_local.c $(headers) $(CC) $(CFLAGS) -c eeprom_local.c eeprom_remote.o : eeprom_remote.c $(headers) $(CC) $(CFLAGS) -c eeprom_remote.c lbp.o : lbp.c $(headers) $(CC) $(CFLAGS) -c lbp.c lbp16.o : lbp16.c $(headers) $(CC) $(CFLAGS) -c lbp16.c hostmot2.o : hostmot2.c $(headers) $(CC) $(CFLAGS) -c hostmot2.c eeprom.o : eeprom.c $(headers) $(CC) $(CFLAGS) -c eeprom.c bitfile.o : bitfile.c $(headers) $(CC) $(CFLAGS) -c bitfile.c common.o : common.c $(headers) $(CC) $(CFLAGS) -c common.c pci_encoder_read.o : examples/pci_encoder_read.c $(LIBANYIO) $(headers) $(CC) $(CFLAGS) -c examples/pci_encoder_read.c pci_encoder_read: pci_encoder_read.o anyio.h encoder_module.h $(CC) $(CFLAGS) -o pci_encoder_read pci_encoder_read.o $(LIBANYIO) $(LDFLAGS) pci_analog_write.o : examples/pci_analog_write.c $(LIBANYIO) $(headers) $(CC) $(CFLAGS) -c examples/pci_analog_write.c pci_analog_write: pci_analog_write.o anyio.h sserial_module.h $(CC) $(CFLAGS) -o pci_analog_write pci_analog_write.o $(LIBANYIO) $(LDFLAGS) clean : $(RM) *.o $(LIBANYIO) $(BIN) pci_encoder_read pci_analog_write .PHONY: install install: $(BIN) install -p -D --mode=0755 $(OWNERSHIP) $(BIN) $(DESTDIR)/bin/$(BIN) install -p -D --mode=0644 $(OWNERSHIP) mesaflash.1 $(DESTDIR)/share/man/man1/mesaflash.1 mesaflash-3.4.6/README.md000066400000000000000000000023551433153454000147550ustar00rootroot00000000000000# mesaflash Configuration and diagnostic tool for Mesa Electronics PCI(E)/ETH/EPP/USB/SPI boards Quickstart: =========== MesaFlash depends on a couple of packages to build, so install those first: ``` sudo apt install libpci-dev libmd-dev pkg-config build-essential git ``` Clone MesaFlash: ``` git clone https://github.com/LinuxCNC/mesaflash.git ``` From the top level directory, switch to the source directory: ``` cd mesaflash ``` In the source directory to build MesaFlash: ``` make ``` To get command line syntax from a local make: ``` ./mesaflash --help ``` To build and install MesaFlash, bypassing the operating system packaging system: ``` sudo make install ``` To run an installed MesaFlash: ``` mesaflash --help ``` Depending on permissions and the types of devices you wish to access, you may need to run mesaflash as root, `sudo ./mesaflash` or `sudo mesaflash`. Distributions =============== **mesaflash** package is available on [Fedora](https://src.fedoraproject.org/rpms/mesaflash) _(version 31 or newer)_ and can be simply installed by using: ``` # dnf install mesaflash ``` Availability of **mesaflash** for other Linux distributions can be checked on [release-monitoring](https://release-monitoring.org/project/105522/) project page. mesaflash-3.4.6/anyio.c000066400000000000000000000276641433153454000147730ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #include #include #include #include "anyio.h" #include "eeprom.h" #include "bitfile.h" #include "eth_boards.h" #include "pci_boards.h" #include "epp_boards.h" #include "usb_boards.h" #include "spi_boards.h" #include "serial_boards.h" supported_board_entry_t supported_boards[] = { {"ETHER", BOARD_ETH | BOARD_WILDCARD}, {"SPI", BOARD_SPI | BOARD_WILDCARD}, {"7I92", BOARD_ETH}, {"7I93", BOARD_ETH}, {"7I94", BOARD_ETH}, {"7I95", BOARD_ETH}, {"7I96", BOARD_ETH}, {"7I97", BOARD_ETH}, {"7I98", BOARD_ETH}, {"7I80", BOARD_ETH}, {"7I76E", BOARD_ETH}, {"4I74", BOARD_PCI}, {"5I24", BOARD_PCI}, {"5I25", BOARD_PCI}, {"6I24", BOARD_PCI}, {"6I25", BOARD_PCI}, {"5I20", BOARD_PCI}, {"4I65", BOARD_PCI}, {"4I68", BOARD_PCI}, {"5I21", BOARD_PCI}, {"5I22", BOARD_PCI}, {"5I23", BOARD_PCI}, {"4I69", BOARD_PCI}, {"3X20", BOARD_PCI}, {"7C80", BOARD_MULTI_INTERFACE | BOARD_EPP | BOARD_SPI}, {"7C81", BOARD_MULTI_INTERFACE | BOARD_EPP | BOARD_SPI}, {"7I43", BOARD_MULTI_INTERFACE | BOARD_EPP | BOARD_USB}, {"7I90", BOARD_MULTI_INTERFACE | BOARD_EPP | BOARD_SPI | BOARD_SER}, {"7I64", BOARD_MULTI_INTERFACE | BOARD_USB | BOARD_SPI}, {"AUTO", BOARD_MULTI_INTERFACE | BOARD_WILDCARD | BOARD_USB | BOARD_EPP | BOARD_SPI | BOARD_SER | BOARD_PCI}, {NULL, 0}, }; board_t boards[MAX_BOARDS]; int boards_count; int anyio_init(board_access_t *access) { if (access == NULL) { return -EINVAL; } return 0; } void anyio_cleanup(board_access_t *access) { if (access == NULL) { return; } if (access->open_iface & BOARD_ETH) eth_boards_cleanup(access); #if MESAFLASH_IO if (access->open_iface & BOARD_PCI) pci_boards_cleanup(access); if (access->open_iface & BOARD_EPP) epp_boards_cleanup(access); #endif if (access->open_iface & BOARD_USB) usb_boards_cleanup(access); if (access->open_iface & BOARD_SPI) spi_boards_cleanup(access); if (access->open_iface & BOARD_SER) serial_boards_cleanup(access); access->open_iface = 0; } int anyio_find_dev(board_access_t *access) { int i, ret = 0; supported_board_entry_t *supported_board = NULL; if (access == NULL) { return -1; } for (i = 0; supported_boards[i].name != NULL; i++) { if (strncmp(supported_boards[i].name, access->device_name, strlen(supported_boards[i].name)) == 0) { supported_board = &supported_boards[i]; break; } } if (supported_board == NULL) { printf("ERROR: Unsupported device %s\n", access->device_name); return -1; } access->open_iface = 0; if (supported_board->type & BOARD_WILDCARD) access->open_iface = BOARD_WILDCARD; if (access->type == BOARD_ANY) { if (supported_board->type & BOARD_MULTI_INTERFACE) { printf("ERROR: you must select transport layer for board\n"); return -1; } if (supported_board->type & BOARD_ETH) { ret = eth_boards_init(access); access->open_iface |= BOARD_ETH; ret = eth_boards_scan(access); if (ret < 0) { return ret; } } #if MESAFLASH_IO if (supported_board->type & BOARD_PCI) { ret = pci_boards_init(access); if (ret < 0) { return ret; } access->open_iface |= BOARD_PCI; pci_boards_scan(access); } if (supported_board->type & BOARD_EPP) { ret = epp_boards_init(access); if (ret < 0) { return ret; } access->open_iface |= BOARD_EPP; epp_boards_scan(access); } #endif if (supported_board->type & BOARD_USB) { ret = usb_boards_init(access); access->open_iface |= BOARD_USB; usb_boards_scan(access); } if (supported_board->type & BOARD_SPI) { ret = spi_boards_init(access); access->open_iface |= BOARD_SPI; spi_boards_scan(access); } if (supported_board->type & BOARD_SER) { ret = serial_boards_init(access); access->open_iface |= BOARD_SER; serial_boards_scan(access); } } else { if (access->type & BOARD_ETH) { ret = eth_boards_init(access); access->open_iface |= BOARD_ETH; eth_boards_scan(access); } #if MESAFLASH_IO if (access->type & BOARD_PCI) { ret = pci_boards_init(access); if (ret < 0) { return ret; } access->open_iface |= BOARD_PCI; pci_boards_scan(access); } if (access->type & BOARD_EPP) { ret = epp_boards_init(access); if (ret < 0) { return ret; } access->open_iface |= BOARD_EPP; epp_boards_scan(access); } #endif if (access->type & BOARD_USB) { ret = usb_boards_init(access); access->open_iface |= BOARD_USB; usb_boards_scan(access); } if (access->type & BOARD_SPI) { ret = spi_boards_init(access); access->open_iface |= BOARD_SPI; spi_boards_scan(access); } if (access->type & BOARD_SER) { ret = serial_boards_init(access); access->open_iface |= BOARD_SER; serial_boards_scan(access); } } return 0; } board_t *anyio_get_dev(board_access_t *access, int board_number) { int i, j; if (access == NULL) { return NULL; } for (i = 0, j = 0; i < boards_count; i++) { board_t *board = NULL; board = &boards[i]; if (((strncmp(access->device_name, board->llio.board_name, strlen(access->device_name)) == 0) && (strlen(access->device_name) == strlen(board->llio.board_name))) || access->open_iface & BOARD_WILDCARD) { j++; if (j == board_number) { return board; } } } return NULL; } int anyio_dev_write_flash(board_t *board, char *bitfile_name, int fallback_flag, int fix_boot_flag, int sha256_check_flag) { int ret; if (board == NULL) { return -EINVAL; } if (board->llio.write_flash != NULL) { u32 addr = board->flash_start_address; if (fallback_flag == 1) { if (board->fpga_type == FPGA_TYPE_EFINIX) { addr = EFINIX_FALLBACK_ADDRESS; } else { addr = XILINX_FALLBACK_ADDRESS; } } ret = board->llio.write_flash(&(board->llio), bitfile_name, addr, fix_boot_flag, sha256_check_flag); } else { printf("ERROR: Board %s doesn't support flash writing.\n", board->llio.board_name); return -EINVAL; } return ret; } int anyio_dev_verify_flash(board_t *board, char *bitfile_name, int fallback_flag) { int ret; if (board == NULL) { return -EINVAL; } if (board->llio.verify_flash != NULL) { u32 addr = board->flash_start_address; if (fallback_flag == 1) { if (board->fpga_type == FPGA_TYPE_EFINIX) { addr = EFINIX_FALLBACK_ADDRESS; } else { addr = XILINX_FALLBACK_ADDRESS; } } ret = board->llio.verify_flash(&(board->llio), bitfile_name, addr); } else { printf("ERROR: Board %s doesn't support flash verification.\n", board->llio.board_name); return -EINVAL; } return ret; } int anyio_dev_backup_flash(board_t *board, char *bitfile_name) { int ret; if (board == NULL) { return -EINVAL; } if (board->llio.backup_flash != NULL) { ret = board->llio.backup_flash(&(board->llio), bitfile_name); } else { printf("ERROR: Board %s doesn't support backup flash.\n", board->llio.board_name); return -EINVAL; } return ret; } int anyio_dev_restore_flash(board_t *board, char *bitfile_name) { int ret; if (board == NULL) { return -EINVAL; } if (board->llio.restore_flash != NULL) { ret = board->llio.restore_flash(&(board->llio), bitfile_name); } else { printf("ERROR: Board %s doesn't support restore flash.\n", board->llio.board_name); return -EINVAL; } return ret; } int anyio_dev_program_fpga(board_t *board, char *bitfile_name) { int ret; if (board == NULL) { return -EINVAL; } if (board->llio.reset == NULL) { printf("ERROR: Board %s doesn't support FPGA resetting.\n", board->llio.board_name); return -EINVAL; } if (board->llio.program_fpga == NULL) { printf("ERROR: Board %s doesn't support FPGA programming.\n", board->llio.board_name); return -EINVAL; } ret = board->llio.reset(&(board->llio)); if (ret != 0) { return ret; } board->llio.program_fpga(&(board->llio), bitfile_name); return 0; } int anyio_dev_set_remote_ip(board_t *board, char *lbp16_set_ip_addr) { int ret; if (board == NULL) { return -EINVAL; } if ((board->type & BOARD_ETH) == 0) { return -EPERM; } ret = eth_set_remote_ip(lbp16_set_ip_addr); if (ret == 0) { printf("Board IP updated successfully.\n"); printf("You must power cycle board to load updated eeprom settings.\n"); } return ret; } int anyio_dev_reload(board_t *board, int fallback_flag) { if (board == NULL) { return -EINVAL; } if (board->llio.reload == NULL) { printf("ERROR: Board %s doesn't support FPGA configuration reloading.\n", board->llio.board_name); return -EINVAL; } return board->llio.reload(&(board->llio), fallback_flag); } int anyio_dev_reset(board_t *board) { if (board == NULL) { return -EINVAL; } if (board->llio.reset == NULL) { printf("ERROR: Board %s doesn't support FPGA resetting.\n", board->llio.board_name); return -EINVAL; } return board->llio.reset(&(board->llio)); } void anyio_dev_print_hm2_info(board_t *board, int xml_flag) { if (board == NULL) { return; } hm2_read_idrom(&(board->llio.hm2)); hm2_print_pin_file(&(board->llio), xml_flag); } void anyio_dev_print_pin_descriptors(board_t *board) { if (board == NULL) { return; } hm2_read_idrom(&(board->llio.hm2)); hm2_print_pin_descriptors(&board->llio); } void anyio_dev_print_localio_descriptors(board_t *board) { if (board == NULL) { return; } hm2_read_idrom(&(board->llio.hm2)); hm2_print_localio_descriptors(&board->llio); } void anyio_dev_print_sserial_info(board_t *board) { if (board == NULL) { return; } hm2_read_idrom(&(board->llio.hm2)); sserial_module_init(&(board->llio)); } void anyio_bitfile_print_info(char *bitfile_name, int verbose_flag) { FILE *fp; char part_name[32]; if (bitfile_name == NULL) { return; } fp = fopen(bitfile_name, "rb"); if (fp == NULL) { printf("Can't open file %s: %s\n", bitfile_name, strerror(errno)); return; } print_bitfile_header(fp, (char*) &part_name, verbose_flag); fclose(fp); } mesaflash-3.4.6/anyio.h000066400000000000000000000037071433153454000147700ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __ANYIO_H #define __ANYIO_H #ifdef _WIN32 #include #include "winio32/winio.h" #endif #include "boards.h" int anyio_init(board_access_t *access); void anyio_cleanup(board_access_t *access); int anyio_find_dev(board_access_t *access); board_t *anyio_get_dev(board_access_t *access, int board_number); int anyio_dev_write_flash(board_t *board, char *bitfile_name, int fallback_flag, int fix_boot_flag, int sha256_check_flag); int anyio_dev_verify_flash(board_t *board, char *bitfile_name, int fallback_flag); int anyio_dev_backup_flash(board_t *board, char *bitfile_name); int anyio_dev_restore_flash(board_t *board, char *bitfile_name); int anyio_dev_program_fpga(board_t *board, char *bitfile_name); int anyio_dev_set_remote_ip(board_t *board, char *lbp16_set_ip_addr); int anyio_dev_reload(board_t *board, int fallback_flag); int anyio_dev_reset(board_t *board); void anyio_dev_print_hm2_info(board_t *board, int xml_flag); void anyio_dev_print_pin_descriptors(board_t *board); void anyio_dev_print_localio_descriptors(board_t *board); void anyio_dev_print_sserial_info(board_t *board); void anyio_bitfile_print_info(char *bitfile_name, int verbose_flag); #endif mesaflash-3.4.6/bitfile.c000066400000000000000000000155701433153454000152630ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #include #include #include "types.h" #include "bitfile.h" // prints info about bitfile and returns header length or -1 when error int print_bitfile_header(FILE *fp, char *part_name, int verbose_flag) { u8 buff[256]; int sleng; int bytesread, conflength; int ret = 0; char str[80]; char * partns; printf("Checking file... "); bytesread = fread(&buff, 1, 14, fp); ret += bytesread; if (bytesread != 14) { if (feof(fp)) printf("Error: Unexpected end of file\n"); else printf("Error: IO error\n"); return -1; } if ((buff[0] == 0) && (buff[1] == 9)) { printf("OK\n File type: Xilinx bit file\n"); if ((buff[11] == 0) && (buff[12] == 1) && (buff[13] == 0x61)) { bytesread = fread(&buff, 1, 2, fp); ret += bytesread; sleng = buff[0]*256 + buff[1]; bytesread = fread(&buff, 1, sleng, fp); ret += bytesread; if (verbose_flag == 1) { printf(" Design name: %s\n", buff); } bytesread = fread(&buff, 1, 3, fp); ret += bytesread; sleng = buff[1]*256 + buff[2]; bytesread = fread(&buff, 1, sleng, fp); ret += bytesread; if (verbose_flag == 1) { printf(" Part name: %s\n", buff); } strcpy(part_name, (char*) &buff); bytesread = fread(&buff, 1, 3, fp); ret += bytesread; sleng = buff[1]*256 + buff[2]; bytesread = fread(&buff, 1, sleng, fp); ret += bytesread; if (verbose_flag == 1) { printf(" Design date: %s\n", buff); } bytesread = fread(&buff, 1, 3, fp); ret += bytesread; sleng = buff[1]*256 + buff[2]; bytesread = fread(&buff, 1, sleng, fp); ret += bytesread; if (verbose_flag == 1) { printf(" Design time: %s\n", buff); } bytesread = fread(&buff, 1, 5, fp); ret += bytesread; conflength = buff[1]*16777216; conflength = conflength + buff[2]*65536; conflength = conflength + buff[3]*256; conflength = conflength + buff[4]; if (verbose_flag == 1) { printf(" Config Length: %d\n", conflength); } } return ret; } rewind(fp); fgets(str, 20 ,fp); ret += strlen(str); if (strncmp(str,"Version",7) == 0) { printf("OK\n File type: Efinix bin file\n"); if (verbose_flag == 1) { printf(" Compiler %s", str); } fgets(str, 60, fp); ret += strlen(str); if (verbose_flag == 1) { printf(" %s", str); } fgets(str, 60, fp); ret += strlen(str); if (verbose_flag == 1) { printf(" %s", str); } fgets(str, 60, fp); ret += strlen(str); fgets(str, 60, fp); ret += strlen(str); if (verbose_flag == 1) { printf(" %s", str); } fgets(str, 60, fp); ret += strlen(str); if (verbose_flag == 1) { printf(" %s", str); } fgets(str, 60, fp); ret += strlen(str); // the device name is in this string if (verbose_flag == 1) { printf(" %s", str); } partns = strtok(str," "); partns = strtok(NULL," "); partns[(strlen(partns)-1)] = '\0'; strcpy(part_name, partns); fgets(str, 60, fp); ret += strlen(str); if (verbose_flag == 1) { printf(" %s", str); } fgets(str, 60, fp); ret += strlen(str); if (verbose_flag == 1) { printf(" %s", str); } fgets(str, 60, fp); ret += strlen(str); if (verbose_flag == 1) { printf(" %s", str); } return ret; } if ((buff[0] == 0xFF) && (buff[1] == 0xFF) && (buff[2] == 0xFF) && (buff[3] == 0xFF)) { printf("Looks like a BIN file\n"); return -1; } printf("Invalid bitfile header!\n"); return -1; } // // the fpga was originally designed to be programmed serially... even // though we are doing it using a parallel interface, the bit ordering // is based on the serial interface, and the data needs to be reversed // u8 bitfile_reverse_bits(u8 data) { static const u8 swaptab[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 }; return swaptab[data]; } mesaflash-3.4.6/bitfile.h000066400000000000000000000017501433153454000152630ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __BITFILE_H #define __BITFILE_H #include #include "types.h" int print_bitfile_header(FILE *fp, char *part_name, int verbose_flag); u8 bitfile_reverse_bits(u8 data); #endif mesaflash-3.4.6/boards.h000066400000000000000000000047551433153454000151270ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __BOARDS_H #define __BOARDS_H #ifdef _WIN32 #include "winio32/winio.h" #endif #include "hostmot2.h" #include "eeprom.h" #define MAX_BOARDS 8 #define BOARD_ANY (0) #define BOARD_MULTI_INTERFACE (1<<0) #define BOARD_ETH (1<<1) #define BOARD_PCI (1<<2) #define BOARD_EPP (1<<3) #define BOARD_USB (1<<4) #define BOARD_SPI (1<<5) #define BOARD_SER (1<<6) #define BOARD_WILDCARD (1<<30) typedef enum {BOARD_MODE_CPLD, BOARD_MODE_FPGA} board_mode; typedef enum {BOARD_FLASH_NONE = 0, BOARD_FLASH_HM2, BOARD_FLASH_IO, BOARD_FLASH_GPIO, BOARD_FLASH_REMOTE, BOARD_FLASH_EPP} board_flash; typedef enum {FPGA_TYPE_XILINX, FPGA_TYPE_EFINIX} fpga_type; typedef struct { char *name; u32 type; } supported_board_entry_t; typedef struct board_struct board_t; struct board_struct { u32 type; board_mode mode; fpga_type fpga_type; board_flash flash; u8 flash_id; u32 flash_start_address; int fallback_support; int recover; char dev_addr[16]; struct pci_dev *dev; void *base; int len; u64 mem_base; #ifdef _WIN32 tagPhysStruct_t mem_handle; #endif u16 ctrl_base_addr; u16 data_base_addr; u16 base_lo; u16 base_hi; void *region; void *region_hi; int epp_wide; int (*open)(board_t *self); int (*close)(board_t *self); void (*print_info)(board_t *self); llio_t llio; }; typedef struct { char *device_name; u32 type; u32 open_iface; int list; int address; int verbose; int recover; char *dev_addr; char *dev_hi_addr; } board_access_t; extern board_t boards[MAX_BOARDS]; extern int boards_count; #endif mesaflash-3.4.6/common.c000066400000000000000000000064221433153454000151310ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifdef __linux__ #include #elif _WIN32 #include #endif #include #include #include "types.h" #include "common.h" #include "eeprom.h" #ifdef _WIN32 void init_io_library() { InitializeWinIo(); } void release_io_library() { ShutdownWinIo(); } u8 inb(u32 addr) { u32 val; GetPortVal((WORD) addr, &val, 1); return val & 0xFF; } void outb(u8 data, u32 addr) { SetPortVal((WORD) addr, (DWORD) data, 1); } u16 inw(u32 addr) { u32 val; GetPortVal((WORD) addr, &val, 2); return val & 0xFFFF; } void outw(u16 data, u32 addr) { SetPortVal((WORD) addr, (DWORD) data, 2); } u32 inl(u32 addr) { u32 val; GetPortVal((WORD) addr, &val, 4); return val; } void outl(u32 data, u32 addr) { SetPortVal((WORD) addr, (DWORD) data, 4); } void *map_memory(u32 base, u32 size, tagPhysStruct_t *phys) { void *ptr; memset(phys, 0, sizeof(tagPhysStruct_t)); phys->pvPhysAddress = (DWORD64)(DWORD32) base; phys->dwPhysMemSizeInBytes = size; ptr = MapPhysToLin(phys); return ptr; } void *unmap_memory(tagPhysStruct_t *phys) { UnmapPhysicalMemory(phys); } #endif void sleep_ns(u64 nanoseconds) { #ifdef __linux__ struct timespec tv, tvret; tv.tv_sec = 0; tv.tv_nsec = nanoseconds; nanosleep(&tv, &tvret); #elif _WIN32 Sleep(nanoseconds/1000/1000); #endif } void show_formatted_size(u32 size) { if (size < 1024) { printf(" [size=%u]", size); } else if (size < 1024*1024) { printf(" [size=%uK]", size/1024); } else if (size < 0x80000000) { printf(" [size=%uM]", size/(1024*1024)); } else { printf(" [size=%08X]", size); } } void board_init_struct(board_t *board) { memset(board, 0, sizeof(board_t)); board->llio.board = board; board->llio.hm2.llio = &(board->llio); } void show_board_info(board_t *board) { int i; printf("Board info:\n"); if (board->flash_id > 0) { printf(" Flash size: %s (id: 0x%02X)\n", eeprom_get_flash_type(board->flash_id), board->flash_id); } printf(" Connectors count: %d\n", board->llio.num_ioport_connectors); printf(" Pins per connector: %d\n", board->llio.pins_per_connector); printf(" Connectors names:"); for (i = 0; i < board->llio.num_ioport_connectors; i++) { printf(" %s", board->llio.ioport_connector_name[i]); } printf("\n"); printf(" FPGA type: %s\n", board->llio.fpga_part_number); printf(" Number of leds: %d\n", board->llio.num_leds); } mesaflash-3.4.6/common.h000066400000000000000000000026721433153454000151410ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __COMMON_H #define __COMMON_H #include "types.h" #include "boards.h" #ifdef _WIN32 #include "winio32/winio.h" void init_io_library(); void release_io_library(); u8 inb(u32 addr); void outb(u8 data, u32 addr); u16 inw(u32 addr); void outw(u16 data, u32 addr); u32 inl(u32 addr); void outl(u32 data, u32 addr); void *map_memory(u32 base, u32 size, tagPhysStruct_t *phys); void *unmap_memory(tagPhysStruct_t *phys); #endif #define LO_BYTE(x) ((x) & 0xFF) #define HI_BYTE(x) (((x) & 0xFF00) >> 8) void sleep_ns(u64 nanoseconds); void show_formatted_size(u32 size); void board_init_struct(board_t *board); void show_board_info(board_t *board); #endif mesaflash-3.4.6/debian/000077500000000000000000000000001433153454000147135ustar00rootroot00000000000000mesaflash-3.4.6/debian/README.source000066400000000000000000000024221433153454000170720ustar00rootroot00000000000000Debian packaging of LinuxCNC/Mesaflash ====================================== The following steps were performed to transform Upstream's git repository into a source tarball and a debian subdirectory that is compliant with the latest release of the Debian Policy. Steps ----- 1. Generate the source tarball debian/rules get-orig-source 2. Prepare shell to work in temp directory export WORKDIR=$(mktemp -d) mv mesaflash_*.orig.tar.xz ${WORKDIR}/ bash cd $WORKDIR 2. Unpack tar xJvf mesaflash_*.orig.tar.xz 3. Slightly adapt for unstable bash cd $WORKDIR/mesaflash rm debian/compat sed -i 's/debhelper .*,/debhelper-compat (= 13),/' debian/control sed -i '/^Standards-Version: /s/ [0-9.]*/ 4.6.0/' debian/control sed -i '1s/ stable;/ unstable;/' debian/changelog 4. build Debian package dpkg-buildpackage 5. get all the files just created exit mv ${WORKDIR}/mesaflash_* .. Above sketched differences are not impeding routine workflows of Debian packaging. For instance we found that the tool routine-update (from the Debian Science team) deals with these adaptations just fine. How to contribute ----------------- LinuxCNC does not have a representation on salsa.debian.org. Please join us on https://github.com/LinuxCNC/mesaflash/ . mesaflash-3.4.6/debian/changelog000066400000000000000000000104541433153454000165710ustar00rootroot00000000000000mesaflash (3.4.6-1) unstable; urgency=medium * Add new Mesa boards: 7C81, 7I96S, 7I92T * Add OutM and OneShoto module support. * Add backup/restore for PCI cards. * Add support for Efinix FPGAs. * Show daughterboards better. * Add --print-lio to show Local I/O pins. * Add --version. * Better manpage and --help info. * Misc bugfixes. * Upload sponsored by Petter Reinholdtsen. -- Sebastian Kuzminsky Sat, 05 Nov 2022 12:38:09 -0600 mesaflash (3.4.2-1) unstable; urgency=medium * Switch from openssl to libmd for sha256. * Upload sponsored by Petter Reinholdtsen. -- Sebastian Kuzminsky Sun, 16 Jan 2022 09:47:57 -0700 mesaflash (3.4.1-1) unstable; urgency=medium * Add --backup-flash and --restore-flash command-line options. * Add --sha256-check command-line option. * Fix building on more platforms that lack sys/io.h. * Add Homepage link, fix Source link. Closes: #1001880 -- Sebastian Kuzminsky Sat, 15 Jan 2022 12:38:11 -0700 mesaflash (3.4.0-2) unstable; urgency=medium * Revised d/copyright -- Sebastian Kuzminsky Sat, 20 Nov 2021 17:52:00 +0100 mesaflash (3.4.0-1) UNRELEASED; urgency=medium * Cosmetics in preparation of upload to Debian. * Several bug fixes. * Fixes for PCI on Raspberry Pi Compute Module 4. * Better daughter-board reporting. * No longer support building on Windows. * Better IO error detection and handling. -- LinuxCNC Developers Mon, 27 Sep 2021 16:36:14 -0600 mesaflash (3.4.0~pre1-1) UNRELEASED; urgency=medium * Add a manpage. * Fix several compile warnings. * Add `--device AUTO` and `--device SPI`. -- LinuxCNC Developers Fri, 22 May 2020 10:30:23 -0600 mesaflash (3.4.0~pre0-1) UNRELEASED; urgency=medium * mesaflash is now maintained by the LinuxCNC organization. -- LinuxCNC Developers Thu, 23 Apr 2020 10:34:49 -0600 mesaflash (3.3.0~pre0+dfsg-0) UNRELEASED; urgency=low * support Mesa 7i93 ethernet board * support Mesa 7i96 ethernet board * Verify firmware after writing * Many bug fixes -- Sebastian Kuzminsky Tue, 27 Jun 2017 21:52:31 -0600 mesaflash (3.2.1) UNRELEASED; urgency=low * Fix some compile warnings and link issues on Debian Stretch. -- Sebastian Kuzminsky Tue, 27 Jun 2017 10:25:59 -0600 mesaflash (3.2.0) UNRELEASED; urgency=low * Don't check bitfile destinations while gpio recovering 6i24/6i25 boards * Use modules base address from module descriptor, not from regmap * Don't check bitfile id for 5i24 and 6i24 while --write and --verify * Fix support for 7i92, 5i24 and 6i24 * Add support for 6i24 PCIE board * Improve and clean reporting sserial remote data * Show FPGA programming time in verbose mode * Always show full info about bit file while using 'info' command * Add xml output from 'readhmid' command to use with pncconf -- Michael Geszkiewicz 27 Sep 2015 19:24:42 -0500 mesaflash (3.1.0) UNRELEASED; urgency=low * First stable release. * Support 7i90HD under linux in SPI and rs422 mode * Better EPP support * Support ICAP firmware reloading on ethernet and pci boards. * Print more debug data in verbose mode * Use default device address (0x378 for epp and 192.168.1.121 for eth) if --addr option is missing in command line * Reduce overhead of verify operation (thanks jepler) * Don't write and verify flash if bitfile destination part name is not equal to current board fpga name * Add support for 7i92 ethernet board * Update windows port * Correctly generates *.pin files with option --readhmid * Show details about connected sserial devices with --sserial * Factor out all libanyio access code to external static library * Add support for write/verify eeprom on 7i43 board via EPPIO bitfile * Add command to set remote ip address in ethernet eeprom * Remove obsolete command line options * Add example programs how to use libanyio to communicate with 7i77 (encoder in and analog out) -- Michael Geszkiewicz Sat, 24 Nov 2014 01:07:22 -0500 mesaflash (3.0.0) UNRELEASED; urgency=low * Initial release. -- Michael Geszkiewicz Sat, 19 Apr 2014 21:03:31 -0500 mesaflash-3.4.6/debian/compat000066400000000000000000000000021433153454000161110ustar00rootroot000000000000009 mesaflash-3.4.6/debian/control000066400000000000000000000017061433153454000163220ustar00rootroot00000000000000Source: mesaflash Maintainer: LinuxCNC Developers Uploaders: Sebastian Kuzminsky , Jeff Epler Section: misc Priority: optional Standards-Version: 3.9.4 Build-Depends: debhelper (>= 9), libpci-dev, libmd-dev, pkg-config Homepage: https://github.com/LinuxCNC/mesaflash Vcs-Browser: https://github.com/linuxcnc/mesaflash Vcs-Git: https://github.com/LinuxCNC/mesaflash.git -b master Package: mesaflash Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Mesa Electronics utility tool This package provides a tool for the configuration and/or diagnosis of Mesa Electronics boards. The cards provide I/O channels for robotics applications and have a strong user base in the LinuxCNC community. This tool works for all cards, be they directly plugged into your computer via PCI(E) or connected by a cable (ETH/EPP/USB/SPI). mesaflash-3.4.6/debian/copyright000066400000000000000000000030461433153454000166510ustar00rootroot00000000000000Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: mesaflash Upstream-Contact: LinuxCNC Developers Source: https://github.com/LinuxCNC/mesaflash Files: * Copyright: 2013-2015 Michael Geszkiewicz 2014,2016,2020-2021 Jeff Epler 2015 Joe Calderon 2017,2020 Sebastian Kuzminsky 2019-2021 Peter Wallace 2020 Damian Wrobel 2020 Curtis Dutton License: GPL-2.0+ Files: debian/* Copyright: 2015 Chris Radek 2016,2021 Jeff Epler 2014-2021 Sebastian Kuzminsky 2021 Steffen Moeller License: GPL-2.0+ License: GPL-2.0+ This package 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 package 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, see . On Debian systems, the complete text of the GNU General Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". mesaflash-3.4.6/debian/rules000077500000000000000000000005401433153454000157720ustar00rootroot00000000000000#!/usr/bin/make -f include /usr/share/dpkg/pkg-info.mk %: dh $@ override_dh_auto_install: $(MAKE) DESTDIR=$$(pwd)/debian/mesaflash/usr install .PHONY: get-orig-source get-orig-source: $(DEB_SOURCE)_$(DEB_VERSION_UPSTREAM).orig.tar.xz $(DEB_SOURCE)_$(DEB_VERSION_UPSTREAM).orig.tar.xz: git archive --prefix="mesaflash/" HEAD | xz --compress > $@ mesaflash-3.4.6/debian/source/000077500000000000000000000000001433153454000162135ustar00rootroot00000000000000mesaflash-3.4.6/debian/source/format000066400000000000000000000000141433153454000174210ustar00rootroot000000000000003.0 (quilt) mesaflash-3.4.6/debian/watch000066400000000000000000000002621433153454000157440ustar00rootroot00000000000000version=3 opts=uversionmangle=s/-pre/~pre/,filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/mesaflash-$1\.tar\.gz/ \ https://github.com/LinuxCNC/mesaflash/tags .*/v?(\d\S*)\.tar\.gz mesaflash-3.4.6/eeprom.c000066400000000000000000000517601433153454000151350ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #include #include #include #include #include #include #include #include #include #include #include "types.h" #include "eeprom.h" #include "eeprom_local.h" #include "eeprom_remote.h" #include "boards.h" #include "bitfile.h" u8 boot_block[BOOT_BLOCK_SIZE] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0x99, 0x55, 0x66, 0x31, 0xE1, 0xFF, 0xFF, 0x32, 0x61, 0x00, 0x00, 0x32, 0x81, 0x0B, 0x08, 0x32, 0xA1, 0x00, 0x00, 0x32, 0xC1, 0x0B, 0x01, 0x30, 0xA1, 0x00, 0x00, 0x33, 0x01, 0x21, 0x00, 0x32, 0x01, 0x00, 0x1F, 0x30, 0xA1, 0x00, 0x0E, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00 }; u8 page_buffer[PAGE_SIZE]; u8 file_buffer[SECTOR_SIZE]; spi_eeprom_dev_t eeprom_access; char *eeprom_get_flash_type(u8 flash_id) { switch (flash_id) { case ID_EEPROM_1M: return "1Mb"; case ID_EEPROM_2M: return "2Mb"; case ID_EEPROM_4M: return "4Mb"; case ID_EEPROM_8M: return "8Mb"; case ID_EEPROM_16M: return "16Mb"; case ID_EEPROM_32M: return "32Mb"; default: return "unknown"; } } static u32 eeprom_get_flash_size(u8 flash_id) { switch (flash_id) { case ID_EEPROM_1M: return 0x100000 / 8; case ID_EEPROM_2M: return 0x200000 / 8; case ID_EEPROM_4M: return 0x400000 / 8; case ID_EEPROM_8M: return 0x800000 / 8; case ID_EEPROM_16M: return 0x1000000 / 8; case ID_EEPROM_32M: return 0x2000000 / 8; } return 0; } // modify MSB of boot block jmp address to user area void eeprom_prepare_boot_block(u8 flash_id) { switch (flash_id) { case ID_EEPROM_1M: boot_block[25] = 0x01; break; case ID_EEPROM_2M: boot_block[25] = 0x02; break; case ID_EEPROM_4M: boot_block[25] = 0x04; break; case ID_EEPROM_8M: boot_block[25] = 0x08; break; case ID_EEPROM_16M: boot_block[25] = 0x10; break; case ID_EEPROM_32M: boot_block[25] = 0x20; break; } } u32 eeprom_calc_user_space(u8 flash_id) { switch (flash_id) { case ID_EEPROM_1M: return 0x10000; break; case ID_EEPROM_2M: return 0x20000; break; case ID_EEPROM_4M: return 0x40000; break; case ID_EEPROM_8M: return 0x80000; break; case ID_EEPROM_16M: return 0x100000; break; case ID_EEPROM_32M: return 0x200000; break; default: return 0x80000; break; } } static int check_boot(llio_t *self) { int i; eeprom_access.read_page(self, 0x0, &page_buffer); for (i = 0; i < BOOT_BLOCK_SIZE; i++) { if (boot_block[i] != page_buffer[i]) { return -1; } } return 0; } static void write_boot(llio_t *self) { printf("Erasing sector 0 for boot block\n"); eeprom_access.erase_sector(self, BOOT_ADDRESS); memset(&file_buffer, 0, PAGE_SIZE); memcpy(&file_buffer, &boot_block, BOOT_BLOCK_SIZE); eeprom_access.write_page(self, 0x0, &file_buffer); printf("BootBlock installed\n"); } int start_programming(llio_t *self, u32 start_address, int fsize) { board_t *board = self->board; u32 sec_addr; int esectors, sector, max_sectors; struct timeval tv1, tv2; esectors = (fsize - 1) / SECTOR_SIZE; if (board->fpga_type == FPGA_TYPE_EFINIX) { max_sectors = eeprom_calc_user_space(board->flash_id) / SECTOR_SIZE; } else { if (board->fallback_support == 1) { if (start_address == XILINX_FALLBACK_ADDRESS) { max_sectors = eeprom_calc_user_space(board->flash_id) / SECTOR_SIZE - 1; } else { max_sectors = eeprom_calc_user_space(board->flash_id) / SECTOR_SIZE; } } else { max_sectors = eeprom_get_flash_size(board->flash_id) / SECTOR_SIZE; } } if (esectors > max_sectors) { printf("File Size too large to fit\n"); return -1; } printf("FLASH memory sectors to write: %d, max sectors in area: %d\n", esectors + 1, max_sectors); sec_addr = start_address; printf("Erasing FLASH memory sectors starting from 0x%X...\n", (unsigned int) start_address); printf(" |"); fflush(stdout); gettimeofday(&tv1, NULL); for (sector = 0; sector <= esectors; sector++) { eeprom_access.erase_sector(self, sec_addr); sec_addr = sec_addr + SECTOR_SIZE; printf("E"); fflush(stdout); } if (board->llio.verbose == 1) { gettimeofday(&tv2, NULL); printf("\n Erasing time: %.2f seconds", (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 + (double) (tv2.tv_sec - tv1.tv_sec)); } printf("\n"); return 0; } bool sha256_verify(const char *bitfile_name, bool verbose) { int bytesread, i, j; struct stat file_stat; FILE *fp; char sha256str[SHA256_DIGEST_LENGTH*2+1]; char sha256file_name[PATH_MAX]; unsigned char sha256in[SHA256_DIGEST_LENGTH]; unsigned char sha256bitfile[SHA256_DIGEST_LENGTH]; SHA256_CTX sha256ctx; snprintf(sha256file_name, sizeof(sha256file_name), "%s.sha256", bitfile_name); if (verbose) printf("Start integrity verification file '%s'\n", bitfile_name); if (stat(sha256file_name, &file_stat) != 0) { printf("Can't find checksum file '%s'\n", sha256file_name); return 0; } if (file_stat.st_size < SHA256_DIGEST_LENGTH*2) { printf("Checksum file size too small\n"); return 0; } fp = fopen(sha256file_name, "rt"); if (fp == NULL) { printf("Can't open checksum file '%s': %s\n", sha256file_name, strerror(errno)); return 0; } fread(&sha256str, 1, SHA256_DIGEST_LENGTH*2, fp); fclose(fp); if (verbose) printf("Read checksum string from file '%s' ", sha256file_name); for (i = 0, j = 0; i < SHA256_DIGEST_LENGTH*2; i+=2, j++) { if (sscanf(&sha256str[i], "%2hhx", &sha256in[j]) != 1) { printf("Error: not correct sha256 string\n"); return 0; } } if (verbose) { printf("OK,\nsha256: '"); for (i = 0; i < SHA256_DIGEST_LENGTH; i++) printf("%02x", sha256in[i]); printf("'\n"); } if (stat(bitfile_name, &file_stat) != 0) { printf("Can't find file %s\n", bitfile_name); return 0; } fp = fopen(bitfile_name, "rb"); if (fp == NULL) { printf("Can't open file '%s': %s\n", bitfile_name, strerror(errno)); return 0; } if (verbose) printf("Calculate checksum for file '%s' ", bitfile_name); SHA256_Init(&sha256ctx); while (!feof(fp)) { bytesread = fread(&file_buffer, 1, 8192, fp); SHA256_Update(&sha256ctx, file_buffer, (unsigned long)bytesread); } fclose(fp); SHA256_Final(sha256bitfile, &sha256ctx); if (verbose) { printf("OK,\nsha256: '"); for (i = 0; i < SHA256_DIGEST_LENGTH; i++) printf("%02x", sha256bitfile[i]); printf("'\n"); } if (verbose) printf("Compare sha256 hashes: "); for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { if (sha256in[i] != sha256bitfile[i]) { if (verbose) printf(" error!\n"); return 0; } } if (verbose) printf("OK\n"); return 1; } int eeprom_write(llio_t *self, char *bitfile_name, u32 start_address, int fix_boot_flag, int sha256_check_flag) { board_t *board = self->board; int bytesread, i; u32 eeprom_addr; char part_name[32]; struct stat file_stat; FILE *fp; struct timeval tv1, tv2; if (sha256_check_flag) { if (sha256_verify(bitfile_name, board->llio.verbose)) { printf("Bitfile integrity verification passed\n"); } else { printf("Bitfile integrity verification not passed\n"); return -1; } } if (stat(bitfile_name, &file_stat) != 0) { printf("Can't find bitfile %s\n", bitfile_name); return -1; } fp = fopen(bitfile_name, "rb"); if (fp == NULL) { printf("Can't open bitfile %s: %s\n", bitfile_name, strerror(errno)); return -1; } if (print_bitfile_header(fp, (char*) &part_name, board->llio.verbose) == -1) { fclose(fp); return -1; } if (board->recover == 0) { if (strchr(board->llio.fpga_part_number, '|') == NULL) { if (strcmp(part_name, board->llio.fpga_part_number) != 0) { printf("Error: wrong bitfile destination device: %s, should be %s\n", part_name, board->llio.fpga_part_number); fclose(fp); return -1; } } } // boot blocks are in Xilinx FPGA cards with fallback support if ((board->fallback_support == 1) && (board->fpga_type == FPGA_TYPE_XILINX)) { if (check_boot(self) == -1) { if (fix_boot_flag) { write_boot(self); if (check_boot(self) == -1) { printf("Failed to write valid boot sector\n"); fclose(fp); return -1; } } else { printf("Error: BootSector is invalid\n"); fclose(fp); return -1; } } else { printf("Boot sector OK\n"); } } if (eeprom_access.start_programming(self, start_address, file_stat.st_size) == -1) { fclose(fp); return -1; } printf("Programming FLASH memory sectors starting from 0x%X...\n", (unsigned int) start_address); printf(" |"); fflush(stdout); gettimeofday(&tv1, NULL); eeprom_addr = start_address; while (!feof(fp)) { bytesread = fread(&file_buffer, 1, 8192, fp); i = 0; while (i < bytesread) { eeprom_access.write_page(self, eeprom_addr, &file_buffer[i]); i += PAGE_SIZE; eeprom_addr += PAGE_SIZE; } printf("W"); fflush(stdout); } fclose(fp); printf("\n"); if (board->llio.verbose == 1) { gettimeofday(&tv2, NULL); printf(" Programming time: %.2f seconds\n", (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 + (double) (tv2.tv_sec - tv1.tv_sec)); } printf("Board configuration updated successfully.\n"); return 0; } int eeprom_verify(llio_t *self, char *bitfile_name, u32 start_address) { board_t *board = self->board; int bytesread, i, bindex, all_flash; u32 eeprom_addr; char part_name[32]; struct stat file_stat; FILE *fp; struct timeval tv1, tv2; if (stat(bitfile_name, &file_stat) != 0) { printf("Can't find file %s\n", bitfile_name); return -1; } fp = fopen(bitfile_name, "rb"); if (fp == NULL) { printf("Can't open file %s: %s\n", bitfile_name, strerror(errno)); return -1; } if (file_stat.st_size != eeprom_get_flash_size(board->flash_id)) { if (print_bitfile_header(fp, (char*) &part_name, board->llio.verbose) == -1) { fclose(fp); return -1; } if (strchr(board->llio.fpga_part_number, '|') == NULL) { if (strcmp(part_name, board->llio.fpga_part_number) != 0) { printf("Error: wrong bitfile destination device: %s, should be %s\n", part_name, board->llio.fpga_part_number); fclose(fp); return -1; } } // boot blocks are in Xilinx FPGA cards with fallback support if ((board->fallback_support == 1) && (board->fpga_type == FPGA_TYPE_XILINX)) { if (check_boot(self) == -1) { printf("Error: BootSector is invalid\n"); fclose(fp); return -1; } else { printf("Boot sector OK\n"); } } } else { start_address = 0; all_flash = 1; } printf("Verifying FLASH memory sectors starting from 0x%X...\n", (unsigned int) start_address); printf(" |"); fflush(stdout); gettimeofday(&tv1, NULL); eeprom_addr = start_address; while (!feof(fp)) { bytesread = fread(&file_buffer, 1, 8192, fp); bindex = 0; while (bindex < bytesread) { eeprom_access.read_page(self, eeprom_addr, &page_buffer); for (i = 0; i < PAGE_SIZE; i++, bindex++) { if (file_buffer[bindex] != page_buffer[i]) { printf("\nError at 0x%X expected: 0x%X but read: 0x%X\n", eeprom_addr + i, file_buffer[bindex], page_buffer[i]); return -1; } } eeprom_addr += PAGE_SIZE; } printf("V"); fflush(stdout); } fclose(fp); printf("\n"); if (board->llio.verbose == 1) { gettimeofday(&tv2, NULL); printf(" Verification time: %.2f seconds\n", (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 + (double) (tv2.tv_sec - tv1.tv_sec)); } if (all_flash == 1) { printf("Board FLASH memory verified successfully.\n"); } else { printf("Board configuration verified successfully.\n"); } return 0; } int flash_backup(llio_t *self, char *bitfile_name) { board_t *board = self->board; uint i, page_num; u32 eeprom_addr, eeprom_pages; struct stat file_stat; FILE *fp; struct timeval tv1, tv2; time_t now = time(NULL); struct tm *t = localtime(&now); char auto_name[33]; char bitfile_path[PATH_MAX-8]; SHA256_CTX sha256ctx; unsigned char sha256out[SHA256_DIGEST_LENGTH]; char sha256str[SHA256_DIGEST_LENGTH*2+1]; char sha256file_path[PATH_MAX]; if (eeprom_get_flash_size(board->flash_id) == 0) { printf("Unknown size FLASH memory on the %s board\n", board->llio.board_name); return -1; } printf("Creating backup %s FLASH memory on the %s board:\n", eeprom_get_flash_type(board->flash_id), board->llio.board_name); if (stat(bitfile_name, &file_stat) == 0) { if (S_ISDIR(file_stat.st_mode)) { strftime(auto_name, sizeof(auto_name), "_flash_backup_%d%m%y_%H%M%S.bin", t); snprintf(bitfile_path, sizeof(bitfile_path), (bitfile_name[strlen(bitfile_name)-1] != '/') ? "%s/%s%s" : "%s%s%s", bitfile_name, board->llio.board_name, auto_name); printf("Used auto naming backup file: '%s%s'\n", board->llio.board_name, auto_name); } else { printf("File '%s' already exist.\n", bitfile_name); return -1; } } else { snprintf(bitfile_path, sizeof(bitfile_path), "%s", bitfile_name); } fp = fopen(bitfile_path, "wb"); if (fp == NULL) { printf("Can't create file '%s': %s\n", bitfile_path, strerror(errno)); return -1; } printf("Reading FLASH memory sectors starting from 0x0...\n"); printf(" |"); fflush(stdout); gettimeofday(&tv1, NULL); eeprom_addr = 0; eeprom_pages = eeprom_get_flash_size(board->flash_id) / PAGE_SIZE; page_num = 0; SHA256_Init(&sha256ctx); for (i = 0; i < eeprom_pages; i++) { eeprom_access.read_page(self, eeprom_addr, &page_buffer); fwrite(&page_buffer, 1, PAGE_SIZE, fp); SHA256_Update(&sha256ctx, page_buffer, PAGE_SIZE); eeprom_addr += PAGE_SIZE; page_num++; if(page_num == 32){ page_num = 0; printf("R"); fflush(stdout); } } fclose(fp); SHA256_Final(sha256out, &sha256ctx); for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { sprintf(sha256str + i * 2, "%02x", sha256out[i]); } printf("\n"); if (board->llio.verbose == 1) { gettimeofday(&tv2, NULL); printf(" Backup time: %.2f seconds\n", (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 + (double) (tv2.tv_sec - tv1.tv_sec)); } printf("FLASH memory backup file '%s' created successfully.\n", bitfile_path); snprintf(sha256file_path, sizeof(sha256file_path), "%s.sha256", bitfile_path); fp = fopen(sha256file_path, "wt"); if (fp == NULL) { printf("Can't create file '%s': %s\n", sha256file_path, strerror(errno)); return -1; } fprintf(fp, "%s *./%s\n", sha256str, basename(bitfile_path)); fclose(fp); printf("Checksum file '%s' created successfully,\n", sha256file_path); printf("sha256: '%s'\n", sha256str); return 0; } int flash_erase(llio_t *self) { board_t *board = self->board; u32 sec_addr; int sector, max_sectors; struct timeval tv1, tv2; max_sectors = eeprom_get_flash_size(board->flash_id) / SECTOR_SIZE; printf("FLASH memory sectors to erase: %d\n", max_sectors); sec_addr = 0; printf("Erasing FLASH memory sectors starting from 0x0...\n"); printf(" |"); fflush(stdout); gettimeofday(&tv1, NULL); for (sector = 0; sector < max_sectors; sector++) { eeprom_access.erase_sector(self, sec_addr); sec_addr = sec_addr + SECTOR_SIZE; printf("E"); fflush(stdout); } if (board->llio.verbose == 1) { gettimeofday(&tv2, NULL); printf("\n Erasing time: %.2f seconds", (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 + (double) (tv2.tv_sec - tv1.tv_sec)); } printf("\n"); return 0; } int flash_restore(llio_t *self, char *bitfile_name) { board_t *board = self->board; int bytesread, i, max_sectors; u32 eeprom_addr, eeprom_size; struct stat file_stat; FILE *fp; struct timeval tv1, tv2; if (eeprom_get_flash_size(board->flash_id) == 0) { printf("Unknown size FLASH memory on the %s board\n", board->llio.board_name); return -1; } printf("\nRestoring backup %s FLASH memory on the %s board:\n", eeprom_get_flash_type(board->flash_id), board->llio.board_name); if (sha256_verify(bitfile_name, board->llio.verbose)) { printf("Backup file integrity verification passed\n"); } else { printf("Backup file integrity verification not passed\n"); return -1; } if (stat(bitfile_name, &file_stat) != 0) { printf("Can't find backup file '%s'\n", bitfile_name); return -1; } eeprom_size = eeprom_get_flash_size(board->flash_id); if (file_stat.st_size > eeprom_size) { printf("Backup file size too large for restore FLASH memory\n"); return -1; } if (file_stat.st_size < eeprom_size) { printf("Backup file size too small for restore FLASH memory\n"); return -1; } fp = fopen(bitfile_name, "rb"); if (fp == NULL) { printf("Can't open backup file '%s': %s\n", bitfile_name, strerror(errno)); return -1; } if (flash_erase(self) == -1) { fclose(fp); return -1; } max_sectors = eeprom_size / SECTOR_SIZE; printf("FLASH memory sectors to write: %d\n", max_sectors); printf("Programming FLASH memory sectors starting from 0x0...\n"); printf(" |"); fflush(stdout); gettimeofday(&tv1, NULL); eeprom_addr = 0; //fseek(fp, 0, SEEK_SET); while (!feof(fp)) { bytesread = fread(&file_buffer, 1, 8192, fp); i = 0; while (i < bytesread) { eeprom_access.write_page(self, eeprom_addr, &file_buffer[i]); i += PAGE_SIZE; eeprom_addr += PAGE_SIZE; } printf("W"); fflush(stdout); } fclose(fp); printf("\n"); if (board->llio.verbose == 1) { gettimeofday(&tv2, NULL); printf(" Programming time: %.2f seconds\n", (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 + (double) (tv2.tv_sec - tv1.tv_sec)); } printf("Board FLASH memory writed successfully.\n"); return 0; } void eeprom_init(llio_t *self) { board_t *board = self->board; switch (board->flash) { case BOARD_FLASH_NONE: break; case BOARD_FLASH_HM2: case BOARD_FLASH_IO: case BOARD_FLASH_GPIO: case BOARD_FLASH_EPP: open_spi_access_local(self); break; case BOARD_FLASH_REMOTE: open_spi_access_remote(self); break; } } void eeprom_cleanup(llio_t *self) { board_t *board = self->board; switch (board->flash) { case BOARD_FLASH_NONE: break; case BOARD_FLASH_HM2: case BOARD_FLASH_IO: case BOARD_FLASH_GPIO: case BOARD_FLASH_EPP: close_spi_access_local(self); break; case BOARD_FLASH_REMOTE: close_spi_access_remote(self); break; } } mesaflash-3.4.6/eeprom.h000066400000000000000000000045201433153454000151320ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __EEPROM_H #define __EEPROM_H #include "hostmot2.h" #include "bitfile.h" #define ID_EEPROM_1M 0x10 #define ID_EEPROM_2M 0x11 #define ID_EEPROM_4M 0x12 #define ID_EEPROM_8M 0x13 #define ID_EEPROM_16M 0x14 #define ID_EEPROM_32M 0x15 #define PAGE_SIZE 256 #define SECTOR_SIZE 65536 #define BOOT_BLOCK_SIZE 64 #define BOOT_ADDRESS 0x000000 #define XILINX_FALLBACK_ADDRESS 0x010000 #define EFINIX_FALLBACK_ADDRESS 0x000000 typedef struct { void (*set_cs_low)(llio_t *self); void (*set_cs_high)(llio_t *self); void (*prefix)(llio_t *self); void (*suffix)(llio_t *self); void (*send_byte)(llio_t *self, u8 byte); u8 (*recv_byte)(llio_t *self); void (*read_page)(llio_t *self, u32 addr, void *buff); void (*write_page)(llio_t *self, u32 addr, void *buff); void (*erase_sector)(llio_t *self, u32 addr); int (*start_programming)(llio_t *self, u32 start_address, int fsize); } spi_eeprom_dev_t; extern u8 boot_block[BOOT_BLOCK_SIZE]; char *eeprom_get_flash_type(u8 flash_id); u32 eeprom_calc_user_space(u8 flash_id); void eeprom_prepare_boot_block(u8 flash_id); int start_programming(llio_t *self, u32 start_address, int fsize); int eeprom_write(llio_t *self, char *bitfile_name, u32 start_address, int fix_boot_flag, int sha256_check_flag); int eeprom_verify(llio_t *self, char *bitfile_name, u32 start_address); int flash_backup(llio_t *self, char *bitfile_name); int flash_erase(llio_t *self); int flash_restore(llio_t *self, char *bitfile_name); void eeprom_init(llio_t *self); void eeprom_cleanup(llio_t *self); #endif mesaflash-3.4.6/eeprom_local.c000066400000000000000000000316741433153454000163110ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifdef __linux__ #if MESAFLASH_IO #include #endif #include #elif _WIN32 #include #include "libpci/pci.h" #endif #include #include #include #include #include "types.h" #include "eeprom.h" #include "eeprom_local.h" #include "hostmot2.h" #include "bitfile.h" #include "epp_boards.h" extern u8 boot_block[BOOT_BLOCK_SIZE]; extern u8 page_buffer[PAGE_SIZE]; extern u8 file_buffer[SECTOR_SIZE]; extern spi_eeprom_dev_t eeprom_access; // spi access via hm2 registers static void wait_for_data_hm2(llio_t *self) { u32 i = 0; u32 data = 0; for (i = 0; (((data & 0xFF) & SPI_DAV_MASK) == 0) && (i < 5000) ; i++) { self->read(self, HM2_SPI_CTRL_REG, &data, sizeof(data)); } if (i == 5000) { printf("%x timeout waiting for SPI data\n", data); } } static void set_cs_high_hm2(llio_t *self) { u32 data = 1; self->write(self, HM2_SPI_CTRL_REG, &data, sizeof(data)); } static void set_cs_low_hm2(llio_t *self) { u32 data = 0; self->write(self, HM2_SPI_CTRL_REG, &data, sizeof(data)); } static void prefix_hm2(llio_t *self) { set_cs_low_hm2(self); } static void suffix_hm2(llio_t *self) { set_cs_high_hm2(self); } static void send_byte_hm2(llio_t *self, u8 byte) { u32 data = byte; self->write(self, HM2_SPI_DATA_REG, &data, sizeof(data)); wait_for_data_hm2(self); } static u8 recv_byte_hm2(llio_t *self) { u32 data = 0; u32 recv = 0; self->write(self, HM2_SPI_DATA_REG, &data, sizeof(data)); wait_for_data_hm2(self); self->read(self, HM2_SPI_DATA_REG, &recv, sizeof(recv)); return (u8) recv & 0xFF; } // spi access via gpio pins of xio2001 bridge on 6i25 static u16 GPIO_reg_val; static void set_cs_high_gpio(llio_t *self) { board_t *board = self->board; GPIO_reg_val = GPIO_reg_val | 0x2; pci_write_word(board->dev, XIO2001_GPIO_DATA_REG, GPIO_reg_val); } static void set_cs_low_gpio(llio_t *self) { board_t *board = self->board; GPIO_reg_val = GPIO_reg_val & (~ 0x2); pci_write_word(board->dev, XIO2001_GPIO_DATA_REG, GPIO_reg_val); } static void set_din_high_gpio(llio_t *self) { board_t *board = self->board; GPIO_reg_val = GPIO_reg_val | 0x8; pci_write_word(board->dev, XIO2001_GPIO_DATA_REG, GPIO_reg_val); } static void set_din_low_gpio(llio_t *self) { board_t *board = self->board; GPIO_reg_val = GPIO_reg_val & (~0x8); pci_write_word(board->dev, XIO2001_GPIO_DATA_REG, GPIO_reg_val); } static void set_clock_high_gpio(llio_t *self) { board_t *board = self->board; GPIO_reg_val = GPIO_reg_val | 0x10; pci_write_word(board->dev, XIO2001_GPIO_DATA_REG, GPIO_reg_val); } static void set_clock_low_gpio(llio_t *self) { board_t *board = self->board; GPIO_reg_val = GPIO_reg_val & (~ 0x10); pci_write_word(board->dev, XIO2001_GPIO_DATA_REG, GPIO_reg_val); } static int get_bit_gpio(llio_t *self) { board_t *board = self->board; u16 data; data = pci_read_word(board->dev, XIO2001_GPIO_DATA_REG); if (data & 0x4) return 1; else return 0; } static void prefix_gpio(llio_t *self) { set_cs_high_gpio(self); set_din_low_gpio(self); set_clock_low_gpio(self); set_cs_low_gpio(self); } static void suffix_gpio(llio_t *self) { set_cs_high_gpio(self); set_din_low_gpio(self); } static void init_gpio(llio_t *self) { board_t *board = self->board; pci_write_word(board->dev, XIO2001_GPIO_ADDR_REG, 0x001B); pci_write_word(board->dev, XIO2001_SBAD_STAT_REG, 0x0000); GPIO_reg_val = 0x0003; pci_write_word(board->dev, XIO2001_GPIO_DATA_REG, GPIO_reg_val); } static void restore_gpio(llio_t *self) { board_t *board = self->board; GPIO_reg_val = 0x0003; pci_write_word(board->dev, XIO2001_GPIO_DATA_REG, GPIO_reg_val); pci_write_word(board->dev, XIO2001_GPIO_ADDR_REG, 0x0000); } static void send_byte_gpio(llio_t *self, u8 byte) { u32 mask = DATA_MASK; int i; for (i = 0; i < CMD_LEN; i++) { if ((mask & byte) == 0) set_din_low_gpio(self); else set_din_high_gpio(self); mask >>= 1; set_clock_high_gpio(self); set_clock_low_gpio(self); } } static u8 recv_byte_gpio(llio_t *self) { u32 mask, data = 0; int i; mask = DATA_MASK; for (i = 0; i < DATA_LEN; i++) { if (get_bit_gpio(self) == 1) data |= mask; mask >>= 1; set_clock_high_gpio(self); set_clock_low_gpio(self); } return data; } // spi access via io ports like on 3x20 #if MESAFLASH_IO static void wait_for_data_io(llio_t *self) { board_t *board = self->board; u32 i = 0; u8 data = 0; for (i = 0; (((data & 0xFF) & SPI_DAV_MASK) == 0) && (i < 5000) ; i++) { data = inb(board->data_base_addr + IO_SPI_CS_OFFSET); } if (i == 5000) { printf("%x timeout waiting for SPI data\n", data); } } static void set_cs_high_io(llio_t *self) { board_t *board = self->board; outb(1, board->data_base_addr + IO_SPI_CS_OFFSET); } static void set_cs_low_io(llio_t *self) { board_t *board = self->board; outb(0, board->data_base_addr + IO_SPI_CS_OFFSET); } static void prefix_io(llio_t *self) { set_cs_low_io(self); } static void suffix_io(llio_t *self) { set_cs_high_io(self); } static void send_byte_io(llio_t *self, u8 byte) { board_t *board = self->board; outb(byte, board->data_base_addr + IO_SPI_SREG_OFFSET); } static u8 recv_byte_io(llio_t *self) { board_t *board = self->board; outb(0, board->data_base_addr + IO_SPI_SREG_OFFSET); wait_for_data_io(self); return inb(board->data_base_addr + IO_SPI_SREG_OFFSET); } // spi access via epp on board 7i43 with EPPIO firmware void wait_for_data_epp(llio_t *self) { board_t *board = self->board; u32 i = 0; u8 data = 0; epp_addr8(board, EPP_SPI_CS_REG); for (i = 0; ((data & SPI_DAV_MASK) == 0) && (i < 100) ; i++) { data = epp_read8(board); } if (i == 100) { printf("%x timeout waiting for SPI data\n", data); } } static void set_cs_high_epp(llio_t *self) { board_t *board = self->board; epp_addr8(board, EPP_SPI_CS_REG); epp_write8(board, 1); } static void set_cs_low_epp(llio_t *self) { board_t *board = self->board; epp_addr8(board, EPP_SPI_CS_REG); epp_write8(board, 0); } static void prefix_epp(llio_t *self) { set_cs_low_epp(self); } static void suffix_epp(llio_t *self) { set_cs_high_epp(self); } static void send_byte_epp(llio_t *self, u8 byte) { board_t *board = self->board; epp_addr8(board, EPP_SPI_SREG_REG); epp_write8(board, byte); } static u8 recv_byte_epp(llio_t *self) { board_t *board = self->board; epp_addr8(board, EPP_SPI_SREG_REG); epp_write8(board, 0); wait_for_data_epp(self); epp_addr8(board, EPP_SPI_SREG_REG); return epp_read8(board); } #endif // pci flash static void send_address(llio_t *self, u32 addr) { eeprom_access.send_byte(self, (addr >> 16) & 0xFF); eeprom_access.send_byte(self, (addr >> 8) & 0xFF); eeprom_access.send_byte(self, addr & 0xFF); } static void write_enable(llio_t *self) { eeprom_access.prefix(self); eeprom_access.send_byte(self, SPI_CMD_WRITE_ENABLE); eeprom_access.suffix(self); } static u8 read_status(llio_t *self) { u8 ret; eeprom_access.prefix(self); eeprom_access.send_byte(self, SPI_CMD_READ_STATUS); ret = eeprom_access.recv_byte(self); eeprom_access.suffix(self); return ret; } u8 read_flash_id(llio_t *self) { u8 ret; eeprom_access.prefix(self); eeprom_access.send_byte(self, SPI_CMD_READ_IDROM); send_address(self, 0); // three dummy bytes ret = eeprom_access.recv_byte(self); eeprom_access.suffix(self); return ret; } static void wait_for_write(llio_t *self) { u8 stat = read_status(self); while ((stat & WRITE_IN_PROGRESS_MASK) != 0) { stat = read_status(self); } } // eeprom access functions static void read_page(llio_t *self, u32 addr, void *buff) { int i; eeprom_access.prefix(self); eeprom_access.send_byte(self, SPI_CMD_READ); send_address(self, addr); for (i = 0; i < PAGE_SIZE; i++, buff++) { *((u8 *) buff) = eeprom_access.recv_byte(self); } eeprom_access.suffix(self); } static void write_page(llio_t *self, u32 addr, void *buff) { int i; u8 byte; write_enable(self); eeprom_access.prefix(self); eeprom_access.send_byte(self, SPI_CMD_PAGE_WRITE); send_address(self, addr);// { note that add 0..7 should be 0} for (i = 0; i < PAGE_SIZE; i++) { byte = *(u8 *) (buff + i); eeprom_access.send_byte(self, byte); } eeprom_access.suffix(self); wait_for_write(self); } static void erase_sector(llio_t *self, u32 addr) { write_enable(self); eeprom_access.prefix(self); eeprom_access.send_byte(self, SPI_CMD_SECTOR_ERASE); send_address(self, addr); eeprom_access.suffix(self); wait_for_write(self); } static int local_start_programming(llio_t *self, u32 start_address, int fsize) { int ret; eeprom_access.set_cs_high(self); ret = start_programming(self, start_address, fsize); eeprom_access.set_cs_high(self); return ret; } static void done_programming(llio_t *self) { eeprom_access.set_cs_high(self); } // global functions int local_write_flash(llio_t *self, char *bitfile_name, u32 start_address, int fix_boot_flag, int sha256_check_flag) { int ret; ret = eeprom_write(self, bitfile_name, start_address, fix_boot_flag, sha256_check_flag); done_programming(self); return ret; } int local_verify_flash(llio_t *self, char *bitfile_name, u32 start_address) { return eeprom_verify(self, bitfile_name, start_address); } int local_backup_flash(llio_t *self, char *bitfile_name) { return flash_backup(self, bitfile_name); } int local_restore_flash(llio_t *self, char *bitfile_name) { return flash_restore(self, bitfile_name); } void open_spi_access_local(llio_t *self) { board_t *board = self->board; switch (board->flash) { case BOARD_FLASH_NONE: break; case BOARD_FLASH_HM2: eeprom_access.set_cs_low = &set_cs_low_hm2; eeprom_access.set_cs_high = &set_cs_high_hm2; eeprom_access.prefix = &prefix_hm2; eeprom_access.suffix = &suffix_hm2; eeprom_access.send_byte = &send_byte_hm2; eeprom_access.recv_byte = &recv_byte_hm2; break; case BOARD_FLASH_IO: #if MESAFLASH_IO eeprom_access.set_cs_low = &set_cs_low_io; eeprom_access.set_cs_high = &set_cs_high_io; eeprom_access.prefix = &prefix_io; eeprom_access.suffix = &suffix_io; eeprom_access.send_byte = &send_byte_io; eeprom_access.recv_byte = &recv_byte_io; #endif break; case BOARD_FLASH_GPIO: eeprom_access.set_cs_low = &set_cs_low_gpio; eeprom_access.set_cs_high = &set_cs_high_gpio; eeprom_access.prefix = &prefix_gpio; eeprom_access.suffix = &suffix_gpio; eeprom_access.send_byte = &send_byte_gpio; eeprom_access.recv_byte = &recv_byte_gpio; init_gpio(self); break; case BOARD_FLASH_EPP: #if MESAFLASH_IO eeprom_access.set_cs_low = &set_cs_low_epp; eeprom_access.set_cs_high = &set_cs_high_epp; eeprom_access.prefix = &prefix_epp; eeprom_access.suffix = &suffix_epp; eeprom_access.send_byte = &send_byte_epp; eeprom_access.recv_byte = &recv_byte_epp; #endif break; case BOARD_FLASH_REMOTE: break; } eeprom_access.read_page = &read_page; eeprom_access.write_page = &write_page; eeprom_access.erase_sector = &erase_sector; eeprom_access.start_programming = &local_start_programming; }; void close_spi_access_local(llio_t *self) { board_t *board = self->board; switch (board->flash) { case BOARD_FLASH_NONE: case BOARD_FLASH_HM2: case BOARD_FLASH_IO: case BOARD_FLASH_EPP: case BOARD_FLASH_REMOTE: break; case BOARD_FLASH_GPIO: restore_gpio(self); break; } } mesaflash-3.4.6/eeprom_local.h000066400000000000000000000033331433153454000163050ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __EEPROM_LOCAL_H #define __EEPROM_LOCAL_H #include "hostmot2.h" #define SPI_DAV_MASK 0x04 // gpio access #define XIO2001_SBAD_STAT_REG 0x00B2 #define XIO2001_GPIO_ADDR_REG 0x00B4 #define XIO2001_GPIO_DATA_REG 0x00B6 #define DATA_MASK 0x80 #define ADDR_MASK 0x800000 #define CMD_LEN 8 #define DATA_LEN 8 #define ADDR_LEN 24 // io access #define IO_SPI_SREG_OFFSET 0x40 #define IO_SPI_CS_OFFSET 0x44 // epp access #define EPP_SPI_CS_REG 0x7D #define EPP_SPI_SREG_REG 0x7E u8 read_flash_id(llio_t *self); int local_write_flash(llio_t *self, char *bitfile_name, u32 start_address, int fix_boot_flag, int sha256_check_flag); int local_verify_flash(llio_t *self, char *bitfile_name, u32 start_address); int local_backup_flash(llio_t *self, char *bitfile_name); int local_restore_flash(llio_t *self, char *bitfile_name); void open_spi_access_local(llio_t *self); void close_spi_access_local(llio_t *self); #endif mesaflash-3.4.6/eeprom_remote.c000066400000000000000000000104531433153454000165020ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #include #include #include #include #include "types.h" #include "eeprom.h" #include "eeprom_remote.h" #include "eth_boards.h" #include "lbp16.h" #include "bitfile.h" extern u8 boot_block[BOOT_BLOCK_SIZE]; extern u8 page_buffer[PAGE_SIZE]; extern u8 file_buffer[SECTOR_SIZE]; extern spi_eeprom_dev_t eeprom_access; // eeprom access functions static void read_page(llio_t *self, u32 addr, void *buff) { (void)self; lbp16_cmd_addr_data32 write_addr_pck; lbp16_cmd_addr read_page_pck; LBP16_INIT_PACKET8(write_addr_pck, CMD_WRITE_FPGA_FLASH_ADDR32(1), FLASH_ADDR_REG, addr); LBP16_INIT_PACKET4(read_page_pck, CMD_READ_FPGA_FLASH_ADDR32(64), FLASH_DATA_REG); lbp16_send_packet_checked(&write_addr_pck, sizeof(write_addr_pck)); lbp16_send_packet_checked(&read_page_pck, sizeof(read_page_pck)); lbp16_recv_packet_checked(buff, PAGE_SIZE); } static void write_page(llio_t *self, u32 addr, void *buff) { (void)self; lbp16_cmd_addr_data32 write_addr_pck; lbp16_write_flash_page_packets write_page_pck; u32 ignored; LBP16_INIT_PACKET8(write_addr_pck, CMD_WRITE_FPGA_FLASH_ADDR32(1), FLASH_ADDR_REG, addr); lbp16_send_packet_checked(&write_addr_pck, sizeof(write_addr_pck)); LBP16_INIT_PACKET6(write_page_pck.write_ena_pck, CMD_WRITE_COMM_CTRL_ADDR16(1), COMM_CTRL_WRITE_ENA_REG, 0x5A03); LBP16_INIT_PACKET4(write_page_pck.fl_write_page_pck, CMD_WRITE_FPGA_FLASH_ADDR32(64), FLASH_DATA_REG); memcpy(&write_page_pck.fl_write_page_pck.page, buff, 256); lbp16_send_packet_checked(&write_page_pck, sizeof(write_page_pck)); // packet read for board syncing lbp16_read(CMD_READ_FPGA_FLASH_ADDR32(1), FLASH_ADDR_REG, &ignored, 4); } static void erase_sector(llio_t *self, u32 addr) { (void)self; lbp16_erase_flash_sector_packets sector_erase_pck; lbp16_cmd_addr_data32 write_addr_pck; u32 ignored; LBP16_INIT_PACKET8(write_addr_pck, CMD_WRITE_FPGA_FLASH_ADDR32(1), FLASH_ADDR_REG, addr); lbp16_send_packet_checked(&write_addr_pck, sizeof(write_addr_pck)); LBP16_INIT_PACKET6(sector_erase_pck.write_ena_pck, CMD_WRITE_COMM_CTRL_ADDR16(1), COMM_CTRL_WRITE_ENA_REG, 0x5A03); LBP16_INIT_PACKET8(sector_erase_pck.fl_erase_pck, CMD_WRITE_FPGA_FLASH_ADDR32(1), FLASH_SEC_ERASE_REG, 0); lbp16_send_packet_checked(§or_erase_pck, sizeof(sector_erase_pck)); // packet read for board syncing lbp16_read(CMD_READ_FPGA_FLASH_ADDR32(1), FLASH_ADDR_REG, &ignored, 4); } static int remote_start_programming(llio_t *self, u32 start_address, int fsize) { return start_programming(self, start_address, fsize); } // global functions int remote_write_flash(llio_t *self, char *bitfile_name, u32 start_address, int fix_boot_flag, int sha256_check_flag) { return eeprom_write(self, bitfile_name, start_address, fix_boot_flag, sha256_check_flag); } int remote_verify_flash(llio_t *self, char *bitfile_name, u32 start_address) { return eeprom_verify(self, bitfile_name, start_address); } int remote_backup_flash(llio_t *self, char *bitfile_name) { return flash_backup(self, bitfile_name); } int remote_restore_flash(llio_t *self, char *bitfile_name) { return flash_restore(self, bitfile_name); } void open_spi_access_remote(llio_t *self) { (void)self; eeprom_access.read_page = &read_page; eeprom_access.write_page = &write_page; eeprom_access.erase_sector = &erase_sector; eeprom_access.start_programming = &remote_start_programming; }; void close_spi_access_remote(llio_t *self) { (void)self; }; mesaflash-3.4.6/eeprom_remote.h000066400000000000000000000024171433153454000165100ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __EEPROM_REMOTE_H #define __EEPROM_REMOTE_H #include "hostmot2.h" int remote_write_flash(llio_t *self, char *bitfile_name, u32 start_address, int fix_boot_flag, int sha256_check_flag); int remote_verify_flash(llio_t *self, char *bitfile_name, u32 start_address); int remote_backup_flash(llio_t *self, char *bitfile_name); int remote_restore_flash(llio_t *self, char *bitfile_name); void open_spi_access_remote(llio_t *self); void close_spi_access_remote(llio_t *self); #endif mesaflash-3.4.6/encoder_module.c000066400000000000000000000122461433153454000166260ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #include #include #include #include "types.h" #include "encoder_module.h" #include "hostmot2.h" double seconds_per_tsdiv_clock; static void enable_encoder_pins(hostmot2_t *hm2) { int i; for (i = 0; i < HM2_MAX_PINS; i++) { if (hm2->pins[i].gtag == HM2_GTAG_NONE) { break; } if ((hm2->pins[i].sec_tag == HM2_GTAG_MUXED_ENCODER_SEL)) { hm2_set_pin_source(hm2, i, HM2_PIN_SOURCE_IS_SECONDARY); if (hm2->pins[i].sec_pin & HM2_PIN_OUTPUT) { hm2_set_pin_direction(hm2, i, HM2_PIN_DIR_IS_OUTPUT); } } } } // Return the physical ports to default static void disable_encoder_pins(llio_t *llio) { (void)llio; } int encoder_init(encoder_module_t *enc, board_t *board, int instance, int delay) { hm2_module_desc_t *md = hm2_find_module(&(board->llio.hm2), HM2_GTAG_MUXED_ENCODER); u32 clock, control; if (md == NULL) { printf("No encoder module found.\n"); return -1; } if (instance >= (md->instances - 1)) { printf("encoder instance number to high.\n"); return -1; } memset(enc, 0, sizeof(encoder_module_t)); enc->scale = 1.0; enc->board = board; enc->base_address = md->base_address; enc->instance = instance; enc->instance_stride = (md->strides & 0xF0) == 0 ? board->llio.hm2.idrom.instance_stride0 : board->llio.hm2.idrom.instance_stride1; enable_encoder_pins(&(enc->board->llio.hm2)); if (md->clock_tag == HM2_CLOCK_LOW_TAG) { clock = (enc->board->llio.hm2.idrom.clock_low / 1e6 * delay) - 2; seconds_per_tsdiv_clock = (double)(clock + 2) / (double)enc->board->llio.hm2.idrom.clock_low; } else if (md->clock_tag == HM2_CLOCK_HIGH_TAG) { clock = (enc->board->llio.hm2.idrom.clock_high / 1e6 * delay) - 2; seconds_per_tsdiv_clock = (double)(clock + 2) / (double)enc->board->llio.hm2.idrom.clock_high; } enc->board->llio.write(&(enc->board->llio), enc->base_address + HM2_MOD_OFFS_MUX_ENCODER_TSSDIV, &clock, sizeof(clock)); enc->board->llio.read(&(enc->board->llio), enc->base_address + HM2_MOD_OFFS_MUX_ENCODER_LATCH_CCR + enc->instance*enc->instance_stride, &control, sizeof(control)); control |= HM2_ENCODER_FILTER; control &= ~(HM2_ENCODER_QUADRATURE_ERROR); enc->board->llio.write(&(enc->board->llio), enc->base_address + HM2_MOD_OFFS_MUX_ENCODER_LATCH_CCR + enc->instance*enc->instance_stride, &control, sizeof(control)); return 0; } int encoder_cleanup(encoder_module_t *enc) { disable_encoder_pins(&(enc->board->llio)); return 0; } int encoder_read(encoder_module_t *enc) { board_t *board; u32 tsc, count, control; u16 reg_count, reg_time_stamp; int prev_raw_counts = enc->raw_counts, reg_count_diff, tsc_rollover = 0; int dT_clocks; double dT_seconds; int dS_counts; double dS_meters; if (enc == NULL) { return -1; } board = enc->board; board->llio.read(&(board->llio), enc->base_address + HM2_MOD_OFFS_MUX_ENCODER_TS_COUNT, &tsc, sizeof(tsc)); board->llio.read(&(board->llio), enc->base_address + HM2_MOD_OFFS_MUX_ENCODER_COUNTER + enc->instance*enc->instance_stride, &count, sizeof(count)); board->llio.read(&(board->llio), enc->base_address + HM2_MOD_OFFS_MUX_ENCODER_LATCH_CCR + enc->instance*enc->instance_stride, &control, sizeof(control)); if (enc->scale == 0) { enc->scale = 1.0; } reg_count = count & 0xFFFF; reg_count_diff = (int)reg_count - enc->count; reg_time_stamp = count >> 16; if (reg_count_diff == 0) { enc->velocity = 0; } else { if (reg_count_diff > 32768) reg_count_diff -= 65536; if (reg_count_diff < -32768) reg_count_diff += 65536; enc->raw_counts += reg_count_diff; if (reg_time_stamp < enc->time_stamp) { // tsc rollover! tsc_rollover++; } dT_clocks = (reg_time_stamp - enc->time_stamp) + (tsc_rollover << 16); dT_seconds = (double) dT_clocks * seconds_per_tsdiv_clock; dS_counts = enc->raw_counts - prev_raw_counts; dS_meters = (double) dS_counts / enc->scale; if (dT_clocks > 0) { enc->velocity = dS_meters / dT_seconds; } } enc->position = enc->raw_counts / enc->scale; enc->count = reg_count; enc->time_stamp = reg_time_stamp; enc->global_time_stamp = tsc; return 0; } mesaflash-3.4.6/encoder_module.h000066400000000000000000000025241433153454000166310ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __ENCODER_MODULE_H #define __ENCODER_MODULE_H #include "boards.h" #include "hostmot2.h" typedef struct { u16 count; u16 time_stamp; u16 global_time_stamp; int raw_counts; double position; double velocity; double scale; int quad_error; board_t *board; u16 base_address; int instance; int instance_stride; } encoder_module_t; int encoder_init(encoder_module_t *enc, board_t *board, int instance, int delay); int encoder_cleanup(encoder_module_t *enc); int encoder_read(encoder_module_t *enc); #endif mesaflash-3.4.6/epp_boards.c000066400000000000000000000416071433153454000157630ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #if MESAFLASH_IO #ifdef __linux__ #include #include #include #endif #include #include #include #include #include #include #include #include #include "types.h" #include "common.h" #include "eeprom.h" #include "eeprom_local.h" #include "bitfile.h" #include "epp_boards.h" extern board_t boards[MAX_BOARDS]; extern int boards_count; extern u8 boot_block[BOOT_BLOCK_SIZE]; static u8 file_buffer[SECTOR_SIZE]; static inline u8 epp_read_status(board_t *board) { u8 data = inb(board->base_lo + EPP_STATUS_OFFSET); // printf("read status 0x%02X\n", data); return data; } static inline void epp_write_status(board_t *board, u8 status_byte) { outb(status_byte, board->base_lo + EPP_STATUS_OFFSET); // printf("wrote status 0x%02X\n", status_byte); } static inline void epp_write_control(board_t *board, u8 control_byte) { outb(control_byte, board->base_lo + EPP_CONTROL_OFFSET); // printf("wrote control 0x%02X\n", control_byte); } static inline int epp_check_for_timeout(board_t *board) { return epp_read_status(board) & 0x01; } static int epp_clear_timeout(board_t *board) { u8 status; if (!epp_check_for_timeout(board)) { return 1; } /* To clear timeout some chips require double read */ epp_read_status(board); // read in the actual status register status = epp_read_status(board); epp_write_status(board, status | 0x01); // Some reset by writing 1 epp_write_status(board, status & 0xFE); // Others by writing 0 if (epp_check_for_timeout(board)) { printf("failed to clear EPP Timeout!\n"); return 0; // fail } return 1; // success } inline void epp_addr8(board_t *board, u8 addr) { outb(addr, board->base_lo + EPP_ADDRESS_OFFSET); // printf("selected address 0x%02X\n", addr); } static inline void epp_addr16(board_t *board, u16 addr) { outb((addr & 0x00FF), board->base_lo + EPP_ADDRESS_OFFSET); outb((addr >> 8), board->base_lo + EPP_ADDRESS_OFFSET); // printf("selected address 0x%04X\n", addr); } inline u8 epp_read8(board_t *board) { u8 data = inb(board->base_lo + EPP_DATA_OFFSET); // printf("read data 0x%02X\n", data); return data; } static inline u32 epp_read32(board_t *board) { u32 data; if (board->epp_wide) { data = inl(board->base_lo + EPP_DATA_OFFSET); // printf("read data 0x%08X\n", data); } else { u8 a, b, c, d; a = epp_read8(board); b = epp_read8(board); c = epp_read8(board); d = epp_read8(board); data = a + (b << 8) + (c << 16) + (d << 24); } return data; } inline void epp_write8(board_t *board, u8 data) { outb(data, board->base_lo + EPP_DATA_OFFSET); //printf("wrote data 0x%02X\n", data); } static inline void epp_write32(board_t *board, u32 data) { if (board->epp_wide) { outl(data, board->base_lo + EPP_DATA_OFFSET); // printf("wrote data 0x%08X\n", data); } else { epp_write8(board, (data) & 0xFF); epp_write8(board, (data >> 8) & 0xFF); epp_write8(board, (data >> 16) & 0xFF); epp_write8(board, (data >> 24) & 0xFF); } } int epp_read(llio_t *self, u32 addr, void *buffer, int size) { int bytes_remaining = size; board_t *board = self->board; epp_addr16(board, addr | EPP_ADDR_AUTOINCREMENT); for (; bytes_remaining > 3; bytes_remaining -= 4) { *((u32*)buffer) = epp_read32(board); buffer += 4; } for ( ; bytes_remaining > 0; bytes_remaining --) { *((u8*)buffer) = epp_read8(board); buffer ++; } if (epp_check_for_timeout(board)) { printf("EPP timeout on data cycle of read(addr=0x%04x, size=%d)\n", addr, size); // self->needs_reset = 1; epp_clear_timeout(board); return 0; // fail } return 1; // success } int epp_write(llio_t *self, u32 addr, void *buffer, int size) { int bytes_remaining = size; board_t *board = self->board; epp_addr16(board, addr | EPP_ADDR_AUTOINCREMENT); for (; bytes_remaining > 3; bytes_remaining -= 4) { epp_write32(board, *((u32*)buffer)); buffer += 4; } for ( ; bytes_remaining > 0; bytes_remaining --) { epp_write8(board, *((u8*)buffer)); buffer ++; } if (epp_check_for_timeout(board)) { printf("EPP timeout on data cycle of write(addr=0x%04x, size=%d)\n", addr, size); // self->needs_reset = 1; epp_clear_timeout(board); return 0; } return 1; } int epp_program_fpga(llio_t *self, char *bitfile_name) { board_t *board = self->board; int bindex, bytesread; char part_name[32]; struct stat file_stat; FILE *fp; if (stat(bitfile_name, &file_stat) != 0) { printf("Can't find file %s\n", bitfile_name); return -1; } fp = fopen(bitfile_name, "rb"); if (fp == NULL) { printf("Can't open file %s: %s\n", bitfile_name, strerror(errno)); return -1; } if (print_bitfile_header(fp, (char*) &part_name, board->llio.verbose) == -1) { fclose(fp); return -1; } // // send the firmware // // select the CPLD's data address epp_addr8(board, 0); printf("Programming FPGA...\n"); printf(" |"); fflush(stdout); // program the FPGA while (!feof(fp)) { bytesread = fread(&file_buffer, 1, 8192, fp); bindex = 0; while (bindex < bytesread) { epp_write8(board, bitfile_reverse_bits(file_buffer[bindex])); bindex++; } printf("W"); fflush(stdout); } printf("\n"); fclose(fp); // see if it worked if (epp_check_for_timeout(board)) { printf("EPP Timeout while sending firmware!\n"); return -EIO; } printf("Board FPGA programmed successfully.\n"); return 0; } // return 0 if the board has been reset, -errno if not int epp_reset(llio_t *self) { board_t *board = self->board; u8 byte; // // this resets the FPGA *only* if it's currently configured with the // HostMot2 or GPIO firmware // epp_addr16(board, 0x7F7F); epp_write8(board, 0x5A); epp_addr16(board, 0x7F7F); epp_write8(board, 0x5A); // // this code resets the FPGA *only* if the CPLD is in charge of the // parallel port // // select the control register epp_addr8(board, 1); // bring the Spartan3's PROG_B line low for 1 us (the specs require 300-500 ns or longer) epp_write8(board, 0x00); sleep_ns(1000); // bring the Spartan3's PROG_B line high and wait for 2 ms before sending firmware (required by spec) epp_write8(board, 0x01); sleep_ns(2 * 1000 * 1000); // make sure the FPGA is not asserting its /DONE bit byte = epp_read8(board); if ((byte & 0x01) != 0) { printf("/DONE is not low after CPLD reset!\n"); return -EIO; } return 0; } //////////////////////////////////////////////////////////////////////// int epp_boards_init(board_access_t *access) { (void)access; #ifdef __linux__ if (seteuid(0) != 0) { printf("You need root privileges (or setuid root) to access EPP hardware\n"); return -1; } iopl(3); #endif return 0; } void epp_boards_cleanup(board_access_t *access) { (void)access; } static int epp_board_open(board_t *board) { if (board->mode == BOARD_MODE_CPLD) { u8 byte; epp_addr8(board, 0); byte = epp_read8(board); if (byte & 0x01) { board->llio.fpga_part_number = "3s400tq144"; } else { board->llio.fpga_part_number = "3s200tq144"; } } if (board->flash != BOARD_FLASH_NONE) { eeprom_init(&(board->llio)); board->flash_id = read_flash_id(&(board->llio)); if (board->fallback_support == 1) { eeprom_prepare_boot_block(board->flash_id); board->flash_start_address = eeprom_calc_user_space(board->flash_id); } else { board->flash_start_address = 0; } } return 0; } static int epp_board_close(board_t *board) { if (board->flash != BOARD_FLASH_NONE) { eeprom_cleanup(&(board->llio)); } return 0; } void epp_boards_scan(board_access_t *access) { #ifdef __linux__ board_t *board = &boards[boards_count]; u16 epp_addr = 0, epp_hi_addr = 0; u32 hm2_cookie, eppio_cookie; board_init_struct(board); if (access->address == 0) { access->dev_addr = "0x378"; access->dev_hi_addr = "0x778"; epp_addr = 0x378; epp_hi_addr = 0x778; } else { if (strncmp(access->dev_addr, "0x", 2) == 0) { access->dev_addr[0] = '0'; access->dev_addr[1] = '0'; epp_addr = strtol(access->dev_addr, NULL, 16); } else { epp_addr = strtol(access->dev_addr, NULL, 10); } if (epp_addr == 0) { return; } // Parse the base_hi address. if (access->dev_hi_addr != NULL) { if (strncmp(access->dev_hi_addr, "0x", 2) == 0) { access->dev_hi_addr[0] = '0'; access->dev_hi_addr[1] = '0'; epp_hi_addr = strtol(access->dev_hi_addr, NULL, 16); } else { epp_hi_addr = strtol(access->dev_hi_addr, NULL, 10); } } } if (epp_hi_addr == 0) { epp_hi_addr = epp_addr + 0x400; } board->base_lo = epp_addr; board->base_hi = epp_hi_addr; // set up the parport for EPP if(board->base_hi) { outb(0x94, board->base_hi + ECP_CONTROL_HIGH_OFFSET); // select EPP mode in ECR } // select the device and tell it to make itself ready for io epp_write_control(board, 0x04); // set control lines and input mode epp_clear_timeout(board); board->epp_wide = 1; epp_read(&(board->llio), 0, &eppio_cookie, 4); epp_read(&(board->llio), HM2_COOKIE_REG, &hm2_cookie, 4); // Check for a wide mode failure and re-read if ((hm2_cookie & 0x000000FF) == (HM2_COOKIE & 0x000000FF)) { board->epp_wide = 0; epp_read(&(board->llio), 0, &eppio_cookie, 4); epp_read(&(board->llio), HM2_COOKIE_REG, &hm2_cookie, 4); // printf("epp wide is broken!\n"); } if (hm2_cookie == HM2_COOKIE) { u32 idrom_addr; char board_name[8]; u32 *ptr = (u32 *) &board_name; epp_addr16(board, HM2_IDROM_ADDR | EPP_ADDR_AUTOINCREMENT); idrom_addr = epp_read32(board); epp_addr16(board, (idrom_addr + offsetof(hm2_idrom_desc_t, board_name)) | EPP_ADDR_AUTOINCREMENT); *ptr++ = epp_read32(board); *ptr = epp_read32(board); if (strncmp(board_name, "MESA7I90", 8) == 0) { board->type = BOARD_EPP; board->mode = BOARD_MODE_FPGA; strncpy(board->dev_addr, access->dev_addr, 16); strncpy(board->llio.board_name, "7I90HD", 16); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P1"; board->llio.ioport_connector_name[1] = "P2"; board->llio.ioport_connector_name[2] = "P3"; board->llio.fpga_part_number = "6slx9tqg144"; board->llio.num_leds = 2; board->llio.read = &epp_read; board->llio.write = &epp_write; board->llio.write_flash = &local_write_flash; board->llio.verify_flash = &local_verify_flash; board->open = &epp_board_open; board->close = &epp_board_close; board->print_info = &epp_print_info; board->flash = BOARD_FLASH_HM2; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count++; } else if (strncmp(board_name, "MESA7I43", 8) == 0) { board->type = BOARD_EPP; board->mode = BOARD_MODE_FPGA; strncpy(board->dev_addr, access->dev_addr, 16); strncpy(board->llio.board_name, "7I43", 16); board->llio.num_ioport_connectors = 2; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P4"; board->llio.ioport_connector_name[1] = "P3"; board->llio.num_leds = 2; board->llio.read = &epp_read; board->llio.write = &epp_write; board->llio.program_fpga = &epp_program_fpga; board->llio.reset = &epp_reset; board->open = &epp_board_open; board->close = &epp_board_close; board->print_info = &epp_print_info; board->flash = BOARD_FLASH_HM2; board->llio.verbose = access->verbose; boards_count++; } else if(strncmp(board_name, "MESA7C81", 8) == 0) { board->type = BOARD_EPP; board->mode = BOARD_MODE_FPGA; strcpy(board->dev_addr, access->dev_addr); strcpy(board->llio.board_name, "7C81"); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 19; board->llio.ioport_connector_name[0] = "P1+Serial"; board->llio.ioport_connector_name[1] = "P2+Serial"; board->llio.ioport_connector_name[2] = "P7+Serial"; board->llio.bob_hint[0] = BOB_7C81_0; board->llio.bob_hint[1] = BOB_7C81_1; board->llio.bob_hint[2] = BOB_7C81_2; board->llio.num_leds = 4; board->llio.verbose = access->verbose; board->llio.read = &epp_read; board->llio.write = &epp_write; board->llio.write_flash = &local_write_flash; board->llio.verify_flash = &local_verify_flash; board->llio.reset = &epp_reset; board->llio.fpga_part_number = "6slx9tqg144"; board->open = &epp_board_open; board->close = &epp_board_close; board->print_info = &epp_print_info; board->flash = BOARD_FLASH_HM2; board->llio.verbose = access->verbose; board->fallback_support = 1; boards_count++; } } else if (eppio_cookie == HM2_COOKIE) { board->type = BOARD_EPP; board->mode = BOARD_MODE_FPGA; strncpy(board->dev_addr, access->dev_addr, 16); strncpy(board->llio.board_name, "7I43", 16); board->llio.num_ioport_connectors = 2; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P4"; board->llio.ioport_connector_name[1] = "P3"; board->llio.num_leds = 2; board->llio.read = &epp_read; board->llio.write = &epp_write; board->llio.program_fpga = &epp_program_fpga; board->llio.write_flash = &local_write_flash; board->llio.verify_flash = &local_verify_flash; board->open = &epp_board_open; board->close = &epp_board_close; board->print_info = &epp_print_info; board->flash = BOARD_FLASH_EPP; board->llio.verbose = access->verbose; boards_count++; } else { board->type = BOARD_EPP; board->mode = BOARD_MODE_CPLD; strncpy(board->dev_addr, access->dev_addr, 16); strncpy(board->llio.board_name, "7I43", 16); board->llio.num_ioport_connectors = 2; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P4"; board->llio.ioport_connector_name[1] = "P3"; board->llio.num_leds = 2; board->llio.program_fpga = &epp_program_fpga; board->llio.reset = &epp_reset; board->open = &epp_board_open; board->close = &epp_board_close; board->print_info = &epp_print_info; board->llio.verbose = access->verbose; boards_count++; } #endif } void epp_print_info(board_t *board) { printf("\nEPP device %s at 0x%04X:0x%04X\n", board->llio.board_name, board->base_lo, board->base_hi); if (board->llio.verbose == 0) { return; } printf("Communication:\n"); if (board->mode == BOARD_MODE_CPLD) { printf(" controlled by CPLD\n"); } else if (board->mode == BOARD_MODE_FPGA) { printf(" controlled by FPGA\n"); } show_board_info(board); } #endif mesaflash-3.4.6/epp_boards.h000066400000000000000000000026501433153454000157630ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __EPP_BOARDS_H #define __EPP_BOARDS_H #include "boards.h" #define EPP_STATUS_OFFSET 1 #define EPP_CONTROL_OFFSET 2 #define EPP_ADDRESS_OFFSET 3 #define EPP_DATA_OFFSET 4 #define ECP_CONFIG_A_HIGH_OFFSET 0 #define ECP_CONFIG_B_HIGH_OFFSET 1 #define ECP_CONTROL_HIGH_OFFSET 2 #define EPP_ADDR_AUTOINCREMENT 0x8000 void epp_addr8(board_t *board, u8 addr); u8 epp_read8(board_t *board); void epp_write8(board_t *board, u8 data); int epp_boards_init(board_access_t *access); void epp_boards_cleanup(board_access_t *access); void epp_boards_scan(board_access_t *access); void epp_print_info(board_t *board); #endif mesaflash-3.4.6/eth_boards.c000066400000000000000000001022761433153454000157570ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifdef __linux__ #include #include #include #include // struct ip and IP_MAXPACKET (which is 65535) #include // struct udphdr #elif _WIN32 #include #include #endif #include #include #include #include #include #include #include #include #include "types.h" #include "common.h" #include "bitfile.h" #include "eth_boards.h" #include "eeprom_remote.h" #include "lbp16.h" #include "eeprom.h" extern board_t boards[MAX_BOARDS]; extern int boards_count; #ifdef __linux__ int sd; socklen_t len; #elif _WIN32 SOCKET sd; int len; #endif struct sockaddr_in dst_addr, src_addr; // eth access functions inline int eth_send_packet(void *packet, int size) { return sendto(sd, (char*) packet, size, 0, (struct sockaddr *) &dst_addr, sizeof(dst_addr)); } inline int eth_recv_packet(void *buffer, int size) { return recvfrom(sd, (char*) buffer, size, 0, (struct sockaddr *) &src_addr, &len); } static void eth_socket_nonblocking() { #ifdef __linux__ int val = fcntl(sd, F_GETFL); val = val | O_NONBLOCK; fcntl(sd, F_SETFL, val); #elif _WIN32 u_long iMode = 1; ioctlsocket(sd, FIONBIO, &iMode); #endif } static void eth_socket_blocking() { #ifdef __linux__ int val = fcntl(sd, F_GETFL); val = val & ~O_NONBLOCK; fcntl(sd, F_SETFL, val); #elif _WIN32 u_long iMode = 0; ioctlsocket(sd, FIONBIO, &iMode); #endif } void eth_socket_set_dest_ip(char *addr_name) { dst_addr.sin_addr.s_addr = inet_addr(addr_name); } static char *eth_socket_get_src_ip() { return inet_ntoa(src_addr.sin_addr); } static int eth_read(llio_t *self, u32 addr, void *buffer, int size) { (void)self; if ((size/4) > LBP16_MAX_PACKET_DATA_SIZE) { printf("ERROR: LBP16: Requested %d units to read, but protocol supports up to %d units to be read per packet\n", size/4, LBP16_MAX_PACKET_DATA_SIZE); return -1; } return lbp16_read(CMD_READ_HOSTMOT2_ADDR32_INCR(size/4), addr, buffer, size); } static int eth_write(llio_t *self, u32 addr, void *buffer, int size) { (void)self; if ((size/4) > LBP16_MAX_PACKET_DATA_SIZE) { printf("ERROR: LBP16: Requested %d units to write, but protocol supports up to %d units to be write per packet\n", size/4, LBP16_MAX_PACKET_DATA_SIZE); return -1; } return lbp16_write(CMD_WRITE_HOSTMOT2_ADDR32_INCR(size/4), addr, buffer, size); } static int eth_board_open(board_t *board) { eth_socket_set_dest_ip(board->dev_addr); eeprom_init(&(board->llio)); lbp16_read(CMD_READ_FLASH_IDROM, FLASH_ID_REG, &(board->flash_id), 4); if (board->fallback_support == 1) { eeprom_prepare_boot_block(board->flash_id); board->flash_start_address = eeprom_calc_user_space(board->flash_id); } else { board->flash_start_address = 0; } return 0; } static int eth_board_close(board_t *board) { (void)board; return 0; } // Look for an Ethernet board. // Returns 0 if it finds one, -1 if it doesn't find one. static int eth_scan_one_addr(board_access_t *access) { lbp16_cmd_addr packet, packet2; int ret = 0; u32 cookie; LBP16_INIT_PACKET4(packet, CMD_READ_HM2_COOKIE, HM2_COOKIE_REG); lbp16_send_packet_checked(&packet, sizeof(packet)); sleep_ns(2*1000*1000); size_t recv = lbp16_recv_packet(&cookie, sizeof(cookie)); if ((recv > 0) && (cookie == HM2_COOKIE)) { char buff[16]; board_t *board = &boards[boards_count]; board_init_struct(board); eth_socket_blocking(); LBP16_INIT_PACKET4(packet2, CMD_READ_BOARD_INFO_ADDR16_INCR(8), 0); memset(buff, 0, sizeof(buff)); lbp16_send_packet_checked(&packet2, sizeof(packet2)); lbp16_recv_packet_checked(&buff, sizeof(buff)); // Default fpga type is Xilinx board->fpga_type = FPGA_TYPE_XILINX; if (strncmp(buff, "7I80DB-16", 16) == 0) { board->type = BOARD_ETH; strncpy(board->dev_addr, eth_socket_get_src_ip(), 16); strncpy(board->llio.board_name, buff, 16); board->llio.num_ioport_connectors = 4; board->llio.pins_per_connector = 17; board->llio.ioport_connector_name[0] = "J2"; board->llio.ioport_connector_name[1] = "J3"; board->llio.ioport_connector_name[2] = "J4"; board->llio.ioport_connector_name[3] = "J5"; board->llio.fpga_part_number = "6slx16ftg256"; board->llio.num_leds = 4; board->llio.read = ð_read; board->llio.write = ð_write; board->llio.write_flash = &remote_write_flash; board->llio.verify_flash = &remote_verify_flash; board->llio.backup_flash = &remote_backup_flash; board->llio.restore_flash = &remote_restore_flash; board->llio.reset = &lbp16_board_reset; board->llio.reload = &lbp16_board_reload; board->open = ð_board_open; board->close = ð_board_close; board->print_info = ð_print_info; board->flash = BOARD_FLASH_REMOTE; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count ++; } else if (strncmp(buff, "7I80DB-25", 16) == 0) { board->type = BOARD_ETH; strncpy(board->dev_addr, eth_socket_get_src_ip(), 16); strncpy(board->llio.board_name, buff, 16); board->llio.num_ioport_connectors = 4; board->llio.pins_per_connector = 17; board->llio.ioport_connector_name[0] = "J2"; board->llio.ioport_connector_name[1] = "J3"; board->llio.ioport_connector_name[2] = "J4"; board->llio.ioport_connector_name[3] = "J5"; board->llio.fpga_part_number = "6slx25ftg256"; board->llio.num_leds = 4; board->llio.read = ð_read; board->llio.write = ð_write; board->llio.write_flash = &remote_write_flash; board->llio.verify_flash = &remote_verify_flash; board->llio.backup_flash = &remote_backup_flash; board->llio.restore_flash = &remote_restore_flash; board->llio.reset = &lbp16_board_reset; board->llio.reload = &lbp16_board_reload; board->open = ð_board_open; board->close = ð_board_close; board->print_info = ð_print_info; board->flash = BOARD_FLASH_REMOTE; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count ++; } else if (strncmp(buff, "7I80HD-16", 16) == 0) { board->type = BOARD_ETH; strncpy(board->dev_addr, eth_socket_get_src_ip(), 16); strncpy(board->llio.board_name, buff, 16); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P1"; board->llio.ioport_connector_name[1] = "P2"; board->llio.ioport_connector_name[2] = "P3"; board->llio.fpga_part_number = "6slx16ftg256"; board->llio.num_leds = 4; board->llio.read = ð_read; board->llio.write = ð_write; board->llio.write_flash = &remote_write_flash; board->llio.verify_flash = &remote_verify_flash; board->llio.backup_flash = &remote_backup_flash; board->llio.restore_flash = &remote_restore_flash; board->llio.reset = &lbp16_board_reset; board->llio.reload = &lbp16_board_reload; board->open = ð_board_open; board->close = ð_board_close; board->print_info = ð_print_info; board->flash = BOARD_FLASH_REMOTE; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count ++; } else if (strncmp(buff, "7I80HD-25", 16) == 0) { board->type = BOARD_ETH; strncpy(board->dev_addr, eth_socket_get_src_ip(), 16); strncpy(board->llio.board_name, buff, 16); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P1"; board->llio.ioport_connector_name[1] = "P2"; board->llio.ioport_connector_name[2] = "P3"; board->llio.fpga_part_number = "6slx25ftg256"; board->llio.num_leds = 4; board->llio.read = ð_read; board->llio.write = ð_write; board->llio.write_flash = &remote_write_flash; board->llio.verify_flash = &remote_verify_flash; board->llio.backup_flash = &remote_backup_flash; board->llio.restore_flash = &remote_restore_flash; board->llio.reset = &lbp16_board_reset; board->llio.reload = &lbp16_board_reload; board->open = ð_board_open; board->close = ð_board_close; board->print_info = ð_print_info; board->flash = BOARD_FLASH_REMOTE; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count ++; } else if (strncmp(buff, "7I76E-16", 16) == 0) { board->type = BOARD_ETH; strncpy(board->dev_addr, eth_socket_get_src_ip(), 16); // use only the first 5 letters on the 7I76E-16 for the device name compare strncpy(board->llio.board_name, buff, 5); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 17; board->llio.ioport_connector_name[0] = "on-card"; board->llio.ioport_connector_name[1] = "P1"; board->llio.ioport_connector_name[2] = "P2"; board->llio.bob_hint[0] = BOB_7I76; board->llio.fpga_part_number = "6slx16ftg256"; board->llio.num_leds = 4; board->llio.read = ð_read; board->llio.write = ð_write; board->llio.write_flash = &remote_write_flash; board->llio.verify_flash = &remote_verify_flash; board->llio.backup_flash = &remote_backup_flash; board->llio.restore_flash = &remote_restore_flash; board->llio.reset = &lbp16_board_reset; board->llio.reload = &lbp16_board_reload; board->open = ð_board_open; board->close = ð_board_close; board->print_info = ð_print_info; board->flash = BOARD_FLASH_REMOTE; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count ++; } else if (strncmp(buff, "7I92", 16) == 0) { board->type = BOARD_ETH; strncpy(board->dev_addr, eth_socket_get_src_ip(), 16); strncpy(board->llio.board_name, buff, 16); board->llio.num_ioport_connectors = 2; board->llio.pins_per_connector = 17; board->llio.ioport_connector_name[0] = "P2"; board->llio.ioport_connector_name[1] = "P1"; board->llio.fpga_part_number = "6slx9tqg144"; board->llio.num_leds = 4; board->llio.read = ð_read; board->llio.write = ð_write; board->llio.write_flash = &remote_write_flash; board->llio.verify_flash = &remote_verify_flash; board->llio.backup_flash = &remote_backup_flash; board->llio.restore_flash = &remote_restore_flash; board->llio.reset = &lbp16_board_reset; board->llio.reload = &lbp16_board_reload; board->open = ð_board_open; board->close = ð_board_close; board->print_info = ð_print_info; board->flash = BOARD_FLASH_REMOTE; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count ++; } else if (strncmp(buff, "7I92T", 16) == 0) { board->type = BOARD_ETH; board->fpga_type = FPGA_TYPE_EFINIX; strncpy(board->dev_addr, eth_socket_get_src_ip(), 16); strncpy(board->llio.board_name, buff, 16); board->llio.num_ioport_connectors = 2; board->llio.pins_per_connector = 17; board->llio.ioport_connector_name[0] = "P2"; board->llio.ioport_connector_name[1] = "P1"; board->llio.fpga_part_number = "T20F256"; board->llio.num_leds = 4; board->llio.read = ð_read; board->llio.write = ð_write; board->llio.write_flash = &remote_write_flash; board->llio.verify_flash = &remote_verify_flash; board->llio.backup_flash = &remote_backup_flash; board->llio.restore_flash = &remote_restore_flash; board->llio.reset = &lbp16_board_reset; board->llio.reload = &lbp16_board_reload; board->open = ð_board_open; board->close = ð_board_close; board->print_info = ð_print_info; board->flash = BOARD_FLASH_REMOTE; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count ++; } else if (strncmp(buff, "7I93", 16) == 0) { board->type = BOARD_ETH; strncpy(board->dev_addr, eth_socket_get_src_ip(), 16); strncpy(board->llio.board_name, buff, 16); board->llio.num_ioport_connectors = 2; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P2"; board->llio.ioport_connector_name[1] = "P1"; board->llio.fpga_part_number = "6slx9tqg144"; board->llio.num_leds = 4; board->llio.read = ð_read; board->llio.write = ð_write; board->llio.write_flash = &remote_write_flash; board->llio.verify_flash = &remote_verify_flash; board->llio.backup_flash = &remote_backup_flash; board->llio.restore_flash = &remote_restore_flash; board->llio.reset = &lbp16_board_reset; board->llio.reload = &lbp16_board_reload; board->open = ð_board_open; board->close = ð_board_close; board->print_info = ð_print_info; board->flash = BOARD_FLASH_REMOTE; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count ++; } else if (strncmp(buff, "7I94", 16) == 0) { board->type = BOARD_ETH; strncpy(board->dev_addr, eth_socket_get_src_ip(), 16); strncpy(board->llio.board_name, buff, 16); board->llio.num_ioport_connectors = 2; board->llio.pins_per_connector = 21; board->llio.ioport_connector_name[0] = "Expansion+Serial 0..1"; board->llio.ioport_connector_name[1] = "Serial 1..7"; board->llio.bob_hint[0] = BOB_7I94_0; board->llio.bob_hint[1] = BOB_7I94_1; board->llio.fpga_part_number = "6slx9tqg144"; board->llio.num_leds = 4; board->llio.read = ð_read; board->llio.write = ð_write; board->llio.write_flash = &remote_write_flash; board->llio.verify_flash = &remote_verify_flash; board->llio.backup_flash = &remote_backup_flash; board->llio.restore_flash = &remote_restore_flash; board->llio.reset = &lbp16_board_reset; board->llio.reload = &lbp16_board_reload; board->open = ð_board_open; board->close = ð_board_close; board->print_info = ð_print_info; board->flash = BOARD_FLASH_REMOTE; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count ++; } else if (strncmp(buff, "7I95", 16) == 0) { board->type = BOARD_ETH; strncpy(board->dev_addr, eth_socket_get_src_ip(), 16); strncpy(board->llio.board_name, buff, 16); board->llio.num_ioport_connectors = 2; board->llio.pins_per_connector = 29; board->llio.ioport_connector_name[0] = "Step/DIR+Serial+Encoders"; board->llio.ioport_connector_name[1] = "I/O+Expansion"; board->llio.bob_hint[0] = BOB_7I95_0; board->llio.bob_hint[1] = BOB_7I95_1; board->llio.fpga_part_number = "6slx9tqg144"; board->llio.num_leds = 4; board->llio.read = ð_read; board->llio.write = ð_write; board->llio.write_flash = &remote_write_flash; board->llio.verify_flash = &remote_verify_flash; board->llio.backup_flash = &remote_backup_flash; board->llio.restore_flash = &remote_restore_flash; board->llio.reset = &lbp16_board_reset; board->llio.reload = &lbp16_board_reload; board->open = ð_board_open; board->close = ð_board_close; board->print_info = ð_print_info; board->flash = BOARD_FLASH_REMOTE; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count ++; } else if (strncmp(buff, "7I96", 16) == 0) { board->type = BOARD_ETH; strncpy(board->dev_addr, eth_socket_get_src_ip(), 16); strncpy(board->llio.board_name, buff, 16); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 17; board->llio.ioport_connector_name[0] = "TB3"; board->llio.ioport_connector_name[1] = "TB1/TB2"; board->llio.ioport_connector_name[2] = "P1"; board->llio.bob_hint[0] = BOB_7I96_0; board->llio.bob_hint[1] = BOB_7I96_1; board->llio.bob_hint[2] = BOB_7I96_2; board->llio.fpga_part_number = "6slx9tqg144"; board->llio.num_leds = 4; board->llio.read = ð_read; board->llio.write = ð_write; board->llio.write_flash = &remote_write_flash; board->llio.verify_flash = &remote_verify_flash; board->llio.backup_flash = &remote_backup_flash; board->llio.restore_flash = &remote_restore_flash; board->llio.reset = &lbp16_board_reset; board->llio.reload = &lbp16_board_reload; board->open = ð_board_open; board->close = ð_board_close; board->print_info = ð_print_info; board->flash = BOARD_FLASH_REMOTE; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count ++; } else if (strncmp(buff, "7I96S", 16) == 0) { board->type = BOARD_ETH; board->fpga_type = FPGA_TYPE_EFINIX; strncpy(board->dev_addr, eth_socket_get_src_ip(), 16); strncpy(board->llio.board_name, buff, 16); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 17; board->llio.ioport_connector_name[0] = "TB3"; board->llio.ioport_connector_name[1] = "TB1/TB2"; board->llio.ioport_connector_name[2] = "P1"; board->llio.bob_hint[0] = BOB_7I96_0; board->llio.bob_hint[1] = BOB_7I96_1; board->llio.bob_hint[2] = BOB_7I96_2; board->llio.fpga_part_number = "T20F256"; board->llio.num_leds = 4; board->llio.read = ð_read; board->llio.write = ð_write; board->llio.write_flash = &remote_write_flash; board->llio.verify_flash = &remote_verify_flash; board->llio.backup_flash = &remote_backup_flash; board->llio.restore_flash = &remote_restore_flash; board->llio.reset = &lbp16_board_reset; board->llio.reload = &lbp16_board_reload; board->open = ð_board_open; board->close = ð_board_close; board->print_info = ð_print_info; board->flash = BOARD_FLASH_REMOTE; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count ++; } else if (strncmp(buff, "7I97", 16) == 0) { board->type = BOARD_ETH; strncpy(board->dev_addr, eth_socket_get_src_ip(), 16); strncpy(board->llio.board_name, buff, 16); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 17; board->llio.ioport_connector_name[0] = "TB1/TB2/TB3"; board->llio.ioport_connector_name[1] = "TB4/TB5"; board->llio.ioport_connector_name[2] = "P1"; board->llio.bob_hint[0] = BOB_7I97_0; board->llio.bob_hint[1] = BOB_7I97_1; board->llio.bob_hint[2] = BOB_7I97_2; board->llio.fpga_part_number = "6slx9tqg144"; board->llio.num_leds = 4; board->llio.read = ð_read; board->llio.write = ð_write; board->llio.write_flash = &remote_write_flash; board->llio.verify_flash = &remote_verify_flash; board->llio.backup_flash = &remote_backup_flash; board->llio.restore_flash = &remote_restore_flash; board->llio.reset = &lbp16_board_reset; board->llio.reload = &lbp16_board_reload; board->open = ð_board_open; board->close = ð_board_close; board->print_info = ð_print_info; board->flash = BOARD_FLASH_REMOTE; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count ++; } else if (strncmp(buff, "7I98", 16) == 0) { board->type = BOARD_ETH; strncpy(board->dev_addr, eth_socket_get_src_ip(), 16); strncpy(board->llio.board_name, buff, 16); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 17; board->llio.ioport_connector_name[0] = "P1"; board->llio.ioport_connector_name[1] = "P2"; board->llio.ioport_connector_name[2] = "P3"; board->llio.fpga_part_number = "6slx9tqg144"; board->llio.num_leds = 4; board->llio.read = ð_read; board->llio.write = ð_write; board->llio.write_flash = &remote_write_flash; board->llio.verify_flash = &remote_verify_flash; board->llio.backup_flash = &remote_backup_flash; board->llio.restore_flash = &remote_restore_flash; board->llio.reset = &lbp16_board_reset; board->llio.reload = &lbp16_board_reload; board->open = ð_board_open; board->close = ð_board_close; board->print_info = ð_print_info; board->flash = BOARD_FLASH_REMOTE; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count ++; } else { printf("Unsupported ethernet device %s at %s\n", buff, eth_socket_get_src_ip()); ret = -1; } eth_socket_nonblocking(); } else { ret = -1; } return ret; } // public functions int eth_boards_init(board_access_t *access) { (void)access; // open socket #ifdef __linux__ sd = socket (PF_INET, SOCK_DGRAM, 0); #elif _WIN32 int iResult; WSADATA wsaData; u_long iMode = 1; // block mode in windows iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { printf("WSAStartup failed: %d\n", iResult); return; } sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sd == 0) { printf("Can't open socket: %d %d\n", sd, errno); return; } #endif src_addr.sin_family = AF_INET; dst_addr.sin_family = AF_INET; src_addr.sin_port = htons(LBP16_UDP_PORT); dst_addr.sin_port = htons(LBP16_UDP_PORT); len = sizeof(src_addr); lbp16_init(BOARD_ETH); return 0; } void eth_boards_cleanup(board_access_t *access) { (void)access; int i; for (i = 0; i < boards_count; i++) { board_t *board = &boards[i]; eeprom_cleanup(&(board->llio)); } close(sd); } // Scan for Ethernet board(s). // Returns 0 if it found one, -1 on failure. int eth_boards_scan(board_access_t *access) { char addr[16]; int i; char *ptr; int r = 0; if (access->address == 0) { access->dev_addr = LBP16_HW_IP; } #ifdef __linux__ if (inet_pton(AF_INET, access->dev_addr, addr) != 1) { #elif _WIN32 struct sockaddr ss; int size; if (WSAStringToAddress(access->dev_addr, AF_INET, NULL, (struct sockaddr *)&ss, &size) != 0) { #endif return -1; }; eth_socket_nonblocking(); if (access->address == 1) { eth_socket_set_dest_ip(access->dev_addr); r = eth_scan_one_addr(access); } else { strncpy(addr, access->dev_addr, 16); ptr = strrchr(addr, '.'); *ptr = '\0'; // We're scanning for boards, return Success (0) if we find at // least one, return Fail (-1) if we don't find any. r = -1; for (i = 1; i < 255; i++) { char addr_name[32]; int this_r; sprintf(addr_name, "%s.%d", addr, i); eth_socket_set_dest_ip(addr_name); this_r = eth_scan_one_addr(access); if (this_r == 0) { r = 0; } } } eth_socket_blocking(); return r; } void eth_print_info(board_t *board) { lbp16_cmd_addr packet; int i, j; u32 flash_id; char *mem_types[16] = {NULL, "registers", "memory", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "EEPROM", "flash"}; char *mem_writeable[2] = {"RO", "RW"}; char *acc_types[4] = {"8-bit", "16-bit", "32-bit", "64-bit"}; char *led_debug_types[2] = {"Hostmot2", "eth debug"}; char *boot_jumpers_types[4] = {"fixed "LBP16_HW_IP, "fixed from EEPROM", "from BOOTP", "INVALID"}; lbp_mem_info_area mem_area; lbp_eth_eeprom_area eth_area; lbp_timers_area timers_area; lbp_status_area stat_area; lbp_info_area info_area; lbp16_cmd_addr cmds[LBP16_MEM_SPACE_COUNT]; printf("\nETH device %s at ip=%s\n", board->llio.board_name, eth_socket_get_src_ip()); if (board->llio.verbose == 0) return; LBP16_INIT_PACKET4(cmds[0], CMD_READ_AREA_INFO_ADDR16_INCR(LBP16_SPACE_HM2, sizeof(mem_area)/2), 0); LBP16_INIT_PACKET4(cmds[1], CMD_READ_AREA_INFO_ADDR16_INCR(LBP16_SPACE_ETH_CHIP, sizeof(mem_area)/2), 0); LBP16_INIT_PACKET4(cmds[2], CMD_READ_AREA_INFO_ADDR16_INCR(LBP16_SPACE_ETH_EEPROM, sizeof(mem_area)/2), 0); LBP16_INIT_PACKET4(cmds[3], CMD_READ_AREA_INFO_ADDR16_INCR(LBP16_SPACE_FPGA_FLASH, sizeof(mem_area)/2), 0); LBP16_INIT_PACKET4(cmds[4], 0, 0); LBP16_INIT_PACKET4(cmds[5], 0, 0); LBP16_INIT_PACKET4(cmds[6], CMD_READ_AREA_INFO_ADDR16_INCR(LBP16_SPACE_COMM_CTRL, sizeof(mem_area)/2), 0); LBP16_INIT_PACKET4(cmds[7], CMD_READ_AREA_INFO_ADDR16_INCR(LBP16_SPACE_BOARD_INFO, sizeof(mem_area)/2), 0); LBP16_INIT_PACKET4(packet, CMD_READ_ETH_EEPROM_ADDR16_INCR(sizeof(eth_area)/2), 0); memset(ð_area, 0, sizeof(eth_area)); lbp16_send_packet_checked(&packet, sizeof(packet)); lbp16_recv_packet_checked(ð_area, sizeof(eth_area)); LBP16_INIT_PACKET4(packet, CMD_READ_COMM_CTRL_ADDR16_INCR(sizeof(stat_area)/2), 0); memset(&stat_area, 0, sizeof(stat_area)); lbp16_send_packet_checked(&packet, sizeof(packet)); lbp16_recv_packet_checked(&stat_area, sizeof(stat_area)); LBP16_INIT_PACKET4(packet, CMD_READ_BOARD_INFO_ADDR16_INCR(sizeof(info_area)/2), 0); memset(&info_area, 0, sizeof(info_area)); lbp16_send_packet_checked(&packet, sizeof(packet)); lbp16_recv_packet_checked(&info_area, sizeof(info_area)); if (info_area.LBP16_version >= 3) { LBP16_INIT_PACKET4(cmds[4], CMD_READ_AREA_INFO_ADDR16_INCR(LBP16_SPACE_TIMER, sizeof(mem_area)/2), 0); LBP16_INIT_PACKET4(packet, CMD_READ_TIMER_ADDR16_INCR(sizeof(timers_area)/2), 0); memset(&timers_area, 0, sizeof(timers_area)); lbp16_send_packet_checked(&packet, sizeof(packet)); lbp16_recv_packet_checked(&timers_area, sizeof(timers_area)); } printf("Communication:\n"); printf(" transport layer: ethernet IPv4 UDP\n"); printf(" ip address: %s\n", board->dev_addr); printf(" mac address: %02X:%02X:%02X:%02X:%02X:%02X\n", HI_BYTE(eth_area.mac_addr_hi), LO_BYTE(eth_area.mac_addr_hi), HI_BYTE(eth_area.mac_addr_mid), LO_BYTE(eth_area.mac_addr_mid), HI_BYTE(eth_area.mac_addr_lo), LO_BYTE(eth_area.mac_addr_lo)); printf(" protocol: LBP16 version %d\n", info_area.LBP16_version); show_board_info(board); printf("Board firmware info:\n"); printf(" memory spaces:\n"); for (i = 0; i < LBP16_MEM_SPACE_COUNT; i++) { u32 size; if ((cmds[i].cmd_lo == 0) && (cmds[i].cmd_hi == 0)) continue; memset(&mem_area, 0, sizeof(mem_area)); lbp16_send_packet_checked(&cmds[i], sizeof(cmds[i])); lbp16_recv_packet_checked(&mem_area, sizeof (mem_area)); printf(" %d: %.*s (%s, %s", i, (int)sizeof(mem_area.name), mem_area.name, mem_types[(mem_area.size >> 8) & 0x7F], mem_writeable[(mem_area.size & 0x8000) >> 15]); for (j = 0; j < 4; j++) { if ((mem_area.size & 0xFF) & 1 << j) printf(", %s)", acc_types[j]); } size = pow(2, mem_area.range & 0x3F); show_formatted_size(size); if (((mem_area.size >> 8) & 0x7F) >= 0xE) printf(", page size: %u, erase size: %u", (unsigned int) pow(2, (mem_area.range >> 6) & 0x1F), (unsigned int) pow(2, (mem_area.range >> 11) & 0x1F)); printf("\n"); } printf(" [space 0] HostMot2\n"); printf(" [space 2] Ethernet eeprom:\n"); printf(" mac address: %02X:%02X:%02X:%02X:%02X:%02X\n", HI_BYTE(eth_area.mac_addr_hi), LO_BYTE(eth_area.mac_addr_hi), HI_BYTE(eth_area.mac_addr_mid), LO_BYTE(eth_area.mac_addr_mid), HI_BYTE(eth_area.mac_addr_lo), LO_BYTE(eth_area.mac_addr_lo)); printf(" ip address: %u.%u.%u.%u\n", HI_BYTE(eth_area.ip_addr_hi), LO_BYTE(eth_area.ip_addr_hi), HI_BYTE(eth_area.ip_addr_lo), LO_BYTE(eth_area.ip_addr_lo)); printf(" board name: %.*s\n", (int)sizeof(eth_area.name), eth_area.name); printf(" user leds: %s\n", led_debug_types[eth_area.led_debug & 0x1]); printf(" [space 3] FPGA flash eeprom:\n"); lbp16_read(CMD_READ_FLASH_IDROM, FLASH_ID_REG, &flash_id, 4); printf(" flash size: %s (id: 0x%02X)\n", eeprom_get_flash_type(flash_id), flash_id); if (info_area.LBP16_version >= 3) { printf(" [space 4] timers:\n"); printf(" uSTimeStampReg: 0x%04X\n", timers_area.uSTimeStampReg); printf(" WaituSReg: 0x%04X\n", timers_area.WaituSReg); printf(" HM2Timeout: 0x%04X\n", timers_area.HM2Timeout); } printf(" [space 6] LBP16 control/status:\n"); printf(" packets received: all %d, UDP %d, bad %d\n", stat_area.RXPacketCount, stat_area.RXGoodCount, stat_area.RXBadCount); printf(" packets sent: all %d, UDP %d, bad %d\n", stat_area.TXPacketCount, stat_area.TXGoodCount, stat_area.TXBadCount); printf(" parse errors: %d, mem errors %d, write errors %d\n", stat_area.LBPParseErrors, stat_area.LBPMemErrors, stat_area.LBPWriteErrors); printf(" error flags: 0x%04X\n", stat_area.ErrorReg); printf(" debug LED ptr: 0x%04X\n", stat_area.DebugLEDPtr); printf(" scratch: 0x%04X\n", stat_area.Scratch); printf(" [space 7] LBP16 info:\n"); printf(" board name: %.*s\n", (int)sizeof(info_area.name), info_area.name); printf(" LBP16 protocol version %d\n", info_area.LBP16_version); printf(" board firmware version %d\n", info_area.firmware_version); printf(" IP address jumpers at boot: %s\n", boot_jumpers_types[info_area.jumpers]); } int eth_set_remote_ip(char *ip_addr) { lbp16_write_ip_addr_packets write_ip_pck; u32 addr; #ifdef __linux__ if (inet_pton(AF_INET, ip_addr, &addr) != 1) { #elif _WIN32 struct sockaddr ss; int size; if (WSAStringToAddress(ip_addr, AF_INET, NULL, (struct sockaddr *)&addr, &size) != 0) { #endif printf("Error: invalid format of IP address\n"); return -EINVAL; } addr = htonl(addr); LBP16_INIT_PACKET6(write_ip_pck.write_ena_pck, CMD_WRITE_COMM_CTRL_ADDR16(1), COMM_CTRL_WRITE_ENA_REG, 0x5A02); LBP16_INIT_PACKET8(write_ip_pck.eth_write_ip_pck, CMD_WRITE_ETH_EEPROM_ADDR16_INCR(2), ETH_EEPROM_IP_REG, addr); sendto (sd, (char*) &write_ip_pck, sizeof(write_ip_pck), 0, (struct sockaddr *) &dst_addr, sizeof(dst_addr)); return 0; } mesaflash-3.4.6/eth_boards.h000066400000000000000000000025071433153454000157600ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __ETH_BOARDS_H #define __ETH_BOARDS_H #include "boards.h" int eth_boards_init(board_access_t *access); void eth_boards_cleanup(board_access_t *access); int eth_boards_scan(board_access_t *access); void eth_print_info(board_t *board); int eth_send_packet(void *packet, int size); int eth_recv_packet(void *buffer, int size); int lbp16_read(u16 cmd, u32 addr, void *buffer, int size); int lbp16_write(u16 cmd, u32 addr, void *buffer, int size); void eth_socket_set_dest_ip(char *addr_name); int eth_set_remote_ip(char *ip_addr); #endif mesaflash-3.4.6/examples/000077500000000000000000000000001433153454000153075ustar00rootroot00000000000000mesaflash-3.4.6/examples/pci_analog_write.c000066400000000000000000000132211433153454000207600ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #include #include #include #include #include #include #include #include "../anyio.h" #include "../sserial_module.h" #ifdef __linux__ #include #include #elif _WIN32 #include "libpci/pci.h" #endif static int device_flag; static int instance_flag; static int instance = 0; static int delay_flag; static int delay = 50; static int verbose_flag; static board_access_t board_access; static struct option long_options[] = { {"device", required_argument, 0, 'd'}, {"instance", required_argument, 0, 'i'}, {"delay", required_argument, 0, 't'}, {"verbose", no_argument, &verbose_flag, 1}, {0, 0, 0, 0} }; void print_short_usage() { printf("Example program for writing analog output on pci boards\n"); printf("Syntax:\n"); printf(" pci_analog_write --device str [--instance i] [--delay d] [--verbose]\n"); printf(" --device select active device name\n"); printf(" --instance select analog output instance 'i' for reading, default 0\n"); printf(" --delay how long to wait between analog output writes in miliseconds, default 50\n"); printf(" --verbose printf additional info during execution\n"); } int process_cmd_line(int argc, char *argv[]) { int c; while (1) { /* getopt_long stores the option index here. */ int option_index = 0; c = getopt_long(argc, argv, "", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) break; switch (c) { case 0: { /* If this option set a flag, do nothing else now. */ if (long_options[option_index].flag != 0) break; printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); } break; case 'd': { int i; if (device_flag > 0) { printf("Error: multiply --device option\n"); exit(-1); } board_access.device_name = optarg; for (i = 0; optarg[i] != '\0'; i++) board_access.device_name[i] = toupper(board_access.device_name[i]); device_flag++; } break; case 'i': { if (instance_flag > 0) { printf("Error: multiply --instance option\n"); exit(-1); } instance = strtol(optarg, NULL, 10); instance_flag++; } break; case 't': { if (delay_flag > 0) { printf("Error: multiply --delay option\n"); exit(-1); } delay = strtol(optarg, NULL, 10); delay_flag++; } break; case '?': /* getopt_long already printed an error message. */ return -1; break; default: abort(); } } return 0; } int main(int argc, char *argv[]) { board_t *board = NULL; int ret = 0; sserial_module_t ssmod; opd_mode_1_7i77_t out; u32 *out_ptr = (u32 *) &out; if (argc == 1) { print_short_usage(); return 0; } if (process_cmd_line(argc, argv) == -1) { return -1; } board_access.verbose = verbose_flag; if (anyio_init(&board_access) != 0) { // init library return -1; } ret = anyio_find_dev(&board_access); // find board if (ret < 0) { return -1; } board = anyio_get_dev(&board_access, 1); // if found the get board handle if (board == NULL) { printf("No %s board found\n", board_access.device_name); return -1; } board->open(board); // open board for communication board->print_info(board); // print what card it is hm2_read_idrom(&(board->llio.hm2)); // read hostmot2 idrom ret = sserial_init(&ssmod, board, 0, 1, SSLBP_REMOTE_7I77_ANALOG); out.analog0 = 1 * 0xFFF / 10; out.analog1 = 2 * 0xFFF / 10; out.analog2 = 3 * 0xFFF / 10; out.analog3 = 4 * 0xFFF / 10; out.analog4 = 5 * 0xFFF / 10; out.analog5 = 6 * 0xFFF / 10; out.analogena = 1; out.spinena = 1; ssmod.interface0 = *out_ptr; ssmod.interface1 = *(out_ptr + 1); ssmod.interface2 = *(out_ptr + 2); while (1) { sserial_write(&ssmod); printf("sserial remote status %x\n", ssmod.cs); usleep(delay*1000); // wait delay ms } sserial_cleanup(&ssmod); board->close(board); // close board communication anyio_cleanup(&board_access); // close library return 0; } mesaflash-3.4.6/examples/pci_encoder_read.c000066400000000000000000000126531433153454000207270ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #include #include #include #include #include #include #include #include "../anyio.h" #include "../encoder_module.h" #ifdef __linux__ #include #include #elif _WIN32 #include "libpci/pci.h" #endif static int device_flag; static int instance_flag; static int instance = 0; static int delay_flag; static int delay = 50; static int verbose_flag; static board_access_t board_access; static struct option long_options[] = { {"device", required_argument, 0, 'd'}, {"instance", required_argument, 0, 'i'}, {"delay", required_argument, 0, 't'}, {"verbose", no_argument, &verbose_flag, 1}, {0, 0, 0, 0} }; void print_short_usage() { printf("Example program forreading encoder on pci boards\n"); printf("Syntax:\n"); printf(" pci_encoder_read --device str [--instance i] [--delay d] [--verbose]\n"); printf(" --device select active device name\n"); printf(" --instance select encoder instance 'i' for reading, default 0\n"); printf(" --delay how long to wait between encoder reads in miliseconds, default 50\n"); printf(" --verbose printf additional info during execution\n"); } int process_cmd_line(int argc, char *argv[]) { int c; while (1) { /* getopt_long stores the option index here. */ int option_index = 0; c = getopt_long(argc, argv, "", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) break; switch (c) { case 0: { /* If this option set a flag, do nothing else now. */ if (long_options[option_index].flag != 0) break; printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); } break; case 'd': { int i; if (device_flag > 0) { printf("Error: multiply --device option\n"); exit(-1); } board_access.device_name = optarg; for (i = 0; optarg[i] != '\0'; i++) board_access.device_name[i] = toupper(board_access.device_name[i]); device_flag++; } break; case 'i': { if (instance_flag > 0) { printf("Error: multiply --instance option\n"); exit(-1); } instance = strtol(optarg, NULL, 10); instance_flag++; } break; case 't': { if (delay_flag > 0) { printf("Error: multiply --delay option\n"); exit(-1); } delay = strtol(optarg, NULL, 10); delay_flag++; } break; case '?': /* getopt_long already printed an error message. */ return -1; break; default: abort(); } } return 0; } int main(int argc, char *argv[]) { board_t *board = NULL; int ret = 0; encoder_module_t enc; if (argc == 1) { print_short_usage(); return 0; } if (process_cmd_line(argc, argv) == -1) { return -1; } board_access.verbose = verbose_flag; if (anyio_init(&board_access) != 0) { // init library return -1; } ret = anyio_find_dev(&board_access); // find board if (ret < 0) { return -1; } board = anyio_get_dev(&board_access, 1); // if found the get board handle if (board == NULL) { printf("No %s board found\n", board_access.device_name); return -1; } board->open(board); // open board for communication board->print_info(board); // print what card it is hm2_read_idrom(&(board->llio.hm2)); // read hostmot2 idrom ret = encoder_init(&enc, board, instance, delay); // init encoder 'instance' module on 'board' if (ret < 0) { goto fail0; } while (1) { encoder_read(&enc); // read encoder printf("tsc = %u, raw_counts = %u, velocity = %.2f\n", enc.global_time_stamp, enc.raw_counts, enc.velocity); usleep(delay*1000); // wait delay ms } encoder_cleanup(&enc); // cleanup enocder module fail0: board->close(board); // close board communication anyio_cleanup(&board_access); // close library return 0; } mesaflash-3.4.6/hostmot2.c000066400000000000000000001325011433153454000154160ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // Copyright (C) 2018 Sebastian Kuzminsky // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #include #include #include "hostmot2.h" void hm2_read_idrom(hostmot2_t *hm2) { u32 idrom_addr, cookie; int i; hm2->llio->read(hm2->llio, HM2_COOKIE_REG, &(cookie), sizeof(u32)); if (cookie != HM2_COOKIE) { printf("ERROR: no HOSTMOT2 firmware found. %X\n", cookie); return; } // check if it was already read if (strncmp(hm2->config_name, "HOSTMOT2", 8) == 0) return; hm2->llio->read(hm2->llio, HM2_CONFIG_NAME, &(hm2->config_name), HM2_CONFIG_NAME_LEN); hm2->llio->read(hm2->llio, HM2_IDROM_ADDR, &(idrom_addr), sizeof(u32)); hm2->llio->read(hm2->llio, idrom_addr, &(hm2->idrom), sizeof(hm2->idrom)); for (i = 0; i < HM2_MAX_MODULES; i++) { hm2->llio->read(hm2->llio, idrom_addr + hm2->idrom.offset_to_modules + i*sizeof(hm2_module_desc_t), &(hm2->modules[i]), sizeof(hm2_module_desc_t)); } for (i = 0; i < HM2_MAX_PINS; i++) { hm2->llio->read(hm2->llio, idrom_addr + hm2->idrom.offset_to_pins + i*sizeof(hm2_pin_desc_t), &(hm2->pins[i]), sizeof(hm2_module_desc_t)); } } hm2_module_desc_t *hm2_find_module(hostmot2_t *hm2, u8 gtag) { int i; for (i = 0; i < HM2_MAX_MODULES; i++) { if (hm2->modules[i].gtag == gtag) return &(hm2->modules[i]); } return NULL; } void hm2_set_pin_source(hostmot2_t *hm2, u32 pin_number, u8 source) { u32 data; u16 addr; hm2_module_desc_t *md = hm2_find_module(hm2, HM2_GTAG_IOPORT); if (md == NULL) { printf("hm2_set_pin_source(): no IOPORT module found\n"); return; } if (pin_number >= (hm2->idrom.io_ports*hm2->idrom.io_width)) { printf("hm2_set_pin_source(): invalid pin number %d\n", pin_number); return; } addr = md->base_address; hm2->llio->read(hm2->llio, addr + HM2_MOD_OFFS_GPIO_ALT_SOURCE + (pin_number / 24)*4, &data, sizeof(data)); if (source == HM2_PIN_SOURCE_IS_PRIMARY) { data &= ~(1 << (pin_number % 24)); } else if (source == HM2_PIN_SOURCE_IS_SECONDARY) { data |= (1 << (pin_number % 24)); } else { printf("hm2_set_pin_source(): invalid pin source 0x%02X\n", source); return; } hm2->llio->write(hm2->llio, addr + HM2_MOD_OFFS_GPIO_ALT_SOURCE + (pin_number / 24)*4, &data, sizeof(data)); } void hm2_set_pin_direction(hostmot2_t *hm2, u32 pin_number, u8 direction) { u32 data; u16 addr; hm2_module_desc_t *md = hm2_find_module(hm2, HM2_GTAG_IOPORT); if (md == NULL) { printf("hm2_set_pin_direction(): no IOPORT module found\n"); return; } if (pin_number >= (hm2->idrom.io_ports*hm2->idrom.io_width)) { printf("hm2_set_pin_direction(): invalid pin number %d\n", pin_number); return; } addr = md->base_address; hm2->llio->read(hm2->llio, addr + HM2_MOD_OFFS_GPIO_DDR + (pin_number / 24)*4, &data, sizeof(data)); if (direction == HM2_PIN_DIR_IS_INPUT) { data &= ~(1 << (pin_number % 24)); } else if (direction == HM2_PIN_DIR_IS_OUTPUT) { data |= (1 << (pin_number % 24)); } else { printf("hm2_set_pin_direction(): invalid pin direction 0x%02X\n", direction); return; } hm2->llio->write(hm2->llio, addr + HM2_MOD_OFFS_GPIO_DDR + (pin_number / 24)*4, &data, sizeof(data)); } // PIN FILE GENERATING SUPPORT static bob_pin_name_t bob_pin_names[MAX_BOB_NAMES] = { {BOB_7I76, {"TB2-4,5","TB2-2,3","TB2-10,11","TB2-8,9","TB2-16,17","TB2-14,15","TB2-22,23","TB2-20,21", "TB3-4,5","TB3-2,3","Internal-Field-IO","Internal-Field-IO","TB3-18,19","TB3-16,17","TB3-13,14","TB3-10,11","TB3-7,8"}}, {BOB_7I77, {"Internal-TXEn","TB6-5,6","TB6-3,4","Internal-Analog-IO","Internal-Analog-IO","Internal-Field-IO","Internal-Field-IO","Internal-EncMux", "TB3-1,2,9,10","TB3-4,5,12,13","TB3-7,8,15,16","TB3-17,18,TB4-1,2","TB3-20,21,TB4-4,5","TB3-23,24,TB4-7,8","TB4-9,10,17,18","TB4-12,13,20,21","TB4-15,16,23,24"}}, {BOB_7I94_0, {"P1-01/DB25-01","P1-02/DB25-14","P1-03/DB25-02","P1-04/DB25-15", "P1-05/DB25-03","P1-06/DB25-16","P1-07/DB25-04","P1-08/DB25-17","P1-09/DB25-05","P1-11/DB25-06","P1-13/DB25-07", "P1-15/DB25-08","P1-17/DB25-09","P1-19/DB25-10","P1-21/DB25-11","P1-23/DB25-12","P1-25/DB25-13","J6 1,2","J6 3,6","J6 TXEN","J7 1,2"}}, {BOB_7I94_1, {"J7-3,6","J7-TXEN","J8-1,2","J8-3,6","J8-TXEN","J9-1,2","J9-3,6","J9-TXEN","J4-1,2","J4-3,6", "J4-TXEN","J3-1,2","J3-3,6","J3-TXEN","J2-1,2","J2-3,6","J2-TXEN","J1-1,2","J1-3,6","J1-TXEN","P2-/ENA"}}, {BOB_7I95_0, {"TB3-2,3","TB3-4,5","TB3-8,9","TB3-10,11","TB3-14,15","TB3-16,17","TB3-20,21","TB3-22,23", "TB4-2,3","TB4-4,5","TB4-8,9","TB4-10,11","TB2-14,15","TB4-16,17","Internal","TB4-20,21","TB4-22,23","Internal", "TB1-1,2,9,10","TB1-4,5,12,13","TB1-7,8,15,16","TB1-17,18 TB2-1,2","TB1-20,21 TB2-4,5","TB1-23,24,TB2-7,8", "TB2-9,10,17,18","TB2-11,12,20,21","TB2-15,16,23,24","Internal","Internal"}}, {BOB_7I95_1, {"Internal","Internal","Internal","Internal","Internal","TB3 13,14","TB3 15,16","TB3 17,18", "TB3-19,20","TB3-21,22","TB3-23,24","Internal","P1-01/DB25-01","P1-02/DB25-14","P1-03/DB25-02","P1-04/DB25-15", "P1-05/DB25-03","P1-06/DB25-16","P1-07/DB25-04","P1-08/DB25-17","P1-09/DB25-05","P1-11/DB25-06","P1-13/DB25-07", "P1-15/DB25-08","P1-17/DB25-09","P1-19/DB25-10","P1-21/DB25-11","P1-23/DB25-12","P1-25/DB25-13"}}, {BOB_7I96_0, {"TB3-1","TB3-2","TB3-3","TB3-4","TB3-5","TB3-6","TB3-7","TB3-8","TB3-9","TB3-10","TB3-11", "TB3-13,14","TB3-15,16","TB3-17,18","TB3-19,20","TB3-21,22","TB3-23,24"}}, {BOB_7I96_1, {"TB1-2,3","TB1-4,5","TB1-8,9","TB1-10,11","TB1-14,15","TB1-16,17","TB1-20,21","TB1-22,23", "TB2-2,3","TB2-4,5","TB2-7,8","TB2-10,11","TB2-13,14","TB2-16,17","TB2-18,19","Internal-TXEn","Internal"}}, {BOB_7I96_2, {"P1-01/DB25-01","P1-02/DB25-14","P1-03/DB25-02","P1-04/DB25-15", "P1-05/DB25-03","P1-06/DB25-16","P1-07/DB25-04","P1-08/DB25-17","P1-09/DB25-05","P1-11/DB25-06","P1-13/DB25-07", "P1-15/DB25-08","P1-17/DB25-09","P1-19/DB25-10","P1-21/DB25-11","P1-23/DB25-12","P1-25/DB25-13"}}, {BOB_7I97_0, {"TB3-4","TB3-8","TB3-12","TB3-16","TB3-20","TB3-20","TB3-24","TB3-24","TB3-4,8,12,16", "TB1-1,2,9,10","TB1-4,5,12,13","TB1-7,8,15,16","TB1-17,18,TB2 1,2","TB1-20,21,TB2-4,5","TB1-23,24,TB2-7,8", "TB2-9,10,17,18","TB2-12,13,20,21"}}, {BOB_7I97_1, {"TB2-15,16,23,24","Internal-EncMux","TB5-13,14","TB5-15,16","TB5-17,18","TB5-19,20","TB5-21,22", "TB5-23,24","Internal","Internal","Internal","Internal","Internal","Internal","TB4-15,16","TB4-17,18","Internal-TXEn"}}, {BOB_7I97_2, {"P1-01/DB25-01","P1-02/DB25-14","P1-03/DB25-02","P1-04/DB25-15", "P1-05/DB25-03","P1-06/DB25-16","P1-07/DB25-04","P1-08/DB25-17","P1-09/DB25-05","P1-11/DB25-06","P1-13/DB25-07", "P1-15/DB25-08","P1-17/DB25-09","P1-19/DB25-10","P1-21/DB25-11","P1-23/DB25-12","P1-25/DB25-13"}}, {BOB_7C80_0, {"TB7-2,3","TB7-4,5","TB8-2,3","TB8-4,5","TB9-2,3","TB9-4,5","TB10-2,3","TB10-4,5","TB11-2,3","TB11-4,5", "TB12-2,3","TB13-4,5","TB3-3,4","TB3-5,6","Internal","TB4-1,2","TB4-4,5","TB4-7,8","TB5-2","TB5-2","TB5-5,6","TB5-7,8" "Internal","Internal","Internal","Internal","Internal"}}, {BOB_7C80_1, {"Internal","TB13-1,2","TB13-3,4","TB13-5,6","TB13-7,8","TB14-1,2","TB14-3,4","TB14-5,6","TB14-7,8", "Internal", "P1-01/DB25-01","P1-02/DB25-14","P1-03/DB25-02","P1-04/DB25-15", "P1-05/DB25-03","P1-06/DB25-16","P1-07/DB25-04","P1-08/DB25-17","P1-09/DB25-05","P1-11/DB25-06","P1-13/DB25-07", "P1-15/DB25-08","P1-17/DB25-09","P1-19/DB25-10","P1-21/DB25-11","P1-23/DB25-12","P1-25/DB25-13"}}, {BOB_7C81_0, {"P1-01/DB25-01","P1-02/DB25-14","P1-03/DB25-02","P1-04/DB25-15", "P1-05/DB25-03","P1-06/DB25-16","P1-07/DB25-04","P1-08/DB25-17","P1-09/DB25-05","P1-11/DB25-06","P1-13/DB25-07", "P1-15/DB25-08","P1-17/DB25-09","P1-19/DB25-10","P1-21/DB25-11","P1-23/DB25-12","P1-25/DB25-13","P5 3,6","P6 3,6"}}, {BOB_7C81_1, {"P2-01/DB25-01","P2-02/DB25-14","P2-03/DB25-02","P2-04/DB25-15", "P2-05/DB25-03","P2-06/DB25-16","P2-07/DB25-04","P2-08/DB25-17","P2-09/DB25-05","P2-11/DB25-06","P2-13/DB25-07", "P2-15/DB25-08","P2-17/DB25-09","P2-19/DB25-10","P2-21/DB25-11","P2-23/DB25-12","P2-25/DB25-13","P5 TXEN","P6 TXEN"}}, {BOB_7C81_2, {"P7-01/DB25-01","P7-02/DB25-14","P7-03/DB25-02","P7-04/DB25-15", "P7-05/DB25-03","P7-06/DB25-16","P7-07/DB25-04","P7-08/DB25-17","P7-09/DB25-05","P7-11/DB25-06","P7-13/DB25-07", "P7-15/DB25-08","P7-17/DB25-09","P7-19/DB25-10","P7-21/DB25-11","P7-23/DB25-12","P7-25/DB25-13","P5 1,2","P6 1,2"}}, {BOB_7I74, {"CHAN0-RX","CHAN1-RX","CHAN2-RX","CHAN3-RX","CHAN0-TX","CHAN1-TX","CHAN2-TX","CHAN3-TX", "CHAN4-RX","CHAN5-RX","CHAN6-RX","CHAN7-RX","CHAN4-TX","CHAN5-TX","CHAN6-TX","CHAN7-TX","CHAN7-TXEn"}}, {BOB_7I78, {"TB1-4,5","TB1-2,3","TB1-10,11","TB1-8,9","TB1-16,17","TB1-14,15","TB1-22,23","TB1-20,21","TB2-18","TB2-21,22", "TB2-23,24","TB2-12,13","Internal-TXEn","TB2-10,11","TB2-7,8","TB2-4,5","TB2-1,2"}}, {BOB_7I85, {"TB1-19,20","TB1-21,22","TB1-11,12","TB1-13,14","TB1-3,4","TB1-5,6","TB2-19,20","TB2-21,22","TB2-11,12","TB2-13,14", "Internal-EncMux","TB3-1,2,9,10","TB3-4,5,12,13","TB3-7,8,12,13","TB3-17,18,TB2-1,2","TB3-20,21,TB2-4,5","TB3-23,24,TB2-7,8"}}, {BOB_7I85S, {"TB1-19,20","TB1-21,22","TB1-11,12","TB1-13,14","TB1-3,4","TB1-5,6","TB2-19,20","TB2-21,22","TB2-11,12","TB2-13,14", "Internal-EncMux","TB3-1,2,9,10","TB3-4,5,12,13","TB3-7,8,12,13","TB3-17,18,TB2-1,2","TB3-20,21,TB2-4,5","TB3-23,24,TB2-7,8"}}, {BOB_7I88, {"TB2-2,3","TB2-4,5","TB2-8,9","TB2-10,11","TB2-14,15","TB2-16,17","TB2-20,21","TB2-22,23","TB3-2,3","TB3-4,5", "TB3,8,9","TB3-10,11","TB3-13,14","TB3-16,17","TB3-20,21,Opt-TXEn","TB3-22,23","Opt-TB3-20,21"}}, {BOB_7I89, {"TB3-1,2,9,10","TB3-4,5,12,13","TB2-7,8,15,16","TB3-17,18,TB2-1,2","TB3-20,21,TB2-4,5","TB3-23,24,TB2-7,8","TB2-9,10,17,18", "TB2-12,13,20,21","TB2-15,16,23,24","TB1-1,2,9,10","TB1-4,5,12,13","TB1-7,8,15,16","Internal-EncMux","Internal-EncPower","TB1-19,20","TB1-21,22","Internal-TXEn"}}, {BOB_DMM4250, {"Spindle-PWM","Drive-Enable","X-Dir","EStop-In","X-Step","Output-16","Y-Dir", "Output-17","Y-Step","Z-Dir","Z-Step","A-Dir","A-Step,Charge-Pump","X-Limit","Y-Limit","Z-Limit","A-Limit"}}, {BOB_5ABOB, {"Spindle-PWM","Drive-Enable","X-Step","Input-P15","X-Dir","B-Step","Y-Step", "B-Dir,Relay","Y-Dir","Z-Step","Z-Dir","A-Step","A-Dir","Input-P10","Input-P11","Input-P12","Input-P13"}}, {BOB_G540, {"Output-2","Spindle-PWM","X-Step","Fault","X-Dir","Charge-Pump","Y-Step", "Output-1","Y-Dir","Z-Step","Z-Dir","A-Step","A-Dir","Input-1","Input-2","Input-3","Input-4"}}, {BOB_C11, {"Relay-2","Spindle-Rate","Out-2","Input-P15","Out-3","Relay-1","Out-4", "Charge-Pump","Out-5","Out-6","Out-7","Out-8","Out-9","Input-P10","Input-P11","Input-P12","Input-P13"}}, {BOB_C11G, {"Relay-3","Spindle-PWM","Out-2","Input-P15","Out-3","Spindle-Dir","Out-4", "Charge-Pump,Relay-3","Out-5","Out-6","Out-7","Out-8","Out-9","Input-P10","Input-P11","Input-P12","Input-P13"}}, {BOB_7I33TA, {"TB2-4,5","TB2-1,2","TB1-4,5","TB1-1,2","TB2-7,8","TB1-7,8","TB2-10:PWM","TB1-10:PWM","TB2-10:Dir","TB1-10:Dir","TB2-12:Ena","TB1-12:Ena", "TB2-16,17","TB2-13,14","TB1-16,17","TB1-13,14","TB2-19,20","TB1-19,20","TB2-22:PWM","TB1-22:PWM","TB2-22:Dir","TB1-22:Dir","TB2-24:Ena","TB1-24:Ena"}}, {BOB_7I37TA, {"TB1-1,2","TB2-1,2","TB1-3,4","TB2-3,4","TB1-5,6","TB2-5,6","TB1-7,8","TB2-7,8","TB1-9,10","TB2-9,10","TB1-11,12","TB2-11,12", "TB1-13,14","TB2-13,14","TB1-15,16","TB2-15,16","TB1-17,18","TB2-17,18","TB1-19,20","TB2-19,20","TB1-21,22","TB2-21,22","TB1-23,24","TB2-23,24"}}, {BOB_7I44, {"CHAN0-RX","CHAN1-RX","CHAN2-RX","CHAN3-RX","CHAN0-TX","CHAN0-TXEn","CHAN1-TX","CHAN1-TXEn","CHAN2-TX","CHAN2-TXEn","CHAN3-TX","CHAN3-TXEn", "CHAN4-RX","CHAN5-RX","CHAN6-RX","CHAN7-RX","CHAN4-TX","CHAN4-TXEn","CHAN5-TX","CHAN5-TXEn","CHAN6-TX","CHAN6-TXEn","CHAN7-TX","CHAN7-TXEn"}}, {BOB_7I47, {"P2-1,2","P2-4,5","P2-7,8","P2-10,11","P4-1,2","P3-1,2","P4-4,5","P3-4,5","P4-7,8","P3-7,8","P4-9,10","P3-9,10", "P4-12,13","P3-12,13","P4-15,16","P3-15,16","P2-13,14","P2-16,17","P2-19,20","P2-22,23","P4-19,20","P4-22,23","P3-19,20","P3-22,23"}}, {BOB_7I47S, {"P2-1,2","P2-4,5","P2-7,8","P2-10,11","P4-1,2","P3-1,2","P4-4,5","P3-4,5","P4-7,8","P3-7,8","P4-9,10","P3-9,10", "P4-12,13","P3-12,13","P4-15,16","P3-15,16","P2-15,16:Aux","P2-17,18:Dir","P2-19,20:/Ena","P2-23:PWM","P4-19,20","P4-22,23","P3-19,20","P3-22,23"}}, {BOB_7I48, {"/Ena0","P4-1,2,9,10","P4-4,5,12,13","P4-7,8,15,16","P3-1,2,9,10","P3-4,5,12,13","P3-7,8,15,16","P2-1,2,9,10","P2-4,5,12,13","P2-7,8,15,16", "Internal-EncMux","P4-20:PWM-Up","P4-20:PWM-Dwn","P4-24:PWM-Up","P4-24:PWM-Dwn","P3-20:PWM-Up","P3-20:PWM-Dwn","P3-24:PWM-Up","P3-24:PWM-Dwn", "P2-20:PWM-Up","P2-20:PWM-Dwn","P2-24:PWM-Up","P2-24:PWM-Dwn","/Ena1"}}, {BOB_7I52, {"P2-5,6:/Ena","P5-1,2,9,10","P5-4,5,12,13","P5-7,8,15,16","P5-17,18,P4-1,2","P5-20,21,P4-4,5","P5-23,24,P4-7,8","P3-9,10,17,18","P3-12,13,20,21", "P3-15,16,23,24","Internal-EncMux","P2-21,22","P2-19,20","P2-13,14","P2-11,12","P2-5,6","P2-3,4","P3-21,22","P3-19,20","P3-13,14","P3-11,12","P3-5,6","P3-3,4","P3-5,6:/Ena"}}, {BOB_7I52S, {"P2-5,6:/Ena","P5-1,2,9,10","P5-4,5,12,13","P5-7,8,15,16","P5-17,18,P4-1,2","P5-20,21,P4-4,5","P5-23,24,P4-7,8","P3-9,10,17,18","P3-12,13,20,21", "P3-15,16,23,24","Internal-EncMux","P2-21,22","P2-19,20","P2-13,14","P2-11,12","P2-5,6","P2-3,4","P3-21,22","P3-19,20","P3-13,14","P3-11,12","P3-5,6","P3-3,4","P3-5,6:/Ena"}}, }; static struct { int value; const char *name; } bob_names[] = { { BOB_7I76, "7I76" }, { BOB_7I77, "7I77" }, { BOB_7I94_0, "7I94_0" }, { BOB_7I94_1, "7I94_1" }, { BOB_7I95_0, "7I95_0" }, { BOB_7I95_1, "7I95_1" }, { BOB_7I96_0, "7I96_0" }, { BOB_7I96_1, "7I96_1" }, { BOB_7I96_2, "7I96_2" }, { BOB_7I97_0, "7I97_0" }, { BOB_7I97_1, "7I97_1" }, { BOB_7I97_2, "7I97_2" }, { BOB_7C80_0, "7C80_0" }, { BOB_7C80_1, "7C80_1" }, { BOB_7C81_0, "7C81_0" }, { BOB_7C81_1, "7C81_1" }, { BOB_7C81_2, "7C81_2" }, { BOB_7I74, "7I74" }, { BOB_7I78, "7I78" }, { BOB_7I85, "7I85" }, { BOB_7I85S, "7I85S"}, { BOB_7I88, "7I88"}, { BOB_7I89, "7I89"}, { BOB_DMM4250, "DMM4250"}, { BOB_5ABOB, "5ABOB"}, { BOB_G540, "G540"}, { BOB_C11, "C11"}, { BOB_C11G, "C11G"}, { BOB_7I33TA, "7I33TA"}, { BOB_7I37TA, "7I37TA"}, { BOB_7I44, "7I44"}, { BOB_7I47, "7I47"}, { BOB_7I47S, "7I47S"}, { BOB_7I48, "7I48"}, { BOB_7I52, "7I52"}, { BOB_7I52S, "7I52S"}, { -1, NULL }, }; static pin_name_t pin_names[HM2_MAX_TAGS] = { {HM2_GTAG_NONE, {"Null1", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_IRQ_LOGIC, {"Null1", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_WATCHDOG, {"Null1", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_IOPORT, {"Null1", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_ENCODER, {"Quad-A", "Quad-B", "Quad-IDX", "Quad-IDXM", "Quad-Probe", "Shared-IDX", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_MUXED_ENCODER, {"MuxQ-A", "MuxQ-B", "MuxQ-IDX", "MuxQ-IDXM", "Quad-ProbeM", "Shared-IDX", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_MUXED_ENCODER_SEL, {"MuxSel0", "MuxSel1", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_MUXED_ENCODER_MIM, {"MuxQ-A", "MuxQ-B", "MuxQ-IDX", "MuxQ-IDXM", "Quad-ProbeM", "Shared-IDX", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_MUXED_ENCODER_SEL_MIM, {"MuxSel0", "MuxSel1", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_STEPGEN, {"Step/Table1", "Dir/Table2", "Table3", "Table4", "Table5", "Table6", "Table7", "Table8", "Index", "Probe"}}, {HM2_GTAG_PWMGEN, {"PWM", "Dir", "/Enable", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_RCPWMGEN, {"PWM", "Null2","Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_TPPWM, {"PWMA", "PWMB", "PWMC", "NPWMA", "NPWMB", "NPWMC", "/ENA", "FAULT", "Null9", "Null10"}}, {HM2_GTAG_WAVEGEN, {"PDMA", "PDMB", "Trig0", "Trig1", "Trig2", "Trig3", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_DAQ_FIFO, {"Data", "Strobe", "Full", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_BIN_OSC, {"OscOut", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_BIN_DMDMA, {"Null1", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_RESOLVER, {"PwrEn", "PDMP", "PDMM", "ADChan0", "ADChan1", "ADChan2", "SPICS", "SPIClk", "SPIDI0", "SPIDI1"}}, {HM2_GTAG_SSERIAL, {"RXData", "TXData", "TXEn", "TestPin", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_SSERIALB, {"RXData", "TXData", "TXEn", "TestPin", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_TWIDDLER, {"InBit", "IOBit", "OutBit", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_SSR, {"Out", "AC Ref", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_SPI, {"/Frame", "DOut", "SClk", "DIn", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_BSPI, {"/Frame", "DOut", "SClk", "DIn", "CS0", "CS1", "CS2", "CS3", "Null9", "Null10"}}, {HM2_GTAG_DBSPI, {"Null1", "DOut", "SClk", "DIn", "/CS-FRM0", "/CS-FRM1", "/CS-FRM2", "/CS-FRM3", "Null9", "Null10"}}, {HM2_GTAG_DPLL, {"Sync", "DDSMSB", "FOut", "PostOut", "SyncToggle", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_SSI, {"SClk", "SClkEn", "Data", "DAv", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_BISS, {"Clk", "ClkEn", "Din", "DAv", "TData", "STime", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_UART_TX, {"TXData", "TXEna", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_UART_RX, {"RXData", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_PKTUART_TX, {"TXData", "TXEna", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_PKTUART_RX, {"RXData", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_TRAM, {"Null1", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_LED, {"Null1", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_INMUX, {"Addr0", "Addr1", "Addr2", "Addr3", "Addr4", "MuxData", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_SIGMA5, {"TXData", "RXData", "TxEn", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_INM, {"Input0", "Input1", "Input2", "Input3", "Input4", "Input5", "Input6", "Input7", "Input8", "Input9", "Input10", "Input11", "Input12", "Input13", "Input14", "Input15", "Input16", "Input17", "Input18", "Input19", "Input20", "Input21", "Input22", "Input23", "Input24", "Input25", "Input26", "Input27", "Input28", "Input29", "Input30", "Input31"}}, {HM2_GTAG_OUTM, {"Output0", "Output1", "Output2", "Output3", "Output4", "Output5", "Output6", "Output7", "Output8", "Output9", "Output10", "Output11", "Output12", "Output13", "Output14", "Output15", "Output16", "Output17", "Output18", "Output19", "Output20", "Output21", "Output22", "Output23", "Output24", "Output25", "Output26", "Output27", "Output28", "Output29", "Output30", "Output31"}}, {HM2_GTAG_XYMOD, {"XData", "YData", "Clk", "Sync", "Status", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_DPAINTER, {"VidData", "VidClk", "Null3", "Null4", "Null5","Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_ONESHOT, {"Trigger1", "Trigger2","Out1", "Out2", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, }; static pin_name_t pin_names_xml[HM2_MAX_TAGS] = { {HM2_GTAG_NONE, {"Null1", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_IRQ_LOGIC, {"Null1", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_WATCHDOG, {"Null1", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_IOPORT, {"Null1", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_ENCODER, {"Phase A", "Phase B", "Index", "Quad-IDXM", "Quad-Probe", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_MUXED_ENCODER, {"Muxed Phase A", "Muxed Phase B", "Muxed Index", "MuxQ-IDXM", "Quad-ProbeM", "Shared-IDX", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_MUXED_ENCODER_SEL, {"Muxed Encoder Select 0", "Muxed Encoder select 1", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_MUXED_ENCODER_MIM, {"MuxQ-A", "MuxQ-B", "MuxQ-IDX", "MuxQ-IDXM", "Quad-ProbeM", "Shared-IDX", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_MUXED_ENCODER_SEL_MIM, {"MuxSel0", "MuxSel1", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_STEPGEN, {"Step/Table1", "Dir/Table2", "Table3", "Table4", "Table5", "Table6", "Table7", "Table8", "Index", "Probe"}}, {HM2_GTAG_PWMGEN, {"PWM/Up", "Dir/Down", "/Enable", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_RCPWMGEN, {"PWM", "Null2","Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_TPPWM, {"PWMA", "PWMB", "PWMC", "NPWMA", "NPWMB", "NPWMC", "/ENA", "FAULT", "Null9", "Null10"}}, {HM2_GTAG_WAVEGEN, {"PDMA", "PDMB", "Trig0", "Trig1", "Trig2", "Trig3", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_DAQ_FIFO, {"Data", "Strobe", "Full", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_BIN_OSC, {"OscOut", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_BIN_DMDMA, {"Null1", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_RESOLVER, {"PwrEn", "PDMP", "PDMM", "ADChan0", "ADChan1", "ADChan2", "SPICS", "SPIClk", "SPIDI0", "SPIDI1"}}, {HM2_GTAG_SSERIAL, {"RXData", "TXData", "TXEn", "TestPin", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_SSERIALB, {"RXData", "TXData", "TXEn", "TestPin", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_TWIDDLER, {"InBit", "IOBit", "OutBit", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_SSR, {"Out", "AC Ref", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_SPI, {"/Frame", "DOut", "SClk", "DIn", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_BSPI, {"/Frame", "DOut", "SClk", "DIn", "CS0", "CS1", "CS2", "CS3", "Null9", "Null10"}}, {HM2_GTAG_DBSPI, {"Null1", "DOut", "SClk", "DIn", "/CS-FRM0", "/CS-FRM1", "/CS-FRM2", "/CS-FRM3", "Null9", "Null10"}}, {HM2_GTAG_DPLL, {"Sync", "DDSMSB", "FOut", "PostOut", "SyncToggle", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_SSI, {"SClk", "SClkEn", "Din", "DAv", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_BISS, {"Clk", "ClkEn", "Din", "DAv", "TData", "STime", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_UART_TX, {"TXData", "TXEna", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_UART_RX, {"RXData", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_PKTUART_TX, {"TXData", "TXEna", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_PKTUART_RX, {"RXData", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_TRAM, {"Null1", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_LED, {"Null1", "Null2", "Null3", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_INMUX, {"Addr0", "Addr1", "Addr2", "Addr3", "Addr4", "MuxData", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_SIGMA5, {"TXData", "RXData", "TxEn", "Null4", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_INM, {"Input0", "Input1", "Input2", "Input3", "Input4", "Input5", "Input6", "Input7", "Input8", "Input9", "Input10", "Input11", "Input12", "Input13", "Input14", "Input15", "Input16", "Input17", "Input18", "Input19", "Input20", "Input21", "Input22", "Input23", "Input24", "Input25", "Input26", "Input27", "Input28", "Input29", "Input30", "Input31"}}, {HM2_GTAG_OUTM, {"Output0", "Output1", "Output2", "Output3", "Output4", "Output5", "Output6", "Output7", "Output8", "Output9", "Output10", "Output11", "Output12", "Output13", "Output14", "Output15", "Output16", "Output17", "Output18", "Output19", "Output20", "Output21", "Output22", "Output23", "Output24", "Output25", "Output26", "Output27", "Output28", "Output29", "Output30", "Output31"}}, {HM2_GTAG_XYMOD, {"XData", "YData", "Clk", "Sync", "Status", "Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_DPAINTER, {"VidData", "VidClk", "Null3", "Null4", "Null5","Null6", "Null7", "Null8", "Null9", "Null10"}}, {HM2_GTAG_ONESHOT, {"Trigger1", "Trigger2","Out1", "Out2", "Null5", "Null6", "Null7", "Null8", "Null9", "Null10"}}, }; static mod_name_t mod_names[HM2_MAX_TAGS] = { {"Null", HM2_GTAG_NONE}, {"IRQLogic", HM2_GTAG_IRQ_LOGIC}, {"WatchDog", HM2_GTAG_WATCHDOG}, {"IOPort", HM2_GTAG_IOPORT}, {"QCount", HM2_GTAG_ENCODER}, {"StepGen", HM2_GTAG_STEPGEN}, {"PWM", HM2_GTAG_PWMGEN}, {"RCPWM", HM2_GTAG_RCPWMGEN}, {"SPI", HM2_GTAG_SPI}, {"SSI", HM2_GTAG_SSI}, {"UARTTX", HM2_GTAG_UART_TX}, {"UARTRX", HM2_GTAG_UART_RX}, {"PktUARTTX", HM2_GTAG_PKTUART_TX}, {"PktUARTRX", HM2_GTAG_PKTUART_RX}, {"AddrX", HM2_GTAG_TRAM}, {"MuxedQCount", HM2_GTAG_MUXED_ENCODER}, {"MuxedQCountSel", HM2_GTAG_MUXED_ENCODER_SEL}, {"BufSPI", HM2_GTAG_BSPI}, {"DBufSPI", HM2_GTAG_DBSPI}, {"DPLL", HM2_GTAG_DPLL}, {"MuxQCntM", HM2_GTAG_MUXED_ENCODER_MIM}, {"MuxQSelM", HM2_GTAG_MUXED_ENCODER_SEL_MIM}, {"TPPWM", HM2_GTAG_TPPWM}, {"WaveGen", HM2_GTAG_WAVEGEN}, {"DAQFIFO", HM2_GTAG_DAQ_FIFO}, {"BinOsc", HM2_GTAG_BIN_OSC}, {"DMDMA", HM2_GTAG_BIN_DMDMA}, {"DPLL", HM2_GTAG_HM2DPLL}, {"LED", HM2_GTAG_LED}, {"ResolverMod", HM2_GTAG_RESOLVER}, {"SSerial", HM2_GTAG_SSERIAL}, {"SSerialB", HM2_GTAG_SSERIALB}, {"Twiddler", HM2_GTAG_TWIDDLER}, {"SSR", HM2_GTAG_SSR}, {"InMux", HM2_GTAG_INMUX}, {"Sigma5Enc", HM2_GTAG_SIGMA5}, {"InM", HM2_GTAG_INM}, {"OutM", HM2_GTAG_OUTM}, {"LocalIO", HM2_GTAG_LIOPORT}, {"BISS", HM2_GTAG_BISS}, {"XYMod", HM2_GTAG_XYMOD}, {"DataPainter",HM2_GTAG_DPAINTER}, {"OneShot",HM2_GTAG_ONESHOT}, }; static mod_name_t mod_names_xml[HM2_MAX_TAGS] = { {"Null", HM2_GTAG_NONE}, {"IRQLogic", HM2_GTAG_IRQ_LOGIC}, {"Watchdog", HM2_GTAG_WATCHDOG}, {"IOPort", HM2_GTAG_IOPORT}, {"Encoder", HM2_GTAG_ENCODER}, {"StepGen", HM2_GTAG_STEPGEN}, {"PWM", HM2_GTAG_PWMGEN}, {"RCPWM", HM2_GTAG_RCPWMGEN}, {"SPI", HM2_GTAG_SPI}, {"SSI", HM2_GTAG_SSI}, {"UARTTX", HM2_GTAG_UART_TX}, {"UARTRX", HM2_GTAG_UART_RX}, {"PktUARTTX", HM2_GTAG_PKTUART_TX}, {"PktUARTRX", HM2_GTAG_PKTUART_RX}, {"AddrX", HM2_GTAG_TRAM}, {"MuxedQCount", HM2_GTAG_MUXED_ENCODER}, {"MuxedQCountSel", HM2_GTAG_MUXED_ENCODER_SEL}, {"BufSPI", HM2_GTAG_BSPI}, {"DBufSPI", HM2_GTAG_DBSPI}, {"DPLL", HM2_GTAG_DPLL}, {"MuxQCntM", HM2_GTAG_MUXED_ENCODER_MIM}, {"MuxQSelM", HM2_GTAG_MUXED_ENCODER_SEL_MIM}, {"TPPWM", HM2_GTAG_TPPWM}, {"WaveGen", HM2_GTAG_WAVEGEN}, {"DAQFIFO", HM2_GTAG_DAQ_FIFO}, {"BinOsc", HM2_GTAG_BIN_OSC}, {"DMDMA", HM2_GTAG_BIN_DMDMA}, {"DPLL", HM2_GTAG_HM2DPLL}, {"LED", HM2_GTAG_LED}, {"ResolverMod", HM2_GTAG_RESOLVER}, {"SSerial", HM2_GTAG_SSERIAL}, {"SSerialB", HM2_GTAG_SSERIALB}, {"Twiddler", HM2_GTAG_TWIDDLER}, {"SSR", HM2_GTAG_SSR}, {"InMux", HM2_GTAG_INMUX}, {"Sigma5Enc", HM2_GTAG_SIGMA5}, {"InM", HM2_GTAG_INM}, {"OutM", HM2_GTAG_OUTM}, {"LocalIO", HM2_GTAG_LIOPORT}, {"BISS", HM2_GTAG_BISS}, {"XYMod", HM2_GTAG_XYMOD}, {"DataPainter",HM2_GTAG_DPAINTER}, {"OneShot",HM2_GTAG_ONESHOT}, }; static char *find_module_name(int gtag, int xml_flag) { int i; static char unknown[100]; mod_name_t *mod_names_ptr; if (gtag == HM2_GTAG_NONE) { return "None"; } if (xml_flag == 0) { mod_names_ptr = mod_names; } else { mod_names_ptr = mod_names_xml; } for (i = 0; i < HM2_MAX_TAGS; i++) { if (mod_names_ptr[i].tag == gtag) return mod_names_ptr[i].name; } snprintf(unknown, 100, "(unknown-gtag-%d)", gtag); return unknown; } static char *pin_get_pin_name(hm2_pin_desc_t *pin, int xml_flag) { int i; u8 chan; static char buff[100]; pin_name_t *pin_names_ptr; if (xml_flag == 0) { pin_names_ptr = pin_names; } else { pin_names_ptr = pin_names_xml; } for (i = 0; i < HM2_MAX_TAGS; i++) { if (pin_names_ptr[i].tag == pin->sec_tag) { if ((pin->sec_tag == HM2_GTAG_SSERIAL) || (pin->sec_tag == HM2_GTAG_SSERIALB)) { chan = (pin->sec_pin & 0x0F) - 1; if ((pin->sec_pin & 0xF0) == 0x00) { sprintf(buff, "%s%u", pin_names_ptr[i].name[0], chan); return buff; } else if ((pin->sec_pin & 0xF0) == 0x80) { sprintf(buff, "%s%u", pin_names_ptr[i].name[1], chan); return buff; } else if ((pin->sec_pin & 0xF0) == 0x90) { sprintf(buff, "%s%u", pin_names_ptr[i].name[2], chan); return buff; } else if (pin->sec_pin == 0xA1) { sprintf(buff, "%s%u", pin_names_ptr[i].name[3], chan); return buff; } } else if (pin->sec_tag == HM2_GTAG_SSR) { if ((pin->sec_pin & 0xF0) == 0x80) { chan = pin->sec_pin - 0x81; sprintf(buff, "%s-%02u", pin_names_ptr[i].name[0], chan); return buff; } else if (pin->sec_pin == 0xA0) { sprintf(buff, "%s", pin_names_ptr[i].name[1]); return buff; } } else if (pin->gtag == HM2_GTAG_DAQ_FIFO) { chan = pin->sec_chan & 0x1F; if ((pin->sec_pin & 0xE0) == 0x00) { sprintf(buff, "%s%u", pin_names_ptr[i].name[0], chan); return buff; } else if (pin->sec_pin == 0x41) { sprintf(buff, "%s%u", pin_names_ptr[i].name[1], chan); return buff; } else if (pin->sec_pin == 0x81) { sprintf(buff, "%s%u", pin_names_ptr[i].name[2], chan); return buff; } } else if (pin->gtag == HM2_GTAG_TWIDDLER) { chan = pin->sec_chan & 0x1F; if ((pin->sec_pin & 0xC0) == 0x00) { sprintf(buff, "%s%u", pin_names_ptr[i].name[0], chan); return buff; } else if ((pin->sec_pin & 0xC0) == 0xC0) { sprintf(buff, "%s%u", pin_names_ptr[i].name[1], chan); sprintf(buff, "%s%u", pin_names_ptr[i].name[1], chan); return buff; } else if ((pin->sec_pin & 0xC0) == 0x80) { sprintf(buff, "%s%u", pin_names_ptr[i].name[2], chan); return buff; } } else if (pin->gtag == HM2_GTAG_BIN_OSC) { chan = pin->sec_chan & 0x1F; if ((pin->sec_pin & 0x80) == 0x80) { sprintf(buff, "%s%u", pin_names_ptr[i].name[0], chan); return buff; } } else if (pin->sec_tag == HM2_GTAG_INMUX) { if ((pin->sec_pin & 0x80) == 0x80) { // output pins snprintf(buff, sizeof(buff), "Addr%d", pin->sec_pin - 0x81); } else { // input pins snprintf(buff, sizeof(buff), "Data%d", pin->sec_pin - 0x01); } return buff; } else if (pin->sec_tag == HM2_GTAG_OUTM) { if ((pin->sec_pin & 0x80) == 0x80) { // output pins snprintf(buff, sizeof(buff), "Output%d", pin->sec_pin - 0x81); return buff; } } else if (pin->sec_tag == HM2_GTAG_INM) { snprintf(buff, sizeof(buff), "Input%d", pin->sec_pin - 0x01); return buff; } else { sprintf(buff, "%s", pin_names_ptr[i].name[(pin->sec_pin & 0x0F) - 1]); return buff; } }; }; snprintf(buff, sizeof(buff), "Unknown-Gtag%d-Chan%d-Pin%d", pin->sec_tag, pin->sec_chan, pin->sec_pin); return buff; } void hm2_print_pin_file(llio_t *llio, int xml_flag) { unsigned int i, j; const u8 db25_pins[] = {1, 14, 2, 15, 3, 16, 4, 17, 5, 6, 7, 8, 9, 10, 11, 12, 13}; if (xml_flag == 0) { printf("Configuration Name: %.*s\n", 8, llio->hm2.config_name); printf("\nGeneral configuration information:\n\n"); printf(" BoardName : %.*s\n", (int)sizeof(llio->hm2.idrom.board_name), llio->hm2.idrom.board_name); printf(" FPGA Size: %u KGates\n", llio->hm2.idrom.fpga_size); printf(" FPGA Pins: %u\n", llio->hm2.idrom.fpga_pins); printf(" Number of IO Ports: %u\n", llio->hm2.idrom.io_ports); printf(" Width of one I/O port: %u\n", llio->hm2.idrom.port_width); printf(" Clock Low frequency: %.4f MHz\n", (float) llio->hm2.idrom.clock_low/1000000.0); printf(" Clock High frequency: %.4f MHz\n", (float) llio->hm2.idrom.clock_high/1000000.0); printf(" IDROM Type: %u\n", llio->hm2.idrom.idrom_type); printf(" Instance Stride 0: %u\n", llio->hm2.idrom.instance_stride0); printf(" Instance Stride 1: %u\n", llio->hm2.idrom.instance_stride1); printf(" Register Stride 0: %u\n", llio->hm2.idrom.register_stride0); printf(" Register Stride 1: %u\n", llio->hm2.idrom.register_stride1); printf("\nModules in configuration:\n\n"); for (i = 0; i < HM2_MAX_MODULES; i++) { if ((llio->hm2.modules[i].gtag == 0) && (llio->hm2.modules[i].version == 0) && (llio->hm2.modules[i].clock_tag == 0) && (llio->hm2.modules[i].instances == 0)) break; printf(" Module: %s\n", find_module_name(llio->hm2.modules[i].gtag, xml_flag)); printf(" There are %u of %s in configuration\n", llio->hm2.modules[i].instances, find_module_name(llio->hm2.modules[i].gtag, xml_flag)); printf(" Version: %u\n", llio->hm2.modules[i].version); printf(" Registers: %u\n", llio->hm2.modules[i].registers); printf(" BaseAddress: %04X\n", llio->hm2.modules[i].base_address); printf(" ClockFrequency: %.3f MHz\n", llio->hm2.modules[i].clock_tag == HM2_CLOCK_LOW_TAG ? (float) llio->hm2.idrom.clock_low/1000000.0 : (float) llio->hm2.idrom.clock_high/1000000.0); printf(" Register Stride: %u bytes\n", (llio->hm2.modules[i].strides & 0x0F) == 0 ? llio->hm2.idrom.register_stride0 : llio->hm2.idrom.register_stride1); printf(" Instance Stride: %u bytes\n\n", (llio->hm2.modules[i].strides & 0xF0) == 0 ? llio->hm2.idrom.instance_stride0 : llio->hm2.idrom.instance_stride1); } printf("Configuration pin-out:\n"); for (i = 0; i < llio->hm2.idrom.io_ports; i++) { if (llio->bob_hint[i] != 0) { printf("\nIO Connections for %s -> %s\n", llio->ioport_connector_name[i],bob_names[llio->bob_hint[i]-1].name ); } else { printf("\nIO Connections for %s\n", llio->ioport_connector_name[i]); } if ((llio->hm2.idrom.port_width == 17) && (llio->bob_hint[i] == 0)) { printf("DB25 pin# I/O Pri. func Sec. func Chan Sec. Pin func Sec. Pin Dir\n\n"); } else { printf("Pin# I/O Pri. func Sec. func Chan Sec. Pin func Sec. Pin Dir\n\n"); } for (j = 0; j < llio->hm2.idrom.port_width; j++) { hm2_pin_desc_t *pin = &(llio->hm2.pins[i*(llio->hm2.idrom.port_width) + j]); int pin_nr; switch (llio->hm2.idrom.port_width) { case 17: pin_nr = db25_pins[(i*(llio->hm2.idrom.port_width) + j) % 17]; break; case 24: pin_nr = (i*(llio->hm2.idrom.port_width) + j) % (llio->hm2.idrom.port_width)*2 + 1; break; case 32: pin_nr = i*(llio->hm2.idrom.port_width) + j; break; default: pin_nr = 0; break; } if (llio->bob_hint[i] != 0) { printf("%-18s",bob_pin_names[llio->bob_hint[i]-1].name[j]); } else { printf("%2u ", pin_nr); } printf(" %3u", i*(llio->hm2.idrom.port_width) + j); printf(" %-8s", find_module_name(pin->gtag, xml_flag)); if (pin->sec_tag == HM2_GTAG_NONE) { printf(" %-15s", "None"); } else { printf(" %-15s", find_module_name(pin->sec_tag, xml_flag)); if (pin->sec_chan & HM2_CHAN_GLOBAL) { printf(" Global "); } else { printf(" %2u ", pin->sec_chan); } printf("%-12s", pin_get_pin_name(pin, xml_flag)); if (pin->sec_pin & HM2_PIN_OUTPUT) { printf(" (Out)"); } else { printf(" (In)"); } } printf("\n"); } } printf("\n"); } else { printf("\n"); printf("\n"); printf(" %.*s\n", (int)sizeof(llio->hm2.idrom.board_name), llio->hm2.idrom.board_name); printf(" %d\n", llio->hm2.idrom.io_ports); printf(" %d\n", llio->hm2.idrom.port_width*llio->hm2.idrom.io_ports); printf(" %d\n", llio->hm2.idrom.port_width); printf(" %8d\n", llio->hm2.idrom.clock_low); printf(" %8d\n", llio->hm2.idrom.clock_high); printf(" \n"); for (i = 0; i < HM2_MAX_MODULES; i++) { if ((llio->hm2.modules[i].gtag == 0) && (llio->hm2.modules[i].version == 0) && (llio->hm2.modules[i].clock_tag == 0) && (llio->hm2.modules[i].instances == 0)) break; printf(" \n"); printf(" %s\n", find_module_name(llio->hm2.modules[i].gtag, xml_flag)); printf(" %2d\n", llio->hm2.modules[i].instances); printf(" \n"); } printf(" \n"); printf(" \n"); for (i = 0; i < llio->hm2.idrom.io_ports; i++) { for (j = 0; j < llio->hm2.idrom.port_width; j++) { hm2_pin_desc_t *pin = &(llio->hm2.pins[i*(llio->hm2.idrom.port_width) + j]); int pin_nr; switch (llio->hm2.idrom.port_width) { case 17: pin_nr = db25_pins[(i*(llio->hm2.idrom.port_width) + j) % 17]; break; case 24: pin_nr = (i*(llio->hm2.idrom.port_width) + j) % (llio->hm2.idrom.port_width)*2 + 1; break; case 32: pin_nr = i*(llio->hm2.idrom.port_width) + j; break; default: pin_nr = 0; break; } printf(" \n"); printf(" %s\n", llio->ioport_connector_name[i]); printf(" %s\n", find_module_name(pin->sec_tag, xml_flag)); printf(" "); if (pin->sec_tag != HM2_GTAG_NONE) { printf("%s", pin_get_pin_name(pin, xml_flag)); if (pin->sec_pin & HM2_PIN_OUTPUT) { printf(" (Out)"); } else { printf(" (In)"); } } printf("\n"); if (llio->bob_hint[i] != 0) { printf(" %-18s\n",bob_pin_names[llio->bob_hint[i]-1].name[j]); } else { printf(" %2d\n", pin_nr); } printf(" \n"); } } printf(" \n"); printf("\n"); } } void hm2_print_pin_descriptors(llio_t *llio) { int num_pins; num_pins = llio->hm2.idrom.io_ports * llio->hm2.idrom.port_width; printf("%d HM2 Pin Descriptors:\n", num_pins); for (int i = 0; i < num_pins; i ++) { hm2_pin_desc_t *pd = &llio->hm2.pins[i]; printf(" pin %d:\n", i); printf( " Primary Tag: 0x%02X (%s)\n", pd->gtag, find_module_name(pd->gtag, 0) ); if (llio->hm2.pins[i].sec_tag != 0) { printf( " Secondary Tag: 0x%02X (%s)\n", llio->hm2.pins[i].sec_tag, find_module_name(pd->sec_tag, 0) ); printf(" Secondary Unit: 0x%02X\n", pd->sec_chan); printf( " Secondary Pin: 0x%02X (%s, %s)\n", pd->sec_pin, pin_get_pin_name(pd, 0), (pd->sec_pin & 0x80) ? "Output" : "Input" ); } } } void hm2_print_localio_descriptors (llio_t *llio) { int i; int lio_number; i = llio->hm2.idrom.io_ports * llio->hm2.idrom.port_width; lio_number = 0; while (llio->hm2.pins[i].gtag == HM2_GTAG_LIOPORT) { i++; lio_number++; } printf("%d HM2 Local Pin Descriptors:\n", lio_number); i = llio->hm2.idrom.io_ports * llio->hm2.idrom.port_width; lio_number = 0; while (llio->hm2.pins[i].gtag == HM2_GTAG_LIOPORT) { hm2_pin_desc_t *pd = &llio->hm2.pins[i]; printf(" pin %d:\n", lio_number); printf( " Primary Tag: 0x%02X (%s)\n", pd->gtag, find_module_name(pd->gtag, 0) ); if (llio->hm2.pins[i].sec_tag != 0) { printf( " Secondary Tag: 0x%02X (%s)\n", llio->hm2.pins[i].sec_tag, find_module_name(pd->sec_tag, 0) ); printf(" Secondary Unit: 0x%02X\n", pd->sec_chan); printf( " Secondary Pin: 0x%02X (%s, %s)\n", pd->sec_pin, pin_get_pin_name(pd, 0), (pd->sec_pin & 0x80) ? "Output" : "Input" ); } i++; lio_number++; } } int hm2_find_bob_hint_by_name(const char *name) { for (size_t i=0; bob_names[i].name; i++) { if(strcasecmp(bob_names[i].name, name) == 0) { return bob_names[i].value; } } return 0; } void hm2_print_bob_hint_names() { printf("Valid daughterboard names are:\n"); for (size_t i=0; bob_names[i].name; i++) { printf("%10s,",bob_names[i].name); if ((((i+1) % 6) == 0) & (i != 0)) { printf("\n"); }; } } mesaflash-3.4.6/hostmot2.h000066400000000000000000000062111433153454000154210ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __HOSTMOT2_H #define __HOSTMOT2_H #include "types.h" #include "hostmot2_def.h" typedef struct { int index; char name[64]; } sw_mode_t; typedef struct { u32 unit; u16 sw_revision; u16 hw_revision; char name[4]; sw_mode_t sw_modes[256]; int sw_modes_cnt; } sserial_device_t; #define HM2_MAX_TAGS 255 #define MAX_BOB_NAMES 36 #define ANYIO_MAX_IOPORT_CONNECTORS 8 typedef struct llio_struct llio_t; typedef struct { llio_t *llio; char config_name[8]; hm2_idrom_desc_t idrom; hm2_module_desc_t modules[HM2_MAX_MODULES]; hm2_pin_desc_t pins[HM2_MAX_PINS]; } hostmot2_t; struct llio_struct { int (*read)(llio_t *self, u32 addr, void *buffer, int size); int (*write)(llio_t *self, u32 addr, void *buffer, int size); int (*write_flash)(llio_t *self, char *bitfile_name, u32 start_address, int fix_boot_flag, int sha256_check_flag); int (*verify_flash)(llio_t *self, char *bitfile_name, u32 start_address); int (*backup_flash)(llio_t *self, char *bitfile_name); int (*restore_flash)(llio_t *self, char *bitfile_name); int (*program_fpga)(llio_t *self, char *bitfile_name); int (*reset)(llio_t *self); int (*reload)(llio_t *self, int fallback_flag); int num_ioport_connectors; int pins_per_connector; const char *ioport_connector_name[ANYIO_MAX_IOPORT_CONNECTORS]; u16 bob_hint[ANYIO_MAX_IOPORT_CONNECTORS]; int num_leds; const char *fpga_part_number; char board_name[16]; void *board; hostmot2_t hm2; sserial_interface_t ss_interface[HM2_SSERIAL_MAX_INTERFACES]; sserial_device_t ss_device[HM2_SSERIAL_MAX_CHANNELS]; int verbose; }; typedef struct { u8 tag; char *name[32]; } pin_name_t; typedef struct { u16 bobname; char *name[32]; } bob_pin_name_t; typedef struct { char *name; u8 tag; } mod_name_t; void hm2_read_idrom(hostmot2_t *hm2); hm2_module_desc_t *hm2_find_module(hostmot2_t *hm2, u8 gtag); void hm2_print_pin_file(llio_t *llio, int xml_flag); void hm2_print_pin_descriptors(llio_t *llio); void hm2_print_localio_descriptors(llio_t *llio); void hm2_set_pin_source(hostmot2_t *hm2, u32 pin_number, u8 source); void hm2_set_pin_direction(hostmot2_t *hm2, u32 pin_number, u8 direction); void sserial_module_init(llio_t *llio); int hm2_find_bob_hint_by_name(const char *arg); void hm2_print_bob_hint_names(); #endif mesaflash-3.4.6/hostmot2_def.h000066400000000000000000000250451433153454000162450ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __HOSTMOT2_DEF_H #define __HOSTMOT2_DEF_H #include "types.h" #define HM2_AREA_SIZE 0x10000 // // Pin Descriptor constants // #define HM2_PIN_SOURCE_IS_PRIMARY 0x00 #define HM2_PIN_SOURCE_IS_SECONDARY 0x01 #define HM2_PIN_DIR_IS_INPUT 0x02 #define HM2_PIN_DIR_IS_OUTPUT 0x04 #define HM2_GTAG_NONE 0x00 #define HM2_GTAG_IRQ_LOGIC 0x01 #define HM2_GTAG_WATCHDOG 0x02 #define HM2_GTAG_IOPORT 0x03 #define HM2_GTAG_ENCODER 0x04 #define HM2_GTAG_STEPGEN 0x05 #define HM2_GTAG_PWMGEN 0x06 #define HM2_GTAG_SPI 0x07 #define HM2_GTAG_SSI 0x08 #define HM2_GTAG_UART_TX 0x09 #define HM2_GTAG_UART_RX 0x0A #define HM2_GTAG_TRAM 0x0B #define HM2_GTAG_MUXED_ENCODER 0x0C #define HM2_GTAG_MUXED_ENCODER_SEL 0x0D #define HM2_GTAG_BSPI 0x0E #define HM2_GTAG_DBSPI 0x0F #define HM2_GTAG_DPLL 0x10 #define HM2_GTAG_MUXED_ENCODER_MIM 0x11 #define HM2_GTAG_MUXED_ENCODER_SEL_MIM 0x12 #define HM2_GTAG_TPPWM 0x13 #define HM2_GTAG_WAVEGEN 0x14 #define HM2_GTAG_DAQ_FIFO 0x15 #define HM2_GTAG_BIN_OSC 0x16 #define HM2_GTAG_BIN_DMDMA 0x17 #define HM2_GTAG_BISS 0x18 #define HM2_GTAG_FABS 0x19 #define HM2_GTAG_HM2DPLL 0x1A #define HM2_GTAG_PKTUART_TX 0x1B #define HM2_GTAG_PKTUART_RX 0x1C #define HM2_GTAG_INMUX 0x1E #define HM2_GTAG_SIGMA5 0x1F #define HM2_GTAG_INM 0x23 #define HM2_GTAG_DPAINTER 0x2A #define HM2_GTAG_XYMOD 0x2B #define HM2_GTAG_RCPWMGEN 0x2C #define HM2_GTAG_OUTM 0x2D #define HM2_GTAG_LIOPORT 0x40 #define HM2_GTAG_LED 0x80 #define HM2_GTAG_RESOLVER 0xC0 #define HM2_GTAG_SSERIAL 0xC1 #define HM2_GTAG_TWIDDLER 0xC2 #define HM2_GTAG_SSR 0xC3 #define HM2_GTAG_CPDRIVE 0xC4 #define HM2_GTAG_DSAD 0xC5 #define HM2_GTAG_SSERIALB 0xC6 #define HM2_GTAG_ONESHOT 0xC7 // HM2 EEPROM SPI INTERFACE #define HM2_SPI_CTRL_REG 0x0070 #define HM2_SPI_DATA_REG 0x0074 // HM2 ICAP INTERFACE #define HM2_ICAP_REG 0x0078 #define HM2_ICAP_COOKIE 0x1CAB1CAB // hm2 access #define SPI_CMD_PAGE_WRITE 0x02 #define SPI_CMD_READ 0x03 #define SPI_CMD_READ_STATUS 0x05 #define SPI_CMD_WRITE_ENABLE 0x06 #define SPI_CMD_READ_IDROM 0xAB #define SPI_CMD_SECTOR_ERASE 0xD8 #define WRITE_IN_PROGRESS_MASK 0x01 // IDROM #define HM2_COOKIE_REG 0x0100 #define HM2_CONFIG_NAME 0x0104 #define HM2_IDROM_ADDR 0x010C #define HM2_CONFIG_NAME_LEN 8 #define HM2_COOKIE 0x55AACAFE #define HM2_MAX_MODULES 32 #define HM2_MAX_PINS 144 typedef struct { u32 idrom_type; u32 offset_to_modules; u32 offset_to_pins; char board_name[8]; u32 fpga_size; u32 fpga_pins; u32 io_ports; u32 io_width; u32 port_width; u32 clock_low; u32 clock_high; u32 instance_stride0; u32 instance_stride1; u32 register_stride0; u32 register_stride1; } hm2_idrom_desc_t; #define HM2_CLOCK_LOW_TAG 0x01 #define HM2_CLOCK_HIGH_TAG 0x02 typedef struct { u8 gtag; u8 version; u8 clock_tag; u8 instances; u16 base_address; u8 registers; u8 strides; u32 mp_bitmap; } hm2_module_desc_t; #define HM2_CHAN_GLOBAL 0x80 #define HM2_PIN_OUTPUT 0x80 typedef struct { u8 sec_pin; u8 sec_tag; u8 sec_chan; u8 gtag; } hm2_pin_desc_t; // LEDS MODULE #define HM2_MOD_OFFS_LED 0x0200 // WATCHDOG MODULE #define HM2_MOD_OFFS_WD_TIMER 0x0000 #define HM2_MOD_OFFS_WD_STATUS 0x0100 #define HM2_MOD_OFFS_WD_RESET 0x0200 // GPIO MODULE #define HM2_MOD_OFFS_GPIO 0x0000 #define HM2_MOD_OFFS_GPIO_DDR 0x0100 #define HM2_MOD_OFFS_GPIO_ALT_SOURCE 0x0200 #define HM2_MOD_OFFS_GPIO_OPEN_DRAIN 0x0300 #define HM2_MOD_OFFS_GPIO_INVERT_OUT 0x0400 // STEPGEN MODULE #define HM2_MOD_OFFS_STEPGEN_RATE 0x0000 #define HM2_MOD_OFFS_STEPGEN_ACCUM 0x0100 #define HM2_MOD_OFFS_STEPGEN_MODE 0x0200 #define HM2_MOD_OFFS_STEPGEN_DIR_SETUP 0x0300 #define HM2_MOD_OFFS_STEPGEN_DIR_HOLD 0x0400 #define HM2_MOD_OFFS_STEPGEN_STEP_LEN 0x0500 #define HM2_MOD_OFFS_STEPGEN_STEP_SPACE 0x0600 #define HM2_MOD_OFFS_STEPGEN_TABLE_DATA 0x0700 #define HM2_MOD_OFFS_STEPGEN_TABLE_LEN 0x0800 #define HM2_MOD_OFFS_STEPGEN_DDS 0x0900 // ENCODER MODULE #define HM2_MOD_OFFS_ENCODER_COUNTER 0x0000 #define HM2_MOD_OFFS_ENCODER_LATCH_CCR 0x0100 #define HM2_MOD_OFFS_ENCODER_TSSDIV 0x0200 #define HM2_MOD_OFFS_ENCODER_TS_COUNT 0x0300 #define HM2_MOD_OFFS_ENCODER_FILTER_RATE 0x0400 // MUXED ENCODER MODULE #define HM2_MOD_OFFS_MUX_ENCODER_COUNTER 0x0000 #define HM2_MOD_OFFS_MUX_ENCODER_LATCH_CCR 0x0100 #define HM2_MOD_OFFS_MUX_ENCODER_TSSDIV 0x0200 #define HM2_MOD_OFFS_MUX_ENCODER_TS_COUNT 0x0300 #define HM2_MOD_OFFS_MUX_ENCODER_FILTER_RATE 0x0400 #define HM2_ENCODER_QUADRATURE_ERROR (1 << 15) #define HM2_ENCODER_AB_MASK_POLARITY (1 << 14) #define HM2_ENCODER_LATCH_ON_PROBE (1 << 13) #define HM2_ENCODER_PROBE_POLARITY (1 << 12) #define HM2_ENCODER_FILTER (1 << 11) #define HM2_ENCODER_COUNTER_MODE (1 << 10) #define HM2_ENCODER_INDEX_MASK (1 << 9) #define HM2_ENCODER_INDEX_MASK_POLARITY (1 << 8) #define HM2_ENCODER_INDEX_JUSTONCE (1 << 6) #define HM2_ENCODER_CLEAR_ON_INDEX (1 << 5) #define HM2_ENCODER_LATCH_ON_INDEX (1 << 4) #define HM2_ENCODER_INDEX_POLARITY (1 << 3) #define HM2_ENCODER_INPUT_INDEX (1 << 2) #define HM2_ENCODER_INPUT_B (1 << 1) #define HM2_ENCODER_INPUT_A (1 << 0) #define HM2_ENCODER_CONTROL_MASK 0x0000FFFF // SSERIAL MODULE #define HM2_SSERIAL_MAX_INTERFACES 4 #define HM2_SSERIAL_MAX_CHANNELS 8 #define HM2_MOD_OFFS_SSERIAL_CMD 0x0000 #define HM2_MOD_OFFS_SSERIAL_DATA 0x0100 #define HM2_MOD_OFFS_SSERIAL_CS 0x0200 #define HM2_MOD_OFFS_SSERIAL_INTERFACE0 0x0300 #define HM2_MOD_OFFS_SSERIAL_INTERFACE1 0x0400 #define HM2_MOD_OFFS_SSERIAL_INTERFACE2 0x0500 #define SSLBP_TYPE_LOC 0 #define SSLBP_WIDTH_LOC 1 #define SSLBP_MAJOR_REV_LOC 2 #define SSLBP_MINOR_REV_LOC 3 #define SSLBP_CHANNEL_START_LOC 4 #define SSLBP_CHANNEL_STRIDE_LOC 5 #define SSLBP_PROCESSOR_TYPE_LOC 6 #define SSLBP_NR_CHANNELS_LOC 7 #define SSLBP_CLOCK_LOC 0x230 #define SSLBP_START_NORMAL 0x0900 #define SSLBP_START_SETUP 0x0F00 #define SSLBP_STOP 0x0800 #define SSLBP_DOIT 0x1000 #define SSLBP_REQUEST 0x2000 #define SSLBP_RESET 0x4000 #define SSLBP_READ 0x0000 #define SSLBP_WRITE 0x8000 #define SSLBP_CMD_START_NORMAL_MODE(x) (SSLBP_START_NORMAL | ((1 << x) & 0xFF)) #define SSLBP_CMD_START_SETUP_MODE(x) (SSLBP_START_SETUP | ((1 << x) & 0xFF)) #define SSLBP_CMD_STOP(x) (SSLBP_STOP | ((1 << x) & 0xFF)) #define SSLBP_CMD_STOPALL (SSLBP_STOP) #define SSLBP_CMD_RESET (SSLBP_RESET) #define SSLBP_CMD_DOIT(x) (SSLBP_DOIT | ((1 << x) & 0xFF)) #define SSLBP_CMD_READ(x) (SSLBP_REQUEST | SSLBP_READ | (x & 0x3FF)) #define SSLBP_CMD_WRITE(x) (SSLBP_REQUEST | SSLBP_WRITE | ((x & 0x3FF)) #define LBP_DATA 0xA0 #define LBP_MODE 0xB0 #define LBP_IN 0x00 #define LBP_IO 0x40 #define LBP_OUT 0x80 #define LBP_PAD 0x00 #define LBP_BITS 0x01 #define LBP_UNSIGNED 0x02 #define LBP_SIGNED 0x03 #define LBP_NONVOL_UNSIGNED 0x04 #define LBP_NONVOL_SIGNED 0x05 #define LBP_STREAM 0x06 #define LBP_BOOLEAN 0x07 #define LBP_ENCODER 0x08 #define LBP_ENCODER_H 0x18 // For Fanuc Absolute Encoders with separate #define LBP_ENCODER_L 0x28 // part and full count fields #define SSLBP_REMOTE_7I76_IO_SPINDLE 0x10000000 #define SSLBP_REMOTE_7I77_ANALOG 0x11000000 #define SSLBP_REMOTE_7I77_IO 0x12000000 // must match BOB name order # define BOB_7I76 1 # define BOB_7I77 2 # define BOB_7I94_0 3 # define BOB_7I94_1 4 # define BOB_7I95_0 5 # define BOB_7I95_1 6 # define BOB_7I96_0 7 # define BOB_7I96_1 8 # define BOB_7I96_2 9 # define BOB_7I97_0 10 # define BOB_7I97_1 11 # define BOB_7I97_2 12 # define BOB_7C80_0 13 # define BOB_7C80_1 14 # define BOB_7C81_0 15 # define BOB_7C81_1 16 # define BOB_7C81_2 17 # define BOB_7I74 18 # define BOB_7I78 19 # define BOB_7I85 20 # define BOB_7I85S 21 # define BOB_7I88 22 # define BOB_7I89 23 # define BOB_DMM4250 24 # define BOB_5ABOB 25 # define BOB_G540 26 # define BOB_C11 27 # define BOB_C11G 28 # define BOB_7I33TA 29 # define BOB_7I37TA 30 # define BOB_7I44 31 # define BOB_7I47 32 # define BOB_7I47S 33 # define BOB_7I48 34 # define BOB_7I52 35 # define BOB_7I52S 36 struct sserial_pdd_struct { u8 record_type; u8 data_size; u8 data_type; u8 data_dir; float param_min; float param_max; u16 param_addr; } __attribute__ ((__packed__)); typedef struct sserial_pdd_struct sserial_pdd_t; struct sserial_md_struct { u8 record_type; u8 mode_index; u8 mode_type; u8 unused; }; typedef struct sserial_md_struct sserial_md_t; typedef struct { u8 type; u8 width; u8 ver_major; u8 ver_minor; u8 gp_inputs; u8 gp_outputs; u8 processor_type; u8 channels_count; u32 clock; int baud_rate; } sserial_interface_t; #endif mesaflash-3.4.6/lbp.c000066400000000000000000000066671433153454000144310ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifdef _WIN32 #include #endif #include #include #include #include #include #include "types.h" #include "boards.h" #include "lbp.h" #ifdef __linux__ static int sd = -1; #elif _WIN32 HANDLE sd; #endif void lbp_send_checked(void *packet, int size) { #ifdef __linux__ int result = write(sd, packet, size); if (result != size) { perror("write(lbp_send_checked)"); abort(); } #elif _WIN32 BOOL result = WriteFile(sd, packet, size, &send, NULL); if (!result) { printf("WriteFile(lbp_send_checked): %d\n", GetLastError()); } #endif } void lbp_recv_checked(void *packet, int size) { #ifdef __linux__ int result = read(sd, packet, size); if (result != size) { perror("read(lbp_recv_checked)"); abort(); } #elif _WIN32 BOOL result = ReadFile(sd, packet, size, &recv, NULL); if (!result) { printf("ReadFile(lbp_recv_checked): %d\n", GetLastError()); } #endif } u8 lbp_read_ctrl(u8 cmd) { u8 data; lbp_send_checked(&cmd, 1); lbp_recv_checked(&data, 1); if (LBP_SENDRECV_DEBUG) printf("send(%X), recv(%X)\n", cmd, data); return data; } int lbp_read(u16 addr, void *buffer) { lbp_cmd_addr packet; u32 *ptr = buffer; packet.cmd = LBP_CMD_READ | LBP_ARGS_32BIT; packet.addr_hi = LO_BYTE(addr); packet.addr_lo = HI_BYTE(addr); lbp_send_checked(&packet, sizeof(lbp_cmd_addr)); lbp_recv_checked(buffer, 4); if (LBP_SENDRECV_DEBUG) printf("lbp_read(%02X:%04X): %08X\n", packet.cmd, addr, *ptr); return 0; } int lbp_write(u16 addr, void *buffer) { lbp_cmd_addr_data packet; packet.cmd = LBP_CMD_WRITE | LBP_ARGS_32BIT; packet.addr_hi = LO_BYTE(addr); packet.addr_lo = HI_BYTE(addr); memcpy(&packet.data, buffer, 4); lbp_send_checked(&packet, sizeof(lbp_cmd_addr_data)); if (LBP_SENDRECV_DEBUG) printf("lbp_write(%02X:%04X)\n", packet.cmd, addr); return 0; } void lbp_print_info() { u8 data; data = lbp_read_ctrl(LBP_CMD_READ_VERSION); printf(" LBP version %d\n", data); } void lbp_init(board_access_t *access) { #ifdef __linux__ sd = open(access->dev_addr, O_RDWR, O_NONBLOCK); if (sd == -1) perror("Unable to open the serial port\n"); #elif _WIN32 char dev_name[32]; snprintf(dev_name, 32, "\\\\.\\%s", access->dev_addr); sd = CreateFile(dev_name, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if (sd == INVALID_HANDLE_VALUE) { printf("Unable to open the serial port %d\n", errno); } #endif } void lbp_release() { #ifdef __linux__ close(sd); #endif } mesaflash-3.4.6/lbp.h000066400000000000000000000060201433153454000144150ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __LBP_H #define __LBP_H #include "types.h" #include "common.h" #define LBP_SENDRECV_DEBUG 0 #define LBP_COOKIE 0x5A #define LBP_ARGS_8BIT 0b00000000 #define LBP_ARGS_16BIT 0b00000001 #define LBP_ARGS_32BIT 0b00000010 #define LBP_ARGS_64BIT 0b00000011 #define LBP_ADDR 0b00000100 #define LBP_NO_ADDR 0b00000000 #define LBP_ADDR_AUTO_INC 0b00001000 #define LBP_RPC_INCLUDES_DATA 0b00010000 #define LBP_WRITE 0b00100000 #define LBP_READ 0b00000000 #define LBP_CMD_RW 0b01000000 #define LBP_CMD_READ (LBP_CMD_RW | LBP_READ | LBP_ADDR) #define LBP_CMD_WRITE (LBP_CMD_RW | LBP_WRITE | LBP_ADDR) #define LBP_CMD_READ_UNIT_ADDR 0xC0 #define LBP_CMD_READ_STATUS 0xC1 #define LBP_CMD_READ_ENA_RPCMEM 0xCA #define LBP_CMD_READ_CMD_TIMEOUT 0xCB #define LBP_CMD_READ_DEV_NAME0 0xD0 #define LBP_CMD_READ_DEV_NAME1 0xD1 #define LBP_CMD_READ_DEV_NAME2 0xD2 #define LBP_CMD_READ_DEV_NAME3 0xD3 #define LBP_CMD_READ_CONFIG_NAME0 0xD4 #define LBP_CMD_READ_CONFIG_NAME1 0xD5 #define LBP_CMD_READ_CONFIG_NAME2 0xD6 #define LBP_CMD_READ_CONFIG_NAME3 0xD7 #define LBP_CMD_READ_LO_ADDR 0xD8 #define LBP_CMD_READ_HI_ADDR 0xD9 #define LBP_CMD_READ_VERSION 0xDA #define LBP_CMD_READ_UNIT_ID 0xDB #define LBP_CMD_READ_RPC_PITCH 0xDC #define LBP_CMD_READ_RPC_SIZE_LO 0xDD #define LBP_CMD_READ_RPC_SIZE_HI 0xDE #define LBP_CMD_READ_COOKIE 0xDF #define LBP_CMD_READ_NV 0xEC #define LBP_NVEEPROM_BYTE 0x01 struct lbp_cmd_addr_struct { u8 cmd; u8 addr_hi; u8 addr_lo; } __attribute__ ((__packed__)); typedef struct lbp_cmd_addr_struct lbp_cmd_addr; struct lbp_cmd_addr_data_struct { u8 cmd; u8 addr_hi; u8 addr_lo; u32 data; } __attribute__ ((__packed__)); typedef struct lbp_cmd_addr_data_struct lbp_cmd_addr_data; void lbp_send_checked(void *packet, int size); void lbp_recv_checked(void *packet, int size); u8 lbp_read_ctrl(u8 cmd); int lbp_read(u16 addr, void *buffer); int lbp_write(u16 addr, void *buffer); void lbp_print_info(); void lbp_init(board_access_t *access); void lbp_release(); #endif mesaflash-3.4.6/lbp16.c000066400000000000000000000151331433153454000145640ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #include #include #include #include #include "types.h" #include "lbp16.h" #include "eth_boards.h" #include "serial_boards.h" static lbp16_access_t lbp16_access; void lbp16_send_packet_checked(void *packet, int size) { int result = lbp16_access.send_packet(packet, size); if (size != result) { perror("lbp16_access.send_packet"); abort(); } } int lbp16_recv_packet(void *packet, int size) { return lbp16_access.recv_packet(packet, size); } void lbp16_recv_packet_checked(void *packet, int size) { int result = lbp16_access.recv_packet(packet, size); if (size != result) { perror("lbp16_access.recv_packet"); abort(); } } int lbp16_read(u16 cmd, u32 addr, void *buffer, int size) { lbp16_cmd_addr packet; u8 local_buff[size]; LBP16_INIT_PACKET4(packet, cmd, addr); if (LBP16_SENDRECV_DEBUG) { printf("SEND: %02X %02X %02X %02X | REQUEST %d bytes\n", packet.cmd_hi, packet.cmd_lo, packet.addr_hi, packet.addr_lo, size); } lbp16_access.send_packet(&packet, sizeof(packet)); lbp16_access.recv_packet(&local_buff, sizeof(local_buff)); if (LBP16_SENDRECV_DEBUG) { printf("RECV: %zd bytes\n", sizeof(local_buff)); } memcpy(buffer, local_buff, size); return 0; } int lbp16_write(u16 cmd, u32 addr, void *buffer, int size) { static struct { lbp16_cmd_addr wr_packet; u8 tmp_buffer[LBP16_MAX_PACKET_DATA_SIZE*8]; } packet; LBP16_INIT_PACKET4(packet.wr_packet, cmd, addr); memcpy(&packet.tmp_buffer, buffer, size); if (LBP16_SENDRECV_DEBUG) { printf("SEND: %02X %02X %02X %02X | WRITE %d bytes\n", packet.wr_packet.cmd_hi, packet.wr_packet.cmd_lo, packet.wr_packet.addr_hi, packet.wr_packet.addr_lo, size); } lbp16_access.send_packet(&packet, sizeof(lbp16_cmd_addr) + size); return 0; } int lbp16_board_reset(llio_t *self) { (void)self; lbp16_cmd_addr_data16 packet; LBP16_INIT_PACKET6(packet, CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1C, 0x0001); // reset if != 0 lbp16_send_packet_checked(&packet, sizeof(packet)); return 0; } int lbp16_board_reload(llio_t *self, int fallback_flag) { board_t *board = self->board; u32 boot_addr; u16 fw_ver; lbp16_cmd_addr_data16 packet[14]; lbp16_cmd_addr fw_packet; LBP16_INIT_PACKET4(fw_packet, CMD_READ_BOARD_INFO_ADDR16(1), offsetof(lbp_info_area, firmware_version)); lbp16_send_packet_checked(&fw_packet, sizeof(fw_packet)); lbp16_recv_packet_checked(&fw_ver, sizeof(fw_ver)); if ((board->type & BOARD_ETH) && (fw_ver < 15)) { printf("ERROR: FPGA reload only supported by ethernet card firmware > 14.\n"); return -1; } else if ((board->type & BOARD_SER) && (fw_ver < 2)) { printf("ERROR: FPGA reload only supported by serial card firmware > 2.\n"); return -1; } if (board->fpga_type == FPGA_TYPE_EFINIX) { // Efinix config register instructions if (fallback_flag == 1) { LBP16_INIT_PACKET6(packet[0], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x0004); // image number 0 + config enable LBP16_INIT_PACKET6(packet[1], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x000C); // image number 0 + config enable + config start } else { LBP16_INIT_PACKET6(packet[0], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x0005); // image number 1 + config enable LBP16_INIT_PACKET6(packet[1], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x000D); // image number 1 + config enable + config start } lbp16_send_packet_checked(&packet, sizeof(packet)); } else { // Xilinx ICAP instructions if (fallback_flag == 1) { boot_addr = 0x10000; } else { boot_addr = 0x0; } boot_addr |= 0x0B000000; // plus read command in high byte LBP16_INIT_PACKET6(packet[0], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0xFFFF); // dummy LBP16_INIT_PACKET6(packet[1], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0xFFFF); // dummy LBP16_INIT_PACKET6(packet[2], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0xAA99); // sync LBP16_INIT_PACKET6(packet[3], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x5566); // sync LBP16_INIT_PACKET6(packet[4], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x3261); // load low flash start address LBP16_INIT_PACKET6(packet[5], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, boot_addr & 0xFFFF); // start addr LBP16_INIT_PACKET6(packet[6], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x3281); // load high start address + read command LBP16_INIT_PACKET6(packet[7], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, boot_addr >> 16); // start addr (plus read command in high byte) LBP16_INIT_PACKET6(packet[8], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x30A1); // load command register LBP16_INIT_PACKET6(packet[9], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x000E); // IPROG command LBP16_INIT_PACKET6(packet[10], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x2000); // NOP LBP16_INIT_PACKET6(packet[11], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x2000); // NOP LBP16_INIT_PACKET6(packet[12], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x2000); // NOP LBP16_INIT_PACKET6(packet[13], CMD_WRITE_COMM_CTRL_ADDR16(1), 0x1E, 0x2000); // NOP lbp16_send_packet_checked(&packet, sizeof(packet)); } return 0; } void lbp16_init(int board_type) { switch (board_type) { case BOARD_ETH: lbp16_access.send_packet = ð_send_packet; lbp16_access.recv_packet = ð_recv_packet; break; case BOARD_SER: lbp16_access.send_packet = &serial_send_packet; lbp16_access.recv_packet = &serial_recv_packet; break; default: break; } } void lbp_cleanup(int board_type) { (void)board_type; } mesaflash-3.4.6/lbp16.h000066400000000000000000000225601433153454000145730ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __LBP16_H #define __LBP16_H #include "types.h" #include "common.h" #define LBP16_SENDRECV_DEBUG 0 #define LBP16_UDP_PORT 27181 #define LBP16_HW_IP "192.168.1.121" #define LBP16_MEM_SPACE_COUNT 8 #define LBP16_CMD_SIZE 2 #define LBP16_ADDR_SIZE 2 #define LBP16_CMDADDR_PACKET_SIZE (LBP16_CMD_SIZE + LBP16_ADDR_SIZE) #define LBP16_CMDONLY_PACKET_SIZE (LBP16_CMD_SIZE) #define LBP16_MAX_PACKET_DATA_SIZE 0x7F #define FLASH_ADDR_REG 0x0000 #define FLASH_DATA_REG 0x0004 #define FLASH_ID_REG 0x0008 #define FLASH_SEC_ERASE_REG 0x000C #define ETH_EEPROM_IP_REG 0x0020 #define COMM_CTRL_WRITE_ENA_REG 0x001A #define LBP16_ADDR_AUTO_INC 0x0080 #define LBP16_ARGS_8BIT 0x0000 #define LBP16_ARGS_16BIT 0x0100 #define LBP16_ARGS_32BIT 0x0200 #define LBP16_ARGS_64BIT 0x0300 #define LBP16_SPACE_HM2 0x0000 #define LBP16_SPACE_ETH_CHIP 0x0400 #define LBP16_SPACE_ETH_EEPROM 0x0800 #define LBP16_SPACE_FPGA_FLASH 0x0C00 #define LBP16_SPACE_TIMER 0x1000 #define LBP16_SPACE_COMM_CTRL 0x1800 #define LBP16_SPACE_BOARD_INFO 0x1C00 #define LBP16_SPACE_ACC 0x0000 #define LBP16_INFO_ACC 0x2000 #define LBP16_READ 0x0000 #define LBP16_ADDR 0x4000 #define LBP16_NO_ADDR 0x0000 #define LBP16_WRITE 0x8000 #define CMD_READ_AREA_INFO_16 (LBP16_READ | LBP16_ADDR | LBP16_INFO_ACC | LBP16_ARGS_16BIT) #define CMD_READ_ADDR_16 (LBP16_READ | LBP16_ADDR | LBP16_SPACE_ACC | LBP16_ARGS_16BIT) #define CMD_READ_ADDR_32 (LBP16_READ | LBP16_ADDR | LBP16_SPACE_ACC | LBP16_ARGS_32BIT) #define CMD_WRITE_ADDR_16 (LBP16_WRITE | LBP16_ADDR | LBP16_SPACE_ACC | LBP16_ARGS_16BIT) #define CMD_WRITE_ADDR_16_INCR (LBP16_WRITE | LBP16_ADDR | LBP16_SPACE_ACC | LBP16_ADDR_AUTO_INC | LBP16_ARGS_16BIT) #define CMD_WRITE_ADDR_32 (LBP16_WRITE | LBP16_ADDR | LBP16_SPACE_ACC | LBP16_ARGS_32BIT) #define CMD_WRITE_ADDR_32_INCR (LBP16_WRITE | LBP16_ADDR | LBP16_SPACE_ACC | LBP16_ADDR_AUTO_INC | LBP16_ARGS_32BIT) #define CMD_READ_AREA_INFO_ADDR16(space, size) (CMD_READ_AREA_INFO_16 | space | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_READ_AREA_INFO_ADDR16_INCR(space, size) (CMD_READ_AREA_INFO_16 | LBP16_ADDR_AUTO_INC | space | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_READ_HOSTMOT2_ADDR32(size) (CMD_READ_ADDR_32 | LBP16_SPACE_HM2 | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_READ_HOSTMOT2_ADDR32_INCR(size) (CMD_READ_ADDR_32 | LBP16_SPACE_HM2 | LBP16_ADDR_AUTO_INC | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_READ_ETH_CHIP_ADDR16(size) (CMD_READ_ADDR_16 | LBP16_SPACE_ETH_CHIP | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_READ_ETH_CHIP_ADDR16_INCR(size) (CMD_READ_ADDR_16 | LBP16_SPACE_ETH_CHIP | LBP16_ADDR_AUTO_INC | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_READ_ETH_EEPROM_ADDR16(size) (CMD_READ_ADDR_16 | LBP16_SPACE_ETH_EEPROM | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_READ_ETH_EEPROM_ADDR16_INCR(size) (CMD_READ_ADDR_16 | LBP16_SPACE_ETH_EEPROM | LBP16_ADDR_AUTO_INC | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_READ_FPGA_FLASH_ADDR32(size) (CMD_READ_ADDR_32 | LBP16_SPACE_FPGA_FLASH | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_READ_TIMER_ADDR16(size) (CMD_READ_ADDR_16 | LBP16_SPACE_TIMER | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_READ_TIMER_ADDR16_INCR(size) (CMD_READ_ADDR_16 | LBP16_SPACE_TIMER | LBP16_ADDR_AUTO_INC | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_READ_COMM_CTRL_ADDR16(size) (CMD_READ_ADDR_16 | LBP16_SPACE_COMM_CTRL | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_READ_COMM_CTRL_ADDR16_INCR(size) (CMD_READ_ADDR_16 | LBP16_SPACE_COMM_CTRL | LBP16_ADDR_AUTO_INC | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_READ_BOARD_INFO_ADDR16(size) (CMD_READ_ADDR_16 | LBP16_SPACE_BOARD_INFO | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_READ_BOARD_INFO_ADDR16_INCR(size) (CMD_READ_ADDR_16 | LBP16_SPACE_BOARD_INFO | LBP16_ADDR_AUTO_INC | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_WRITE_HOSTMOT2_ADDR32(size) (CMD_WRITE_ADDR_32 | LBP16_SPACE_HM2 | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_WRITE_HOSTMOT2_ADDR32_INCR(size) (CMD_WRITE_ADDR_32 | LBP16_SPACE_HM2 | LBP16_ADDR_AUTO_INC | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_WRITE_FPGA_FLASH_ADDR32(size) (CMD_WRITE_ADDR_32 | LBP16_SPACE_FPGA_FLASH | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_WRITE_COMM_CTRL_ADDR16(size) (CMD_WRITE_ADDR_16 | LBP16_SPACE_COMM_CTRL | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_WRITE_ETH_EEPROM_ADDR16(size) (CMD_WRITE_ADDR_16 | LBP16_SPACE_ETH_EEPROM | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) #define CMD_WRITE_ETH_EEPROM_ADDR16_INCR(size) (CMD_WRITE_ADDR_16_INCR | LBP16_SPACE_ETH_EEPROM | ((size) & LBP16_MAX_PACKET_DATA_SIZE)) // common packets #define CMD_READ_HM2_COOKIE (CMD_READ_HOSTMOT2_ADDR32(1)) #define CMD_READ_FLASH_IDROM (CMD_READ_FPGA_FLASH_ADDR32(1)) typedef struct { u8 cmd_hi; u8 cmd_lo; } lbp16_cmd; typedef struct { u8 cmd_hi; u8 cmd_lo; u8 addr_hi; u8 addr_lo; } lbp16_cmd_addr; typedef struct { u8 cmd_hi; u8 cmd_lo; u8 addr_hi; u8 addr_lo; u8 data_hi; u8 data_lo; } lbp16_cmd_addr_data16; typedef struct { u8 cmd_hi; u8 cmd_lo; u8 addr_hi; u8 addr_lo; u8 data1; u8 data2; u8 data3; u8 data4; } lbp16_cmd_addr_data32; typedef struct { u8 cmd_hi; u8 cmd_lo; u8 addr_hi; u8 addr_lo; u8 page[256]; } lbp16_write_flash_page_packet; typedef struct { lbp16_cmd_addr_data16 write_ena_pck; lbp16_cmd_addr_data32 fl_erase_pck; } lbp16_erase_flash_sector_packets; typedef struct { lbp16_cmd_addr_data16 write_ena_pck; lbp16_write_flash_page_packet fl_write_page_pck; } lbp16_write_flash_page_packets; typedef struct { lbp16_cmd_addr_data16 write_ena_pck; lbp16_cmd_addr_data32 eth_write_ip_pck; } lbp16_write_ip_addr_packets; #define LBP16_INIT_PACKET4(packet, cmd, addr) do { \ packet.cmd_hi = LO_BYTE(cmd); \ packet.cmd_lo = HI_BYTE(cmd); \ packet.addr_hi = LO_BYTE(addr); \ packet.addr_lo = HI_BYTE(addr); \ } while (0); #define LBP16_INIT_PACKET4_SERIAL(packet, cmd, addr) do { \ packet.cmd_hi = HI_BYTE(cmd); \ packet.cmd_lo = LO_BYTE(cmd); \ packet.addr_hi = HI_BYTE(addr); \ packet.addr_lo = LO_BYTE(addr); \ } while (0); #define LBP16_INIT_PACKET6(packet, cmd, addr, data) do { \ packet.cmd_hi = LO_BYTE(cmd); \ packet.cmd_lo = HI_BYTE(cmd); \ packet.addr_hi = LO_BYTE(addr); \ packet.addr_lo = HI_BYTE(addr); \ packet.data_hi = LO_BYTE(data); \ packet.data_lo = HI_BYTE(data); \ } while (0); #define LBP16_INIT_PACKET8(packet, cmd, addr, data) do { \ packet.cmd_hi = LO_BYTE(cmd); \ packet.cmd_lo = HI_BYTE(cmd); \ packet.addr_hi = LO_BYTE(addr); \ packet.addr_lo = HI_BYTE(addr); \ packet.data1 = LO_BYTE(data); \ packet.data2 = HI_BYTE(data); \ packet.data3 = LO_BYTE((data >> 16) & 0xFFFF); \ packet.data4 = HI_BYTE((data >> 16) & 0xFFFF); \ } while (0); typedef struct { u16 cookie; u16 size; u16 range; u16 addr; u8 name[8]; } lbp_mem_info_area; typedef struct { u16 reserved1; u16 mac_addr_lo; u16 mac_addr_mid; u16 mac_addr_hi; u16 reserved2; u16 reserved3; u16 reserved4; u16 reserved5; u8 name[16]; u16 ip_addr_lo; u16 ip_addr_hi; u16 reserved6; u16 reserved7; u16 led_debug; u16 reserved8; u16 reserved9; u16 reserved10; } lbp_eth_eeprom_area; typedef struct { u16 uSTimeStampReg; u16 WaituSReg; u16 HM2Timeout; } lbp_timers_area; typedef struct { u16 ErrorReg; u16 LBPParseErrors; u16 LBPMemErrors; u16 LBPWriteErrors; u16 RXPacketCount; u16 RXGoodCount; u16 RXBadCount; u16 TXPacketCount; u16 TXGoodCount; u16 TXBadCount; u16 led_mode; u16 DebugLEDPtr; u16 Scratch; } lbp_status_area; typedef struct { u8 name[16]; u16 LBP16_version; u16 firmware_version; u16 jumpers; } lbp_info_area; typedef struct { int (*send_packet)(void *packet, int size); int (*recv_packet)(void *buffer, int size); } lbp16_access_t; void lbp16_init(int board_type); void lbp16_cleanup(int board_type); int lbp16_read(u16 cmd, u32 addr, void *buffer, int size); int lbp16_write(u16 cmd, u32 addr, void *buffer, int size); int lbp16_board_reset(llio_t *self); int lbp16_board_reload(llio_t *self, int fallback_flag); void lbp16_send_packet_checked(void *packet, int size); int lbp16_recv_packet(void *packet, int size); void lbp16_recv_packet_checked(void *packet, int size); #endif mesaflash-3.4.6/mesaflash.1000066400000000000000000000101151433153454000155140ustar00rootroot00000000000000.TH MESAFLASH 1 "November 5 2022" "version 3.4.6" .SH NAME MesaFlash \- utility to flash Mesa Electronics FPGA Cards .SH SYNOPSIS .B mesaflash [options] [commands] .SH DESCRIPTION .B mesaflash Read, write, configure Mesa Electronics FPGA cards. .SH OPTIONS .TP .BI --device " name" Select active device name. If no command is given it will detect board with given name and print info about it. The special values "ETHER", "SPI" and "AUTO" will attempt to detect a device on ethernet, SPI, or any interface; --addr still needs to be specified for non-PCI devices. .TP .BI --addr " [ip]|[device]" Use ip or device name to look for (IP address for Ethernet boards, serial device name for USB boards and serial boards, SPI device name for SPI boards) .TP .B --addr_hi Set the high register address for the EPP interface. .TP .B --epp Use EPP interface to connect to board, only for boards with multiple interfaces (7c80, 7c81, 7i43, 7i90, 7i64). .TP .B --usb Use USB interface to connect to board, only for boards with multiple interfaces (7c80, 7c81, 7i43, 7i90, 7i64). .TP .B --spi Use SPI interface to connect to board, only for boards with multiple interfaces (7c80, 7c81, 7i43, 7i90, 7i64). .TP .B --serial Use serial interface to connect to board, only for boards with multiple interfaces (7i43, 7i90, 7i64). .TP .B --fallback Use the fallback area of the FLASH memory while executing commands. .TP .B --recover Access board using PCI bridge GPIO (currently only 6I24/6I25). .TP .B --xml Format output from 'readhmid' command into XML. .TP .BI --dbname# " name" Set daughter board name to 'name' for FPGA connector 'N'. Allows readhmid to include daughterboard terminal names, where # can be in the range 1 to 6 (1 means first FPGA connector). .TP .B --verbose Print detailed information while running commands. .SH COMMANDS .TP .BI --write " filename" Writes a standard bitfile 'filename' configuration to the userarea of the FLASH memory (IMPORTANT! 'filename' must be VALID FPGA configuration file). .TP .B --fix-boot-block If a write operation does not detect a valid boot block, write one. .TP .B --no-auto-verify Don't automatically verify after writing. .TP .BI --verify " filename" Verifies the FLASH memory configuration against the bitfile 'filename'. .TP .BI --program " filename" Writes a standard bitfile 'filename' configuration to the FPGA (IMPORTANT! 'filename' must be VALID FPGA configuration file). .TP .BI --backup-flash " filename|dirname" Backup all content the FLASH memory to the file 'filename' or to the directory 'dirname' with auto naming dump file. .TP .BI --restore-flash " filename" Restore all content the FLASH memory from a file 'filename' (IMPORTANT! Can't use a dump file from different types of boards. Unacceptable interrupt the restoring process. If the restoring process was interrupted, do not turn off the board power and do not reload board, and run restore process again). Required SHA256 checksum file 'filename.sha256'. .TP .B --sha256-check Integrity check FPGA configuration bitfile before writing. Required SHA256 checksum file 'filename.sha256'. .TP .B --readhmid Print hostmot2 configuration in PIN file format. .TP .B --print-pd Print hostmot2 Pin Descriptors. .TP .B --reload Do full FPGA reload from FLASH memory (only Ethernet, SPI and PCI boards). .TP .B --reset Do full firmware reset (only Ethernet and serial boards). .TP .B --sserial Print full information about all sserial remote boards. .TP .BI --rpo " address" Read hostmot2 variable directly at 'address'. .TP .BI --wpo " address value" Write hostmot2 variable directly at 'address' with 'value'. .TP .BI --set ip="n.n.n.n" Set board IP address in EEPROM memory to n.n.n.n (only Ethernet boards). .TP .BI --info " filename" Print info about configuration in 'filename'. .TP .B --help Print the help message .SH BUGS No known bugs. .SH AUTHOR LinuxCNC Developer Community .PP Michael Geszkiewicz .PP Peter Wallace .SH COPYRIGHT GNU GPL v2+ License .PP Copyright (c) 2020 Sebastian Kuzminsky .PP Copyright (c) 2019 Peter Wallace .PP Copyright (c) 2013-2015 Michael Geszkiewicz mesaflash-3.4.6/mesaflash.c000066400000000000000000000540631433153454000156100ustar00rootroot00000000000000// // Copyright (C) 2020 Sebastian Kuzminsky // Copyright (C) 2013-2015 Michael Geszkiewicz // Copyright (C) Mesa Electronics // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #include #include #include #include #include #include #include "anyio.h" #ifdef __linux__ #include #elif _WIN32 #include "libpci/pci.h" #endif #ifndef VERSION #define VERSION "3.4.6" #endif static int device_flag; static int addr_flag; static int addr_hi_flag; static int write_flag; static int fix_boot_flag; static int verify_flag; static int backup_flash_flag; static int restore_flash_flag; static int sha256_check_flag; static int auto_verify_flag = 1; static int fallback_flag; static int recover_flag; static int program_flag; static int readhmid_flag; static int print_pd_flag; static int print_lio_flag; static int reload_flag; static int reset_flag; static int sserial_flag; static int epp_flag; static int usb_flag; static int spi_flag; static int serial_flag; static int rpo_flag; static int wpo_flag; static u16 rpo_addr; static u16 wpo_addr; static u32 wpo_data; static int set_flag; static int xml_flag; static char *lbp16_set_ip_addr; static int info_flag; static int verbose_flag; static char bitfile_name[255]; static board_access_t access; static int bob_hints[6]; #define array_size(x) ((sizeof(x) / sizeof(x[0]))) static struct option long_options[] = { {"device", required_argument, 0, 'd'}, {"addr", required_argument, 0, 'a'}, {"addr_hi", required_argument, 0, 'b'}, {"write", required_argument, 0, 'w'}, {"no-auto-verify", no_argument, &auto_verify_flag, 0}, {"fix-boot-block", no_argument, &fix_boot_flag, 1}, {"verify", required_argument, 0, 'v'}, {"backup-flash", required_argument, 0, 'f'}, {"restore-flash", required_argument, 0, 'n'}, {"sha256-check", no_argument, &sha256_check_flag, 1}, {"fallback", no_argument, &fallback_flag, 1}, {"recover", no_argument, &recover_flag, 1}, {"program", required_argument, 0, 'p'}, {"readhmid", no_argument, &readhmid_flag, 1}, {"print-pd", no_argument, &print_pd_flag, 1}, {"print-lio", no_argument, &print_lio_flag, 1}, {"reload", no_argument, &reload_flag, 1}, {"reset", no_argument, &reset_flag, 1}, {"sserial", no_argument, &sserial_flag, 1}, {"epp", no_argument, &epp_flag, 1}, {"usb", no_argument, &usb_flag, 1}, {"spi", no_argument, &spi_flag, 1}, {"serial", no_argument, &serial_flag, 1}, {"rpo", required_argument, 0, 'r'}, {"wpo", required_argument, 0, 'o'}, {"set", required_argument, 0, 's'}, {"xml", no_argument, &xml_flag, 1}, {"dbname1", required_argument, NULL, '1'}, {"dbname2", required_argument, NULL, '2'}, {"dbname3", required_argument, NULL, '3'}, {"dbname4", required_argument, NULL, '4'}, {"dbname5", required_argument, NULL, '5'}, {"dbname6", required_argument, NULL, '6'}, {"info", required_argument, 0, 'i'}, {"help", no_argument, 0, 'h'}, {"verbose", no_argument, &verbose_flag, 1}, {"version", no_argument, 0, 'x'}, {0, 0, 0, 0} }; void print_short_usage() { printf("Mesaflash version %s\n", VERSION); printf("Configuration and diagnostic tool for Mesa Electronics PCI(E)/ETH/EPP/USB/SPI boards\n"); printf("Try 'mesaflash --help' for more information\n"); } void print_version() { printf("Mesaflash version %s\n", VERSION); } void print_usage() { printf("Syntax:\n"); printf(" mesaflash --device device_name [options]\n"); printf(" mesaflash --device device_name [options] --write filename\n"); printf(" mesaflash --device device_name [options] --verify filename\n"); printf(" mesaflash --device device_name [options] --program filename\n"); printf(" mesaflash --device device_name [options] --backup-flash filename | dirname\n"); printf(" mesaflash --device device_name [options] --restore-flash filename\n"); printf(" mesaflash --device device_name [options] --readhmid\n"); printf(" mesaflash --device device_name [options] --reload | --reset\n"); printf(" mesaflash --device device_name [options] --sserial\n"); printf(" mesaflash --device device_name [options] --rpo address\n"); printf(" mesaflash --device device_name [options] --wpo address=value\n"); printf(" mesaflash --device device_name [options] --set ip=n.n.n.n\n"); printf(" mesaflash --info file_name\n"); printf(" mesaflash --help\n"); printf("\n"); printf("Options:\n"); printf(" --device Select active device name. If no command is given it\n"); printf(" will detect board with given name and print info\n"); printf(" about it.\n"); printf(" --addr Select for looking for (IP address for\n"); printf(" Ethernet boards, serial device name for USB boards\n"); printf(" and serial boards, SPI device name for SPI boards)\n"); printf(" --addr_hi Set the high register address for the EPP interface.\n"); printf(" --epp Use EPP interface to connect to board, only for boards\n"); printf(" with multiple interfaces (7c80, 7c81, 7i43, 7i90, 7i64).\n"); printf(" --usb Use USB interface to connect to board, only for boards\n"); printf(" with multiple interfaces (7c80, 7c81, 7i43, 7i90, 7i64).\n"); printf(" --spi Use SPI interface to connect to board, only for boards\n"); printf(" with multiple interfaces (7c80, 7c81, 7i43, 7i90, 7i64).\n"); printf(" --serial Use serial interface to connect to board, only for\n"); printf(" boards with multiple interfaces (7i43, 7i90, 7i64).\n"); printf(" --fallback Use the fallback area of the FLASH memory while executing\n"); printf(" commands.\n"); printf(" --recover Access board using PCI bridge GPIO (currently\n"); printf(" only 6I24/6I25).\n"); printf(" --xml Format output from 'readhmid' command into XML.\n"); printf(" --dbname# Set daughter board name to for FPGA connector \n"); printf(" Allows readhmid to include daughterboard terminal names,\n"); printf(" where # can be in the range 1 to 6\n"); printf(" (1 means first FPGA connector).\n"); printf(" --verbose Print detailed information while running commands.\n"); printf("\n"); printf("Commands:\n"); printf(" --write Writes a standard bitfile 'filename' configuration to\n"); printf(" the userarea of the FLASH (IMPORTANT! 'filename' must\n"); printf(" be VALID FPGA configuration file).\n"); printf(" --fix-boot-block If a write operation does not detect a valid boot\n"); printf(" block, write one.\n"); printf(" --no-auto-verify Don't automatically verify after writing.\n"); printf(" --verify Verifies the FLASH configuration against the\n"); printf(" bitfile 'filename'.\n"); printf(" --program Writes a standard bitfile 'filename' configuration to\n"); printf(" the FPGA (IMPORTANT! 'filename' must be VALID FPGA\n"); printf(" configuration file).\n"); printf(" --backup-flash Backup all content the FLASH memory to the file 'filename'\n"); printf(" or to the directory 'dirname' with auto naming dump file.\n"); printf(" --restore-flash Restore all content the FLASH memory from a file 'filename'\n"); printf(" (IMPORTANT! Can't use a dump file from different types\n"); printf(" of boards. Unacceptable interrupt the restoring process.\n"); printf(" If the restoring process was interrupted, do not turn off\n"); printf(" the board power and do not reload board, and run restore\n"); printf(" process again).\n"); printf(" Required SHA256 checksum file 'filename.sha256'.\n"); printf(" --sha256-check Integrity check FPGA configuration bitfile before writing.\n"); printf(" Required SHA256 checksum file 'filename.sha256'.\n"); printf(" --readhmid Print hostmot2 configuration in PIN file format.\n"); printf(" --print-pd Print hostmot2 Pin Descriptors.\n"); printf(" --print-lio Print hostmot2 local I/O pins.\n"); printf(" --reload Do full FPGA reload from flash (only Ethernet, SPI and\n"); printf(" PCI boards).\n"); printf(" --reset Do full firmware reset (only Ethernet and serial boards).\n"); printf(" --sserial Print full information about all sserial remote boards.\n"); printf(" --rpo addrs Read hostmot2 register directly at 'addrs'.\n"); printf(" --wpo addrs=data Write hostmot2 register directly at 'addrs'\n"); printf(" with 'data'.\n"); printf(" --set ip=n.n.n.n Set board IP address in EEPROM memory to n.n.n.n (only\n"); printf(" Ethernet boards).\n"); printf(" --info Print info about configuration in 'filename'.\n"); printf(" --version Print the version.\n"); printf(" --help Print this help message.\n"); } int process_cmd_line(int argc, char *argv[]) { int c; while (1) { /* getopt_long stores the option index here. */ int option_index = 0; c = getopt_long(argc, argv, "", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) break; switch (c) { case 0: { /* If this option set a flag, do nothing else now. */ if (long_options[option_index].flag != 0) break; printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); } break; case 'd': { int i; if (device_flag > 0) { printf("Error: multiple --device options\n"); exit(-1); } access.device_name = optarg; for (i = 0; optarg[i] != '\0'; i++) access.device_name[i] = toupper(access.device_name[i]); device_flag++; } break; case 'a': { if (addr_flag > 0) { printf("Error: multiple --addr options\n"); exit(-1); } access.dev_addr = optarg; addr_flag++; } break; case 'b': { if (addr_hi_flag > 0) { printf("Error: multiple --addr_hi options\n"); exit(-1); } access.dev_hi_addr = optarg; addr_hi_flag++; } break; case 'w': { if (write_flag > 0) { printf("Error: multiple --write options\n"); exit(-1); } size_t len = strlen(optarg); if (len+1 > sizeof(bitfile_name)) { printf("--write argument too long (max %zu)\n", sizeof(bitfile_name)-1); return 1; } strcpy(bitfile_name, optarg); write_flag++; } break; case 'p': { if (program_flag > 0) { printf("Error: multiple --program options\n"); exit(-1); } size_t len = strlen(optarg); if (len+1 > sizeof(bitfile_name)) { printf("--program argument too long (max %zu)\n", sizeof(bitfile_name)-1); return 1; } strcpy(bitfile_name, optarg); program_flag++; } break; case 'r': { if (rpo_flag > 0) { printf("Error: multiple --rpo options\n"); exit(-1); } if (strncmp(optarg, "0x", 2) == 0) { optarg[0] = '0'; optarg[1] = '0'; rpo_addr = strtol(optarg, NULL, 16); } else { rpo_addr = strtol(optarg, NULL, 10); } rpo_flag++; } break; case 'o': { char *pch; if (wpo_flag > 0) { printf("Error: multiple --wpo options\n"); exit(-1); } pch = strtok(optarg, "="); if (strncmp(pch, "0x", 2) == 0) { pch[0] = '0'; pch[1] = '0'; wpo_addr = strtol(pch, NULL, 16); } else { wpo_addr = strtol(pch, NULL, 10); } pch = strtok(NULL, "="); if (strncmp(pch, "0x", 2) == 0) { pch[0] = '0'; pch[1] = '0'; wpo_data = strtol(pch, NULL, 16); } else { wpo_data = strtol(pch, NULL, 10); } wpo_flag++; } break; case 's': { if (set_flag > 0) { printf("Error: multiple --set options\n"); exit(-1); } if (strncmp(optarg, "ip=", 3) == 0) { char *pch; pch = strtok(optarg, "="); pch = strtok(NULL, "="); lbp16_set_ip_addr = pch; } else { printf("Error: Unknown set command syntax, see --help for examples\n"); exit(-1); } set_flag++; } break; case 'v': { if (verify_flag > 0) { printf("Error: multiple --verify options\n"); exit(-1); } size_t len = strlen(optarg); if (len+1 > sizeof(bitfile_name)) { printf("--verify argument too long (max %zu)\n", sizeof(bitfile_name)-1); return 1; } strcpy(bitfile_name, optarg); verify_flag++; } break; case 'f': { if (backup_flash_flag > 0) { printf("Error: multiple --backup-flash options\n"); exit(-1); } size_t len = strlen(optarg); if (len+1 > sizeof(bitfile_name)) { printf("--backup-flash argument too long (max %zu)\n", sizeof(bitfile_name)-1); return 1; } strncpy(bitfile_name, optarg, 255); backup_flash_flag++; } break; case 'n': { if (restore_flash_flag > 0) { printf("Error: multiple --restore-flash options\n"); exit(-1); } size_t len = strlen(optarg); if (len+1 > sizeof(bitfile_name)) { printf("--restore-flash argument too long (max %zu)\n", sizeof(bitfile_name)-1); return 1; } strncpy(bitfile_name, optarg, 255); restore_flash_flag++; } break; case 'i': { if (info_flag > 0) { printf("Error: multiple --info options\n"); exit(-1); } size_t len = strlen(optarg); if (len+1 > sizeof(bitfile_name)) { printf("--info argument too long (max %zu)\n", sizeof(bitfile_name)-1); return 1; } strcpy(bitfile_name, optarg); info_flag++; } break; case 'h': { print_usage(); exit(0); } break; case 'x': { print_version(); exit(0); } break; case '1': case '2': case '3': case '4': case '5': case '6': { int bob_idx = c - '1'; int hint = hm2_find_bob_hint_by_name(optarg); if (hint == 0) { printf("--dbname%c %s not recognized\n", c, optarg); hm2_print_bob_hint_names(); exit(-1); } bob_hints[bob_idx] = hint; } break; case '?': /* getopt_long already printed an error message. */ return -1; break; default: abort(); } } access.type = BOARD_ANY; if ((epp_flag == 1) && (usb_flag == 0) && (spi_flag == 0) && (serial_flag == 0)) { access.type = BOARD_EPP; } else if ((epp_flag == 0) && (usb_flag == 1) && (spi_flag == 0) && (serial_flag == 0)) { access.type = BOARD_USB; } else if ((epp_flag == 0) && (usb_flag == 0) && (spi_flag == 1) && (serial_flag == 0)) { access.type = BOARD_SPI; } else if ((epp_flag == 0) && (usb_flag == 0) && (spi_flag == 0) && (serial_flag == 1)) { access.type = BOARD_SER; } return 0; } int main(int argc, char *argv[]) { int ret = 0; if (argc == 1) { print_short_usage(); return 0; } if (process_cmd_line(argc, argv) == -1) return -1; if (info_flag == 1) { anyio_bitfile_print_info(bitfile_name, 1); } else if (device_flag == 1) { board_t *board = NULL; access.verbose = verbose_flag; access.recover = recover_flag; access.address = addr_flag; if (anyio_init(&access) != 0) exit(1); ret = anyio_find_dev(&access); if (ret < 0) { printf("No %s board found\n", access.device_name); return -1; } board = anyio_get_dev(&access, 1); if (board == NULL) { printf("No %s board found\n", access.device_name); return -1; } board->open(board); for(size_t i=0; illio.bob_hint[i] = bob_hints[i]; } } if (readhmid_flag == 1) { anyio_dev_print_hm2_info(board, xml_flag); } else if (print_pd_flag == 1) { anyio_dev_print_pin_descriptors(board); } else if (print_lio_flag == 1) { anyio_dev_print_localio_descriptors(board); } else if (sserial_flag == 1) { anyio_dev_print_sserial_info(board); } else if (rpo_flag == 1) { u32 data; board->llio.read(&(board->llio), rpo_addr, &data, sizeof(u32)); printf("%08X\n", data); } else if (wpo_flag == 1) { board->llio.write(&(board->llio), wpo_addr, &wpo_data, sizeof(u32)); } else if (set_flag == 1) { ret = anyio_dev_set_remote_ip(board, lbp16_set_ip_addr); } else if (write_flag == 1) { ret = anyio_dev_write_flash(board, bitfile_name, fallback_flag, fix_boot_flag, sha256_check_flag); if (ret == 0) { if (auto_verify_flag) { ret = anyio_dev_verify_flash(board, bitfile_name, fallback_flag); } } if (ret == 0) { if (reload_flag == 1) { ret = anyio_dev_reload(board, fallback_flag); if (ret == -1) { printf("\nYou must power cycle the hardware to load a new firmware.\n"); } } else if (board->llio.reload) { printf("\nYou must power cycle the hardware or use the --reload command to load a new firmware.\n"); } else { printf("\nYou must power cycle the hardware\n"); } } } else if (verify_flag == 1) { ret = anyio_dev_verify_flash(board, bitfile_name, fallback_flag); } else if (backup_flash_flag == 1) { ret = anyio_dev_backup_flash(board, bitfile_name); } else if (restore_flash_flag == 1) { ret = anyio_dev_restore_flash(board, bitfile_name); if (ret == 0) { if (auto_verify_flag) { ret = anyio_dev_verify_flash(board, bitfile_name, fallback_flag); } } } else if (program_flag == 1) { ret = anyio_dev_program_fpga(board, bitfile_name); } else if (reload_flag == 1) { anyio_dev_reload(board, fallback_flag); } else if (reset_flag == 1) { anyio_dev_reset(board); } else { board->print_info(board); } board->close(board); anyio_cleanup(&access); } else { printf("No action requested. Please specify at least --device or --info.\n"); } return ret; } mesaflash-3.4.6/pci_boards.c000066400000000000000000001546441433153454000157600ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #if MESAFLASH_IO #ifdef __linux__ #include #include #include #include #elif _WIN32 #include #include "libpci/pci.h" #endif #include #include #include #include #include #include #include #include #include #include "types.h" #include "common.h" #include "eeprom.h" #include "eeprom_local.h" #include "bitfile.h" #include "pci_boards.h" #ifdef __linux__ static int open_as_root(const char *path, int flags) { if (seteuid(0) != 0) { printf("You need root privileges (or setuid root) to access PCI hardware\n"); return -1; } int fd = open(path, flags); int eno = errno; if (seteuid(getuid()) != 0) { printf("Failed to restore euid: %s\n", strerror(errno)); return -1; } if (fd < 0) { errno = eno; printf("%s can't open /dev/mem: %s", __func__, strerror(errno)); } return fd; } #endif extern board_t boards[MAX_BOARDS]; extern int boards_count; static int memfd = -1; struct pci_access *pacc; static u8 file_buffer[SECTOR_SIZE]; u16 setup_eeprom_5i20[256] = { 0x9030, // DEVICE ID 0x10B5, // VENDOR ID 0x0290, // PCI STATUS 0x0000, // PCI COMMAND 0x1180, // CLASS CODE (Changed to Data Acq to fool some BIOSs) 0x0000, // CLASS CODE / REV 0x3131, // SUBSYSTEM ID 0x10B5, // SUBSYSTEM VENDOR ID 0x0000, // MSB NEW CAPABILITY POINTER 0x0040, // LSB NEW CAPABILITY POINTER 0x0000, // RESERVED 0x0100, // INTERRUPT PIN 0x0000, // MSW OF POWER MANAGEMENT CAPABILITIES 0x0000, // LSW OF POWER MANAGEMANT CAPABILITIES 0x0000, // MSW OF POWER MANAGEMENT DATA / PMCSR BRIDGE SUPPORT EXTENSION 0x0000, // LSW OF POWER MANAGEMENT CONTROL STATUS 0x0000, // MSW OF HOT SWAP CONTROL / STATUS 0x0000, // LSW OF HOTSWAP NEXT CAPABILITY POINTER / HOT SWAP CONTROL 0x0000, // PCI VITAL PRODUCT DATA ADDRESS 0x0000, // PCI VITAL PRODUCT NEXT CAPABILITY POINTER / PCI VITAL PRODUCT DATA CONTROL 0x0FFF, // MSW OF LOCAL ADDRESS SPACE 0 RANGE 0xFF01, // LSW OF LOCAL ADDRESS SPACE 0 RANGE 0x0FFF, // MSW OF LOCAL ADDRESS SPACE 1 RANGE 0xFF01, // LSW OF LOCAL ADDRESS SPACE 1 RANGE 0x0FFF, // MSW OF LOCAL ADDRESS SPACE 2 RANGE 0x0000, // LSW OF LOCAL ADDRESS SPACE 2 RANGE 0x0FFF, // MSW OF LOCAL ADDRESS SPACE 3 RANGE 0x0000, // LSW OF LOCAL ADDRESS SPACE 3 RANGE 0x0000, // MSW OF EXPANSION ROM RANGE 0x0000, // LSW OF EXPANSION ROM RANGE 0x0000, // MSW OF LOCAL ADDRESS SPACE 0 LOCAL BASE ADDRESS (REMAP) 0x0001, // LSW OF LOCAL ADDRESS SPACE 0 LOCAL BASE ADDRESS (REMAP) 0x0000, // MSW OF LOCAL ADDRESS SPACE 1 LOCAL BASE ADDRESS (REMAP) 0x0001, // LSW OF LOCAL ADDRESS SPACE 1 LOCAL BASE ADDRESS (REMAP) 0x0000, // MSW OF LOCAL ADDRESS SPACE 2 LOCAL BASE ADDRESS (REMAP) 0x0001, // LSW OF LOCAL ADDRESS SPACE 2 LOCAL BASE ADDRESS (REMAP) 0x0000, // MSW OF LOCAL ADDRESS SPACE 3 LOCAL BASE ADDRESS (REMAP) 0x0001, // LSW OF LOCAL ADDRESS SPACE 3 LOCAL BASE ADDRESS (REMAP) 0x0000, // MSW OF EXPANSION ROM LOCAL BASE ADDRESS (REMAP) 0x0000, // LSW OF EXPANSION ROM LOCAL BASE ADDRESS (REMAP) 0x0040, // MSW OF LOCAL ADDRESS SPACE 0 BUS DESCRIPTOR 0x0002, // LSW OF LOCAL ADDRESS SPACE 0 BUS DESCRIPTOR 0x0080, // MSW OF LOCAL ADDRESS SPACE 1 BUS DESCRIPTOR 0x0002, // LSW OF LOCAL ADDRESS SPACE 1 BUS DESCRIPTOR 0x0040, // MSW OF LOCAL ADDRESS SPACE 2 BUS DESCRIPTOR 0x0002, // LSW OF LOCAL ADDRESS SPACE 2 BUS DESCRIPTOR 0x0080, // MSW OF LOCAL ADDRESS SPACE 3 BUS DESCRIPTOR 0x0002, // LSW OF LOCAL ADDRESS SPACE 3 BUS DESCRIPTOR 0x0000, // MSW OF EXPANSION ROM BUS DESCRIPTOR 0x0002, // LSW OF EXPANSION ROM BUS DESCRIPTOR 0x0000, // MSW OF CHIP SELECT 0 BASE ADDRESS 0x0000, // LSW OF CHIP SELECT 0 BASE ADDRESS 0x0000, // MSW OF CHIP SELECT 1 BASE ADDRESS 0x0000, // LSW OF CHIP SELECT 1 BASE ADDRESS 0x0000, // MSW OF CHIP SELECT 2 BASE ADDRESS 0x0000, // LSW OF CHIP SELECT 2 BASE ADDRESS 0x0000, // MSW OF CHIP SELECT 3 BASE ADDRESS 0x0000, // LSW OF CHIP SELECT 3 BASE ADDRESS 0x0000, // SERIAL EEPROM WRITE PROTECTED ADDRESS BOUNDARY 0x0041, // LSW OF INTERRUPT CONTROL / STATUS 0x0878, // MSW OF PCI TARGET RESPONSE, SERIAL EEPROM, AND INITIALIZATION CONTROL 0x0000, // LSW OF PCI TARGET RESPONSE, SERIAL EEPROM, AND INITIALIZATION CONTROL 0x024B, // MSW OF GENERAL PURPOSE I/O CONTROL 0x009B, // LSW OF GENERAL PURPOSE I/O CONTROL }; u16 setup_eeprom_3x20_10[256] = { 0x9056, // DEVICE ID PCIIDR[31:16] 0x10B5, // VENDOR ID PCIIDR[15:0] 0x0680, // CLASS CODE PCICCR[23:8] 0x0000, // CLASS CODE/REVISION PCICCR[7:0]/PCIREV[7:0] 0x0000, // MAXIMUM LATENCY/MINIMUM GRANT PCIMLR[7:0]/PCIMGR[7:0] 0x0100, // INTERRUPT PIN/INTERRUPT PIN ROUTING PCIIPR[7:0]/PCIIL[7:0] 0x0000, // MSW OF MAILBOX0 MBOX0[31:16] 0x0000, // LSW OF MAILBOX0 MBOX0[15:0] 0x0000, // MSW OF MAILBOX1 MBOX1[31:16] 0x0000, // LSW OF MAILBOX1 MBOX1[15:0] 0xFFFF, // MSW OF PCI-LOCAL RANGE0 LAS0RR[31:16] 0xFF01, // LSW OF PCI-LOCAL RANGE0 LAS0RR[15:0] 0x0000, // MSW OF PCI-LOCAL REMAP0 LAS0BA[31:16] 0x0001, // LSW OF PCI-LOCAL REMAP0 LAS0BA[15:0] 0x0200, // MSW OF DMA ARBITRATION REGISTER MARBR[31:16] 0x0000, // LSW OF DMA ARBITRATION REGISTER MARBR[15:0] 0x0030, // MSW OF SERIAL EEPROM WP ADDRESS PROT_AREA[15:0] 0x0500, // LSW OF MISC CONT REG/LSW OF BIG/LITTLE REG LMISC[7:0]/BIGEND[7:0] 0xFFFF, // MSW OF PCI EXPANSION ROM RANGE EROMRR[31:16] 0x0000, // LSW OF PCI EXPANSION ROM RANGE EROMRR[15:0] 0x0000, // MSW OF PCI EXPANSION ROM REMAP EROMBA[31:16] 0x0000, // LSW OF PCI EXPANSION ROM REMAP EROMBA[15:0] 0x4243, // MSW OF BUS DESCRIPTORS FOR LOCAL SPACE 0 LBRD0[31:16] 0x0043, // LSW OF BUS DESCRIPTORS FOR LOCAL SPACE 0 LBRD0[15:0] 0x0000, // MSW OF PCI INITIATOR - PCI RANGE DMRR[31:16] 0x0000, // LSW OF PCI INITIATOR - PCI RANGE DMRR[15:0] 0x0000, // MSW OF PCI INITIATOR - PCI LOCAL BASE ADD DMLBAM[31:16] 0x0000, // LSW OF PCI INITIATOR - PCI LOCAL BASE ADD DMLBAM[15:0] 0x0000, // MSW OF PCI INITIATOR - PCI LBA I/O CONF DMLBA[31:16] 0x0000, // LSW OF PCI INITIATOR - PCI LBA I/O CONF DMLBA[15:0] 0x0000, // MSW OF PCI INITIATOR - PCI BASE ADDRESS DMPBAM[31:16] 0x0000, // LSW OF PCI INITIATOR - PCI BASE ADDRESS DMPBAM[15:0] 0x0000, // MSW OF PCI INITIATOR PCI CONF ADD DMCFGA[31:16] 0x0000, // LSW OF PCI INITIATOR PCI CONF ADD DMCFGA[15:0] 0x3427, // SUBSYSTEM ID PCISID[15:0] 0x10B5, // SUBSYSTEM VENDOR ID PCISVID[15:0] 0xFFFF, // MSW OF PCI-LOCAL RANGE1 LAS1RR[31:16] 0x0000, // LSW OF PCI-LOCAL RANGE1 LAS1RR[15:0] 0x0000, // MSW OF PCI-LOCAL REMAP1 LAS1BA[31:16] 0x0001, // LSW OF PCI-LOCAL REMAP1 LAS1BA[15:0] 0x0000, // MSW OF BUS DESCRIPTORS FOR LOCAL SPACE 1 LBRD1[31:16] 0x0043, // LSW OF BUS DESCRIPTORS FOR LOCAL SPACE 1 LBRD1[15:0] 0x0000, // MSW OF HOT-SWAP CONTROL RESERVED 0x4C06, // LSW OF HS NEXT-CAP POINTER/HS CONT HS_NEXT/HS_CNTL[7:0] }; u16 setup_eeprom_3x20_15[256] = { 0x9056, // DEVICE ID PCIIDR[31:16] 0x10B5, // VENDOR ID PCIIDR[15:0] 0x0680, // CLASS CODE PCICCR[23:8] 0x0000, // CLASS CODE/REVISION PCICCR[7:0]/PCIREV[7:0] 0x0000, // MAXIMUM LATENCY/MINIMUM GRANT PCIMLR[7:0]/PCIMGR[7:0] 0x0100, // INTERRUPT PIN/INTERRUPT PIN ROUTING PCIIPR[7:0]/PCIIL[7:0] 0x0000, // MSW OF MAILBOX0 MBOX0[31:16] 0x0000, // LSW OF MAILBOX0 MBOX0[15:0] 0x0000, // MSW OF MAILBOX1 MBOX1[31:16] 0x0000, // LSW OF MAILBOX1 MBOX1[15:0] 0xFFFF, // MSW OF PCI-LOCAL RANGE0 LAS0RR[31:16] 0xFF01, // LSW OF PCI-LOCAL RANGE0 LAS0RR[15:0] 0x0000, // MSW OF PCI-LOCAL REMAP0 LAS0BA[31:16] 0x0001, // LSW OF PCI-LOCAL REMAP0 LAS0BA[15:0] 0x0200, // MSW OF DMA ARBITRATION REGISTER MARBR[31:16] 0x0000, // LSW OF DMA ARBITRATION REGISTER MARBR[15:0] 0x0030, // MSW OF SERIAL EEPROM WP ADDRESS PROT_AREA[15:0] 0x0500, // LSW OF MISC CONT REG/LSW OF BIG/LITTLE REG LMISC[7:0]/BIGEND[7:0] 0xFFFF, // MSW OF PCI EXPANSION ROM RANGE EROMRR[31:16] 0x0000, // LSW OF PCI EXPANSION ROM RANGE EROMRR[15:0] 0x0000, // MSW OF PCI EXPANSION ROM REMAP EROMBA[31:16] 0x0000, // LSW OF PCI EXPANSION ROM REMAP EROMBA[15:0] 0x4243, // MSW OF BUS DESCRIPTORS FOR LOCAL SPACE 0 LBRD0[31:16] 0x0043, // LSW OF BUS DESCRIPTORS FOR LOCAL SPACE 0 LBRD0[15:0] 0x0000, // MSW OF PCI INITIATOR - PCI RANGE DMRR[31:16] 0x0000, // LSW OF PCI INITIATOR - PCI RANGE DMRR[15:0] 0x0000, // MSW OF PCI INITIATOR - PCI LOCAL BASE ADD DMLBAM[31:16] 0x0000, // LSW OF PCI INITIATOR - PCI LOCAL BASE ADD DMLBAM[15:0] 0x0000, // MSW OF PCI INITIATOR - PCI LBA I/O CONF DMLBA[31:16] 0x0000, // LSW OF PCI INITIATOR - PCI LBA I/O CONF DMLBA[15:0] 0x0000, // MSW OF PCI INITIATOR - PCI BASE ADDRESS DMPBAM[31:16] 0x0000, // LSW OF PCI INITIATOR - PCI BASE ADDRESS DMPBAM[15:0] 0x0000, // MSW OF PCI INITIATOR PCI CONF ADD DMCFGA[31:16] 0x0000, // LSW OF PCI INITIATOR PCI CONF ADD DMCFGA[15:0] 0x3428, // SUBSYSTEM ID PCISID[15:0] 0x10B5, // SUBSYSTEM VENDOR ID PCISVID[15:0] 0xFFFF, // MSW OF PCI-LOCAL RANGE1 LAS1RR[31:16] 0x0000, // LSW OF PCI-LOCAL RANGE1 LAS1RR[15:0] 0x0000, // MSW OF PCI-LOCAL REMAP1 LAS1BA[31:16] 0x0001, // LSW OF PCI-LOCAL REMAP1 LAS1BA[15:0] 0x0000, // MSW OF BUS DESCRIPTORS FOR LOCAL SPACE 1 LBRD1[31:16] 0x0043, // LSW OF BUS DESCRIPTORS FOR LOCAL SPACE 1 LBRD1[15:0] 0x0000, // MSW OF HOT-SWAP CONTROL RESERVED 0x4C06, // LSW OF HS NEXT-CAP POINTER/HS CONT HS_NEXT/HS_CNTL[7:0] }; u16 setup_eeprom_3x20_20[256] = { 0x9056, // DEVICE ID PCIIDR[31:16] 0x10B5, // VENDOR ID PCIIDR[15:0] 0x0680, // CLASS CODE PCICCR[23:8] 0x0000, // CLASS CODE/REVISION PCICCR[7:0]/PCIREV[7:0] 0x0000, // MAXIMUM LATENCY/MINIMUM GRANT PCIMLR[7:0]/PCIMGR[7:0] 0x0100, // INTERRUPT PIN/INTERRUPT PIN ROUTING PCIIPR[7:0]/PCIIL[7:0] 0x0000, // MSW OF MAILBOX0 MBOX0[31:16] 0x0000, // LSW OF MAILBOX0 MBOX0[15:0] 0x0000, // MSW OF MAILBOX1 MBOX1[31:16] 0x0000, // LSW OF MAILBOX1 MBOX1[15:0] 0xFFFF, // MSW OF PCI-LOCAL RANGE0 LAS0RR[31:16] 0xFF01, // LSW OF PCI-LOCAL RANGE0 LAS0RR[15:0] 0x0000, // MSW OF PCI-LOCAL REMAP0 LAS0BA[31:16] 0x0001, // LSW OF PCI-LOCAL REMAP0 LAS0BA[15:0] 0x0200, // MSW OF DMA ARBITRATION REGISTER MARBR[31:16] 0x0000, // LSW OF DMA ARBITRATION REGISTER MARBR[15:0] 0x0030, // MSW OF SERIAL EEPROM WP ADDRESS PROT_AREA[15:0] 0x0500, // LSW OF MISC CONT REG/LSW OF BIG/LITTLE REG LMISC[7:0]/BIGEND[7:0] 0xFFFF, // MSW OF PCI EXPANSION ROM RANGE EROMRR[31:16] 0x0000, // LSW OF PCI EXPANSION ROM RANGE EROMRR[15:0] 0x0000, // MSW OF PCI EXPANSION ROM REMAP EROMBA[31:16] 0x0000, // LSW OF PCI EXPANSION ROM REMAP EROMBA[15:0] 0x4243, // MSW OF BUS DESCRIPTORS FOR LOCAL SPACE 0 LBRD0[31:16] 0x0043, // LSW OF BUS DESCRIPTORS FOR LOCAL SPACE 0 LBRD0[15:0] 0x0000, // MSW OF PCI INITIATOR - PCI RANGE DMRR[31:16] 0x0000, // LSW OF PCI INITIATOR - PCI RANGE DMRR[15:0] 0x0000, // MSW OF PCI INITIATOR - PCI LOCAL BASE ADD DMLBAM[31:16] 0x0000, // LSW OF PCI INITIATOR - PCI LOCAL BASE ADD DMLBAM[15:0] 0x0000, // MSW OF PCI INITIATOR - PCI LBA I/O CONF DMLBA[31:16] 0x0000, // LSW OF PCI INITIATOR - PCI LBA I/O CONF DMLBA[15:0] 0x0000, // MSW OF PCI INITIATOR - PCI BASE ADDRESS DMPBAM[31:16] 0x0000, // LSW OF PCI INITIATOR - PCI BASE ADDRESS DMPBAM[15:0] 0x0000, // MSW OF PCI INITIATOR PCI CONF ADD DMCFGA[31:16] 0x0000, // LSW OF PCI INITIATOR PCI CONF ADD DMCFGA[15:0] 0x3429, // SUBSYSTEM ID PCISID[15:0] 0x10B5, // SUBSYSTEM VENDOR ID PCISVID[15:0] 0xFFFF, // MSW OF PCI-LOCAL RANGE1 LAS1RR[31:16] 0x0000, // LSW OF PCI-LOCAL RANGE1 LAS1RR[15:0] 0x0000, // MSW OF PCI-LOCAL REMAP1 LAS1BA[31:16] 0x0001, // LSW OF PCI-LOCAL REMAP1 LAS1BA[15:0] 0x0000, // MSW OF BUS DESCRIPTORS FOR LOCAL SPACE 1 LBRD1[31:16] 0x0043, // LSW OF BUS DESCRIPTORS FOR LOCAL SPACE 1 LBRD1[15:0] 0x0000, // MSW OF HOT-SWAP CONTROL RESERVED 0x4C06, // LSW OF HS NEXT-CAP POINTER/HS CONT HS_NEXT/HS_CNTL[7:0] }; static void plx9030_SetCSHigh(board_t *board) { u16 data = inw(board->ctrl_base_addr + PLX9030_CTRL_INIT_OFFSET); data = data | PLX9030_EECS_MASK; outw(data, board->ctrl_base_addr + PLX9030_CTRL_INIT_OFFSET); sleep_ns(4000); } static void plx9030_SetCSLow(board_t *board) { u16 data = inw(board->ctrl_base_addr + PLX9030_CTRL_INIT_OFFSET); data = data & (~PLX9030_EECS_MASK); outw(data, board->ctrl_base_addr + PLX9030_CTRL_INIT_OFFSET); sleep_ns(4000); } static void plx9030_SetDinHigh(board_t *board) { u16 data = inw(board->ctrl_base_addr + PLX9030_CTRL_INIT_OFFSET); data = data | PLX9030_EEDI_MASK; outw(data, board->ctrl_base_addr + PLX9030_CTRL_INIT_OFFSET); sleep_ns(4000); } static void plx9030_SetDinLow(board_t *board) { u16 data = inw(board->ctrl_base_addr + PLX9030_CTRL_INIT_OFFSET); data = data & (~PLX9030_EEDI_MASK); outw(data, board->ctrl_base_addr + PLX9030_CTRL_INIT_OFFSET); sleep_ns(4000); } static void plx9030_SetClockHigh(board_t *board) { u16 data = inw(board->ctrl_base_addr + PLX9030_CTRL_INIT_OFFSET); data = data | PLX9030_EECLK_MASK; outw(data, board->ctrl_base_addr + PLX9030_CTRL_INIT_OFFSET); sleep_ns(4000); } static void plx9030_SetClockLow(board_t *board) { u16 data = inw(board->ctrl_base_addr + PLX9030_CTRL_INIT_OFFSET); data = data & (~PLX9030_EECLK_MASK); outw(data, board->ctrl_base_addr + PLX9030_CTRL_INIT_OFFSET); sleep_ns(4000); } static int plx9030_DataHighQ(board_t *board) { u16 data = inw(board->ctrl_base_addr + PLX9030_CTRL_INIT_OFFSET); sleep_ns(4000); if ((data & PLX9030_EEDO_MASK) != 0) return 1; else return 0; } static u16 plx9030_read_eeprom_word(board_t *board, u8 reg) { u8 bit; u16 mask; u16 tdata; plx9030_SetCSLow(board); plx9030_SetDinLow(board); plx9030_SetClockLow(board); plx9030_SetCSHigh(board); // send command first mask = EEPROM_93C66_CMD_MASK; for (bit = 0; bit < EEPROM_93C66_CMD_LEN; bit++) { if ((mask & EEPROM_93C66_CMD_READ) == 0) plx9030_SetDinLow(board); else plx9030_SetDinHigh(board); mask = mask >> 1; plx9030_SetClockLow(board); plx9030_SetClockHigh(board); } // then send address mask = EEPROM_93C66_ADDR_MASK; for (bit = 0; bit < EEPROM_93C66_ADDR_LEN; bit++) { if ((mask & reg) == 0) plx9030_SetDinLow(board); else plx9030_SetDinHigh(board); mask = mask >> 1; plx9030_SetClockLow(board); plx9030_SetClockHigh(board); } // read dummy 0 bit, if zero assume ok if (plx9030_DataHighQ(board) == 1) return 0; mask = EEPROM_93C66_DATA_MASK; tdata = 0; for (bit = 0; bit < EEPROM_93C66_DATA_LEN; bit++) { plx9030_SetClockLow(board); plx9030_SetClockHigh(board); if (plx9030_DataHighQ(board) == 1) tdata = tdata | mask; mask = mask >> 1; } plx9030_SetCSLow(board); plx9030_SetDinLow(board); plx9030_SetClockLow(board); return tdata; } void pci_plx9030_bridge_eeprom_setup_read(board_t *board) { int i; char *bridge_name = "Unknown"; if (board->dev->device_id == DEVICEID_PLX9030) bridge_name = "PLX9030"; else if (board->dev->device_id == DEVICEID_PLX9054) bridge_name = "PLX9054"; else if (board->dev->device_id == DEVICEID_PLX9056) bridge_name = "PLX9056"; printf("%s PCI bridge setup EEPROM:\n", bridge_name); for (i = 0; i < EEPROM_93C66_SIZE; i++) { if ((i > 0) && ((i % 16) == 0)) printf("\n"); if ((i % 16) == 0) printf(" %02X: ", i); printf("%04X ", plx9030_read_eeprom_word(board, i)); } printf("\n"); } static int plx9030_program_fpga(llio_t *self, char *bitfile_name) { board_t *board = self->board; int bindex, bytesread; u32 status, control; char part_name[32]; struct stat file_stat; FILE *fp; struct timeval tv1, tv2; if (stat(bitfile_name, &file_stat) != 0) { printf("Can't find file %s\n", bitfile_name); return -1; } fp = fopen(bitfile_name, "rb"); if (fp == NULL) { printf("Can't open file %s: %s\n", bitfile_name, strerror(errno)); return -1; } if (print_bitfile_header(fp, (char*) &part_name, board->llio.verbose) == -1) { fclose(fp); return -1; } // set /WRITE low for data transfer, and turn on LED status = inl(board->ctrl_base_addr + PLX9030_CTRL_STAT_OFFSET); control = status & ~PLX9030_WRITE_MASK & ~PLX9030_LED_MASK; outl(control, board->ctrl_base_addr + PLX9030_CTRL_STAT_OFFSET); printf("Programming FPGA...\n"); printf(" |"); fflush(stdout); gettimeofday(&tv1, NULL); // program the FPGA while (!feof(fp)) { bytesread = fread(&file_buffer, 1, 8192, fp); bindex = 0; while (bindex < bytesread) { outb(bitfile_reverse_bits(file_buffer[bindex]), board->data_base_addr); bindex++; } printf("W"); fflush(stdout); } fclose(fp); printf("\n"); if (board->llio.verbose == 1) { gettimeofday(&tv2, NULL); printf(" Programming time: %.2f seconds\n", (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 + (double) (tv2.tv_sec - tv1.tv_sec)); } // all bytes transferred, make sure FPGA is all set up now status = inl(board->ctrl_base_addr + PLX9030_CTRL_STAT_OFFSET); if (!(status & PLX9030_INIT_MASK)) { // /INIT goes low on CRC error printf("FPGA asserted /INIT: CRC error\n"); goto fail; } if (!(status & PLX9030_DONE_MASK)) { printf("FPGA did not assert DONE\n"); goto fail; } // turn off write enable and LED control = status | PLX9030_WRITE_MASK | PLX9030_LED_MASK; outl(control, board->ctrl_base_addr + PLX9030_CTRL_STAT_OFFSET); if (board->llio.verbose == 1) { gettimeofday(&tv2, NULL); printf("\n Programming time: %.3f seconds", (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 + (double) (tv2.tv_sec - tv1.tv_sec)); } printf("\nBoard FPGA programmed successfully.\n"); return 0; fail: // set /PROGRAM low (reset device), /WRITE high and LED off status = inl(board->ctrl_base_addr + PLX9030_CTRL_STAT_OFFSET); control = status & ~PLX9030_PROGRAM_MASK; control |= PLX9030_WRITE_MASK | PLX9030_LED_MASK; outl(control, board->ctrl_base_addr + PLX9030_CTRL_STAT_OFFSET); return -EIO; } static int plx9030_reset(llio_t *self) { board_t *board = self->board; u32 status; u32 control; printf("Resetting FPGA... "); status = inl(board->ctrl_base_addr + PLX9030_CTRL_STAT_OFFSET); // set /PROGRAM bit low to reset the FPGA control = status & ~PLX9030_PROGRAM_MASK; // set /WRITE and /LED high (idle state) control |= PLX9030_WRITE_MASK | PLX9030_LED_MASK; // and write it back outl(control, board->ctrl_base_addr + PLX9030_CTRL_STAT_OFFSET); // verify that /INIT and DONE went low status = inl(board->ctrl_base_addr + PLX9030_CTRL_STAT_OFFSET); if (status & (PLX9030_DONE_MASK | PLX9030_INIT_MASK)) { printf("FPGA did not reset: /INIT = %d, DONE = %d\n", (status & PLX9030_INIT_MASK ? 1 : 0), (status & PLX9030_DONE_MASK ? 1 : 0) ); return -EIO; } // set /PROGRAM high, let FPGA come out of reset control = status | PLX9030_PROGRAM_MASK; outl(control, board->ctrl_base_addr + PLX9030_CTRL_STAT_OFFSET); // wait for /INIT to go high when it finishes clearing memory // This should take no more than 100uS. If we assume each PCI read // takes 30nS (one PCI clock), that is 3300 reads. Reads actually // take several clocks, but even at a microsecond each, 3.3mS is not // an excessive timeout value { int count = 3300; do { status = inl(board->ctrl_base_addr + PLX9030_CTRL_STAT_OFFSET); if (status & PLX9030_INIT_MASK) break; } while (count-- > 0); if (count == 0) { printf("FPGA did not come out of /INIT\n"); return -EIO; } } printf("OK\n"); return 0; } static void plx9030_fixup_LASxBRD_READY(llio_t *self) { board_t *board = self->board; int offsets[] = {PLX9030_LAS0BRD_OFFSET, PLX9030_LAS1BRD_OFFSET, PLX9030_LAS2BRD_OFFSET, PLX9030_LAS3BRD_OFFSET}; int i; for (i = 0; i < 4; i ++) { u32 val; int addr = board->ctrl_base_addr + offsets[i]; val = inl(addr); if (!(val & PLX9030_LASxBRD_READY)) { printf("LAS%dBRD #READY is off, enabling now\n", i); val |= PLX9030_LASxBRD_READY; outl(val, addr); } } } static int plx905x_program_fpga(llio_t *self, char *bitfile_name) { board_t *board = self->board; int bindex, bytesread, i; u32 status; char part_name[32]; struct stat file_stat; FILE *fp; struct timeval tv1, tv2; if (stat(bitfile_name, &file_stat) != 0) { printf("Can't find file %s\n", bitfile_name); return -1; } fp = fopen(bitfile_name, "rb"); if (fp == NULL) { printf("Can't open file %s: %s\n", bitfile_name, strerror(errno)); return -1; } if (print_bitfile_header(fp, (char*) &part_name, board->llio.verbose) == -1) { fclose(fp); return -1; } printf("Programming FPGA...\n"); printf(" |"); fflush(stdout); gettimeofday(&tv1, NULL); // program the FPGA while (!feof(fp)) { bytesread = fread(&file_buffer, 1, 8192, fp); bindex = 0; while (bindex < bytesread) { outb(bitfile_reverse_bits(file_buffer[bindex]), board->data_base_addr); bindex++; } printf("W"); fflush(stdout); } fclose(fp); printf("\n"); if (board->llio.verbose == 1) { gettimeofday(&tv2, NULL); printf(" Programming time: %.2f seconds\n", (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 + (double) (tv2.tv_sec - tv1.tv_sec)); } // all bytes transferred, make sure FPGA is all set up now for (i = 0; i < PLX905X_DONE_WAIT; i++) { status = inl(board->ctrl_base_addr + PLX905X_CTRL_STAT_OFFSET); if (status & PLX905X_DONE_MASK) break; } if (i >= PLX905X_DONE_WAIT) { printf("Error: Not /DONE; programming not completed.\n"); return -EIO; } if (board->llio.verbose == 1) { gettimeofday(&tv2, NULL); printf("\n Programming time: %.3f seconds", (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 + (double) (tv2.tv_sec - tv1.tv_sec)); } printf("\nBoard FPGA programmed successfully.\n"); return 0; } static int plx905x_reset(llio_t *self) { board_t *board = self->board; int i; u32 status, control; printf("Resetting FPGA... "); // set GPIO bits to GPIO function status = inl(board->ctrl_base_addr + PLX905X_CTRL_STAT_OFFSET); control = status | PLX905X_DONE_ENABLE | PLX905X_PROG_ENABLE; outl(control, board->ctrl_base_addr + PLX905X_CTRL_STAT_OFFSET); // Turn off /PROGRAM bit and insure that DONE isn't asserted outl(control & ~PLX905X_PROGRAM_MASK, board->ctrl_base_addr + PLX905X_CTRL_STAT_OFFSET); status = inl(board->ctrl_base_addr + PLX905X_CTRL_STAT_OFFSET); if (status & PLX905X_DONE_MASK) { // Note that if we see DONE at the start of programming, it's most // likely due to an attempt to access the FPGA at the wrong I/O // location. printf("/DONE status bit indicates busy at start of programming\n"); return -EIO; } // turn on /PROGRAM output bit outl(control | PLX905X_PROGRAM_MASK, board->ctrl_base_addr + PLX905X_CTRL_STAT_OFFSET); // Delay for at least 100 uS. to allow the FPGA to finish its reset // sequencing. 3300 reads is at least 100 us, could be as long as a // few ms for (i = 0; i < 3300; i++) { status = inl(board->ctrl_base_addr + PLX905X_CTRL_STAT_OFFSET); } printf("OK\n"); return 0; } void memcpy32(void *vdest, void *vsrc, int size) { volatile u32 *dest = (volatile u32*)vdest; volatile u32 *src = (volatile u32*)vsrc; while(size) { *dest = *src; dest++; src++; size --; } } int pci_read(llio_t *self, u32 addr, void *buffer, int size) { board_t *board = self->board; assert(size % 4 == 0); memcpy32(buffer, board->base + addr, size/4); return 0; } int pci_write(llio_t *self, u32 addr, void *buffer, int size) { board_t *board = self->board; assert(size % 4 == 0); memcpy32(board->base + addr, buffer, size/4); return 0; } static int pci_board_reload(llio_t *self, int fallback_flag) { board_t *board = self->board; int i; u32 boot_addr, bar0_reg, cookie; u16 cmd_reg; pci_read(&(board->llio), HM2_ICAP_REG, &cookie, sizeof(u32)); if (cookie != HM2_ICAP_COOKIE) { printf("ERROR: Active firmware too old to support --reload\n"); return -1; } if (fallback_flag == 1) { boot_addr = 0x10000; } else { boot_addr = 0x0; } boot_addr |= 0x0B000000; // plus read command in high byte u32 data[14] = { 0xFFFF, // dummy 0xFFFF, // dummy 0xAA99, // sync 0x5566, // sync 0x3261, // load low flash start address boot_addr & 0xFFFF, // start addr 0x3281, // load high start address + read command boot_addr >> 16, // start addr (plus read command in high byte) 0x30A1, // load command register 0x000E, // IPROG command 0x2000, // NOP 0x2000, // NOP 0x2000, // NOP 0x2000 // NOP }; cmd_reg = pci_read_word(board->dev, PCI_COMMAND); bar0_reg = pci_read_long(board->dev, PCI_BASE_ADDRESS_0); for (i = 0; i < 14; i++) { pci_write(&(board->llio), HM2_ICAP_REG, &data[i], sizeof(u32)); usleep(1000); } printf("Waiting for FPGA configuration..."); sleep(2); printf("OK\n"); pci_write_word(board->dev, PCI_COMMAND, cmd_reg); pci_write_long(board->dev, PCI_BASE_ADDRESS_0, bar0_reg); return 0; } static void pci_fix_bar_lengths(struct pci_dev *dev) { #ifdef _WIN32 int i; for (i = 0; i < 6; i++) { u32 saved_bar, size; if (dev->base_addr == 0) continue; saved_bar = pci_read_long(dev, PCI_BASE_ADDRESS_0 + i*4); pci_write_long(dev, PCI_BASE_ADDRESS_0 + i*4, 0xFFFFFFFF); size = pci_read_long(dev, PCI_BASE_ADDRESS_0 + i*4); if (size & PCI_BASE_ADDRESS_SPACE_IO) size = ~(size & PCI_BASE_ADDRESS_IO_MASK) & 0xFF; else size = ~(size & PCI_BASE_ADDRESS_MEM_MASK); pci_write_long(dev, PCI_BASE_ADDRESS_0 + i*4, saved_bar); dev->size[i] = size + 1; } #else (void)dev; #endif } static int pci_board_open(board_t *board) { if (board->mem_base != 0) { #ifdef __linux__ char path[256]; struct pci_dev *dev = board->dev; snprintf(path, sizeof(path), "/sys/bus/pci/devices/%04x:%02x:%02x.%x/enable", dev->domain, dev->bus, dev->dev, dev->func); int enable_fd = open_as_root(path, O_RDWR); if (enable_fd < 0) { perror("open_as_root(enable)"); abort(); } write(enable_fd, "1\n", 2); close(enable_fd); board->base = mmap(0, board->len, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, board->mem_base); if (board->base == NULL || board->base == MAP_FAILED) { perror("mmap pci"); abort(); } #elif _WIN32 board->base = map_memory(board->mem_base, board->len, &(board->mem_handle)); #endif } if (board->flash != BOARD_FLASH_NONE) { eeprom_init(&(board->llio)); board->flash_id = read_flash_id(&(board->llio)); if (board->fallback_support == 1) { eeprom_prepare_boot_block(board->flash_id); board->flash_start_address = eeprom_calc_user_space(board->flash_id); } else { board->flash_start_address = 0; } } return 0; } static int pci_board_close(board_t *board) { if (board->base) { #ifdef __linux__ munmap(board->base, board->len); char path[256]; struct pci_dev *dev = board->dev; snprintf(path, sizeof(path), "/sys/bus/pci/devices/%04x:%02x:%02x.%x/enable", dev->domain, dev->bus, dev->dev, dev->func); int enable_fd = open_as_root(path, O_RDWR); if (enable_fd < 0) { perror("open_as_root(enable)"); abort(); } write(enable_fd, "0\n", 2); close(enable_fd); #elif _WIN32 unmap_memory(&(board->mem_handle)); #endif } eeprom_cleanup(&(board->llio)); return 0; } int pci_boards_init(board_access_t *access) { (void)access; int eno; #ifdef __linux__ if (seteuid(0) != 0) { printf("You need root privileges (or setuid root) to access PCI hardware\n"); return -1; } pacc = pci_alloc(); pci_init(pacc); // inicjowanie biblioteki libpci memfd = open("/dev/mem", O_RDWR); eno = errno; if (seteuid(getuid()) != 0) { printf("Failed to restore euid: %s\n", strerror(errno)); return -1; } if (memfd < 0) { printf("%s can't open /dev/mem: %s", __func__, strerror(eno)); return -1; } iopl(3); #elif _WIN32 init_io_library(); #endif return 0; } void pci_boards_cleanup(board_access_t *access) { (void)access; #ifdef __linux__ close(memfd); #elif _WIN32 release_io_library(); #endif pci_cleanup(pacc); } void pci_boards_scan(board_access_t *access) { struct pci_dev *dev; board_t *board; pci_scan_bus(pacc); for (dev = pacc->devices; dev != NULL; dev = dev->next) // first run - fill data struct pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES | PCI_FILL_CLASS); if (access->recover == 1) { for (dev = pacc->devices; dev != NULL; dev = dev->next) { board = &boards[boards_count]; board_init_struct(board); if ((dev->vendor_id == VENDORID_XIO2001) && (dev->device_id == DEVICEID_XIO2001)) { board->type = BOARD_PCI; strcpy(board->llio.board_name, "6I25 (RECOVER)"); board->llio.num_ioport_connectors = 2; board->llio.pins_per_connector = 17; board->llio.ioport_connector_name[0] = "P3"; board->llio.ioport_connector_name[1] = "P2"; board->llio.fpga_part_number = "6slx9tqg144"; board->llio.num_leds = 2; board->llio.write_flash = &local_write_flash; board->llio.verify_flash = &local_verify_flash; board->open = &pci_board_open; board->close = &pci_board_close; board->print_info = &pci_print_info; board->mem_base = 0; board->dev = dev; board->flash = BOARD_FLASH_GPIO; board->fallback_support = 1; board->recover = 1; board->llio.verbose = access->verbose; boards_count++; break; } } return; } for (dev = pacc->devices; dev != NULL; dev = dev->next) { board = &boards[boards_count]; board_init_struct(board); if (dev->vendor_id == VENDORID_MESAPCI) { if (dev->device_id == DEVICEID_MESA4I74) { board->type = BOARD_PCI; strcpy((char *) board->llio.board_name, "4I74"); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P1"; board->llio.ioport_connector_name[1] = "P3"; board->llio.ioport_connector_name[2] = "P4"; board->llio.fpga_part_number = "6slx9tqg144"; board->llio.num_leds = 0; board->llio.read = &pci_read; board->llio.write = &pci_write; board->llio.write_flash = &local_write_flash; board->llio.verify_flash = &local_verify_flash; board->llio.backup_flash = &local_backup_flash; board->llio.restore_flash = &local_restore_flash; board->open = &pci_board_open; board->close = &pci_board_close; board->print_info = &pci_print_info; pci_fix_bar_lengths(dev); board->mem_base = dev->base_addr[0] & PCI_ADDR_MEM_MASK; board->len = dev->size[0]; board->dev = dev; board->flash = BOARD_FLASH_HM2; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count++; } else if (dev->device_id == DEVICEID_MESA5I24) { board->type = BOARD_PCI; strcpy(board->llio.board_name, "5I24"); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P4"; board->llio.ioport_connector_name[1] = "P3"; board->llio.ioport_connector_name[2] = "P2"; board->llio.fpga_part_number = "6slx16ftg256 | 6slx25ftg256"; board->llio.num_leds = 4; board->llio.read = &pci_read; board->llio.write = &pci_write; board->llio.write_flash = &local_write_flash; board->llio.verify_flash = &local_verify_flash; board->llio.reload = &pci_board_reload; board->llio.backup_flash = &local_backup_flash; board->llio.restore_flash = &local_restore_flash; board->open = &pci_board_open; board->close = &pci_board_close; board->print_info = &pci_print_info; pci_fix_bar_lengths(dev); board->mem_base = dev->base_addr[0] & PCI_ADDR_MEM_MASK; board->len = dev->size[0]; board->dev = dev; board->flash = BOARD_FLASH_HM2; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count++; } else if (dev->device_id == DEVICEID_MESA5I25) { board->type = BOARD_PCI; strcpy(board->llio.board_name, "5I25"); board->llio.num_ioport_connectors = 2; board->llio.pins_per_connector = 17; board->llio.ioport_connector_name[0] = "P3"; board->llio.ioport_connector_name[1] = "P2"; board->llio.fpga_part_number = "6slx9tqg144"; board->llio.num_leds = 2; board->llio.read = &pci_read; board->llio.write = &pci_write; board->llio.write_flash = &local_write_flash; board->llio.verify_flash = &local_verify_flash; board->llio.reload = &pci_board_reload; board->llio.backup_flash = &local_backup_flash; board->llio.restore_flash = &local_restore_flash; board->open = &pci_board_open; board->close = &pci_board_close; board->print_info = &pci_print_info; pci_fix_bar_lengths(dev); board->mem_base = dev->base_addr[0] & PCI_ADDR_MEM_MASK; board->len = dev->size[0]; board->dev = dev; board->flash = BOARD_FLASH_HM2; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count++; } else if (dev->device_id == DEVICEID_MESA6I24) { board->type = BOARD_PCI; strcpy(board->llio.board_name, "6I24"); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P4"; board->llio.ioport_connector_name[1] = "P3"; board->llio.ioport_connector_name[2] = "P2"; board->llio.fpga_part_number = "6slx16ftg256 | 6slx25ftg256"; board->llio.num_leds = 4; board->llio.read = &pci_read; board->llio.write = &pci_write; board->llio.write_flash = &local_write_flash; board->llio.verify_flash = &local_verify_flash; board->llio.reload = &pci_board_reload; board->llio.backup_flash = &local_backup_flash; board->llio.restore_flash = &local_restore_flash; board->open = &pci_board_open; board->close = &pci_board_close; board->print_info = &pci_print_info; pci_fix_bar_lengths(dev); board->mem_base = dev->base_addr[0] & PCI_ADDR_MEM_MASK; board->len = dev->size[0]; board->dev = dev; board->flash = BOARD_FLASH_HM2; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count++; } else if (dev->device_id == DEVICEID_MESA6I25) { board->type = BOARD_PCI; strcpy(board->llio.board_name, "6I25"); board->llio.num_ioport_connectors = 2; board->llio.pins_per_connector = 17; board->llio.ioport_connector_name[0] = "P3"; board->llio.ioport_connector_name[1] = "P2"; board->llio.fpga_part_number = "6slx9tqg144"; board->llio.num_leds = 2; board->llio.read = &pci_read; board->llio.write = &pci_write; board->llio.write_flash = &local_write_flash; board->llio.verify_flash = &local_verify_flash; board->llio.reload = &pci_board_reload; board->llio.backup_flash = &local_backup_flash; board->llio.restore_flash = &local_restore_flash; board->open = &pci_board_open; board->close = &pci_board_close; board->print_info = &pci_print_info; pci_fix_bar_lengths(dev); board->mem_base = dev->base_addr[0] & PCI_ADDR_MEM_MASK; board->len = dev->size[0]; board->dev = dev; board->flash = BOARD_FLASH_HM2; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count++; } } else if (dev->vendor_id == VENDORID_PLX) { if (dev->device_id == DEVICEID_PLX9030) { u16 ssid = pci_read_word(dev, PCI_SUBSYSTEM_ID); if (ssid == SUBDEVICEID_MESA5I20) { board->type = BOARD_PCI; strcpy(board->llio.board_name, "5I20"); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P2"; board->llio.ioport_connector_name[1] = "P3"; board->llio.ioport_connector_name[2] = "P4"; board->llio.fpga_part_number = "2s200pq208"; board->llio.num_leds = 8; board->llio.read = &pci_read; board->llio.write = &pci_write; board->llio.program_fpga = &plx9030_program_fpga; board->llio.reset = &plx9030_reset; board->open = &pci_board_open; board->close = &pci_board_close; board->print_info = &pci_print_info; pci_fix_bar_lengths(dev); board->mem_base = dev->base_addr[5] & PCI_ADDR_MEM_MASK; board->len = dev->size[5]; board->ctrl_base_addr = dev->base_addr[1] & PCI_ADDR_IO_MASK; board->data_base_addr = dev->base_addr[2] & PCI_ADDR_IO_MASK; board->dev = dev; board->flash = BOARD_FLASH_NONE; board->llio.verbose = access->verbose; boards_count++; // fix up LASxBRD READY if needed plx9030_fixup_LASxBRD_READY(&(board->llio)); } else if (ssid == SUBDEVICEID_MESA4I65) { board->type = BOARD_PCI; strcpy(board->llio.board_name, "4I65"); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P1"; board->llio.ioport_connector_name[1] = "P3"; board->llio.ioport_connector_name[2] = "P4"; board->llio.fpga_part_number = "2s200pq208"; board->llio.num_leds = 8; board->llio.read = &pci_read; board->llio.write = &pci_write; board->llio.program_fpga = &plx9030_program_fpga; board->llio.reset = &plx9030_reset; board->open = &pci_board_open; board->close = &pci_board_close; board->print_info = &pci_print_info; pci_fix_bar_lengths(dev); board->mem_base = dev->base_addr[5] & PCI_ADDR_MEM_MASK; board->len = dev->size[5]; board->ctrl_base_addr = dev->base_addr[1] & PCI_ADDR_IO_MASK; board->data_base_addr = dev->base_addr[2] & PCI_ADDR_IO_MASK; board->dev = dev; board->flash = BOARD_FLASH_NONE; board->llio.verbose = access->verbose; boards_count++; // fix up LASxBRD READY if needed plx9030_fixup_LASxBRD_READY(&(board->llio)); } } else if (dev->device_id == DEVICEID_PLX9054) { u16 ssid = pci_read_word(dev, PCI_SUBSYSTEM_ID); if ((ssid == SUBDEVICEID_MESA4I68_OLD) || (ssid == SUBDEVICEID_MESA4I68)) { board->type = BOARD_PCI; strcpy(board->llio.board_name, "4I68"); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P1"; board->llio.ioport_connector_name[1] = "P2"; board->llio.ioport_connector_name[2] = "P4"; board->llio.fpga_part_number = "3s400pq208"; board->llio.num_leds = 4; board->llio.read = &pci_read; board->llio.write = &pci_write; board->llio.program_fpga = &plx905x_program_fpga; board->llio.reset = &plx905x_reset; board->open = &pci_board_open; board->close = &pci_board_close; board->print_info = &pci_print_info; pci_fix_bar_lengths(dev); board->mem_base = dev->base_addr[3] & PCI_ADDR_MEM_MASK; board->len = dev->size[3]; board->ctrl_base_addr = dev->base_addr[1] & PCI_ADDR_IO_MASK; board->data_base_addr = dev->base_addr[2] & PCI_ADDR_IO_MASK; board->dev = dev; board->flash = BOARD_FLASH_NONE; board->llio.verbose = access->verbose; boards_count++; } else if (ssid == SUBDEVICEID_MESA5I21) { board->type = BOARD_PCI; strcpy(board->llio.board_name, "5I21"); board->llio.num_ioport_connectors = 2; board->llio.pins_per_connector = 32; board->llio.ioport_connector_name[0] = "P1"; board->llio.ioport_connector_name[1] = "P1"; board->llio.fpga_part_number = "3s400pq208"; board->llio.num_leds = 8; board->llio.read = &pci_read; board->llio.write = &pci_write; board->llio.program_fpga = &plx905x_program_fpga; board->llio.reset = &plx905x_reset; board->open = &pci_board_open; board->close = &pci_board_close; board->print_info = &pci_print_info; pci_fix_bar_lengths(dev); board->mem_base = dev->base_addr[3] & PCI_ADDR_MEM_MASK; board->len = dev->size[3]; board->ctrl_base_addr = dev->base_addr[1] & PCI_ADDR_IO_MASK; board->data_base_addr = dev->base_addr[2] & PCI_ADDR_IO_MASK; board->dev = dev; board->flash = BOARD_FLASH_NONE; board->llio.verbose = access->verbose; boards_count++; } else if ((ssid == SUBDEVICEID_MESA5I22_10) || (ssid == SUBDEVICEID_MESA5I22_15)) { board->type = BOARD_PCI; strcpy(board->llio.board_name, "5I22"); board->llio.num_ioport_connectors = 4; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P2"; board->llio.ioport_connector_name[1] = "P3"; board->llio.ioport_connector_name[2] = "P4"; board->llio.ioport_connector_name[3] = "P5"; if (ssid == SUBDEVICEID_MESA5I22_10) { board->llio.fpga_part_number = "3s1000fg320"; } else if (ssid == SUBDEVICEID_MESA5I22_15) { board->llio.fpga_part_number = "3s1500fg320"; } board->llio.num_leds = 8; board->llio.read = &pci_read; board->llio.write = &pci_write; board->llio.program_fpga = &plx905x_program_fpga; board->llio.reset = &plx905x_reset; board->open = &pci_board_open; board->close = &pci_board_close; board->print_info = &pci_print_info; pci_fix_bar_lengths(dev); board->mem_base = dev->base_addr[3] & PCI_ADDR_MEM_MASK; board->len = dev->size[3]; board->ctrl_base_addr = dev->base_addr[1] & PCI_ADDR_IO_MASK; board->data_base_addr = dev->base_addr[2] & PCI_ADDR_IO_MASK; board->dev = dev; board->flash = BOARD_FLASH_NONE; board->llio.verbose = access->verbose; boards_count++; } else if (ssid == SUBDEVICEID_MESA5I23) { board->type = BOARD_PCI; strcpy(board->llio.board_name, "5I23"); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P2"; board->llio.ioport_connector_name[1] = "P3"; board->llio.ioport_connector_name[2] = "P4"; board->llio.fpga_part_number = "3s400pq208"; board->llio.num_leds = 2; board->llio.read = &pci_read; board->llio.write = &pci_write; board->llio.program_fpga = &plx905x_program_fpga; board->llio.reset = &plx905x_reset; board->open = &pci_board_open; board->close = &pci_board_close; board->print_info = &pci_print_info; pci_fix_bar_lengths(dev); board->mem_base = dev->base_addr[3] & PCI_ADDR_MEM_MASK; board->len = dev->size[3]; board->ctrl_base_addr = dev->base_addr[1] & PCI_ADDR_IO_MASK; board->data_base_addr = dev->base_addr[2] & PCI_ADDR_IO_MASK; board->dev = dev; board->flash = BOARD_FLASH_NONE; board->llio.verbose = access->verbose; boards_count++; } else if ((ssid == SUBDEVICEID_MESA4I69_16) || (ssid == SUBDEVICEID_MESA4I69_25)) { board->type = BOARD_PCI; strcpy(board->llio.board_name, "4I69"); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P1"; board->llio.ioport_connector_name[1] = "P3"; board->llio.ioport_connector_name[2] = "P4"; if (ssid == SUBDEVICEID_MESA4I69_16) { board->llio.fpga_part_number = "6slx16ftg256"; } else if (ssid == SUBDEVICEID_MESA4I69_25) { board->llio.fpga_part_number = "6slx25ftg256"; } board->llio.num_leds = 8; board->llio.read = &pci_read; board->llio.write = &pci_write; board->llio.program_fpga = &plx905x_program_fpga; board->llio.reset = &plx905x_reset; board->open = &pci_board_open; board->close = &pci_board_close; board->print_info = &pci_print_info; pci_fix_bar_lengths(dev); board->mem_base = dev->base_addr[3] & PCI_ADDR_MEM_MASK; board->len = dev->size[3]; board->ctrl_base_addr = dev->base_addr[1] & PCI_ADDR_IO_MASK; board->data_base_addr = dev->base_addr[2] & PCI_ADDR_IO_MASK; board->dev = dev; board->flash = BOARD_FLASH_NONE; board->llio.verbose = access->verbose; boards_count++; } } else if (dev->device_id == DEVICEID_PLX9056) { u16 ssid = pci_read_word(dev, PCI_SUBSYSTEM_ID); if ((ssid == SUBDEVICEID_MESA3X20_10) || (ssid == SUBDEVICEID_MESA3X20_15) || (ssid == SUBDEVICEID_MESA3X20_20)) { board->type = BOARD_PCI; strcpy(board->llio.board_name, "3X20"); board->llio.num_ioport_connectors = 6; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P4"; board->llio.ioport_connector_name[1] = "P5"; board->llio.ioport_connector_name[2] = "P6"; board->llio.ioport_connector_name[3] = "P9"; board->llio.ioport_connector_name[4] = "P8"; board->llio.ioport_connector_name[5] = "P7"; if (ssid == SUBDEVICEID_MESA3X20_10) { board->llio.fpga_part_number = "3s1000fg456"; } else if (ssid == SUBDEVICEID_MESA3X20_15) { board->llio.fpga_part_number = "3s1500fg456"; } else if (ssid == SUBDEVICEID_MESA3X20_20) { board->llio.fpga_part_number = "3s2000fg456"; } board->llio.num_leds = 0; board->llio.read = &pci_read; board->llio.write = &pci_write; board->llio.program_fpga = &plx905x_program_fpga; board->llio.reset = &plx905x_reset; board->llio.write_flash = &local_write_flash; board->llio.verify_flash = &local_verify_flash; board->open = &pci_board_open; board->close = &pci_board_close; board->print_info = &pci_print_info; pci_fix_bar_lengths(dev); board->mem_base = dev->base_addr[3] & PCI_ADDR_MEM_MASK; board->len = dev->size[3]; board->ctrl_base_addr = dev->base_addr[1] & PCI_ADDR_IO_MASK; board->data_base_addr = dev->base_addr[2] & PCI_ADDR_IO_MASK; board->dev = dev; board->flash = BOARD_FLASH_IO; board->fallback_support = 0; board->llio.verbose = access->verbose; boards_count++; } } else if (dev->device_id == DEVICEID_PLX8112) { board->type = BOARD_PCI; strcpy(board->llio.board_name, "5I71"); board->open = &pci_board_open; board->close = &pci_board_close; board->print_info = &pci_print_info; board->dev = dev; board->llio.verbose = access->verbose; boards_count++; } } } } void pci_print_info(board_t *board) { int i; printf("\nPCI device %s at %04X:%02X:%02X.%1X\n", board->llio.board_name, board->dev->domain, board->dev->bus, board->dev->dev, board->dev->func); if (board->llio.verbose == 0) return; printf(" Device ID [%04X:%04X], Subsystem device ID [%04X:%04X]\n", board->dev->vendor_id, board->dev->device_id, pci_read_word(board->dev, PCI_SUBSYSTEM_VENDOR_ID), pci_read_word(board->dev, PCI_SUBSYSTEM_ID)); for (i = 0; i < 6; i++) { u32 flags = pci_read_long(board->dev, PCI_BASE_ADDRESS_0 + 4*i); if (board->dev->base_addr[i] != 0) { if (flags & PCI_BASE_ADDRESS_SPACE_IO) { printf(" Region %d: I/O at %04X", i, (unsigned int) (board->dev->base_addr[i] & PCI_BASE_ADDRESS_IO_MASK)); show_formatted_size(board->dev->size[i]); printf("\n"); } else { printf(" Region %d: Memory at %016" PRIx64, i, board->dev->base_addr[i]); show_formatted_size(board->dev->size[i]); printf("\n"); } } } printf("Communication:\n"); if (board->ctrl_base_addr > 0) printf(" Ctrl I/O addr: %04X\n", board->ctrl_base_addr); if (board->data_base_addr > 0) printf(" Data I/O addr: %04X\n", board->data_base_addr); if (board->mem_base > 0) printf(" Memory: %016" PRIx64 "\n", board->mem_base); show_board_info(board); } #endif mesaflash-3.4.6/pci_boards.h000066400000000000000000000107261433153454000157550ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __PCI_BOARDS_H #define __PCI_BOARDS_H #include "types.h" #include "boards.h" #define VENDORID_MESAPCI 0x2718 #define VENDORID_PLX 0x10B5 #define VENDORID_XIO2001 0x104C #define DEVICEID_MESA4I74 0x4174 #define DEVICEID_MESA5I24 0x5124 #define DEVICEID_MESA5I25 0x5125 #define DEVICEID_MESA6I24 0x6124 #define DEVICEID_MESA6I25 0x6125 #define DEVICEID_PLX9030 0x9030 #define DEVICEID_PLX9054 0x9054 #define DEVICEID_PLX9056 0x9056 #define DEVICEID_PLX8112 0x8112 #define DEVICEID_XIO2001 0x8240 #define SUBDEVICEID_MESA5I20 0x3131 #define SUBDEVICEID_MESA4I65 0x3132 #define SUBDEVICEID_MESA4I68_OLD 0x3133 #define SUBDEVICEID_MESA4I68 0x3311 #define SUBDEVICEID_MESA5I21 0x3312 #define SUBDEVICEID_MESA5I22_15 0x3313 #define SUBDEVICEID_MESA5I22_10 0x3314 #define SUBDEVICEID_MESA5I23 0x3315 #define SUBDEVICEID_MESA3X20_10 0x3427 #define SUBDEVICEID_MESA3X20_15 0x3428 #define SUBDEVICEID_MESA3X20_20 0x3429 #define SUBDEVICEID_MESA4I69_16 0x3472 #define SUBDEVICEID_MESA4I69_25 0x3473 #define EEPROM_93C66_SIZE 256 #define EEPROM_93C66_CMD_LEN 3 #define EEPROM_93C66_ADDR_LEN 8 #define EEPROM_93C66_DATA_LEN 16 #define EEPROM_93C66_CMD_WREN 4 #define EEPROM_93C66_CMD_WRITE 5 #define EEPROM_93C66_CMD_READ 6 #define EEPROM_93C66_CMD_ERASE 7 #define EEPROM_93C66_CMD_MASK 0x04 #define EEPROM_93C66_ADDR_MASK 0x80 #define EEPROM_93C66_DATA_MASK 0x8000 // // PLX 9030 (5i20, 4i65) // // I/O registers #define PLX9030_CTRL_INIT_OFFSET 0x0052 #define PLX9030_CTRL_STAT_OFFSET 0x0054 /* 9030 GPIO register (region 1) */ // bit number in 9030 INIT register #define PLX9030_EECLK_MASK 0x0100 #define PLX9030_EECS_MASK 0x0200 #define PLX9030_EEDI_MASK 0x0400 #define PLX9030_EEDO_MASK 0x0800 // bit number in 9030 GPIO register #define PLX9030_GPIO_3_MASK (1<<11) /* GPIO 3 */ #define PLX9030_DONE_MASK (1<<11) /* GPIO 3 */ #define PLX9030_INIT_MASK (1<<14) /* GPIO 4 */ #define PLX9030_LED_MASK (1<<17) /* GPIO 5 */ #define PLX9030_GPIO_6_MASK (1<<20) /* GPIO 6 */ #define PLX9030_WRITE_MASK (1<<23) /* GPIO 7 */ #define PLX9030_PROGRAM_MASK (1<<26) /* GPIO 8 */ // the LAS?BRD registers are in the PLX 9030 // // The HostMot2 firmware needs the #READY bit (0x2) set in order to work, // but the EEPROMs on some older 5i20 cards dont set them right. // The driver detects this problem and fixes it up. // #define PLX9030_LAS0BRD_OFFSET 0x28 #define PLX9030_LAS1BRD_OFFSET 0x2C #define PLX9030_LAS2BRD_OFFSET 0x30 #define PLX9030_LAS3BRD_OFFSET 0x34 #define PLX9030_LASxBRD_READY 0x2 // // PLX 9054 (5i22, 5i23, 4i68, 4i69) // Note: also used for the PLX 9056 (3x20) // // I/O register indices. #define PLX905X_CTRL_STAT_OFFSET 0x006C // 32-bit control/status register. #define PLX9056_VPD_ADDR 0x4E #define PLX9056_VPD_DATA 0x50 #define PLX9056_VPD_FMASK 0x8000 // F bit in VPD address register // bit number in 9054 GPIO register // yes, the direction control bits are not in the same order as the I/O bits #define PLX905X_DONE_MASK (1<<17) // GPI #define PLX905X_PROGRAM_MASK (1<<16) // GPO, active low #define PLX905X_DONE_ENABLE (1<<18) // GPI direction control, 1=input #define PLX905X_PROG_ENABLE (1<<19) // GPO direction control, 1=output /* how long should we wait for DONE when programming 9054-based cards */ #define PLX905X_DONE_WAIT 20000 int pci_boards_init(board_access_t *access); void pci_boards_cleanup(board_access_t *access); void pci_boards_scan(board_access_t *access); void pci_print_info(board_t *board); #endif mesaflash-3.4.6/serial_boards.c000066400000000000000000000257321433153454000164570ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #include #include #include #include #include #include #include #include #include #include #include "types.h" #include "anyio.h" #include "serial_boards.h" #include "lbp16.h" #include "eeprom.h" #include "eeprom_remote.h" extern board_t boards[MAX_BOARDS]; extern int boards_count; static int sd = -1; // serial access functions int serial_send_packet(void *packet, int size) { int rc, ret; int r = 0, timeouts = 0; struct timespec timeout = {0, 50*1000*1000}; struct pollfd fds[1]; fds[0].fd = sd; fds[0].events = POLLOUT; while (r < size) { rc = ppoll(fds, 1, &timeout, NULL); if (rc > 0) { ret = write(sd, packet, size); r += ret; } else if (rc == 0) { timeouts ++; if (timeouts == 5) { printf("serial write timeout!\n"); return -1; } } else if (rc < 0) { break; } } return r; } int serial_recv_packet(void *packet, int size) { int rc, ret; int r = 0, timeouts = 0; struct timespec timeout = {0, 300*1000*1000}; struct pollfd fds[1]; fds[0].fd = sd; fds[0].events = POLLIN; char buffer[1024]; while (r < size) { rc = ppoll(fds, 1, &timeout, NULL); if (rc > 0) { ret = read(sd, buffer + r, 1); if (ret < 0) { printf("serial read error: %s\n", strerror(errno)); return -1; } else if (ret == 0) { printf("serial read EOF\n"); return -1; } r += ret; } else if (rc == 0) { timeouts ++; if (timeouts == 5) { printf("serial read timeout!\n"); return -1; } } else if (rc < 0) { break; } } memcpy(packet, buffer, r); return r; } static int serial_read(llio_t *self, u32 addr, void *buffer, int size) { (void)self; return lbp16_read(CMD_READ_HOSTMOT2_ADDR32_INCR(size/4), addr, buffer, size); } static int serial_write(llio_t *self, u32 addr, void *buffer, int size) { (void)self; return lbp16_write(CMD_WRITE_HOSTMOT2_ADDR32_INCR(size/4), addr, buffer, size); } static int serial_board_open(board_t *board) { eeprom_init(&(board->llio)); lbp16_read(CMD_READ_FLASH_IDROM, FLASH_ID_REG, &(board->flash_id), sizeof(u32)); if (board->fallback_support == 1) { eeprom_prepare_boot_block(board->flash_id); board->flash_start_address = eeprom_calc_user_space(board->flash_id); } else { board->flash_start_address = 0; } return 0; } static int serial_board_close(board_t *board) { (void)board; return 0; } // public functions int serial_boards_init(board_access_t *access) { #ifdef __linux__ struct termios options; sd = open(access->dev_addr, O_RDWR | O_NOCTTY | O_NONBLOCK); if (sd == -1) { perror("Unable to open the serial port\n"); } tcgetattr(sd, &options); /* Get the current options for the port */ cfsetispeed(&options, B115200); /* Set the baud rates to 9600 */ cfsetospeed(&options, B115200); options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; options.c_cflag &= ~(PARENB | PARODD); // shut off parity options.c_lflag = 0; options.c_cflag &= ~CRTSCTS; /* Disable hardware flow control */ options.c_iflag &= ~IGNBRK; options.c_oflag = 0; tcsetattr(sd, TCSANOW, &options); #elif _WIN32 char dev_name[32]; snprintf(dev_name, 32, "\\\\.\\%s", access->dev_addr); sd = CreateFile(dev_name, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if (sd == INVALID_HANDLE_VALUE) { printf("Unable to open the serial port %d\n", errno); } #endif lbp16_init(BOARD_SER); return 0; } void serial_boards_cleanup(board_access_t *access) { (void)access; close(sd); } void serial_boards_scan(board_access_t *access) { lbp16_cmd_addr packet; char buff[16]; LBP16_INIT_PACKET4(packet, CMD_READ_BOARD_INFO_ADDR16_INCR(8), 0); lbp16_send_packet_checked(&packet, sizeof(packet)); lbp16_recv_packet_checked(buff, 16); if (strncmp(buff, "7I90HD", 6) == 0) { board_t *board = &boards[boards_count]; board_init_struct(board); board->type = BOARD_SER; strncpy(board->dev_addr, access->dev_addr, 16); strncpy(board->llio.board_name, buff, 16); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P1"; board->llio.ioport_connector_name[1] = "P2"; board->llio.ioport_connector_name[2] = "P3"; board->llio.fpga_part_number = "6slx9tqg144"; board->llio.num_leds = 2; board->llio.read = &serial_read; board->llio.write = &serial_write; board->llio.write_flash = &remote_write_flash; board->llio.verify_flash = &remote_verify_flash; board->llio.reset = &lbp16_board_reset; board->llio.reload = &lbp16_board_reload; board->open = &serial_board_open; board->close = &serial_board_close; board->print_info = &serial_print_info; board->flash = BOARD_FLASH_REMOTE; board->fallback_support = 1; board->llio.verbose = access->verbose; boards_count++; } } void serial_print_info(board_t *board) { lbp16_cmd_addr packet; int i, j; char *mem_types[16] = {NULL, "registers", "memory", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "EEPROM", "flash"}; char *mem_writeable[2] = {"RO", "RW"}; char *acc_types[4] = {"8-bit", "16-bit", "32-bit", "64-bit"}; lbp_mem_info_area mem_area; lbp_timers_area timers_area; lbp_status_area stat_area; lbp_info_area info_area; lbp16_cmd_addr cmds[LBP16_MEM_SPACE_COUNT]; printf("\nSerial device %s at %s\n", board->llio.board_name, board->dev_addr); if (board->llio.verbose == 0) return; LBP16_INIT_PACKET4(cmds[0], CMD_READ_AREA_INFO_ADDR16_INCR(LBP16_SPACE_HM2, sizeof(mem_area)/2), 0); LBP16_INIT_PACKET4(cmds[1], 0, 0); LBP16_INIT_PACKET4(cmds[2], 0, 0); LBP16_INIT_PACKET4(cmds[3], CMD_READ_AREA_INFO_ADDR16_INCR(LBP16_SPACE_FPGA_FLASH, sizeof(mem_area)/2), 0); LBP16_INIT_PACKET4(cmds[4], 0, 0); LBP16_INIT_PACKET4(cmds[5], 0, 0); LBP16_INIT_PACKET4(cmds[6], CMD_READ_AREA_INFO_ADDR16_INCR(LBP16_SPACE_COMM_CTRL, sizeof(mem_area)/2), 0); LBP16_INIT_PACKET4(cmds[7], CMD_READ_AREA_INFO_ADDR16_INCR(LBP16_SPACE_BOARD_INFO, sizeof(mem_area)/2), 0); LBP16_INIT_PACKET4(packet, CMD_READ_COMM_CTRL_ADDR16_INCR(sizeof(stat_area)/2), 0); memset(&stat_area, 0, sizeof(stat_area)); lbp16_send_packet_checked(&packet, sizeof(packet)); lbp16_recv_packet_checked(&stat_area, sizeof(stat_area)); LBP16_INIT_PACKET4(packet, CMD_READ_BOARD_INFO_ADDR16_INCR(sizeof(info_area)/2), 0); memset(&info_area, 0, sizeof(info_area)); lbp16_send_packet_checked(&packet, sizeof(packet)); lbp16_recv_packet_checked(&info_area, sizeof(info_area)); if (info_area.LBP16_version >= 3) { LBP16_INIT_PACKET4(cmds[4], CMD_READ_AREA_INFO_ADDR16_INCR(LBP16_SPACE_TIMER, sizeof(mem_area)/2), 0); LBP16_INIT_PACKET4(packet, CMD_READ_TIMER_ADDR16_INCR(sizeof(timers_area)/2), 0); memset(&timers_area, 0, sizeof(timers_area)); lbp16_send_packet_checked(&packet, sizeof(packet)); lbp16_recv_packet_checked(&timers_area, sizeof(timers_area)); } printf("Communication:\n"); printf(" transport layer: serial\n"); printf(" protocol: LBP16 version %d\n", info_area.LBP16_version); show_board_info(board); printf("Board firmware info:\n"); printf(" memory spaces:\n"); for (i = 0; i < LBP16_MEM_SPACE_COUNT; i++) { u32 size; if ((cmds[i].cmd_lo == 0) && (cmds[i].cmd_hi == 0)) continue; memset(&mem_area, 0, sizeof(mem_area)); lbp16_send_packet_checked(&cmds[i], sizeof(cmds[i])); lbp16_recv_packet_checked(&mem_area, sizeof (mem_area)); printf(" %d: %.*s (%s, %s", i, (int)sizeof(mem_area.name), mem_area.name, mem_types[(mem_area.size >> 8) & 0x7F], mem_writeable[(mem_area.size & 0x8000) >> 15]); for (j = 0; j < 4; j++) { if ((mem_area.size & 0xFF) & 1 << j) printf(", %s)", acc_types[j]); } size = pow(2, mem_area.range & 0x3F); show_formatted_size(size); if (((mem_area.size >> 8) & 0x7F) >= 0xE) printf(", page size: %u, erase size: %u", (unsigned int) pow(2, (mem_area.range >> 6) & 0x1F), (unsigned int) pow(2, (mem_area.range >> 11) & 0x1F)); printf("\n"); } printf(" [space 0] HostMot2\n"); printf(" [space 3] FPGA flash eeprom:\n"); printf(" flash size: %s (id: 0x%02X)\n", eeprom_get_flash_type(board->flash_id), board->flash_id); if (info_area.LBP16_version >= 3) { printf(" [space 4] timers:\n"); printf(" uSTimeStampReg: 0x%04X\n", timers_area.uSTimeStampReg); printf(" WaituSReg: 0x%04X\n", timers_area.WaituSReg); printf(" HM2Timeout: 0x%04X\n", timers_area.HM2Timeout); } printf(" [space 6] LBP16 control/status:\n"); printf(" packets received: all %d, good %d, bad %d\n", stat_area.RXPacketCount, stat_area.RXGoodCount, stat_area.RXBadCount); printf(" packets sent: all %d, good %d, bad %d\n", stat_area.TXPacketCount, stat_area.TXGoodCount, stat_area.TXBadCount); printf(" parse errors: %d, mem errors %d, write errors %d\n", stat_area.LBPParseErrors, stat_area.LBPMemErrors, stat_area.LBPWriteErrors); printf(" error flags: 0x%04X\n", stat_area.ErrorReg); printf(" debug LED ptr: 0x%04X\n", stat_area.DebugLEDPtr); printf(" scratch: 0x%04X\n", stat_area.Scratch); printf(" [space 7] LBP16 info:\n"); printf(" board name: %.*s\n", (int)sizeof(info_area.name), info_area.name); printf(" LBP16 protocol version %d\n", info_area.LBP16_version); printf(" board firmware version %d\n", info_area.firmware_version); } mesaflash-3.4.6/serial_boards.h000066400000000000000000000022251433153454000164540ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __SERIAL_BOARDS_H #define __SERIAL_BOARDS_H #include "anyio.h" int serial_send_packet(void *packet, int size); int serial_recv_packet(void *packet, int size); int serial_boards_init(board_access_t *access); void serial_boards_cleanup(board_access_t *access); void serial_boards_scan(board_access_t *access); void serial_print_info(board_t *board); #endif mesaflash-3.4.6/spi_boards.c000066400000000000000000000242231433153454000157650ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "types.h" #include "eeprom.h" #include "eeprom_local.h" #include "spi_boards.h" #include "common.h" extern board_t boards[MAX_BOARDS]; extern int boards_count; static bool canDo32 = true; static int sd = -1; struct spi_ioc_transfer settings; static int spidev_set_lsb_first(int fd, u8 lsb_first) { return ioctl(fd, SPI_IOC_WR_LSB_FIRST, &lsb_first); } static int spidev_set_mode(int fd, u8 mode) { return ioctl(fd, SPI_IOC_WR_MODE, &mode); } static int spidev_set_max_speed_hz(int fd, u32 speed_hz) { return ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed_hz); } static int spidev_set_bits_per_word(int fd, u8 bits) { return ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); } static u32 read_command(u16 addr, unsigned nelem) { bool increment = true; return (addr << 16) | SPILBP_CMD_READ | (increment ? SPILBP_ADDR_AUTO_INC : 0) | (nelem << 4); } static u32 write_command(u16 addr, unsigned nelem) { bool increment = true; return (addr << 16) | SPILBP_CMD_WRITE | (increment ? SPILBP_ADDR_AUTO_INC : 0) | (nelem << 4); } static int spi_board_open(board_t *board) { eeprom_init(&(board->llio)); board->flash_id = read_flash_id(&(board->llio)); if (board->fallback_support == 1) { eeprom_prepare_boot_block(board->flash_id); board->flash_start_address = eeprom_calc_user_space(board->flash_id); } else { board->flash_start_address = 0; } return 0; } static int spi_board_close(board_t *board) { (void)board; return 0; } int spi_boards_init(board_access_t *access) { settings.speed_hz = 20 * 1000 * 1000; settings.bits_per_word = 32; sd = open(access->dev_addr, O_RDWR); if(sd == -1) { perror("open"); return -1; } spidev_set_lsb_first(sd, false); spidev_set_mode(sd, 0); if (spidev_set_bits_per_word(sd, settings.bits_per_word) < 0) { fprintf(stderr,"unable to set bpw32, fallback to bpw8\n"); canDo32 = false; settings.bits_per_word = 8; spidev_set_bits_per_word(sd, settings.bits_per_word); } spidev_set_max_speed_hz(sd, settings.speed_hz); return 0; } void spi_boards_cleanup(board_access_t *access) { (void)access; if(sd != -1) close(sd); } void reorderBuffer(char *pBuf, int numInts) { int lcv; for (lcv = 0; lcv < numInts; lcv++) { pBuf[0] ^= pBuf[3]; pBuf[3] ^= pBuf[0]; pBuf[0] ^= pBuf[3]; pBuf[1] ^= pBuf[2]; pBuf[2] ^= pBuf[1]; pBuf[1] ^= pBuf[2]; pBuf += 4; } } int spi_read(llio_t *self, u32 addr, void *buffer, int size) { (void)self; if(size % 4 != 0) return -1; int numInts = 1+size/4; u32 trxbuf[numInts]; trxbuf[0] = read_command(addr, size/4); memset(trxbuf+1, 0, size); struct spi_ioc_transfer t; t = settings; t.tx_buf = t.rx_buf = (uint64_t)(intptr_t)trxbuf; t.len = sizeof(trxbuf); if (!canDo32) { reorderBuffer((char *) trxbuf, 1); } int r = ioctl(sd, SPI_IOC_MESSAGE(1), &t); if(r < 0) return r; if (!canDo32) { reorderBuffer((char *) trxbuf, numInts); } memcpy(buffer, trxbuf+1, size); return 0; } int spi_write(llio_t *self, u32 addr, void *buffer, int size) { (void)self; if(size % 4 != 0) return -1; int numInts = 1+size/4; u32 txbuf[numInts]; txbuf[0] = write_command(addr, size/4); memcpy(txbuf + 1, buffer, size); struct spi_ioc_transfer t; t = settings; t.tx_buf = (uint64_t)(intptr_t)txbuf; t.len = sizeof(txbuf); if (!canDo32) { reorderBuffer((char *) txbuf, numInts); } int r = ioctl(sd, SPI_IOC_MESSAGE(1), &t); if(r <= 0) return r; return 0; } static int spi_board_reload(llio_t *self, int fallback_flag) { board_t *board = self->board; int i; u32 boot_addr, cookie; spi_read(&(board->llio), HM2_ICAP_REG, &cookie, sizeof(u32)); if (cookie != HM2_ICAP_COOKIE) { printf("ERROR: Active firmware too old to support --reload\n"); return -1; } if (fallback_flag == 1) { boot_addr = 0x10000; } else { boot_addr = 0x0; } boot_addr |= 0x0B000000; // plus read command in high byte u32 data[14] = { 0xFFFF, // dummy 0xFFFF, // dummy 0xAA99, // sync 0x5566, // sync 0x3261, // load low flash start address boot_addr & 0xFFFF, // start addr 0x3281, // load high start address + read command boot_addr >> 16, // start addr (plus read command in high byte) 0x30A1, // load command register 0x000E, // IPROG command 0x2000, // NOP 0x2000, // NOP 0x2000, // NOP 0x2000 // NOP }; for (i = 0; i < 14; i++) { spi_write(&(board->llio), HM2_ICAP_REG, &data[i], sizeof(u32)); usleep(1000); } printf("Waiting for FPGA configuration..."); sleep(2); printf("OK\n"); return 0; } void spi_boards_scan(board_access_t *access) { u32 buf[4]; u32 cookie[] = {0x55aacafe, 0x54534f48, 0x32544f4d}; board_t *board = &boards[boards_count]; board_init_struct(board); if (spi_read(&(board->llio), HM2_COOKIE_REG, &buf, sizeof(buf)) < 0) { return; } if(memcmp(buf, cookie, sizeof(cookie))) { fprintf(stderr, "Unexpected cookie at %04x..%04zx:\n%08x %08x %08x\n", HM2_COOKIE_REG, HM2_COOKIE_REG + sizeof(buf), buf[0], buf[1], buf[2]); return; } char ident[8]; if(spi_read(&(board->llio), buf[3] + 0xc, &ident, sizeof(ident)) < 0) return; if(!memcmp(ident, "MESA7I90", 8)) { board_t *board = &boards[boards_count]; board->type = BOARD_SPI; strcpy(board->dev_addr, access->dev_addr); strcpy(board->llio.board_name, "7I90"); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P1"; board->llio.ioport_connector_name[1] = "P2"; board->llio.ioport_connector_name[2] = "P3"; board->llio.num_leds = 2; board->llio.verbose = access->verbose; board->llio.write = spi_write; board->llio.read = spi_read; board->llio.write_flash = local_write_flash; board->llio.verify_flash = local_verify_flash; board->llio.reload = &spi_board_reload; board->llio.fpga_part_number = "6slx9tqg144"; board->open = spi_board_open; board->close = spi_board_close; board->print_info = spi_print_info; board->flash = BOARD_FLASH_HM2; board->fallback_support = 1; boards_count ++; } else if(!memcmp(ident, "MESA7C80", 8)) { board_t *board = &boards[boards_count]; board->type = BOARD_SPI; strcpy(board->dev_addr, access->dev_addr); strcpy(board->llio.board_name, "7C80"); board->llio.num_ioport_connectors = 2; board->llio.pins_per_connector = 27; board->llio.ioport_connector_name[0] = "StepGens+Misc"; board->llio.ioport_connector_name[1] = "Outputs+P1"; board->llio.bob_hint[0] = BOB_7C80_0; board->llio.bob_hint[1] = BOB_7C80_1; board->llio.num_leds = 4; board->llio.verbose = access->verbose; board->llio.write = spi_write; board->llio.read = spi_read; board->llio.write_flash = local_write_flash; board->llio.verify_flash = local_verify_flash; board->llio.reload = &spi_board_reload; board->llio.fpga_part_number = "6slx9tqg144"; board->open = spi_board_open; board->close = spi_board_close; board->print_info = spi_print_info; board->flash = BOARD_FLASH_HM2; board->fallback_support = 1; boards_count ++; } else if(!memcmp(ident, "MESA7C81", 8)) { board_t *board = &boards[boards_count]; board->type = BOARD_SPI; strcpy(board->dev_addr, access->dev_addr); strcpy(board->llio.board_name, "7C81"); board->llio.num_ioport_connectors = 3; board->llio.pins_per_connector = 19; board->llio.ioport_connector_name[0] = "P1+Serial"; board->llio.ioport_connector_name[1] = "P2+Serial"; board->llio.ioport_connector_name[2] = "P7+Serial"; board->llio.bob_hint[0] = BOB_7C81_0; board->llio.bob_hint[1] = BOB_7C81_1; board->llio.bob_hint[2] = BOB_7C81_2; board->llio.num_leds = 4; board->llio.verbose = access->verbose; board->llio.write = spi_write; board->llio.read = spi_read; board->llio.write_flash = local_write_flash; board->llio.verify_flash = local_verify_flash; board->llio.reload = &spi_board_reload; board->llio.fpga_part_number = "6slx9tqg144"; board->open = spi_board_open; board->close = spi_board_close; board->print_info = spi_print_info; board->flash = BOARD_FLASH_HM2; board->fallback_support = 1; boards_count ++; } else { for(size_t i=0; i #include #include #include "types.h" #include "hostmot2.h" #include "sserial_module.h" #include "lbp.h" // Temporarily enable the pins that are not masked by sserial_mode static void enable_sserial_pins(llio_t *llio) { u32 port_pin, port; u32 pin = -1; u16 chan_counts[] = {0,0,0,0,0,0,0,0}; hm2_module_desc_t *md = hm2_find_module(&(llio->hm2), HM2_GTAG_IOPORT); u16 addr = md->base_address; for (port = 0; port < 2; port ++) { u32 ddr_reg = 0; u32 src_reg = 0; for (port_pin = 0; port_pin < llio->hm2.idrom.port_width; port_pin++) { pin++; if (llio->hm2.pins[pin].sec_tag == HM2_GTAG_SSERIAL) { // look for highest-indexed pin to determine number of channels if ((llio->hm2.pins[pin].sec_pin & 0x0F) > chan_counts[llio->hm2.pins[pin].sec_chan]) { chan_counts[llio->hm2.pins[pin].sec_chan] = (llio->hm2.pins[pin].sec_pin & 0x0F); } // check if the channel is enabled //printf("sec unit = %i, sec pin = %i\n", llio->hm2.pins[pin].sec_chan, llio->hm2.pins[pin].sec_pin & 0x0F); src_reg |= (1 << port_pin); if (llio->hm2.pins[pin].sec_pin & 0x80) ddr_reg |= (1 << port_pin); } } llio->write(llio, addr + HM2_MOD_OFFS_GPIO_DDR + 4*port, &ddr_reg, sizeof(u32)); llio->write(llio, addr + HM2_MOD_OFFS_GPIO_ALT_SOURCE + 4*port, &src_reg, sizeof(u32)); } } // Return the physical ports to default static void disable_sserial_pins(llio_t *llio) { int port; u32 ddr_reg = 0; u32 src_reg = 0; hm2_module_desc_t *md = hm2_find_module(&(llio->hm2), HM2_GTAG_IOPORT); u16 addr = md->base_address; for (port = 0; port < 2; port ++) { llio->write(llio, addr + HM2_MOD_OFFS_GPIO_DDR + 4*port, &ddr_reg, sizeof(u32)); llio->write(llio, addr + HM2_MOD_OFFS_GPIO_ALT_SOURCE + 4*port, &src_reg, sizeof(u32)); } } void sslbp_send_local_cmd(sserial_module_t *ssmod, int interface, u32 cmd) { ssmod->board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_CMD + interface*0x40, &(cmd), sizeof(u32)); } u32 sslbp_read_local_cmd(sserial_module_t *ssmod, int interface) { u32 data; ssmod->board->llio.read(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_CMD + interface*0x40, &(data), sizeof(u32)); return data; } u8 sslbp_read_data(sserial_module_t *ssmod, int interface) { u32 data; ssmod->board->llio.read(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_DATA + interface*0x40, &(data), sizeof(u32)); return data & 0xFF; } void sslbp_wait_complete(sserial_module_t *ssmod, int interface) { while (sslbp_read_local_cmd(ssmod, interface) != 0) {} } void sslbp_send_remote_cmd(sserial_module_t *ssmod, int interface, int channel, u32 cmd) { ssmod->board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_CS + interface*0x40 + channel*4, &(cmd), sizeof(u32)); } u8 sslbp_read_local8(sserial_module_t *ssmod, int interface, u32 addr) { sslbp_send_local_cmd(ssmod, interface, SSLBP_CMD_READ(addr)); sslbp_wait_complete(ssmod, interface); return sslbp_read_data(ssmod, interface); } u32 sslbp_read_local32(sserial_module_t *ssmod, int interface, u32 addr) { int byte = 4; u32 ret = 0; for (; byte--;) ret = (ret << 8) | sslbp_read_local8(ssmod, interface, addr + byte); return ret; } u8 sslbp_read_remote8(sserial_module_t *ssmod, int interface, int channel, u32 addr) { u32 data; sslbp_send_remote_cmd(ssmod, interface, channel, ((LBP_CMD_READ | LBP_ADDR_AUTO_INC) << 24) | addr); sslbp_send_local_cmd(ssmod, interface, SSLBP_CMD_DOIT(channel)); sslbp_wait_complete(ssmod, interface); ssmod->board->llio.read(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_INTERFACE0 + interface*0x40 + channel*4, &(data), sizeof(u32)); return data & 0xFF; } u16 sslbp_read_remote16(sserial_module_t *ssmod, int interface, int channel, u32 addr) { int byte; u16 ret = 0; for (byte = 1; byte >= 0; byte--) ret = (ret << 8) | sslbp_read_remote8(ssmod, interface, channel, addr + byte); return ret; } u32 sslbp_read_remote32(sserial_module_t *ssmod, int interface, int channel, u32 addr) { int byte; u32 ret = 0; for (byte = 3; byte >=0; byte--) ret = (ret << 8) | sslbp_read_remote8(ssmod, interface, channel, addr + byte); return ret; } void sslbp_write_remote8(sserial_module_t *ssmod, int interface, int channel, u32 addr, u8 data) { u32 d = data; sslbp_send_remote_cmd(ssmod, interface, channel, ((LBP_CMD_WRITE | LBP_ARGS_8BIT | LBP_ADDR_AUTO_INC) << 24) | addr); ssmod->board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_INTERFACE0 + interface*0x40 + channel*4, &(d), sizeof(u32)); sslbp_send_local_cmd(ssmod, interface, SSLBP_CMD_DOIT(channel)); sslbp_wait_complete(ssmod, interface); } void sslbp_write_remote16(sserial_module_t *ssmod, int interface, int channel, u32 addr, u16 data) { u32 d = data; sslbp_send_remote_cmd(ssmod, interface, channel, ((LBP_CMD_WRITE | LBP_ARGS_16BIT | LBP_ADDR_AUTO_INC) << 24) | addr); ssmod->board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_INTERFACE0 + interface*0x40 + channel*4, &(d), sizeof(u32)); sslbp_send_local_cmd(ssmod, interface, SSLBP_CMD_DOIT(channel)); sslbp_wait_complete(ssmod, interface); } void sslbp_write_remote32(sserial_module_t *ssmod, int interface, int channel, u32 addr, u32 data) { u32 d = data; sslbp_send_remote_cmd(ssmod, interface, channel, ((LBP_CMD_WRITE | LBP_ARGS_32BIT | LBP_ADDR_AUTO_INC) << 24) | addr); ssmod->board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_INTERFACE0 + interface*0x40 + channel*4, &(d), sizeof(u32)); sslbp_send_local_cmd(ssmod, interface, SSLBP_CMD_DOIT(channel)); sslbp_wait_complete(ssmod, interface); } u16 sslbp_read_nv_remote16(sserial_module_t *ssmod, int interface, int channel, u32 addr) { u16 data; u32 cmd = LBP_CMD_READ_NV << 24; ssmod->board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_CS + interface*0x40 + channel*4, &(cmd), sizeof(u32)); cmd = LBP_NVEEPROM_BYTE; ssmod->board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_INTERFACE0 + interface*0x40 + channel*4, &(cmd), sizeof(u32)); sslbp_send_local_cmd(ssmod, interface, SSLBP_CMD_DOIT(channel)); sslbp_wait_complete(ssmod, interface); data = sslbp_read_remote16(ssmod, interface, channel, addr); cmd = LBP_CMD_READ_NV << 24; ssmod->board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_CS + interface*0x40 + channel*4, &(cmd), sizeof(u32)); cmd = 0; ssmod->board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_INTERFACE0 + interface*0x40 + channel*4, &(cmd), sizeof(u32)); sslbp_send_local_cmd(ssmod, interface, SSLBP_CMD_DOIT(channel)); sslbp_wait_complete(ssmod, interface); return data; } u32 sslbp_read_nv_remote32(sserial_module_t *ssmod, int interface, int channel, u32 addr) { u32 data; u32 cmd = LBP_CMD_READ_NV << 24; ssmod->board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_CS + interface*0x40 + channel*4, &(cmd), sizeof(u32)); cmd = LBP_NVEEPROM_BYTE; ssmod->board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_INTERFACE0 + interface*0x40 + channel*4, &(cmd), sizeof(u32)); sslbp_send_local_cmd(ssmod, interface, SSLBP_CMD_DOIT(channel)); sslbp_wait_complete(ssmod, interface); data = sslbp_read_remote32(ssmod, interface, channel, addr); cmd = LBP_CMD_READ_NV << 24; ssmod->board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_CS + interface*0x40 + channel*4, &(cmd), sizeof(u32)); cmd = 0; ssmod->board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_INTERFACE0 + interface*0x40 + channel*4, &(cmd), sizeof(u32)); sslbp_send_local_cmd(ssmod, interface, SSLBP_CMD_DOIT(channel)); sslbp_wait_complete(ssmod, interface); return data; } void sslbp_read_remote_bytes(sserial_module_t *ssmod, int interface, int channel, u32 addr, void *buffer, int size) { char *ptr = (char *) buffer; while (size != 0) { u8 data = sslbp_read_remote8(ssmod, interface, channel, addr); *(ptr++) = data; addr++; size--; if (size < 0) { if (data == 0) break; } } } int sserial_init(sserial_module_t *ssmod, board_t *board, int interface_num, int channel_num, u32 remote_type) { u32 cmd, status; hm2_module_desc_t *md = hm2_find_module(&(board->llio.hm2), HM2_GTAG_SSERIAL); if (md == NULL) { printf("No sserial module found.\n"); return -1; } if (interface_num >= HM2_SSERIAL_MAX_INTERFACES) { printf("sserial interface number too high.\n"); return -1; } if (channel_num >= HM2_SSERIAL_MAX_CHANNELS) { printf("sserial channel number too high.\n"); return -1; } memset(ssmod, 0, sizeof(sserial_module_t)); ssmod->board = board; ssmod->interface_num = interface_num; ssmod->channel_num = channel_num; ssmod->base_address = md->base_address; ssmod->instance_stride = (md->strides & 0xF0) == 0 ? board->llio.hm2.idrom.instance_stride0 : board->llio.hm2.idrom.instance_stride1; enable_sserial_pins(&(ssmod->board->llio)); sslbp_send_local_cmd(ssmod, interface_num, SSLBP_CMD_STOPALL | SSLBP_CMD_RESET); // assert reset flag sslbp_send_local_cmd(ssmod, interface_num, SSLBP_CMD_STOPALL); // deassert reset flag sslbp_wait_complete(ssmod, interface_num); // wait for reset to finish ssmod->interface.type = sslbp_read_local8(ssmod, interface_num, SSLBP_TYPE_LOC); ssmod->interface.width = sslbp_read_local8(ssmod, interface_num, SSLBP_WIDTH_LOC); ssmod->interface.ver_major = sslbp_read_local8(ssmod, interface_num, SSLBP_MAJOR_REV_LOC); ssmod->interface.ver_minor = sslbp_read_local8(ssmod, interface_num, SSLBP_MINOR_REV_LOC); ssmod->interface.gp_inputs = sslbp_read_local8(ssmod, interface_num, SSLBP_CHANNEL_START_LOC); ssmod->interface.gp_outputs = sslbp_read_local8(ssmod, interface_num, SSLBP_CHANNEL_STRIDE_LOC); ssmod->interface.processor_type = sslbp_read_local8(ssmod, interface_num, SSLBP_PROCESSOR_TYPE_LOC); ssmod->interface.channels_count = sslbp_read_local8(ssmod, interface_num, SSLBP_NR_CHANNELS_LOC); ssmod->interface.baud_rate = sslbp_read_local32(ssmod, interface_num, ssmod->interface.gp_inputs + 42); ssmod->interface.clock = sslbp_read_local32(ssmod, interface_num, SSLBP_CLOCK_LOC); if (0) {//ssmod->board->llio.verbose == 1) { printf("SSLBP port %d:\n", interface_num); printf(" interface type: %0x\n", ssmod->interface.type); printf(" interface width: %d\n", ssmod->interface.width); printf(" SSLBP Version: %d.%d\n", ssmod->interface.ver_major, ssmod->interface.ver_minor); printf(" SSLBP Channel Start: %d\n", ssmod->interface.gp_inputs); printf(" SSLBP Channel Stride: %d\n", ssmod->interface.gp_outputs); printf(" SSLBP Processor Type: %x\n", ssmod->interface.processor_type); printf(" SSLBP Channels: %d\n", ssmod->interface.channels_count); printf(" SSLBP Baud Rate: %.1f Mb\n", ssmod->interface.baud_rate/1000000.0); printf(" SSLBP Clock: %u MHz\n", ssmod->interface.clock/1000000); } cmd = 0; board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_CS + interface_num*ssmod->instance_stride + channel_num*4, &(cmd), sizeof(u32)); sslbp_send_local_cmd(ssmod, interface_num, SSLBP_CMD_START_SETUP_MODE(channel_num)); sslbp_wait_complete(ssmod, interface_num); if (sslbp_read_data(ssmod, interface_num) != 0) { printf("Error reading sserial interface %d channel %d\n", interface_num, channel_num); return -1; } board->llio.read(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_CS + interface_num*ssmod->instance_stride + channel_num*4, &(status), sizeof(u32)); board->llio.read(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_INTERFACE0 + interface_num*ssmod->instance_stride + channel_num*4, &(status), sizeof(u32)); if ((status & 0xFF000000) != remote_type) { printf("Found wrong remote at %d:%d, request %x but found %x\n", interface_num, channel_num, remote_type, status); return -1; } ssmod->device.unit = status; board->llio.read(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_INTERFACE1 + interface_num*ssmod->instance_stride + channel_num*4, &(ssmod->device.name), sizeof(u32)); board->llio.read(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_INTERFACE2 + interface_num*ssmod->instance_stride + channel_num*4, &(status), sizeof(u32)); printf("device at %d:%d: %.*s (unit 0x%08X)\n", interface_num, channel_num, 4, ssmod->device.name, ssmod->device.unit); sslbp_send_local_cmd(ssmod, 0, SSLBP_CMD_STOPALL); sslbp_wait_complete(ssmod, 0); cmd = 0; board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_CS + channel_num*4, &(cmd), sizeof(cmd)); printf("starting device %d:%d\n", interface_num, channel_num); sslbp_send_local_cmd(ssmod, 0, SSLBP_CMD_START_NORMAL_MODE(channel_num)); sslbp_wait_complete(ssmod, 0); board->llio.read(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_DATA + channel_num*4, &(status), sizeof(u32)); if (status != 0) { printf("Error while starting sserial: %X\n", status); return -1; } return 0; } int sserial_cleanup(sserial_module_t *ssmod) { disable_sserial_pins(&(ssmod->board->llio)); return 0; } int sserial_write(sserial_module_t *ssmod) { ssmod->board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_INTERFACE0 + ssmod->interface_num*ssmod->instance_stride + ssmod->channel_num*4, &(ssmod->interface0), sizeof(u32)); ssmod->board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_INTERFACE1 + ssmod->interface_num*ssmod->instance_stride + ssmod->channel_num*4, &(ssmod->interface1), sizeof(u32)); ssmod->board->llio.write(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_INTERFACE2 + ssmod->interface_num*ssmod->instance_stride + ssmod->channel_num*4, &(ssmod->interface2), sizeof(u32)); sslbp_send_local_cmd(ssmod, 0, SSLBP_CMD_DOIT(1)); sslbp_wait_complete(ssmod, 0); ssmod->board->llio.read(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_DATA + ssmod->interface_num*ssmod->instance_stride + ssmod->channel_num*4, &(ssmod->data), sizeof(u32)); ssmod->board->llio.read(&(ssmod->board->llio), ssmod->base_address + HM2_MOD_OFFS_SSERIAL_CS + ssmod->interface_num*ssmod->instance_stride + ssmod->channel_num*4, &(ssmod->cs), sizeof(u32)); return 0; } void sserial_module_init(llio_t *llio) { u32 cmd, status, data, addr; u16 d; int port, channel, i; hm2_module_desc_t *md = hm2_find_module(&(llio->hm2), HM2_GTAG_SSERIAL); sserial_module_t ssmodule, *ssmod = &ssmodule; char *record_types[9] = {"PADDING", "BITFIELD", "UNSIGNED", "SIGNED", "NV UNSIGNED", "NV SIGNED", "STREAM", "BOOLEAN", "ENCODER"}; char *baud_rates[12] = {"9600b", "19200b", "38400b", "57600b", "115200b", "230400b", "460800b", "921600b", "1.25Mb", "2.5Mb", "5Mb", "10Mb"}; if (md == NULL) return; memset(ssmod, 0, sizeof(sserial_module_t)); ssmod->board = llio->board; ssmod->base_address = md->base_address; ssmod->instance_stride = (md->strides & 0xF0) == 0 ? llio->hm2.idrom.instance_stride0 : llio->hm2.idrom.instance_stride1; enable_sserial_pins(llio); for (port = 0; port < 1; port++) { sslbp_send_local_cmd(ssmod, port, SSLBP_CMD_STOPALL | SSLBP_CMD_RESET); // assert reset flag sslbp_send_local_cmd(ssmod, port, SSLBP_CMD_STOPALL); // deassert reset flag sslbp_wait_complete(ssmod, port); // wait for reset to finish llio->ss_interface[port].type = sslbp_read_local8(ssmod, port, 0); llio->ss_interface[port].width = sslbp_read_local8(ssmod, port, 1); llio->ss_interface[port].ver_major = sslbp_read_local8(ssmod, port, SSLBP_MAJOR_REV_LOC); llio->ss_interface[port].ver_minor = sslbp_read_local8(ssmod, port, SSLBP_MINOR_REV_LOC); llio->ss_interface[port].gp_inputs = sslbp_read_local8(ssmod, port, SSLBP_CHANNEL_START_LOC); llio->ss_interface[port].gp_outputs = sslbp_read_local8(ssmod, port, SSLBP_CHANNEL_STRIDE_LOC); llio->ss_interface[port].processor_type = sslbp_read_local8(ssmod, port, SSLBP_PROCESSOR_TYPE_LOC); llio->ss_interface[port].channels_count = sslbp_read_local8(ssmod, port, SSLBP_NR_CHANNELS_LOC); llio->ss_interface[port].baud_rate = sslbp_read_local32(ssmod, port, llio->ss_interface[port].gp_inputs + 42); llio->ss_interface[port].clock = sslbp_read_local32(ssmod, port, SSLBP_CLOCK_LOC); printf("SSLBP port %d:\n", port); printf(" SSLBP Version: %d.%d\n", llio->ss_interface[port].ver_major, llio->ss_interface[port].ver_minor); printf(" SSLBP Channels: %d\n", llio->ss_interface[port].channels_count); printf(" SSLBP Baud Rate: %d\n", llio->ss_interface[port].baud_rate); if (llio->verbose == 1) { printf(" interface type: %0x\n", llio->ss_interface[port].type); printf(" interface width: %d\n", llio->ss_interface[port].width); printf(" SSLBP Channel Start: %d\n", llio->ss_interface[port].gp_inputs); printf(" SSLBP Channel Stride: %d\n", llio->ss_interface[port].gp_outputs); printf(" SSLBP Processor Type: %x\n", llio->ss_interface[port].processor_type); printf(" SSLBP Clock: %u MHz\n", llio->ss_interface[port].clock/1000000); } for (channel = 0; channel < llio->ss_interface[port].width; channel++) { cmd = 0; llio->write(llio, ssmod->base_address + HM2_MOD_OFFS_SSERIAL_CS + port*0x40 + channel*4, &(cmd), sizeof(u32)); sslbp_send_local_cmd(ssmod, port, SSLBP_CMD_START_SETUP_MODE(channel)); sslbp_wait_complete(ssmod, port); if (sslbp_read_data(ssmod, port) != 0) continue; llio->read(llio, ssmod->base_address + HM2_MOD_OFFS_SSERIAL_CS + port*0x40 + channel*4, &(status), sizeof(u32)); llio->read(llio, ssmod->base_address + HM2_MOD_OFFS_SSERIAL_INTERFACE0 + port*0x40 + channel*4, &(status), sizeof(u32)); llio->ss_device[channel].unit = status; llio->read(llio, ssmod->base_address + HM2_MOD_OFFS_SSERIAL_INTERFACE1 + port*0x40 + channel*4, &(status), sizeof(u32)); llio->ss_device[channel].name[0] = status & 0xFF; llio->ss_device[channel].name[1] = (status >> 8) & 0xFF; llio->ss_device[channel].name[2] = (status >> 16) & 0xFF; llio->ss_device[channel].name[3] = (status >> 24) & 0xFF; llio->read(llio, ssmod->base_address + HM2_MOD_OFFS_SSERIAL_INTERFACE2 + port*0x40 + channel*4, &(status), sizeof(u32)); printf(" sserial device at channel %d: %.*s", channel, 4, llio->ss_device[channel].name); if ((llio->ss_device[channel].unit & 0xFF000000) == SSLBP_REMOTE_7I76_IO_SPINDLE) { printf(" GPIO+SPINDLE"); } else if ((llio->ss_device[channel].unit & 0xFF000000) == SSLBP_REMOTE_7I77_IO) { printf(" GPIO"); } else if ((llio->ss_device[channel].unit & 0xFF000000) == SSLBP_REMOTE_7I77_ANALOG) { printf(" ANALOG"); } if (llio->verbose == 0) { printf(" (unit 0x%08X)\n", llio->ss_device[channel].unit); } else { printf("\n"); } addr = (status >> 16) & 0xFFFF; while (1) { sserial_pdd_t sserial_pdd; sserial_md_t sserial_md; u8 record_type; char name[48], unit[48]; d = sslbp_read_remote16(ssmod, port, channel, addr); if (d == 0) break; record_type = sslbp_read_remote8(ssmod, port, channel, d); addr += 2; if (record_type == LBP_DATA) { sslbp_read_remote_bytes(ssmod, port, channel, d, &(sserial_pdd), sizeof(sserial_pdd_t)); sslbp_read_remote_bytes(ssmod, port, channel, d + sizeof(sserial_pdd_t), &(unit), -1); sslbp_read_remote_bytes(ssmod, port, channel, d + sizeof(sserial_pdd_t) + strlen(unit) + 1, &(name), -1); if (strncmp(name, "SwRevision", 10) == 0) { sslbp_read_remote_bytes(ssmod, port, channel, sserial_pdd.param_addr, &(d), sserial_pdd.data_size/8); llio->ss_device[channel].sw_revision = d; printf(" SwRevision = %u\n", d); } else if (strncmp(name, "HwRevision", 10) == 0) { sslbp_read_remote_bytes(ssmod, port, channel, sserial_pdd.param_addr, &(d), sserial_pdd.data_size/8); llio->ss_device[channel].hw_revision = d; printf(" HwRevision = %u\n", d); } else if (strncmp(name, "NVBaudRate", 10) == 0) { d = sslbp_read_nv_remote16(ssmod, port, channel, sserial_pdd.param_addr); printf(" NVBaudRate = %s\n", baud_rates[d]); } else if (strncmp(name, "NVUnitNumber", 12) == 0) { data = sslbp_read_nv_remote32(ssmod, port, channel, sserial_pdd.param_addr); printf(" NVUnitNumber = 0x%08X\n", data); } else if (strncmp(name, "NVWatchDogTimeout", 17) == 0) { d = sslbp_read_nv_remote16(ssmod, port, channel, sserial_pdd.param_addr); printf(" NVWatchDogTimeout = %ums\n", d); } else if ((strncmp(name, "NV", 2) == 0) || (sserial_pdd.data_type == LBP_UNSIGNED && strncmp(unit, "None", 4) == 0)) { if (llio->verbose == 1) { printf(" %s", name); if (sserial_pdd.data_type == LBP_UNSIGNED || sserial_pdd.data_type == LBP_NONVOL_UNSIGNED) { if (sserial_pdd.data_size == 16) { d = sslbp_read_nv_remote16(ssmod, port, channel, sserial_pdd.param_addr); printf(" = %x", d); } else if (sserial_pdd.data_size == 32) { data = sslbp_read_nv_remote32(ssmod, port, channel, sserial_pdd.param_addr); printf(" = %08X", data); } } printf(" [%u bits %s", sserial_pdd.data_size, record_types[sserial_pdd.data_type]); if (sserial_pdd.data_dir & LBP_IO) { printf(" IO"); } else if (sserial_pdd.data_dir & LBP_OUT) { printf(" OUT"); } else { printf(" IN"); } printf(" | UNIT: %s", unit); if ((sserial_pdd.data_type == LBP_SIGNED) || (sserial_pdd.data_type == LBP_UNSIGNED) || (sserial_pdd.data_type == LBP_NONVOL_SIGNED) || (sserial_pdd.data_type == LBP_NONVOL_UNSIGNED)) { printf(" | RANGE: %.2f - %.2f", sserial_pdd.param_min, sserial_pdd.param_max); } printf(" | ADDR: %04X", sserial_pdd.param_addr); printf("]\n"); } } } else if (record_type == LBP_MODE) { sslbp_read_remote_bytes(ssmod, port, channel, d, &(sserial_md), sizeof(sserial_md_t)); sslbp_read_remote_bytes(ssmod, port, channel, d + sizeof(sserial_md_t), &(name), -1); if (sserial_md.mode_type == 0x01) { sw_mode_t *sw_mode = &llio->ss_device[channel].sw_modes[llio->ss_device[channel].sw_modes_cnt]; if (strlen(name)+1 > sizeof(sw_mode->name)) { printf("name too long while reading LBP_MODE (max %zu)\n", sizeof(sw_mode->name)-1); abort(); } sw_mode->index = sserial_md.mode_index; strcpy(sw_mode->name, name); llio->ss_device[channel].sw_modes_cnt++; } } } for (i = 0; i < llio->ss_device[channel].sw_modes_cnt; i++) { printf(" SOFTWARE MODE %s [index %02X]\n", llio->ss_device[channel].sw_modes[i].name, llio->ss_device[channel].sw_modes[i].index); sslbp_send_local_cmd(ssmod, port, SSLBP_CMD_STOP(channel)); sslbp_wait_complete(ssmod, port); cmd = llio->ss_device[channel].sw_modes[i].index << 24; llio->write(llio, ssmod->base_address + HM2_MOD_OFFS_SSERIAL_CS + port*0x40 + channel*4, &(cmd), sizeof(u32)); sslbp_send_local_cmd(ssmod, port, SSLBP_CMD_START_SETUP_MODE(channel)); sslbp_wait_complete(ssmod, port); if (sslbp_read_data(ssmod, port) != 0) continue; llio->read(llio, HM2_MOD_OFFS_SSERIAL_INTERFACE2 + port*0x40 + channel*4, &(status), sizeof(u32)); addr = status & 0xFFFF; while (1) { sserial_pdd_t sserial_pdd; sserial_md_t sserial_md; u8 record_type; char name[48], unit[48]; d = sslbp_read_remote16(ssmod, port, channel, addr); if (d == 0) break; record_type = sslbp_read_remote8(ssmod, port, channel, d); addr += 2; if (record_type == LBP_DATA) { sslbp_read_remote_bytes(ssmod, port, channel, d, &(sserial_pdd), sizeof(sserial_pdd_t)); sslbp_read_remote_bytes(ssmod, port, channel, d + sizeof(sserial_pdd_t), &(unit), -1); sslbp_read_remote_bytes(ssmod, port, channel, d + sizeof(sserial_pdd_t) + strlen(unit) + 1, &(name), -1); if (llio->verbose == 1) { printf(" DATA %s [%u bits %s", name, sserial_pdd.data_size, record_types[sserial_pdd.data_type]); if (sserial_pdd.data_dir & LBP_IO) { printf(" IO"); } else if (sserial_pdd.data_dir & LBP_OUT) { printf(" OUT"); } else { printf(" IN"); } printf(" | UNIT: %s", unit); if ((sserial_pdd.data_type == LBP_SIGNED) || (sserial_pdd.data_type == LBP_UNSIGNED) || (sserial_pdd.data_type == LBP_NONVOL_SIGNED) || (sserial_pdd.data_type == LBP_NONVOL_UNSIGNED)) { printf(" | RANGE: %.2f - %.2f", sserial_pdd.param_min, sserial_pdd.param_max); } printf(" | ADDR: %04X", sserial_pdd.param_addr); printf("]\n"); } } else if (record_type == LBP_MODE) { sslbp_read_remote_bytes(ssmod, port, channel, d, &(sserial_md), sizeof(sserial_md_t)); sslbp_read_remote_bytes(ssmod, port, channel, d + sizeof(sserial_md_t), &(name), -1); } } } } } disable_sserial_pins(llio); } mesaflash-3.4.6/sserial_module.h000066400000000000000000000035171433153454000166570ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __SSERIAL_MODULE_H #define __SSERIAL_MODULE_H #include "boards.h" #include "hostmot2.h" struct opd_mode_1_7i77_struct { unsigned int analog0 : 13; unsigned int analog1 : 13; unsigned int analog2 : 13; unsigned int analog3 : 13; unsigned int analog4 : 13; unsigned int analog5 : 13; unsigned int analogena : 1; unsigned int spinena : 1; unsigned int ignore1 : 16; } __attribute__ ((__packed__, aligned(4))); typedef struct opd_mode_1_7i77_struct opd_mode_1_7i77_t; typedef struct { board_t *board; int instance_stride; int interface_num; int channel_num; u16 base_address; u32 data; u32 cs; u32 interface0; u32 interface1; u32 interface2; sserial_interface_t interface; sserial_device_t device; } sserial_module_t; int sserial_init(sserial_module_t *ssmod, board_t *board, int interface_num, int channel_num, u32 remote_type); int sserial_cleanup(sserial_module_t *ssmod); void sserial_module_init(llio_t *llio); int sserial_write(sserial_module_t *ssmod); #endif mesaflash-3.4.6/types.h000066400000000000000000000022251433153454000150070ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __TYPES_H #define __TYPES_H #include #ifdef __linux__ typedef u_int8_t u8; typedef u_int16_t u16; typedef u_int32_t u32; #elif _WIN32 #include typedef BYTE u8; typedef WORD u16; typedef DWORD u32; #endif #include #if ULONG_MAX > 0xffffffff typedef unsigned long u64; #else typedef unsigned long long u64; #endif #endif mesaflash-3.4.6/usb_boards.c000066400000000000000000000153561433153454000157720ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #include #include #include #include #include #include "types.h" #include "common.h" #include "eeprom.h" #include "bitfile.h" #include "lbp.h" #include "hostmot2.h" #include "usb_boards.h" extern board_t boards[MAX_BOARDS]; extern int boards_count; static u8 file_buffer[SECTOR_SIZE]; int usb_read(llio_t *self, u32 addr, void *buffer, int size) { (void)self; while (size > 0) { lbp_read(addr & 0xFFFF, buffer); addr += 4; buffer += 4; size -= 4; } return 0; } int usb_write(llio_t *self, u32 addr, void *buffer, int size) { (void)self; while (size > 0) { lbp_write(addr & 0xFFFF, buffer); addr += 4; buffer += 4; size -= 4; } return 0; } static int usb_program_fpga(llio_t *self, char *bitfile_name) { board_t *board = self->board; int bindex, bytesread; char part_name[32]; struct stat file_stat; FILE *fp; u8 cmd = '0'; if (stat(bitfile_name, &file_stat) != 0) { printf("Can't find file %s\n", bitfile_name); return -1; } fp = fopen(bitfile_name, "rb"); if (fp == NULL) { printf("Can't open file %s: %s\n", bitfile_name, strerror(errno)); return -1; } if (print_bitfile_header(fp, (char*) &part_name, board->llio.verbose) == -1) { fclose(fp); return -1; } printf("Programming FPGA...\n"); printf(" |"); fflush(stdout); lbp_send_checked(&cmd, 1); lbp_send_checked(&cmd, 1); lbp_send_checked(&cmd, 1); lbp_send_checked(&cmd, 1); // program the FPGA while (!feof(fp)) { bytesread = fread(&file_buffer, 1, 8192, fp); bindex = 0; while (bindex < bytesread) { file_buffer[bindex] = bitfile_reverse_bits(file_buffer[bindex]); bindex++; } lbp_send_checked(&file_buffer, bytesread); printf("W"); fflush(stdout); } printf("\n"); fclose(fp); return 0; } static int usb_board_open(board_t *board) { (void)board; return 0; } static int usb_board_close(board_t *board) { (void)board; return 0; } int usb_boards_init(board_access_t *access) { lbp_init(access); return 0; } void usb_boards_cleanup(board_access_t *access) { (void)access; lbp_release(); } void usb_boards_scan(board_access_t *access) { board_t *board = &boards[boards_count]; u8 cmd, data; char dev_name[4]; board_init_struct(board); data = lbp_read_ctrl(LBP_CMD_READ_COOKIE); if (data == LBP_COOKIE) { dev_name[0] = lbp_read_ctrl(LBP_CMD_READ_DEV_NAME0); dev_name[1] = lbp_read_ctrl(LBP_CMD_READ_DEV_NAME1); dev_name[2] = lbp_read_ctrl(LBP_CMD_READ_DEV_NAME2); dev_name[3] = lbp_read_ctrl(LBP_CMD_READ_DEV_NAME3); if (strncmp(dev_name, "7I64", 4) == 0) { board->type = BOARD_USB; strcpy(board->dev_addr, access->dev_addr); strncpy(board->llio.board_name, dev_name, 4); board->llio.verbose = access->verbose; boards_count++; } else if (strncmp(dev_name, "7I43", 4) == 0) { // found 7i43 with HOSTMOT2 board->type = BOARD_USB; board->mode = BOARD_MODE_FPGA; strcpy(board->dev_addr, access->dev_addr); strcpy(board->llio.board_name, "7I43"); board->llio.num_ioport_connectors = 2; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P3"; board->llio.ioport_connector_name[1] = "P4"; board->llio.num_leds = 8; board->llio.read = &usb_read; board->llio.write = &usb_write; board->open = &usb_board_open; board->close = &usb_board_close; board->print_info = &usb_print_info; board->llio.verbose = access->verbose; u32 cookie; lbp_read(HM2_COOKIE_REG, &cookie); if (cookie == HM2_COOKIE) { u32 fpga_size; u32 addr; lbp_read(HM2_IDROM_ADDR, &addr); lbp_read((addr & 0xFFFF) + offsetof(hm2_idrom_desc_t, fpga_size), &fpga_size); if (fpga_size == 400) { board->llio.fpga_part_number = "3s400tq144"; } else { board->llio.fpga_part_number = "3s200tq144"; } } boards_count++; } return; } cmd = '1'; lbp_send_checked(&cmd, 1); lbp_recv_checked(&data, 1); if ((data & 0x01) == 0) { // found 7i43 without flashed FPGA board->type = BOARD_USB; board->mode = BOARD_MODE_CPLD; strcpy(board->dev_addr, access->dev_addr); strcpy(board->llio.board_name, "7I43"); board->llio.num_ioport_connectors = 2; board->llio.pins_per_connector = 24; board->llio.ioport_connector_name[0] = "P3"; board->llio.ioport_connector_name[1] = "P4"; cmd = '0'; lbp_send_checked(&cmd, 1); lbp_recv_checked(&data, 1); if (data & 0x01) board->llio.fpga_part_number = "3s400tq144"; else board->llio.fpga_part_number = "3s200tq144"; board->llio.num_leds = 8; board->llio.program_fpga = &usb_program_fpga; board->llio.verbose = access->verbose; board->open = &usb_board_open; board->close = &usb_board_close; board->print_info = &usb_print_info; boards_count++; return; } } void usb_boards_release(board_access_t *access) { (void)access; lbp_release(); } void usb_print_info(board_t *board) { printf("\nUSB device %s at %s\n", board->llio.board_name, board->dev_addr); if (board->llio.verbose == 1) { if (board->mode == BOARD_MODE_CPLD) { printf(" controlled by CPLD\n"); lbp_print_info(); } else if (board->mode == BOARD_MODE_FPGA) { printf(" controlled by FPGA\n"); } } } mesaflash-3.4.6/usb_boards.h000066400000000000000000000021241433153454000157640ustar00rootroot00000000000000// // Copyright (C) 2013-2014 Michael Geszkiewicz // // 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // #ifndef __USB_BOARDS_H #define __USB_BOARDS_H #include "boards.h" int usb_boards_init(board_access_t *access); void usb_boards_cleanup(board_access_t *access); void usb_boards_scan(board_access_t *access); void usb_boards_release(board_access_t *access); void usb_print_info(board_t *board); #endif