Version 1.7.15

An easy programming interface for the Cypress Cy7c68013(A) USB2.0 controller.

^ What is USB2.DLL?
  USB2.DLL is an easy programming interface for the USB2.0 controller CY7C68013 and the "USB High-Speed interface" from Braintechnology. It can be used by nearly any programming language and can save much time to realize your usb2.0 project, since you don't have to study the complex topic of USB programming.


^ About USB High-Speed Interface Module V2.0 & V2.5 from Braintechnology

The USB2.DLL is developed using the usb2.0 interface from Braintechnology. The interface is ideal to realize your own developments in the USB2.0 sector.

Pinout of the module:

Version 2.0   Version 2.5


Connection Description
3 freely programmable IO Ports, each having 8 IO-lines. The Port lines work with 3.3V logic levels.
PortB is an 8-Bit data bus, if the parallel interface is initiated in 8-bit mode. if it is initiated in 16 bit mode, PortB is the least, and PortD the most significant byte.
The IO-lines are 5V tolerant and able to sink and source 4mA (=IOL and IOH).
i2c interface for connection of EEProm, LC displays, i2c port expander and other i2c-hardware. The Pull-up resistor necessary for i2c is already integrated on the module. The internal EEProm is also connected to this bus.
Supply voltages for your target circuit. They are generated from USB bus.
Freely definable outputs, which can only be used by the parallel bus.
Freely definable inputs, which can only be used by the parallel bus.
IFCLK If the parallel interface is activated, this connection may be used to supply an external clock or server a clock of 48Mhz, depending on the  parallel mode you use. The bus is synchronous to this clock. More Information can be found in the section Parallelport-functions.
CLKOUT serves a clock of 48MHz (clock frequency of the CPU)
/WAKEUP This pin should be tied to +3.3V


^ Installation
  You have to install EzUsb-driver from Cypress to use USB2.DLL. It can be downloaded from the Website of Cypress, or Braintechnology.

The DLL must be in the search path for DLLs. That is either the system-directory of the computer, or the directory of your application.

A registration using regsvr32 is not necessary, since this is no activex-dll.


^ Some general things about this DLL
  Each function of the DLL returns a value of the type Boolean. If it is TRUE (1), the function was successful. If it is FALSE (0), an error occurred. The source of an error can be determined using the functions UsbGetError and UsbGetErrorStringByNr.

Nearly every function has a call parameter named DevNum. It must contain the number of the USB interface you want to access. The first attached interface has the number 0, the second number 1, ...

If only one interface is attached, you have to pass the value 0.

The DLL has a debug console that can be activated by creating the registry key:

and creating a DWORD with the name "Debug" and the value "1".

When any dll function will be called a debug window gets opened showing error messages and other informations suitable for debugging purposes.

The Debug mode can be deactivated by deleting the key or setting the value "Debug" to 0.


^ Examples

There are 3 simple examples included, which clarify the access to the interface:


This program demonstrates the programming of the parallel bus. You have to press the button Initialize Parallel Interface before pressing any other button. A click on button Write! writes the count of bytes you specified in the edit-field to the parallel bus. A click on button  Read! does the equivalent for read access.

Note: This Demo uses parallel mode 4.


Using this example you can read and write values to the internal EEProm. The speed of the i2c-Bus can be selected (100/400KHz).

To write a value you have to fill the edit-fields ADDRESS and VALUE and click on the button Write.

For reading a value from the EEProm enter the ADDRESS and click on Read. The Read value will be shown in the value-field.


With the help of this example the states and directions of all IO-lines may be set or read.
Every I/O-Line is visualized with 3 elements:

  • A "number", which can be changed to 0 or 1 by clicking on it. It sets the logic state of the IO-line. Changes affect themselves only, if the line is set as an output.
  • An arrow, which indicates the current direction of the respective IO-line. If the arrow points left, the IO line is an Input, if it points right, it is an Output.
  • A "LED", which indicates the current state (HI/Low) of the IO line.

Future versions will contain examples for Visual C++ and Visual Basic.


^ Header and Includes for different programming languages

The folder "Includes" contains includes and samples for different programming languages like Visual Basic, Delphi and Visual C++

If you want to use the DLL in another programming language and no include exists you may perhaps need a description of the used data types in call- and return parameters:


Data type length in Bytes signed/unsigned Description
boolean 1 - A boolean contains the value 1 (=true) oder 0 (=false)
byte 1 unsigned An unsigned value from 0 to 255
word 2 unsigned An unsigned value from 0 to 65535
dword 4 unsigned An unsigned value from 0 to (2^32)-1
pchar 4 - Pointer to a zero terminated string (as it is used in C)
pointer 4 - An untyped Pointer

