I’ve had the enjoyable experience of playing around with the Cy7c68013a chip on the Ez-Usb development board for the past few weeks. I thought I’d post a few tips for developing in this type of environment with open source software.
-
Convert to Linux
The tools that Cypress provides with the development kit are Windows based. You can download a number of their items directly from their website, but i didn’t find a way to unpack their source code examples without running their installer in a Windows session. The installer creates a new directory: C:\Cypress\ You can ignore the bin directory. Copy the docs directory (You’ll need the TRM) and the examples directory to your Linux machine. The examples won’t compile on Linux (The c51 compiler provided by Keil is Windows based) but they provide good insight into how to do a few things when it isn’t immediately clear by reading the TRM. You may also be interested in their util sources but I’ve found only minor uses for these since there are open source alternatives to a lot of what they do.
-
Convert to SDCC
On Linux, you’ll compile programs for the 8051 chip with SDCC. You can install it from their sources or from a package provided by your Linux distribution. SDCC works very similar to gcc but provides output that can be loaded onto embedded devices.
A couple important switches for compiling:
- -mmcs51 Tells the compiler to produce output for the 8051 chip
- -xram-loc Tells the compiler where to start putting xdata variables
(If a program suddenly doesn’t work after you add an xdata variable, try playing with this 1st.)
-
Convert the fx2regs.h file
The fx2regs.h file provided with cypress won’t compile with SDCC (It’s Keil specific). There are a few things you can do.
- Just use the 8051.h (or 8052.h) file provided by sdcc. (Works if you don’t need lots of the extended registers. Also works for getting started with basic examples.
- Rewrite it in non compiler specific macros. SDCC comes with a compiler.h file that has macros for SFR, SBIT, etc. You can use these and generate a header file that can be compiled on more than one platform.
- Use a convert utility. There is a perl script on SDCCs contrib folder that can convert Keil to SDCC headers.
(For clarification, this script is included in the source tarball.) - Rewrite it yourself by hand. Well, if you don’t trust the conversion script anyway.
-
Learn how to run programs
The Cy7c68013a chip handles some basic USB commands for you. 1st of all, it will enumerate itself. 2nd, it will allow you to upload and download firmware to the 8051. This 2nd tidbit is vital. You can 1st upload a byte to the reset bit location in firmware (putting the chip in reset), then upload a new firmware, and then upload a byte that puts it back out of reset, thus running your program.
This fairly straight forward process is documented in the TRM. Even cooler though, someone already implemented it for you so you don’t have to. I use the cycfx2prog utility. It’s GPLed and the source is available to download.
After compiling a simple program (which produces an ihx-intel hex file), you can upload it like this:
> cycfx2prog prg:program.ihx run
-
Port a couple example programs to SDCC.
I started by rewriting a few of the examples and libraries for testing. I recommend 1st getting serial io working so you can debug easier. After that, play around with the i2c board and lights. Finally, test writing to eeprom. (For eeprom images, the hex2bix program that comes with the development kit can easily be ported to run on Linux by using linux time libraries instead of the windows files.)
Perhaps this section deserves it’s own blog post later on.
Anyway, I haven’t yet found anything that can’t be done on Linux with the Ez-USB kit.
UPDATE 12/5/08: Added Open Source FX2 Library.
Hey, this is great info! I just bought a SerMod56 from AcquireDevices.com (a cheap, really small board with the FX2LP chip), downloaded Cypress’ GPIF designer and the SDCC package. Do you have any sample c files that could be compiled on sdcc just to test things out? Maybe a sample command line, too? The sdcc docs are kind of general since it supports multiple targets.
I really appreciate the info, and it was VERY timely for my project!
I have two different kinds of gear that I have controlled through the PC parallel port, one is my own “bus”, the other is driving GPIB devices. I think I can see how to control my own bus pretty easily by having the 8-bit data on one 8-bit output port, and sending the control signals on the other port, and having the GPIF enable the control signals and do the timing. But, I am starting at ground zero with USB and the FX2.
Thanks,
Jon
As a matter of fact, I’ve developed a library that handles serial io, i2c/eeprom read/write, setupdata (device descriptors) etc, and usb jump table stuff (for usb interrupts). I’m quite possibly going to opensource the whole thing.
Does your device have a serial port attached. The fx2 chip has two serial ports but they aren’t necessarily attached to anything.
If you do have a serial port, I could send you my serial IO example.
This is great. I just started down the same road three days ago. I have a small CY7C68014A board that I had built that I have developed much of the firmware to with the Keil evaluation compiler. I have hit their 4kB limit and am now looking at switching to SDCC. I have SDCC installed and need to start porting. I can not find the keil2sdcc.pl script they mention in my install. I built SDCC from a source snapshot. Is keil2sdcc.pl included with the source snapshots? I so, where is it located?
Ahh, yes it is in the source directories of the tar ball. It is not installed into /usr/local with the make install.
Here is another resource I used during my process of creating my own sdcc framework for the chip:
They ported the bulkloop example entirely to sdcc.
Their code is still pretty much the Keil code however, but with sdcc changes.
I’ve about completed my own framework. I’ll most likely open source it if interest is high enough. Do post back if you’re interested in more information.
Yes I am interested in more information. I’m currently working on recompiling USBJmpTb.a51 with ASX8051.
The link I posted in the last comment has usbjumptb converted to asm for sdcc/asx8051. You just need to download the bulkloop example source and grab it from there.
Glad to see this chipset is not dead yet……
I attempted to find tools that ran on other platforms, other than windows, but windows is a requirment to extract many of the Cypress examples.
Unfortunatly nothing beats the keil package for debugging & single stepping .
Hello there! First of all excuse me for my bad english.
I’m also working with the EZ-USB FX2LP and right now I’m trying to transfer my projects from Keil to SDCC. But I have a few problems with this. When I’m downloading the fx2fw example .hex file (that I found in your link) to my FX2 everything works fine. But when I try to build this .hex file on my own with SDCC including the files from the sdcc.zip folder in my project nothing seems to work anymore. After I have downloaded the file with the CyConsole the CyConsole doesn’t detect my Device any more and when I restart the Console it even doesn’t open. I already tried to invoke the flags you mentioned ( -mmcs51 and -xram-loc ) but it seems to have no effect. I wondered with what version of SDCC you all are working with? I’m working with the 2.8.0. Do you maybe know any bugs known with this version in this combination? I really don’t know how to go on… Did anyone of you experience problems like that? Maybe you can give me a hint or even help me out of this. Would be really great to hear something from you!
Thanks
Philipp
Hi Philipp,
I had an issue that I think relates the the endianness of sdcc vs keil. If I compiled a program with keil, I needed to use CyConsole to download and run it. If I used sdcc on lInux, I needed to use my own programs on Linux. If I didn’t do this, I found the firmware just didn’t run. The problem is that for two byte values, the hex bytes are swapped and your code gets downloaded to the wrong memory locations if you load it on the wrong platform.
That being said, you can reset your fx2 board back to the default state using CyConsole.
1) flip the eeprom switch to use the small eeprom
2) press the reset button
3) flip the switch back to use the large eeprom
4) use cyconsole to download the default iic file to the eeprom.
The default iic file is found in the Cypress folder in the examples folder.
I’ve actually completed enough sdcc code that I can do that without using Windows. I have a reset firmware that I can use to fix the device too. When I get things figured out at work, I’ll most likely open source the whole library.
Well, I’m making VERY slow progress. I’ve been using Wolfgang Weiser’s fx2pipe program as a template to start from. It demonstrates 39 MB/sec read and 31 MB/s writes, which is astonishing (doing nothing with the data, of course).
I wanted to use the GPIF section of the chip, but all I have is a Keil-flavored code snipped created by Cypress’ GPIF Designer. I spliced this into my fx2pipe firmware and got it to compile, but it causes fx2pipe to give an error code that is 20 decimal digits long. It looks suspiciously like 2^63 – 1.
Does anyone have any examples of code for the GPIF, or any suggestions on how to debug it?
The C code from GPIF Designer defines an array of bytes and initializes it, then in the code uses MSB and LSB to make up the high and low bytes of the address of that array to point the GPIF logic at it.
The code looks like :
// use dual autopointer feature…
AUTOPTRSETUP = 0x07; // inc both pointers,
// …warning: this introduces pdata hole(s)
// …at E67B (XAUTODAT1) and E67C (XAUTODAT2)
// source
AUTOPTRH1 = MSB( &WaveData );
AUTOPTRL1 = LSB( &WaveData );
// destination
AUTOPTRH2 = 0xE4;
AUTOPTRL2 = 0x00;
// transfer
for ( i = 0x00; i > 8) & 0xff)
#define LSB(word) (unsigned char)((unsigned int) (word) & 0xff)
Whick look like they OUGHT to work, but I don’t know for sure if they are doing the right thing. So, any comments on that?
Thanks,
Jon
I plan on playing around with the GPIF in the days to come. I have an FPGA that I believe can be driven by the GPIF but I haven’t quite got that far yet. I haven’t found any way to generate the waveforms except on Windows, I don’t know if that will cause a problem or not to load them on Linux. You may have a MSB,LSB problem like with other file formats when you cross platforms.
I used Cypress’ GPIF Designer, which cranks out Keil-flavored code for the 8051 in the CY7C68013A. So, I don’t think there is an endian-ness problem. The GPIF is not so complicated that you couldn’t hand-code the register values, either. basically, for a specific waveform, there is a 32-byte array that is loaded into the logic, and the correspondence between those bytes and the waveform seems pretty straightforward.
In my application, I was going to be controlling a string of instruments on a bus with 3 control signals and a byte-wide data path. So, using the 16-bit wide path, and having some of the control bits enable bus drivers, it looks like it would be very easy to control my external bus with just 2 driver chips, and not need any FPGA or other external logic. The GPIF can put in all the delays between state transitions.
I haven’t cooked up any Linux-side code to talk to the USB module, I’m just using Wolfgang Weiser’s fx2pipe program so far.
it downloads the 8051 code and then transfers data to or from the device. I have verified I can alter his 8051 code in small ways, such as changing the interface clock and sending it out the chip’s pin. But, when I spliced in the GPIF setup code from the GPIF Designer, fx2pipe croaked, and I didn’t see such things as the interface clock coming out the pin, so I am guessing that the 8051 code ran into some sort of problem. I don’t have any 8051 debug capability right now.
Jon
Oh, as for that MSB/LSB code pasted on 11/19, I think I have that figured out. I looked at the .asm code, and it is not efficient, but it appears to be right.
This is what I ended up with :
#define MSB(word) (unsigned char)(((unsigned int)(word) >> 8) & 0xff)
#define LSB(word) (unsigned char)((unsigned int) (word) & 0xff)
Yeah, I was just going through the generated code that GPIF cranks out. Most of it, if not all, could be directly used in an SDCC compiled version. I’m about to try generating my own Waveforms to read data from an FPGA.
Also, we just purchased a domain that we’ll be using to host open source software. When we get that all set up, I’ll release a code repository that has my entire sdcc framework code and library utilities for writing to this chip. (i2c, eeprom, serial, usb jump table etc).
I just verified that the GPIF designer code can be used by SDCC. I’m using my own fx2regs.h file and made my own SYNCDELAY macro instead of using Cypress’ delay.h. Other than that, it works fine.
As far as getting things to work go, one thing I’ve had to watch out for is that as code size increases, you need to make sure your xdata, code, usb jump tables, descriptors, etc, are all not overlapping.
As far as getting things to work go, one thing I’ve had to watch out for is that as code size increases, you need to make sure your xdata, code, usb jump tables, descriptors, etc, are all not overlapping.
[QUOTE]
Yeah, that sounds like a good thing to check, the wave table alone is 128 bytes. I’ll have to examine the asm output to see how all this fits. [/QUOTE]
Is there any simple debug strategy to check what is going on in the FX2? Right now, I’m running blind – either the USB communication works or it doesn’t. I know Keil has a debugging program, do we have something like that for the FX2 and Linux?
As for the GPIF designer compatibility, so far the only thing I’ve seen is a couple registers have SLIGHTLY different names, not too hard to figure out what the right names were in my fx2regs.h file.
Thanks,
Jon
on the development board, it has a serial connector so for debugging, I’ve been using printf. I get my firmware working pretty good on that and then move it to a different board with no serial console when I’m pretty comfortable with how it is working. I also have turned lights on and off to let me know when certain events have occurred. That only works if you have lights to work with I guess.
I’m using GPIF designer on my project as well. I’m having trouble however creating a FIFO read properly. I am connected as 8 bits to an imager with two control signals coming from the imager (frame valid and line valid). The imager puts FV high for the duration of each frame and puts LV high for each individual line of pixel bytes. FV connects to RDY0, LV connects to RDY1. I have no control lines going to the imager. The imager is constantly running. I can see how to configure the waveforms in GPIF designer for reading whenever FV and LV are high and I can see how to configure the waveforms to go idle when TCXpire happens signaling the FIFO is full, but I don’t see how to create a waveform that does both. What would be an appropriate waveform for both?
The funny thing is that right before you commented, I just got a gpif waveform to successfully configure an FPGA with a bitfile. That is a FIFO write instead of read, but reads are generally simpler.
* You can add a decision point (the status) line that monitors tcxpire and loops the the appropriate state. I also noticed that you can let the waveform cycle through the idle state and it will re-execute if there are more transactions so you don’t _have_ to use a decision point.
* You can use a flowstate to monitor rdy0/rdy1. The documentation isn’t great on flowstates but it’s a start.
I just added a github repository. I’ll be pushing my sdcc library shortly.
http://github.com/mulicheng/fx2lib/tree/master
I guess I should mention that the imager is providing the clock to the GPIF. Thus I don’t see how I can go through the idle state without missing bytes from the databus. I can only go idle when LV or LV & FV are low.
Doesn’t the imager listen to one of your control inputs for a ready state? Like using ctl0 for busy or something? If not, you’re right, I think you’d have to use a decision point and the flowstates to capture the data correctly.
I’m going to be building an imager next!
The imager is configured via I2C and dumps its data via an 8 bit bus and the Fv and LV lines.
Just a side note, I was able to successfully run the GPIF designer on Linux with the latest Wine distribution. I just ran the installer and everything seems to be working fine.
perhaps gpif isn’t really necessary if the imager is supplying a free-running clock to the peripheral interface you might be able to just strobe slave fifo read with an 8051 gpio… if you just “must” to play with gpif and you “must” design your waveform not past through idle (where btw a ton of error handling is done for you) then consider performing long transfers using either the transaction count expire in-place of rdy5 feature in a decision point or spin-lock the gpif engine in a decision point and use gpif abort feature… the flowstate engine resides on top of the gpif engine specifically to handle udma protocol
forgot to mention that if you go with the spin-lock choice then you may also wish to take a look at the re-execute feature, depending on your physical interface protocol, error handling desires, etc. is the imager has some sort of blanking signal then that would be a better choice then the 8051 gpio (should be less work on the host software app side, anyways)
Anybody check out my fx2lib repository? I’ve got i2c and gpif routines that are working pretty well for me.
How do you associate the GPIF FIFO with a particular endpoint FIFO?
I coded up an enum in my library that has the endpoint values:
GPIF_EP2, GPIF_EP4 etc.
You can look at the gpif_fifo_read/write functions to see how you do it. Basically, you write the value and a read/write bit to the GPIFTRIG register and the the GPIF reads or writes the data to/from the specific endpoint.
Cool! Thanks for the pointer to GPIFTRIG. Now I have a firmware file that I am ready to have Linux download to my device on (en/ren)umeration. I’m working without external memory.
No prob. I’ve just started the list, and there are not lots of users, but I recommend joining the fx2lib-devel mailing list I created. I’m right in the middle of firmware stuff and it would be nice to collaborate as much as possible.
Just another side note, the fx2lib contains c++ bindings to libusb for usage in Python that allow you to download firmware to a device. There are also sample makefiles for creating your bix file.
It’s really easy once you have the bix file:
python
> from fx2load import *
> openfx2(, )
> reset_bix(‘<path to file’)
That’s it!
Dennis, how do I join the fx2lib-devel mailing list? I went to the link in your message, but couldn’t find any “join” menu entry.
Thanks,
Jon
Added a link on the project home page fx2lib to the subscribe page.
For any of you following this page, I was able to send a bitfile to an FPGA with the gpif, then read and write data from the FPGA via my custom interface between the FPGA and the firmware, and finally, stream raw image data from the image sensor connected to the FPGA back to the PC w/ libusb. All programmed is done with SDCC. So fx2lib is in pretty good shape. It’s not perfect, but it is enough to get the job done. Let me know if you’d like additional information.
i’m working with the FX2 and sdcc too. as a base framework i use the firmware from the gnu radio project. the USRP board contains an fx2 and there firmware is nice. usint interrupt autovectors by default with easy handling and stuff like that. specialy interesting is, that they are using GPIF for transfer and they have some perl scripts to convert GPIF designer code to an sdcc clean code. oh, by the way, GPIF designer and the Hex2Bix.exe tool are running fine here with wine.
Thanks for the additional info. I’ll have to take a look at their project and make sure I didn’t miss anything in my library I’ve created.
I also run the GPIF designer on Linux via Wine. Hex2Bix on the other hand, I don’t use at all because objcopy has ihx to binary support built in and it seems to be working just fine. I made a few modifications to the Hex2Bix program and compiled it on Linux too though. I can use that to create IIC files if I need.
Hi Dennis,
Thanks for the nice post. I have made a FW for SDCC and am able to do all the stuff without GPIF.But as I include the gpif.c (generated from gpif designer)my code does not work. I don’t find any major difference in your lib/header files and my framewrok. If you can post an example of a simple GPIF design it will be very helpful.
Are you using the fx2lib code? I plan on adding an example to that when I get a moment. Part of the problem with a GPIF example is that you have to have a device connected to the fx2 that the GPIF can talk to. Everybody’s devices are different though.
I can provide some additional comments if you like. Why don’t you subscribe to the fx2lib mailing list and ask on there. You can find the list link at http://fx2lib.wiki.sourceforge.net/.
Maybe you are interested in the ZTEX Firmware Kit + Driver
API for EZ-USB based hardware:
http://www.ztex.de/firmware-kit/index.e.html
It is Open Source and runs on Linux and Windows. It is mainly intended for our USB and/or FPGA boards but should run on every EZ-USB based hardware.
The Firmware Kit (for EZ-USB Microcontrollers) is written in C (requires SDCC compiler). The Firmware is assembled using a macro processor which allows to specify all required settings by a few macros. The necessary USB descriptors and the descriptor handling routines are generated automatically.
The driver API is written in Java and allows platform independent device drivers.
Glad to see there are multiple options. I’ll have to take a closer look when I get a chance.