Electronics -- USB-FX2: Software Examples with IOA collection of example software for the USB-FX2 board which make use of some IO lines on the board. Download All Examples in an ArchiveIn order to try the examples on this page, you should download this tarball since the code on this page does not contain the necessary include files which are (of course) part of the archive.
For building and running, please refer to the local examples since it works just the same here. However, make sure to do the required external signal wiring for each example as lined out in the example explanation below. Note: All these examples have been tested with my USB-FX2 board. If you experience trouble, please fix them and drop me a note. Also check out the troubleshooting hints. Bulk Read BenchmarkFirst, let's start with the simplest program making use of the IO lines on the USB-FX2 board: A bulk read benchmark firmware which spends all its time just trying to send data like mad over the USB link - as much as the host can sustain. Here's the code: Basically, we run the FX2LP in synchronious slave FIFO mode with AUTOIN enabled. However, we use internal interface clocking at maximum speed (48 MHz) and simply tie the write stobe line low to have data committed into the FIFOs as fast as possible. Since we're using the complete 16bit wide bus at 48 MHz, the theoretical FIFO transfer rate is 96MBytes/sec which is way above maximum theoretical USB-2.0 bandwidth of 60MBytes/s (well, even less due to protocol overhead). Hence, this firmware can be used to test host controller and host software performance. static void Initialize(void) { CPUCS = 0x12; // 48MHz, output to CLKOUT signal enabled. // Internally clocked (48MHz) sync slave fifo mode. // Output to IFCLK not enabled (set bit5 to enable). IFCONFIG = 0xc3; SYNCDELAY; REVCTL = 0x03; SYNCDELAY; // See TRM... // Configure EP6 (IN) for bulk input, quad-buffered (4*512 bytes). EP6CFG = 0xe0; SYNCDELAY; FIFORESET = 0x80; SYNCDELAY; // NAK all requests from host. FIFORESET = 0x82; SYNCDELAY; // Reset individual EP (2,4,6,8) FIFORESET = 0x84; SYNCDELAY; FIFORESET = 0x86; SYNCDELAY; FIFORESET = 0x88; SYNCDELAY; FIFORESET = 0x00; SYNCDELAY; // Resume normal operation. // Configure EP6 for AUTOIN, 16bit wide bus. EP6FIFOCFG = 0x0d; SYNCDELAY; // PORTACFG: FLAGD SLCS(*) 0 0 0 0 INT1 INT0 PORTACFG = 0x00; SYNCDELAY; // (delay maybe not needed) // All default polarities: SLWR active low,... FIFOPINPOLAR=0x00; SYNCDELAY; // This determines how much data is accumulated in the FIFOs before a // USB packet is committed. Use 512 bytes to be sure. EP6AUTOINLENH = 0x02; SYNCDELAY; // MSB EP6AUTOINLENL = 0x00; SYNCDELAY; // LSB } void main() { Initialize(); for(;;) {} }
When running the example (make run), you should see something like this:
cycfx2prog prg:bench_in.ihx run bench_bulk:6,16777216
Using ID 04b4:8613 on 006.004.
Putting 8051 into reset.
Programming 8051 using "bench_in.ihx".
Putting 8051 out of reset.
Read 16777216 bytes in 828 msec (chunk size 65536): 19.332 Mb/sec (256 calls, 65536 bytes/call)
So, that's a transfer rate of 19MBytes/sec. Not bad already but please note: This benchmark uses libusb and libusb clearly sucks performance-wise. Don't worry if you see ridiculously small numbers like 3Mb/s (!) on your computer (which may even go up with increasing interrupt load like playing music). The USB-FX2 is perfect like that but we can do better on the host side. Although the actual maximum transfer rate always also depends on the host controller in the computer (Intel ones seem to work fastest), clever software keeping several URBs in the request queue (like e.g. used in the FX2Pipe program or also by the SSRP project and by my USB Oscilloscope, too) are able to boost us up up to beyond 40Mb/s on Intel HCs (and over 35Mb/s on my Via-based PCI expansion card). By the way, using the dbulk command to cycfx2prog, you can see the data acutually read from the FIFO lines and watch how they change when you tie individual port A or port D lines LOW or HIGH. However, note that since the FX2 has 2kb of internal buffer (it is programmed for quad-buffered operation with a buffer size of 512 bytes) you need to read more than 2kb before you see the changes on the input pins on the screen. Slave FIFO ConfigurationsSince we're after speed, we either want to run the FX2LP in synchronious slave FIFO mode or in GPIF master mode. (SLWR signal timing constraints on behalf of the FX2 limit asynchronious transfers to somewhere below 16Mb/s; synchronious FIFO throughput is 96Mb/s and hence above USB-2.0 bandwidth.) Slave FIFO mode is gererally simpler than GPIF master especially when dealing with simple attached logic (like an AD or DA converter as opposed to an IDE drive). In (synchronious) slave FIFO mode, the most interesting pins are the following ones (for a complete list please refer to the TRM):
And the most important config registers are:
Simple bulk IO firmware can easily be implemented taking the above bench_in example as a pattern and simply substituting the correct values for IFCONFIG, EPxCFG and EPxFIFOCFG (and maybe some other related registers found in the TRM). As a further example, see e.g. the my USB Oscilloscope firmware.
|