If the keyword "Var" is used in front of a parameter, a pointer to a value is expected. It is equivalent to the "*" operator in C, or the keyword "byRef" in Visual Basic.


^ Latency times and speed
  Because of the protocoll used by USB a data transfer can only be initiated after a frame or microframe (USB2) occurs. This results in a latency time of approx. 1ms for USB1.1 and approx. 1/8ms for USB2. So applications, which need a low latency time will need an usb2 interface.

You should keep the latency times in mind during programming. It is inefficient to transfer larger data sets in "small pieces".

// Example 1:
for i := 0 to 63 do
  UsbParOut(0, @Buffer[i], 1); // Writes 1 Byte to the parallel bus

// Example 2:
UsbParOut(0, @Buffer, 64); // Writes 64 Byte to the parallel bus

While the Data transfer in example 1 needs about 8ms (USB2) to complete, example 2 needs only about 1/8ms.


  Functions of the DLL
    General functions
^     UsbInit
  function UsbInit(DevNum : Byte) : Boolean;

Initializes the USB interface specified by DevNum. The Initialization procedure programs the current firmware to the controller and its call is necessary to be able to communicate with the controller.

If no license is set before calling UsbInit the function tries to find a file named "license.dat" in the current working directory and the DLL's folder. If this file it found, the license will be set automatically.

The interface is not opened exclusively, i.e. several programs can access the Interface at the same time. Therefore no "closing" of the DLL is necessary.


^     UsbGetError
  function UsbGetError : Byte;

If an error occurs during communication with the interface, this function delivers the error number. If the returned value is 0, no error occurred. After calling this function, the reported error will be cleared.

Error number Description
0 no error
1 File not found
2 Device not present: The device is not connected or the driver is not installed correctly
3 Unable to open device
4 Usb transfer failed: The usb transfer timed out or the device has been removed during a usb transfer
5 Out of memory: The DLL failed to allocate memory
6 Invalid parameter: One of the parameters passed to a function is wrong or out of range
7 Interface is not initialized: The interface has not been initialized using UsbInt
8 I2c transfer timed out: The i2c transfer timed out. Perhaps the i2c timeout value has to be modified using UsbSeti2cTimeout
9 I2c bus error (lost arbitration)
10 The i2c slave did not acknowledge
11 Eeprom write timed out: The EEprom did not ackknowledge during the selected EEprom timeout. Perhaps the timeout has to be increased using the function UsbEEpSetTimeout.
12 SPI bus has to be initialized before calling this function: You called an SPI-transfer function, but did not initialize the SPI bus using UsbSpiInit before
13 Parallel bus has to be initialized before calling this function: You called an Parallel bus function without initializing it using UsbParInit or UsbParInitUsingArray
14 UsbParIn transfer timed out
15 UsbParOut transfer timed out
16 Internal error-Transaction number mismatch

The error number can also be automatically translated to a human readable string by calling the function UsbGetErrorStringByNr.


^     UsbGetErrorStringByNr
  function UsbGetErrorStringByNr(ErrNr : Byte; var PString : PChar) : boolean;

When passing the Error number retrieved by UsbGetError in ErrNr, a pointer to the error message will be returned in PString. For compatibility reasons a pointer to a PChar will be used. A PChar is a pointer to a zero terminated Array of Char, as it is used in C or several windows-api functions.

PString is a "pointer to a pointer to a string array", so an address of a pchar will be received using this function.


^     UsbSetLicense

function UsbSetLicense(Filename : PChar) : boolean;

If this function is not executed before calling any other function of the dll, a messagebox will be shown about every 5 minutes to indicate that you are using a demo version. If you have registered and got a license-file from us, you have to pass the Filename (and Path) of the license-file to remove the popup window.

If no path is specified the file will be opened from the current working directory (CWD).


^     UsbCheckSpeed

function UsbCheckSpeed(DevNum : Byte; var Speed : Byte) : boolean;

Returns a value in variable Speed. If Speed is 0, the usb controller is connected to a usb1.1, if Speed is 1 to a USB2 host controller.


^     UsbOpen

function UsbOpen(DevNum : Byte) : boolean;

If this function is not used, the device will be opened and closed every time you call a function of the dll. This results in a small loss of time, but multiple applications can access the device at the same time.

If you call this function, the device will be opened exclusive and speed up data transfers, but you have to call the function UsbClose when your application exists.

This function has to be called (if it is used) after calling the function UsbInit.


^     UsbClose

