fx2 firmware with WCID support

233 views
Skip to first unread message

Jenn

unread,
Aug 17, 2015, 11:09:36 AM8/17/15
to FPGALink Users
I am interested in extending the fx2 firmware with WCID driver support. This would be very useful in making libfpgalink devices work with windows machines.

Currently I am having trouble building the firmware. My development machine is running ubuntu 15.04 and I have the makestuff environment working. I've installed SDCC version 3.4.0 and the fx2lib software from here in makestuff/3rd/fx2lib.
The fx2lib software seems to build fine and produces fx2.lib. However when I try to build the firmware, the build fails with "?ASlink-Warning-Undefined Global '_handle_get_descriptor' referenced by module 'setupdat'"
Do you have any tips on fixing this error?

Thanks
Jenn

Chris McClelland

unread,
Aug 17, 2015, 12:32:53 PM8/17/15
to fpgalin...@googlegroups.com
Hi Jenn,

Long time, no see. Hope you're well.

Note that you don't need to alter anything or recompile the firmware merely to use Pete Batard's driver with the "standard" VID:PID (1D50:602B) - I already use his "Zadig" tool to install Windows drivers, whereupon libusb-1.0 (and therefore libfpgalink.dll) "just works".

However, if your aim is simply to replace the VID:PID with your company's own IDs so the WCID process kicks in and installs the driver automatically on your customers' machines, you can build an appropriate firmware like this:

https://gist.github.com/makestuff/15037f8a06d213d380bc

Note here I've passed VID=1d50 PID=602c on the build line. The process works for me on Linux (Debian8/x64, sdcc 3.4.0 #8981) and Windows (7/x64, sdcc 3.4.0 #8956). You need Python installed (2.7 or 3.x) to run the FX2 firmware build.

Any problems, let me know. If you get the WCID auto-install working for your VID:PID, let me know. I'd also be interested (purely from a "what cool stuff are people doing?" point of view) in what your product is actually doing.

Chris


