Friday, August 29, 2014

Writing a Windows 8.1 Driver for the Intel Qx3 Microscope in Visual Studio 2013 (1 of?)

I found an Intel Qx3 Play camera at Goodwill for $0.99.  I've wanted a microscope for the lab, and it's cheap!  How could I say no?  :)

Unfortunately Intel has chosen not to make modern drivers for this 13 year old kit.  That's unfortunate, but I don't blame them.  To get it to work with their software I have to go all the way back to Windows Me or Windows 2000.  That isn't going to happen.  This thing is so old that they don't even have it on their website anymore.  I would have to download it from cNet. 

There is some good news.  The unit works with Linux.  I fired up an Ubuntu Live CD and verified that it works.  Yeah!  Unfortunately I can't use a Hyper-V VM and Ubuntu because USB passthrough only works with Windows Server 2012 and Windows 8 guest operating systems.  :/

So that sucks. 

Fine.  I'll try to get it working in Windows instead.  How hard could it be to write a USB device driver?  It's simple Algebra.
Negative - I haven't programmed in C since puberty.
Negative - I've never written a Windows driver before.

Negative x Negative = I'm POSITIVE I can do this.

This is the perfect combination of hubris and obsession for this to be an awesome project.

So I got the chip specifications and developer's guide from this page:
Ironically, that is where the Linux developers parked their stuff when they wrote this driver for Linux.

Next up I read the developer documentation on the slashdot site and started slogging through the writing a driver documentation on MSDN.  I also grabbed a copy of "Developing Drivers with the Windows Driver Foundation".  That's a link to Amazon, but I actually read it on Safari.  It's  a little light bedtime reading.

One of the first steps is choosing a driver model: MSDN: Choose a model for developing a USB client driver.  From the chip documentation I learned that I need one control endpoint and one isosynchronous endpoint.  That narrows down my choices significantly.

I had hoped to make it work with the baked-in Windows USB Video Driver module by writing an extension to usbvideo.sys but that won't work.  The camera either supports that or it doesn't.

The remaining options are writing a Kernel Mode Driver (hard) or using the generic WinUSB driver and building all of the intelligence into the application.  For now I've chosen the latter, as it is a much simpler solution.  The unfortunate bit is that this driver will only work in Windows 8.1.  It is the only OS that supports isosynchronous data transfers with winusb.

Fast forward 48 hours.  I've installed Visual Studio 2013, Update 3, and the Windows Driver Framework for Windows 8.  (This takes forever.  :D )(Seriously, you can take a nap.)  I used the Visual Studio WinUSB template to kick out the .inf for the driver and a stub application.  This MSDN tutorial is incredibly helpful: Write a Windows desktop app based on the WinUSB template.  Yesterday I got a stub application working which can identify when the device is plugged in and read the firmware version from it.  Today I moved all of the device specific code into its own class and started cranking out all of the functions needed to make to work.  It's just after midnight and I have 70% of the API written for the Control Channel.

With any luck I'll get the isosynchronous endpoint communication working tomorrow and get some data to play with.  My plan is to release the source code, driver, and completed application as open source.  This is awesome!

Useful things I've learned so far.
Windows 8.1 will not permit you to install an unsigned driver by default.
- The workaround is to reboot with "shutdown -r -o -f -t 15" and select the advanced mode that will allow you to install the driver.

The security of the sprintf command has been tightened down significantly.
- I had to switch to using sprintf_s to get past a fatal compiler warning.

Time for bed before I become more hallucinogenic/delusional from sleep deprivation.


Murfyn said...

I have a QX3 I bought at Goodwill. I use it with an old laptop that runs XP (that I also found at Goodwill).

Anonymous said...

Did it work?! I am looking for a solution too! I can get the software to run with no problems, but I can't get the computer to recognize the microscope.

Elizabeth Greene said...

I don't have it working fully yet. I can read data a single frame from the camera but it won't send me a second without rebooting the device. The data in the frame is jibberish too. I have it on my list of things to finish, but it's going to be a while before I get back to it.

Benton Holmes said...

I just found some of these in my new classroom. I was hoping to get them to work for a lab with my students but I haven't had any luck tricking the classroom computer into working with it. I was just wondering if anything ever came of this attempt?

Elizabeth Greene said...

@Benton Holmes: Not yet. I've gotten distracted by a bunch of shiny things. It's on the corner of my desk accumulating dust. :/

Todd Finley said...

I would be interested in this driver if you ever complete it as well. I have a 13 year old son who found a QX3 in a box of my old computer stuff and has had me trying to find a working driver ever since. Please email me if you have any hope for me.

Dexter Consolidated Schools said...

I would be interested also as I have two at a school I work at and would like to be able to use them.