function UsbClose(DevNum : Byte) : boolean;

Closes the device, when it has been opened using UsbOpen. If UsbOpen is not used, UsbClose does not need to be called.


^     UsbGetVersion

procedure UsbGetVersion(VersionStr : PChar);

Returns the Versionnumber of usb2dll as String in VersionStr. VersionStr has to point to a memory area of at least 8 Byte length.

^     UsbSetTimeout

function UsbSetTimeout(DevNum : Byte; timeout : Word) : boolean;

Will set the timeout for i2c and parallel bus transfers. The parameter timeout specifies the timeout in count of milliseconds (for example 5 is equivalent to 5ms).

The default value is 10 milliseconds.


^     UsbWaituSec
  procedure UsbWaituSec(usec : DWord);

Waits for the specified count of micro seconds (=1/1000ms or 1/1000000 s).


^     UsbGetStatus
  function UsbGetStatus(DevNum : Byte) : Boolean;

If the retrieving of error codes is turned of by UsbRetrieveAllErrors this function can be called to manually retrieve the status from the firmware.


^     UsbRetrieveAllErrors
  function UsbRetrieveAllErrors(DevNum : Byte; RetrieveAll : Boolean) : boolean;

Some functions (currently UsbI2cWriteByte(s) and UsbParOut) retrieve an error code from the firmware, although it might not be needed. This additional retrievment of the error code slows down the execution of the command, as an additional usb transfer is needed.
With the parameter RetrieveAll = false this additional error retrievement can be turned off.

The default is that error codes are read from the firmware.


^     UsbDevicePresent

function UsbDevicePresent(DevNum : Byte) : Boolean;

This function returns true (1) if the specified Device is present. It it returns false the driver is not installed correctly or the device is not connected.


^     UsbDeviceInitialized

function UsbDeviceInitialized(DevNum : Byte) : Boolean;

UsbDeviceInitialized returns true (1) if UsbInit has been called for the specified DevNum before. If it has not been called the function will return false (0).


^     UsbRegisterDeviceEvent

procedure UsbRegisterDeviceEvent(cb : TPowerCallbackProc);

UsbRegisterDeviceEvent registers a callback function to the Dll. The callback function will be called wenn an usb2dll device is connected or disconnected to/from the system. called the function will return false (0).

TPowerCallbackProc = procedure(removed : Boolean); stdcall;

The Callback procedure has an parameter. When the callback function is called the value of the parameter "removed" is set to true when a device was removed, or false if a new device was connected.


^   IO functions
^     UsbSetIOState
  function UsbSetIOState(DevNum, LineNum, State : Byte) : boolean;

A single IO line can be set to High (State=1) or Low (State=0). LineNum must contain the number of the IO line you want to set.

The assignment is as follows:

LineNum IO-line   LineNum IO-line   LineNum IO-line   LineNum IO-line   LineNum IO-line
0 PortA.0   8 PortB.0   16 PortD.0   24 PortC.0   32 PortE.0
1 PortA.1   9 PortB.1   17 PortD.1   25 PortC.1   33 PortE.1
2 PortA.2   10 PortB.2   18 PortD.2   26 PortC.2   34 PortE.2
3 PortA.3   11 PortB.3   19 PortD.3   27 PortC.3   35 PortE.3
4 PortA.4   12 PortB.4   20 PortD.4   28 PortC.4   36 PortE.4
5 PortA.5   13 PortB.5   21 PortD.5   29 PortC.5   37 PortE.5
6 PortA.6   14 PortB.6   22 PortD.6   30 PortC.6   38 PortE.6
7 PortA.7   15 PortB.7   23 PortD.7   31 PortC.7   39 PortE.7

PortC and PortE are only available for the -100 and -128 version of the FX2 controller.

The IO-Line must be programmed as output by using UsbSetIODir or UsbSetPortDir, to make the changes affect.


^     UsbSetIODir
  function UsbSetIODir(DevNum, LineNum, Dir : Byte) : boolean;

Sets the direction of a single IO line to output (Dir=1) or input (Dir=0). After initialization of the interface all io lines are set as input (tristate).

The assignments of LineNum to IO-lines corresponds to UsbSetIOState.


^     UsbGetIOState
  function UsbGetIOState(DevNum, LineNum : Byte; var State : Byte) : boolean;

Returns in parameter State the condition of an IO-line. If it is High, then State=1, is it Low, then State=0.

The assignments of LineNum to IO-lines corresponds to UsbSetIOState.


    Port functions
^     UsbSetPortState
  function UsbSetPortState(DevNum, PortNum, State : Byte) : boolean;