--
You received this message because you are subscribed to the "FPGALink Users" mailgroup (see https://github.com/makestuff/libfpgalink/wiki/FPGALink).
 
To post to this group, send email to fpgalin...@googlegroups.com
To unsubscribe from this group, send email to
fpgalink-user...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/fpgalink-users?hl=en
---
You received this message because you are subscribed to the Google Groups "FPGALink Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fpgalink-user...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Chris McClelland

unread,
Aug 17, 2015, 1:10:36 PM8/17/15
to fpgalin...@googlegroups.com
Sorry, I just noticed there's more to this - adding another descriptor, etc. You may find that difficult to fit that in with the default configuration (which assumes 8KiB of RAM, so the firmware will work with FX2 chips as well as FX2LP chips). It's pretty tight. If you know you're only using FX2LP chips (i.e CY7C68013A, CY7C68014A etc), you can tell the firmware build to assume 16KiB of RAM with USE_16K=1 on the build-line (i.e next to VID=XXXX, PID=YYYY). Alternatively, if you DO want to support 8KiB configurations, you can save some space by removing the FLAGS="-DEEPROM" from the build-line; that will remove the capability to write the EEPROM. You can still do upgrades by first RAM-loading a firmware that DOES support EEPROM-writes, but obviously it's an extra step in the process.

Chris

Jenn

unread,
Aug 17, 2015, 2:35:21 PM8/17/15
to FPGALink Users
Hi Chris,

First of all, your directions worked perfecty. I didn't know that you could use the makestuff framework to build fx2lib, so I downloaded and installed that seperately, and I think that is where my problems came in. Is there a README or other guide on how to use the makestuff framework? Thanks for your help.

Everything is going well here, I graduated and am now a postdoc in my group and trying to update some of our hardware.
I work in a molecular spectroscopy research group at The Ohio State University. Most of our research consists of doing spectroscopy in the "Terahertz" region, which for us is from ~200GHz to ~1500GHz.
Our spectrometers are home-built and are currently cobbled together from many vendor supplied evaluation boards. You can read about the system here.
I am slowly trying to integrate the functions of clock generation, the AD9910 eval board, and the data collection onto a single circuitboard. The first step was a simple fractional N synthesizer which produces the A/D sample clock. For this I just used the clocking resources in a spartan-6, and libfpgalink to allow configuration from the host computer. The current project is an add-on the the original board which has an AD9910 DDS chip and produces a frequency ramp.
Since the software that runs the spectrometers is written in C# and runs on windows machines, the WCID driver would be convienent, but not necessary.

If you are curious, the boards are here: FPGA Board, AD9910 Add-on

Thanks again for a great piece of software,
Jenn

Jenn

unread,
Aug 20, 2015, 12:01:29 PM8/20/15
to FPGALink Users
So, I got WCID working within the 8K limit.

The code changes were made in the fx2lib code in setupdat.c and setupdat.h, and some extra data was placed in descriptors.a51.
Unfortunately this is kind of a hack, since there is a vendor command byte defined in descriptors.a51 which is then hard-coded into setupdat.h, and ideally the user should be able to choose this command without re-compiling fx2lib, but it does work.

This does allow fpgalink devices to automatically install on windows machines that support WCID without mussing about with drivers.

If you want I can post the changes I made, they are relatively minor.

Jenn

On Monday, August 17, 2015 at 11:09:36 AM UTC-4, Jenn wrote:

Peter Stuge

unread,
Aug 20, 2015, 1:31:34 PM8/20/15
to FPGALink Users
Jenn wrote:
> So, I got WCID working within the 8K limit.

Well done!


But please try to avoid spreading the WCID terminology.

Microsoft named their extra descriptors "Microsoft OS Descriptors"
long before the WCID term was invented by a third party, and MSFT
likewise established "WinUSB Device" as the term for a USB device
which uses MODs and a control request to signal Windows to
automatically load the WinUSB.sys driver (and more!).

https://msdn.microsoft.com/en-us/library/windows/hardware/hh450799.aspx


> If you want I can post the changes I made, they are relatively minor.

Yes please - I think that would be great!


Many thanks

//Peter

Chris McClelland

unread,
Aug 20, 2015, 3:03:21 PM8/20/15
to fpgalin...@googlegroups.com
There used to be some docs on the MakeStuff website, but TBH there's not much to it - install a C compiler, Python (if needed) and the FPGA tools, then download the 3.5MiB build infrastructure zip file, unpack it to C:\, and run the setup.exe. For example, look at [1].

That's some very cool stuff you're working on!

Do you have a C# wrapper for the FPGALink DLL, similar to the Java wrapper[2]? If so would you be interested in contributing it?

--

Chris McClelland

unread,
Aug 20, 2015, 3:06:31 PM8/20/15
to fpgalin...@googlegroups.com
Great news!

Yes, if you let me see the changes I'll see what can be done about fixing up fx2lib so the command-byte can be made "application"-configurable.

Chris


--

Jenn

unread,
Aug 21, 2015, 10:06:46 AM8/21/15
to FPGALink Users
Actually, all of the non-embedded windows stuff is handled by a collegue, I can ask him about a wrapper, but I don't think it would be very complete. Since we are a university research group, "good enough to work" usually takes precedence over a complete and robust solution.

Here are the changes I made to fx2lib:

in setupdat.h:
Added an entry to the SETUP_DATA enum
typedef enum {
    GET_STATUS
,
    CLEAR_FEATURE
,
   
// 0x02 is reserved
    SET_FEATURE
=0x03,
   
// 0x04 is reserved
    SET_ADDRESS
=0x05, // this is handled by EZ-USB core unless RENUM=0
    GET_DESCRIPTOR
,
    SET_DESCRIPTOR
,
    GET_CONFIGURATION
,
    SET_CONFIGURATION
,
    GET_INTERFACE
,
    SET_INTERFACE
,
    SYNC_FRAME
,
    WCID_VENDOR
=0x88
} SETUP_DATA;

This value (0x88) is the vendor code I chose for the Microsoft OS string descriptor.

in setupdat.c:
added two more external references to sections in descriptors.a51:
extern __code WORD WCIDFeature;
extern __code WORD WCIDstring;
changed the string descriptor case in handle_get_descriptor() to include branch if string 0xEE is requested:
...
case DSCR_STRING_TYPE:
           
//printf ( "Get String Descriptor idx: %d\n", SETUPDAT[2] );
           
{
        BYTE idx
= SETUPDAT[2];
       
if (idx == 0xEE) {
           
// special string descriptor for WCID
            STRING_DSCR
* pStr = (STRING_DSCR*)&WCIDstring;
            SUDPTRH
= MSB((WORD)pStr);
            SUDPTRL
= LSB((WORD)pStr);
       
} else {
       
                    STRING_DSCR
* pStr = (STRING_DSCR*)&dev_strings;
                   
// pStr points to string 0
                    BYTE cur
=0; // current check
                   
do {
                       
if (idx==cur++) break;
                       
//printf ( "Length of pStr: %d\n", pStr->dsc_len );
                       
//printf ( "pstr: %04x to ", pStr );
                        pStr
= (STRING_DSCR*)((BYTE*)pStr + pStr->dsc_len);
                       
//printf ( "%04x\n" , pStr );
                       
if (pStr->dsc_type != DSCR_STRING_TYPE) pStr=NULL;
                   
} while ( pStr && cur<=idx);
               
                   
if (pStr) {
                       
/* BYTE i;
                        //printf ( "found str: '");
                        for (i=0;i<pStr->dsc_len-2;++i) {
                           printf ( i%2==0?"%c":"%02x", *((BYTE*)(&pStr->pstr)+i));
                        } printf ( "\n"); */

                       
                        SUDPTRH
= MSB((WORD)pStr);
                        SUDPTRL
= LSB((WORD)pStr);
                       
//SUDPTRH = MSB((WORD)&dev_strings);
                       
//SUDPTRL = LSB((WORD)&dev_strings);
                   
} else {STALLEP0();}
       
}
       
}
           
break;
...
added a case to handle_setupdata() to take care of the Microsoft OS feature discriptor vendor command:
...
case WCID_VENDOR:
       
if (SETUPDAT[4] == 0x04 && SETUPDAT[5] == 0x00) {
       
SUDPTRH = MSB((WORD)&WCIDFeature);
            SUDPTRL
= LSB((WORD)&WCIDFeature);
       
} else if (!handle_vendorcommand(SETUPDAT[1])) {
            printf
( "Unhandled Vendor Command: %02x\n" , SETUPDAT[1] );
            STALLEP0
();
         
}
       
break;
...








On Monday, August 17, 2015 at 11:09:36 AM UTC-4, Jenn wrote:

Jenn

unread,
Aug 21, 2015, 10:13:08 AM8/21/15
to FPGALink Users
Sorry, that somehow got posted before I was done with it.

In descriptors.a51:
added two new sections at the end of the device strings:
...
string2end
:

_WCIDstring
:
   
.db     0x12
   
.db DSCR_STRING_TYPE
   
.db 0x4d, 0x00, 0x53, 0x00, 0x46, 0x00, 0x54, 0x00, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00
   
.db 0x88
   
.db 0x00
WCIDstringend:

_WCIDFeature
:
   
.db    0x28, 0x00, 0x00, 0x00
   
.db    0x00, 0x01
   
.db    0x04, 0x00
   
.db    0x01
   
.db    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
   
.db    0x00
   
.db    0x01
   
.db    0x57, 0x49, 0x4E, 0x55, 0x53, 0x42, 0x00, 0x00
   
.db    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
   
.db    0x00, 0x00, 0x00, 0x00, 0x00, 0x00
WCIDFeatureend:

_dev_strings_end
:
   
.dw 0x0000                       ; in case you wanted to look at memory between _dev_strings and _dev_strings_end
 

The problem comes in when you have to make the vendor command defined in descriptors.a51 in the _WCIDstring section(second to last byte, 0x88) match the WCID_VENDOR case in handle_setupdata().



On Monday, August 17, 2015 at 11:09:36 AM UTC-4, Jenn wrote:

Chris McClelland

unread,
Aug 21, 2015, 10:24:11 AM8/21/15
to fpgalin...@googlegroups.com
Great, thanks. I'll take a look and see if I can make it work nicely.

Don't worry about the C# stuff then. Last time I did any C# was more than ten years ago, so I probably wouldn't have time to add a new binding for it right now even if I did have a "good enough to work" solution as a baseline. If anyone else asks about C#/.Net bindings I might refer them back to you though.

Chris


--

Tim Ansell

unread,
Aug 21, 2015, 11:14:23 AM8/21/15
to fpgalin...@googlegroups.com
FYI I've been working on improving fx2lib (https://github.com/mithro/fx2lib), collecting peoples modifications and pushing the changes upstream (to http://github.com/djmuhlestein/fx2lib). It sounds like it would be an excellent thing to make sure goes upstream too.

Tim 'mithro' Ansell

Tim Ansell

unread,
Oct 18, 2015, 2:35:53 AM10/18/15
to fpgalin...@googlegroups.com, Jenn
Hi Jenn,

I've created a branch of my fx2lib which makes the changes you mention above. See https://github.com/mithro/fx2lib/tree/wcid (and specifically https://github.com/mithro/fx2lib/commit/8828cb58903263cb62477bec4018631a4c961d4d).

Are you able to explain how to test the your work?

Thanks!

Tim 'mithro' Ansell


--
Reply all
Reply to author
Forward
0 new messages