It has been a while since I posted something here. Lately I have been working on USB firmware and software applications. There are loads of things to post but have very less free time. I’ll post them when I got a free time.
What this article primarily talks about is on a method to communicate with the joystick using your own application. It may be to control a robot, who knows. I will be using a simple MFC application to communicate with the joystick.
In order to understand the article properly you should have at least a slight understanding about,
- MFC applications
- USB specifications
- HID class specifications
A helicopter view of how this communication works,
You have the device. A driver is needed to communicate with the device. The driver has something called IOCTLs which are used by the applications/libraries to communicate with the device. Ya, that’s enough.
HIDAPI is some sort of a library which is cross platform (i will be using it in windows though) and it will take care of all the IOCTL calls and provide us with an API to easily communicate with the device. In other words, we do not need to worry about specific IOCTL details, rather we just need to know how to use the API functions. HIDAPI uses the windows generic driver to communicate with the joystick or any other HID class USB devices. You can find HIDAPI home page here.
First thing I did was connecting the joystick to the pc and sniffing the USB packets using USBlyzer. After that I understood that there is an Interrupt Transfer which has 8 bytes of data. And it simply floods the USBlyzer window. I tried a bit to find the protocol but I haven’t had any luck. So I decided I will figure it out myself.
I cloned HIDAPI source through git and built it using MSVC2010. After I built the solution it creates a ‘dll’ file which has all the functions and a ‘lib’ file which has information about the dll file.
After that, I linked my MFC dialog application with the ‘dll’ file using MSVC2005. I statically linked the ‘dll’ to make it simpler. About ‘dll’s and linking to them will not be covered here as they are covered in detail in MSDN articles and it is pointless to duplicate them here. I will post a few as references at the end of this article. If you have any issue just drop a comment.
Following is the code I used to connect the joystick,
m_iReturnCode = 0;
struct hid_device_ *m_pstrctDevice;
struct hid_device_info *strctDevInfo = NULL;
m_pstrctDevice = NULL;
m_iReturnCode = hid_init();
strctDevInfo = hid_enumerate(VID,PID);
m_pstrctDevice = hid_open(VID,PID,NULL);
Please note that this is just the code related to the HIDAPI. Here the ‘hid_init’ function will initialize the API. Then the ‘hid_enumerate’ function will find all the devices in the system which has the mentioned VID(Vendor ID) and PID(Peripheral ID) values. Then the ‘hid_open’ function will open the device and return a handle to use to control the device.
After this code I designed a simple UI to read the incoming data from the joystick. I used standard MFC dialog box.
The code related to the HIDAPI for the ‘Read’ button on clicked event is,
unsigned char* pucData = (unsigned char*) malloc(sizeof(char) * 64);
m_iReturnCode = hid_read(m_pstrctDevice,pucData,64);
Here the function will store any incoming data in the ‘pucData’ buffer. I will post the full code at the end of the article.
After designing the UI I pressed keys in the joystick one by one and documented the changes of the data read through the application. Following are my findings,
Final test application,
After decoding the protocol I designed a simple test application to demonstrate the behavior. I called hid_read function within a while loop inside a separate thread and decoded the protocol using switch statements.
If you click on Start and then press joystick buttons, the pressed button will be displayed in the application. Click on stop in order to stop the button detection. If you want to read the status of the joystick only once, press the joystick button first and then click on Read to get the status to the Edit Box.
You can clone the above repository and start adding cool stuff to it if you like.