Sets one of the ports to the states passed by the parameter State. PortNum is the number of the io-port you want to modify. 

The assignments are as follows:


PortNum Port
0 PortA
1 PortB
2 PortD
3 PortC (FX2-100 and FX2-128 only)
4 PortE (FX2-100 and FX2-128 only)

If a bit of State is 1, the appropriate port pin is switched to high-state.

To make the changes affect, the directions of IO-Lines have to be set to Output using UsbSetIODir or UsbSetPortDir.


^     UsbSetPortDir
  function UsbSetPortDir(DevNum, PortNum, Dir : Byte) : boolean;

Sets the direction bits of the port specified by PortNum.

If a bit is 1, the appropriate io line becomes an output, otherwise an input.

The assignments of PortNum to the io-ports are the same as in UsbSetPortState


^     UsbGetPortState
  function UsbGetPortState(DevNum, PortNum : Byte; var State : Byte) : boolean;

Returns the state of the port specified by PortNum.

The assignments of PortNum to the io-ports are the same as for UsbSetPortState


    i2c-Bus functions
  The i2c functions use the hardware i2c bus of the fx2 controller. It supports clock stretching devices and multi-master enviroments.

As a non-working i2c slave or a short circuit of the i2c bus lines might halt a transfer, a timeout is implemented for i2c transfers. It can be set using the functions UsbSetTimeout or UsbI2cSetTimeout. The default timeout value is 10ms.

A usual i2c slave address is composed of a 7 bit address and 1 Read/Write bit:

Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
A6 A5 A4 A3 A2 A1 A0 R/W

All i2c transfer functions expect just the 7 bit address (A0-6) for their "slaveaddress" parameter, as the R/W bit is added internally:

Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
0 A6 A5 A4 A3 A2 A1 A0


^     UsbI2CSetTimeout

function UsbI2CSetTimeout(DevNum : Byte; Timeout : Word) : Boolean;

Sets the timeout for I2C transfers in millisecond steps. The default timeout is 10 ms.


^     UsbI2CSetSpeed
  function UsbI2CSetSpeed(DevNum, Speed : Byte) : boolean;

Sets the speed of i2c interface. If Speed=0 is passed, the i2c works with a clock of 100khz. Speed=1 switches i2c interface to high speed mode (400khz clock).


^     UsbI2CWriteByte
  function UsbI2CWriteByte(DevNum, SlaveAddr, Data : Byte) : boolean;

Writes the byte Data to the i2c-device with the 7-bit slave address SlaveAddr.


^     UsbI2CWriteBytes
  function UsbI2CWriteBytes(DevNum, SlaveAddr, Length : Word; P : Pointer) : boolean;

Writes the block of Data specified by pointer P with the length Length to the i2c device with 7-bit slave address SlaveAddr.

If Length is zero, 65536 Bytes will be written.


^     UsbI2CReadByte
  function UsbI2CReadByte(DevNum, SlaveAddr : Byte; var Data : Byte) : boolean;

Reads a single Byte from i2c-device with the 7-bit slave address SlaveAddr. The read value will be passed to Data.


^     UsbI2CReadBytes
  function UsbI2CReadBytes(DevNum, SlaveAddr, Length : Word; PData : Pointer) : boolean;

Reads a data block with the length of Length Bytes from the i2c-device with the 7-bit slave adress SlaveAddr.

If Length is zero, 65536 bytes will be read.


^     UsbI2CWriteAndReadBytes
  function UsbI2CWriteAndReadBytes(DevNum, SlaveAddr : Byte; WriteLen, ReadLen : Word; PWrite, PRead : Pointer) : boolean;

Writes the block of Data specified by pointer PWrite with the length WriteLen to the i2c device with slave address SlaveAddr. After writing a Count of Readlen Bytes will be read from the same i2c-device. The read values will be placed in the buffer PRead points to.

Between the write and the read transfer a restart condition will be sent.

If WriteLen or ReadLen is zero, 65536 bytes will be read or written.


    i2c-EEProm functions
  The EEprom functions may be used to write to a 2-address byte eeprom like the 24lc64 that is present on the Braintechnology module.


^     UsbEEpSetTimeout

function UsbEEpSetTimeout(DevNum : Byte; Timeout : Word) : Boolean;

Sets the timeout for the EEprom write cycle. This timeout should be greater than the twp value of the eeprom. The default timeout is 10ms.


^     UsbEEpWriteByte
  function UsbEEpWriteByte(DevNum : Byte; Addr : Word; Data : Byte) : boolean;

Writes the Data byte Data to the address Addr of the internal EEProm.


