This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
en:projects:ucecho_fpga [2010/12/21 06:41] – [ucecho for ZTEX USB FPGA boards] 98.207.41.249 | en:projects:ucecho_fpga [2016/09/15 08:35] (current) – gelöscht stefan | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== ucecho for ZTEX USB FPGA boards ====== | ||
- | The following example runs on [[http:// | ||
- | |||
- | The firmware (defined in [[en: | ||
- | |||
- | The Bitstream for the FPGA configuration is defined in [[en: | ||
- | |||
- | The driver (defined in [[en: | ||
- | |||
- | Uploading the Firmware to EEPROM is also supported by the firmware (e.g. using the FWLoader utility). | ||
- | |||
- | The example is a part of the package and may serve a good starting point for own projects. | ||
- | |||
- | ===== Firmware: ucecho.c ===== | ||
- | This is the C source code for the firmware: | ||
- | <code c> | ||
- | # | ||
- | # | ||
- | |||
- | // Cypress vendor ID and product ID may only (!) be used for experimental purposes | ||
- | SET_VPID(0x4b4, | ||
- | |||
- | // define endpoints 2 and 4, both belong to interface 0 (in/out are from the point of view of the host) | ||
- | EP_CONFIG(2, | ||
- | EP_CONFIG(4, | ||
- | |||
- | // identify as ZTEX USB FPGA Module 1.2 (Important for FPGA configuration) | ||
- | IDENTITY_UFM_1_2(1.0.0.0, | ||
- | |||
- | // give them a nice name | ||
- | # | ||
- | |||
- | // this is called automatically after FPGA configuration | ||
- | # | ||
- | OEC = 255; | ||
- | ] | ||
- | |||
- | // include the main part of the firmware kit, define the descriptors, | ||
- | # | ||
- | |||
- | |||
- | void main(void) | ||
- | { | ||
- | WORD i,size; | ||
- | | ||
- | // init everything | ||
- | init_USB(); | ||
- | |||
- | EP2CS &= ~bmBIT0; | ||
- | SYNCDELAY; | ||
- | EP4CS &= ~bmBIT0; | ||
- | |||
- | SYNCDELAY; | ||
- | EP4BCL = 0x80; // skip package, (re)arm EP4 | ||
- | SYNCDELAY; | ||
- | EP4BCL = 0x80; // skip package, (re)arm EP4 | ||
- | |||
- | while (1) { | ||
- | if ( !(EP4CS & bmBIT2) ) { // EP4 is not empty | ||
- | size = (EP4BCH << 8) | EP4BCL; | ||
- | if ( size>0 && size< | ||
- | for ( i=0; i<size; i++ ) { | ||
- | IOC = EP4FIFOBUF[i]; | ||
- | EP2FIFOBUF[i] = IOB; // ... and written back to EP2 buffer | ||
- | } | ||
- | EP2BCH = size >> 8; | ||
- | SYNCDELAY; | ||
- | EP2BCL = size & 255; // arm EP2 | ||
- | } | ||
- | SYNCDELAY; | ||
- | EP4BCL = 0x80; // skip package, (re)arm EP4 | ||
- | } | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | ===== Bitstream: fpga/ | ||
- | This is the VHDL source code for the FPGA bitstream: | ||
- | <code vhdl> | ||
- | library ieee; | ||
- | use IEEE.std_logic_1164.all; | ||
- | use IEEE.numeric_std.all; | ||
- | |||
- | entity ucecho is | ||
- | port( | ||
- | pc : in unsigned(7 downto 0); | ||
- | pb : out unsigned(7 downto 0); | ||
- | CLK : in std_logic | ||
- | ); | ||
- | end ucecho; | ||
- | |||
- | |||
- | --signal declaration | ||
- | architecture RTL of ucecho is | ||
- | |||
- | begin | ||
- | dpUCECHO: process(CLK) | ||
- | begin | ||
- | if CLK' event and CLK = ' | ||
- | if ( pc >= 97 ) and ( pc <= 122) | ||
- | then | ||
- | pb <= pc - 32; | ||
- | else | ||
- | pb <= pc; | ||
- | end if; | ||
- | end if; | ||
- | end process dpUCECHO; | ||
- | | ||
- | end RTL; | ||
- | </ | ||
- | |||
- | |||
- | ===== Java host software: UCEcho.java ===== | ||
- | This is the Java source code for the driver: | ||
- | <code java> | ||
- | import java.io.*; | ||
- | import java.util.*; | ||
- | |||
- | import ch.ntb.usb.*; | ||
- | |||
- | import ztex.*; | ||
- | |||
- | // ***************************************************************************** | ||
- | // ******* ParameterException ************************************************** | ||
- | // ***************************************************************************** | ||
- | // Exception the prints a help message | ||
- | class ParameterException extends Exception { | ||
- | public final static String helpMsg = new String ( | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | | ||
- | public ParameterException (String msg) { | ||
- | super( msg + " | ||
- | } | ||
- | } | ||
- | |||
- | // ***************************************************************************** | ||
- | // ******* Test0 *************************************************************** | ||
- | // ***************************************************************************** | ||
- | class UCEcho extends Ztex1v1 { | ||
- | |||
- | // ******* UCEcho ************************************************************** | ||
- | // constructor | ||
- | public UCEcho ( ZtexDevice1 pDev ) throws UsbException, | ||
- | super ( pDev ); | ||
- | } | ||
- | |||
- | // ******* claimInterface ****************************************************** | ||
- | // claims interface 0 | ||
- | public void claimInterface ( ) throws UsbException{ | ||
- | if ( LibusbJava.usb_claim_interface(handle(), | ||
- | throw new UsbException(" | ||
- | } | ||
- | |||
- | // ******* releaseInterface **************************************************** | ||
- | // releases interface 0 | ||
- | public void releaseInterface ( ) { | ||
- | LibusbJava.usb_release_interface(handle(), | ||
- | } | ||
- | | ||
- | // ******* echo **************************************************************** | ||
- | // writes a string to Endpoint 4, reads it back from Endpoint 2 and writes the output to System.out | ||
- | public void echo ( String input ) throws UsbException { | ||
- | byte buf[] = input.getBytes(); | ||
- | int i = LibusbJava.usb_bulk_write(handle, | ||
- | if ( i<0 ) | ||
- | throw new UsbException(" | ||
- | System.out.println(" | ||
- | |||
- | try { | ||
- | Thread.sleep( 10 ); | ||
- | } | ||
- | catch ( InterruptedException e ) { | ||
- | } | ||
- | |||
- | buf = new byte[1024]; | ||
- | i = LibusbJava.usb_bulk_read(handle, | ||
- | if ( i<0 ) | ||
- | throw new UsbException(" | ||
- | System.out.println(" | ||
- | } | ||
- | | ||
- | // ******* main **************************************************************** | ||
- | public static void main (String args[]) { | ||
- | | ||
- | int devNum = 0; | ||
- | boolean force = false; | ||
- | | ||
- | try { | ||
- | // init USB stuff | ||
- | LibusbJava.usb_init(); | ||
- | |||
- | // scan the USB bus | ||
- | ZtexScanBus1 bus = new ZtexScanBus1( ZtexDevice1.cypressVendorId, | ||
- | if ( bus.numberOfDevices() <= 0) { | ||
- | System.err.println(" | ||
- | System.exit(0); | ||
- | } | ||
- | | ||
- | // scan the command line arguments | ||
- | for (int i=0; i< | ||
- | if ( args[i].equals(" | ||
- | i++; | ||
- | try { | ||
- | if (i> | ||
- | devNum = Integer.parseInt( args[i] ); | ||
- | } | ||
- | catch (Exception e) { | ||
- | throw new ParameterException(" | ||
- | } | ||
- | } | ||
- | else if ( args[i].equals(" | ||
- | force = true; | ||
- | } | ||
- | else if ( args[i].equals(" | ||
- | bus.printBus(System.out); | ||
- | System.exit(0); | ||
- | } | ||
- | else if ( args[i].equals(" | ||
- | System.err.println(ParameterException.helpMsg); | ||
- | System.exit(0); | ||
- | } | ||
- | else throw new ParameterException(" | ||
- | } | ||
- | | ||
- | |||
- | // create the main class | ||
- | UCEcho ztex = new UCEcho ( bus.device(devNum) ); | ||
- | | ||
- | // upload the firmware if necessary | ||
- | if ( force || ! ztex.valid() || ! ztex.dev().productString().equals(" | ||
- | ztex.uploadFirmware( " | ||
- | } | ||
- | | ||
- | // upload the bitstream if necessary | ||
- | if ( force || ! ztex.getFpgaConfiguration() ) { | ||
- | System.out.println(" | ||
- | } | ||
- | |||
- | |||
- | // claim interface 0 | ||
- | ztex.claimInterface(); | ||
- | | ||
- | // read string from stdin and write it to USB device | ||
- | String str = ""; | ||
- | BufferedReader reader = new BufferedReader( new InputStreamReader( System.in ) ); | ||
- | while ( ! str.equals(" | ||
- | System.out.print(" | ||
- | str = reader.readLine(); | ||
- | ztex.echo(str); | ||
- | System.out.println("" | ||
- | } | ||
- | | ||
- | // release interface 0 | ||
- | ztex.releaseInterface(); | ||
- | | ||
- | } | ||
- | catch (Exception e) { | ||
- | System.out.println(" | ||
- | } | ||
- | | ||
- | |||
- | } | ||
- | </ | ||
- | |||
- | ====== C host software: UCEcho.c ====== | ||
- | |||
- | It is also possible to access the device with other programming languages. In this case the firmware must be loaded using the FWLoader utility included in the SDK. | ||
- | |||
- | The C source code of the host software is: | ||
- | |||
- | <code c> | ||
- | /*! | ||
- | | ||
- | | ||
- | | ||
- | |||
- | This program is free software; you can redistribute it and/or modify | ||
- | it under the terms of the GNU General Public License version 3 as | ||
- | | ||
- | |||
- | This program is distributed in the hope that it will be useful, but | ||
- | | ||
- | | ||
- | | ||
- | |||
- | You should have received a copy of the GNU General Public License | ||
- | along with this program; if not, see http:// | ||
- | !*/ | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | |||
- | #define BUFSIZE | ||
- | |||
- | struct usb_device *device; | ||
- | usb_dev_handle *handle; | ||
- | char buf[BUFSIZE]; | ||
- | |||
- | // find the first ucecho device | ||
- | struct usb_device *find_device () | ||
- | { | ||
- | struct usb_bus *bus_search; | ||
- | struct usb_device *device_search; | ||
- | |||
- | bus_search = usb_busses; | ||
- | while (bus_search != NULL) | ||
- | { | ||
- | device_search = bus_search-> | ||
- | while (device_search != NULL) | ||
- | { | ||
- | if ( (device_search-> | ||
- | { | ||
- | handle = usb_open(device_search); | ||
- | usb_get_string_simple(handle, | ||
- | if ( ! strncmp(" | ||
- | return device_search; | ||
- | usb_close(handle); | ||
- | } | ||
- | device_search = device_search-> | ||
- | } | ||
- | bus_search = bus_search-> | ||
- | } | ||
- | | ||
- | return NULL; | ||
- | } | ||
- | |||
- | // main | ||
- | int main(int argc, char *argv[]) | ||
- | { | ||
- | usb_init(); | ||
- | usb_find_busses(); | ||
- | usb_find_devices(); | ||
- | |||
- | device = find_device(); | ||
- | |||
- | if ( device == NULL ) { // nothing found | ||
- | fprintf(stderr, | ||
- | return 1; | ||
- | } | ||
- | |||
- | if (usb_claim_interface(handle, | ||
- | fprintf(stderr, | ||
- | return 1; | ||
- | } | ||
- | | ||
- | while ( strcmp(" | ||
- | // read string from stdin | ||
- | printf(" | ||
- | scanf(" | ||
- | |||
- | // write string to ucecho device | ||
- | int i = usb_bulk_write(handle, | ||
- | if ( i < 0 ) { | ||
- | fprintf(stderr, | ||
- | return 1; | ||
- | } | ||
- | printf(" | ||
- | |||
- | // read string back from ucecho device | ||
- | i = usb_bulk_read(handle, | ||
- | if ( i < 0 ) { | ||
- | fprintf(stderr, | ||
- | return 1; | ||
- | } | ||
- | printf(" | ||
- | |||
- | } | ||
- | |||
- | usb_release_interface(handle, | ||
- | usb_close(handle); | ||
- | return 0; | ||
- | } | ||
- | </ | ||
- | |||
- | ====== Example call ====== | ||
- | |||
- | It follows an example call with output: | ||
- | < | ||
- | stefan@ws2:/ | ||
- | FPGA configuration time: 1353 ms | ||
- | Enter a string or `quit' to exit the program: Hello world! | ||
- | Send 12 bytes: `Hello world!' | ||
- | Read 12 bytes: `HELLO WORLD!' | ||
- | |||
- | Enter a string or `quit' to exit the program: quit | ||
- | Send 4 bytes: `quit' | ||
- | Read 4 bytes: `QUIT' | ||
- | </ |