^     UsbEEpWriteBytes
  function UsbEEpWriteBytes(DevNum : Byte; Addr : Word; Length : Byte; PData : Pointer) : boolean;

Writes a data block specified by Pointer PData with a length of Length Bytes to the EEProm address Addr.


^     UsbEEpReadByte
  function UsbEEpReadByte(DevNum : Byte; Addr : Word; var Data : Byte) : boolean;

Reads a single data byte from address Addr of internal EEProm. The read value will be returned in Data


^     UsbEEpReadBytes
  function UsbEEpReadBytes(DevNum : Byte; Addr : Word; Length : Byte; PData : Pointer) : boolean;

Reads a Data block with the length of Length Bytes from the internal EEProm. The read values will be written to the memory PData points to.


^     UsbEEpSetAddr

function UsbEEpSetAddr(DevNum, SlaveAddr : Byte) : boolean;

This function sets the i2c-slaveaddress of the eeprom.

The adresses of the 2 diffrent USB2-modules from  Braintechnology are:


Modul Slaveaddress
USB HighSpeed Interface Modul V2.0 0x50
USB HighSpeed Interface Modul V2.5 0x51

If you use the new version you have to call UsbEEpSetAddr like this:

UsbEEpSetAddr(0, 0x51);


    SPI functions

The SPI bus functions implement a SPI master and consists of 4 I/O lines:

PortA.7 = /SS (Slave select - Output)
PortA.6 = SCK (Clockline - Output)
PortA.5 = MOSI (Master Out Slave In - Output)
PortA.4 = MISO (Master In Slave Out - Output)

Data is transfered bit-wise synchronous to SCK over the data lines MOSI and MISO. /SS gets low before a data byte will be transfered and high after a byte has been transfered.

^     UsbSpiInit

function UsbSpiInit(DevNum : Byte; LsbFirst : Boolean; SPIMode : Byte; Speed : Byte) : Boolean;

Initializes the Spi bus with the specified parameters:

If LsbFirst is true (1), the first bit transfered is the LSB (Bit 0), if it is false (0), the MSB (Bit 7) will be transfered first.

Speed selects the bitrate of the bus:

0 = 50 kHz
1 = 25 kHz
2 = 10 kHz
3 = 5 kHz
4 = 2 kHz
5 = 1 kHz

SPIMode defines the idle state of the clockline and the edges data is transfered:

Bit 0 = 0: The Idle state of SCK is 0. The leading edge is a 0 to 1 transition, trailing edge a 1 to 0 transition
Bit 0 = 1: The Idle state of SCK is 1. The leading edge is a 1 to 0 transition, trailing edge a 0 to 1 transition

Bit 1 = 0: Data is sampled at leading edge of SCK and Setup on the trailing edge
Bit 1 = 1: Data is sampled at trailing edge of SCK and Setup on the leading edge

Bit 2 = 0: SS line is low between bytes
Bit 2 = 1: The SS line is low for the whole SPI message


^     UsbSpiTransfer

function UsbSpiTransfer(DevNum : Byte; PWrite, PRead : Pointer; Len : Word) : Boolean;

Transfers a Datablock in both directions (in and out) over the SPI bus. Len specifies the count of byte to be transfered, PWrite has to point to a data block with data bytes to be written, PRead will receive the read data.


^     UsbSpiTransferByte

function UsbSpiTransferByte(DevNum : Byte; DatWrite : Byte; var PDatRead : Byte) : Boolean;

Transfers a single Byte (8 bit) in both directions using the SPI bus.



The parallel port functions implement the GPIF of the FX2 controller. The GPIF is basically a hardware-statemachine that can describe how the data should be transfered over the parallel bus. Although other characteristics of the bus can be selected, like the buswidth (8/16 bit), the clockrate (and source) of the statemachine that influences the burst rate, etc.

As it is not very easy to generate a GPIF waveforms there are 10 predefined "parallel modes" available that can be initialized using the function UsbParInit.

GPIF waveforms can also be created using the included program ParBusEditor or the GPIF Designer from Cypress. ParBusEditor creates directly a data block containing the graphically defined waveforms and parameters. The GPIF Designer from Cypress generates a gpif.c template that can be converted to a usb2dll data block using the included utility "GpifCconverter".
When a self generated waveform should be used the Parallel bus has to be initialized using the function UsbParInitUsingArray instead of UsbParInit.

As data is transfered in packets over the USB this behaviour will also be reflected in parallel bus transfers. The data is rather transfered in max. 512 byte (USB2) or 64 byte (USB1) sized rather than a single contiguos data packet. If the connected peripheral requires an equidistant data transfer (for example video/audio streaming applications) an external FIFO needs to be connected.


^     UsbParInit

function UsbParInit(DevNum, mode :Byte) : boolean;

Initializes the Parallel interface (=Parallel bus). An initialization is necessary, to transfer Data over the parallel bus.

The following modes are implemented:

mode Clock source Bus width Max. Data transfer rate (Burst rate)
0 Internal 8 Bit  24 MB/s
1 Internal 16 Bit  48 MB/s
2 External 8 Bit  =IFCLK
3 External 16 Bit  =IFCLK*2
4 Internal 8 Bit  4.8 MB/s
5 Internal 16 Bit  9.6 MB/s
6 External 8 Bit  IFCLK/10
7 External 16 Bit  IFCLK/5
8 - 8 Bit Depend on the connected hardware due to handshaking
9 - 16 Bit Depend on the connected hardware due to handshaking


Mode 0-3

mode = 0:

Mode 0 is a very fast 8 bit bus. You can achieve Burst Data rates of 24MB/s and an average data rate of approximately 23 MB/s.

The following connections are used for this mode:

Connection Description
PortB Bi-directional 8 bit data bus
CTL0 /Wen: An low active write enable signal that gets activated (/Wen=0) during a write access.
CTL1 /Ren: An low active read enable signal that gets activated (/Ren=0) during a read access.
CTL2 /OE: output enable (low-active). This signal may be used to activate the bus-drivers of the target hardware.
RDY0 /EF: empty flag. This signal is an input. If this line will be set to low during a read-cycle, the transfer is stopped until it becomes hi.
RDY1 /FF: full flag. The function is equivalent to /EF, but this signal is used for write transfers.
IFCLK supplies a 48MHz bus-synchronous clock. During a write cycle your hardware must store the data at a falling edge. During a read cycle the Data must be transferred at a rising edge.

mode = 1:

This is a 16 Bit wide variant of parallel mode 0 described above. PortB is the least-, PortD the most significant Byte of the bus. 

mode = 2:

Mode 2 is equivalent to mode 0, but IFCLK is an Input. You can feed a Clock of the range 5-48MHz. The bus works synchronous to this clock.

mode = 3:

Mode 3 is equivalent to mode 0. IFCLK is an input and the bus-width is 16 bit. PortB is the least-, PortD the most significant Byte of the bus. 

Waveform for 3 Write cycles:

Waveform for 3 Read cycles:


Mode 4-7

mode = 4:

A parallel bus with /RD, /WR and /OE lines, as it is usual in much microprocessor busses. Burst data rate is 4.8MB/s.

Connection Description
PortB Bi-directional 8-Bit data bus
CTL0 /RD: an low active read signal. /RD=0 reads a data byte from the bus.
CTL1 /WR: an low active write signal. /WR=0 writes a data byte to the bus.
CTL2 /OE: If this signal is asserted (/OE=0), the output-drivers of your target Hardware have to be driven.
RDY0 /EF: empty flag. The function is equivalent to mode 0
RDY1 /FF: full flag. The function is equivalent to mode 0

mode = 5:

A 16-Bit wide version of mode 4. PortB is the least-, PortD the most significant Byte of the bus. Burst data rate: 9.6MB/s.

mode = 6:

Mode 6 is equivalent to mode 4. IFCLK is an input you have to supply an input clock in the range 5-48MHz. The bus works synchronous to this clock. A writing cycle is fulfilled in 10 clock cycles of the IFCLK signal.

mode = 7:

Mode 7 corresponds to mode 6 with the difference that it has a 16 bit wide bus. PortB is the least-, PortD the most significant Byte of the bus.

Waveform for 2 Write cycles:

Waveform for 2 Read cycles:


Mode 8-9

Mode 8 and 9 have been implemented to transfer data to/from a microcontroller in an easy way. The I/O lines of your microcontroller may be connected 1:1 to the databus and handshakelines of the USB controller.
A handshaking mechanism enables a secure data transmission.

Mode 8 realizes a 8 Bit wide, Mode 9 a 16 Bit wide data bus.

The following connections are used for this bus:

Connection Description
PortB Bidirektional 8-Bit data bus (Mode 9: lower data byte of the 16 bit data bus)
PortD only mode 9: higher data byte of the 16 Bit data bus
CTL0 =STROBE (Output)
CTL1 =DIR (Output)
RDY0 =ACK (Input)

A Data byte will be written the following way (eg. UsbParOut(0, @Buffer, 1);):

  • DIR=1
  • Output the byte to transmit on the data bus
  • STROBE=0
  • Wait until ACK=0
  • STROBE=1
  • Set data bus to tristate
  • Wait until ACK=1

Reading of a Byte (eg. UsbParIn(0, @Buffer, 1);):

  • DIR=0
  • STROBE=0
  • Wait until ACK=0
  • read data byte from data bus
  • STROBE=1
  • Wait until ACK=1
  • DIR=1

In Idle state the I/O lines have the following states:

  • STROBE=1
  • DIR=1
  • ACK=1 (has to be set in your microcontroller program)


The function for datatransfer in your connected microcontroller may work the following way:

if (STROBE == 0) {                   // data transfer initiated by PC
    if (DIR == 0) {                  // PC reads data (UsbParIn)
        State of Data bus = Data byte;
        Switch data bus to output;
        ACK = 0;
        while (STROBE == 0) ;        // wait until STROBE = 1
        Switch data bus to tristate (input);
    } else {                         // PC sends data (UsbParOut)
        Data byte = State of data bus;
        ACK = 0;
        while (STROBE == 0) ;        // wait until STROBE = 1
        ACK = 1;

The Data bus implemented in your controller has to be initilized the following way:

  • Set Data bus  as Input (tristate)
  • Set STROBE and DIR as Input
  • ACK = Output, State Hi (1)

^     UsbParInitUsingArray

function UsbParInitUsingArray(DevNum, Data : Pointer) : boolean; 

Initializes the Parallel interface using a data block. If the above descibed modes don't fullfill your needs you can create a datablock using the Cypress GPID designer (+ GpifCconverter) or our tool ParBusEditor. Theese tools generate a data block that can be passed as a pointer to this function to initialize the parallel bus.


^     UsbParSetTimeout
  function UsbParSetTimeout(DevNum : Byte; Timeout : Word) : Boolean;

This function sets the timeout for Parallel bus transfers. If data is not transfer during the specified Timeout, the transfer will be stopped. The default value is 10ms.


^     UsbParSetWaveforms
  function UsbParSetWaveforms(DevNum, InWfIdx, OutWfIdx : Byte) : Boolean;

The GPIF can contain 4 waveforms. This functions enables you to select which waveform should be used for a following write access (OutWfIdx) or read access (InWfIdx).


^     UsbParOut

function UsbParOut(DevNum : Byte; PData : Pointer; Len : DWord) : boolean; 

Outputs a number of Len data words to the parallel bus. PData is a pointer to the data block to transfer. If the transfer times out the function returns with false (0). The timeout can be set using the functions UsbSetTimeout or UsbParSetTimeout.


If the interface is in 8 Bit mode and 768 bytes have to be transferred:

UsbParOut(0, @Buffer, 768);

If the interface is in 16 Bit mode and 768 Bytes (=384 Words) have to be transmitted:

UsbParOut(0, @Buffer, 384);

^     UsbParIn

function UsbParIn(DevNum : Byte; PData : Pointer; Len : DWord) : boolean; 

Reads Len data words from the parallel bus. PData is a pointer to the Data block, which should receive the read values. If the transfer times out the function returns with false (0). The timeout can be set using the functions UsbSetTimeout or UsbParSetTimeout.


If the interface is in 8 Bit mode and 768 bytes have to be transferred:

UsbParOut(0, @Buffer, 768);

If the interface is in 16 Bit mode and 768 Bytes (=384 Words) have to be received:

UsbParOut(0, @Buffer, 384);


^     UsbGetRdyState

function UsbGetRdyState(DevNum : Byte; var Rdy : Byte) : boolean; stdcall;

Returns in Rdy the state of the RDYx-lines (RDY0, RDY1, etc.).

The state of Bit0 equals the state of RDY0, Bit 1=RDY1, ...

^ Troubleshooting
kind of problem possible reason/solution
  • You are not able to communicate with the controller.
Most likely the driver is not or not correctly installed.

After connecting the Interface Board V2, resp. Cypress FX2 controller the marked entry has to appear in the device-manager (see picture).
If a yellow grounded exclamation mark apears at this entriy or if it is missing, you have to install the EZUSB-drivers again. You can download them at

  • The latency times are high (>=1ms) in spite of using a USB2 interface card.
This problem occurs, when the device-manager does not show an Enhanced Host Controller (EHCI). The USB2 controller addressed by usb2dll is then recognized as low speed device. You will have to reinstall your USB2 Interface drivers again.

When using Windows XP the installation of Service Pack 1 or higher is needed (See Microsoft Knowledge Base Article Q312370).


^ Future extensions
  • Programming of examples and includes for Visual C++, Labview and Java
  • Programming of an event mechanism, which calls special program sections after appearance of hardware interrupts (e.g. pressing a button connected to an io-line)
  • ...and much more


^ Version history
Version Changes
  • some Bugfixes
  • new function: UsbRegisterDeviceEvent
  • Extended UsbSpiInit function to set the Slave select line behaviour.
  • UsbDeviceInitialized function did not return the proper state when initialized devices have been disconnected and connected before calling the function
  • Function UsbSetLicense did not work in .net environments
  • Small internal changes
  • Removal of sporadic "Abort 997" Message dialog appearance
  • Adjusted initialization function to stay compatible to the new FX2/LP controller of Cypress.
  • UsbParIn/Out produced memory leakages
  • Error numbers returned by UsbGetError were wrong (decremented by 1)
  • UsbSpiInit read data at the wrong clock edges
  • Modified C include usb2dll.h
  • Modified ParbusEditor: increased maximum transfer size to 128K and added a warning message if the transfer size exceeds
  • UsbParOut always returned an error when UsbRetrieveAllErrors(false) was called before.
  • UsbParIn failed on some systems when using EzUsb driver.
  • Parallel Mode 0-3-Read: When /EF was low during a transfer /OE did not stay low.
  • The mentioned file GpifCconverter.exe was not included in the distributed archive.
  • Totally rewrite of firmware and dll. This current version has a much better error handling and is able to use EzUsb and CyUsb driver.
  • Old versions had the behaviour to lock the application if something went wrong (eg. a pulled-down i2c line, a failed usb transfer, etc). This behaviour is also removed in this version.
  • New: SPI functions
  • New functions: UsbParSetWaveforms, UsbParSetTimeout, UsbI2cSetTimeout, UsbEEpSetTimeout, UsbRetrieveAllErrors, UsbDevicePresent, UsbDeviceInitialized, UsbUsbParSetTransferSize
  • Added a debug console to show errors that are not handled by an application and make it easier to implement includes for different programming languages.
  • The burst rate of parallel modes 0-3 was wrong
  • Added diagrams for predefined parallel modes
  • 16-bit data transfer did not work correctly
  • Changed some length-parameters to realize larger datatransfers (i2c, eep and parallelbus-functions)
  • adjustable Timeout realized (for i2c and parallelbus functions)
  • changed parallel mode 0-3 (compatible to older versions)
  • The renumeration has been removed completely, because on some computers the function UsbInit failed and Applications just worked correctly after a second start.
  • Parallelbus mode 0 & 1 did not react correctly to /EF and /FF inputs
  • function UsbParInitUsingArray and i2c function did not work correctly
  • New function: UsbEEpSetAddr, UsbGetVersion und UsbGetRdyState
  • New Parallel bus modes 8 and 9, which implement an easy handshaking for communication with microcontrollers
  • New functions: UsbOpen & UsbClose
  • New sections: "troubleshooting", "latency times and speed" and "general informations about parallel bus"
  • The captions of PortD in the figure of Braintechnology-module have been wrong
  • Parallel bus mode 4-7: when /EF has been pulled low during a read access, the transmission stopped, even if it has been pulled high afterwards
  • UsbI2cRead- and UsbEepRead functions returned wrong data if just one Byte was read from the bus.
  • 16 bit wide parallel bus modi did not work correctly.
  • High- and Lowspeed detection (UsbCheckSpeed) did not work correctly on some systems.
  • Function UsbInit will now wait, until windows renumerated the device.
  • Old Versions did not support more than one fx2 interface.


  • The DLL is now 100% usb1.1 compatible.
  • New functions: UsbCheckSpeed and Usbi2cWriteAfterRead.
  • Fixed error in function UsbGetErrorStringByNr and changed calling parameters.
  • Fixed the non-working Parallelbus modes 0-3.
  • added UsbParIn, which enables you to read from parallel bus.
  • The Firmware has not been programmed  correctly. This bug has been repaired in this version.
  • Implementation of parallel bus functions.
  • Changed the names of Calling parameter names for transparency reasons (data types and names changed). 
  • Added functions to access IO-ports parallel.
  • Implementation of i2c and  EEProm functions.
  • complete revision of firmware.
  • rewrote documentation.
  • Added new example application for i2c-EEProm functions (i2c demo)
  • iodemo only worked correctly, when you restarted it. This bug is removed.
  • First public version


^ Contact
  This product is developed by Kai Gossner in order of Braintechnology
Because this product is still in an development stage, we would like to hear from you about suggestions and bugs.

Kai Gossner: