PORTS Forum
Ports and Interfaces => USB => Topic started by: Babu on March 23, 2015, 01:38:14 pm
-
I'm very new to the driver development.
I'm developing a HID device which has say only one switch. And a host application for the same device.
I can continuously poll for the state of the device using HID_GetInputReport.
Instead how can I make whenever there is a change in the device ( switch on/off ), the driver should inform my host application.
How can my host application register for the notifications?
How to make my driver to notify the host application ( like sending the notification along with the data )?
Can we use RAWINPUT mechanism in windows? Does it work only for mice,keyboard or for any device?
If you can provide some link for the sample apps it will be great.
-
My HID page has example code that uses a different thread to poll for received data and notify the main application when new data is available:
http://janaxelson.com/hidpage.htm#MyExampleCode
-
Hi Jan
Thanks for your reply.
Can you let me know which sample code should I look for? Is it generic_hid_cs_62
I would like to know how are you broadcasting the data from the device to OS which in turn can notify the host app using WM_INPUT messages.
-
Yes. The device sends data in interrupt IN transfers.
In my example, cmdGetInputReportInterrupt_Click calls the async routine RequestToGetInputReport, which waits until data is available or a timeout. You don't have to use a click event to request the data. Any routine could call RequestToGetInputReport. Because RequestToGetInputReport is async, the application can do other work while waiting.
-
Hi Jan
Thanks for your reply.
cmdGetInputReportInterrupt_Click is the call which host initiates whenever "Get Input Report" button is clicked.
What I'm looking for is say:
1. Whenever the button in the device is toggled, how can I make the device to inform it to the host? I mean to receive the WM_INPUT message in the host, what the device firmware should do? How the device firmware has to inform the OS about there is a change in the button state.I don't want my host to poll for the report continuously and listen for the states. Whenever there is a change in the device, how the device firmware can notify the host about the changes to host.
I have registered for WM_INPUT message in my host app like
RAWINPUTDEVICE rid;
rid.usUsagePage = 65280;
rid.usUsage = 1;
rid.dwFlags = 0;
rid.hwndTarget = this->GetSafeHwnd();
BOOL bFlag = ::RegisterRawInputDevices( &rid,1,sizeof(RAWINPUTDEVICE) );
But still I'm not getting the WM_INPUT message in my host app when there is button toggle in the device.
So I would like to know to receive this message in the host, what should be done from the device side?
Am I Clear?
-
I don't have a raw input example. If you haven't seen it, check out:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms645546%28v=vs.85%29.aspx
Be sure RegisterRawInputDevices succeeds. (See example above.)
A protocol analyzer will show whether the data is transferring on the bus.
The low-level HID driver retrieves data continuously by polling the device's interrupt IN endpoint according to the bInterval value in the endpoint descriptors. The driver stores the retrieved data, which applications can then access.
HID_GetInputReport bypasses the HID buffer and retrieves Input reports using control transfers.
Be sure your device is also sending data in response to token packets on the interrupt IN endpoint.
-
RegisterRawInputDevices call return true. So I dont see any problem.
But I'm not getting WM_INPUT message still.
Do you mean to check whether data transfer is happening when the button is pressed using protocol analyzer?
I was looking something like whenever the mouse is registered, the host gets all the state changes [ button clicks,mouse move etc ] via WM_INPUT message.
The same thing I want to have it with my HID device.
From the host side,everything looks fine [ The only thing to do from host side is to register the device using RegisterRawInputDevices ].
Should I to do something from the device side?
-
You mentioned retrieving data using HID_GetInputReport. This function uses control transfers. To use raw input, I believe the data must be sent using interrupt transfers. Be sure your device is doing that.
-
Ok I'll check.
If I'm not wrong, if the device sends the data through interrupt transfer, my host app should receive it as WM_INPUT messages.
Am I correct on this?
-
yes
https://msdn.microsoft.com/en-us/library/windows/desktop/ms645590%28v=vs.85%29.aspx
-
When I called HidD_GetInputReport it failed and GetLastError() returned an error saying "device attached to the system is not functioning"
What could be the problem?
I'm able to use the ReadFile but not HidD_GetInputReport?
Should I check something with the end desciptors of the device?
-
Does your device firmware detect and respond to the HID-class Get_Report request?
-
I'm not very clear on your question..
-
I dont have the firmware code with me
-
ReadFile retrieves reports received on the interrupt IN endpoint and stored in the buffer maintained by the host's HID driver.
HidD_GetInputReport bypasses the HID buffer and sends a control request with a HID-class Get Report request.
If your device doesn't support Get Report, it won't send a report in response to the request.
-
How can i check whether the device supports Get Report?
-
My firmware and host code looks something like this: [ I have not copied the complete code ]
//*******************************************************************************************************
// DEVICE CODE
//*******************************************************************************************************
unsigned char ReceivedDataBuffer[64];
unsigned char ToSendDataBuffer[64];
// Main program entry point
void main(void)
{
initialisePic();
// If we are running in interrupt mode attempt to attach the USB device
#if defined(USB_INTERRUPT)
USBDeviceAttach();
#endif
//ON the LED
mStatusLED0_on();
while(1)
{
#if defined(USB_POLLING)
// If we are in polling mode the USB device tasks must be processed here
// (otherwise the interrupt is performing this task)
USBDeviceTasks();
#endif
// Process USB Commands
processUsbCommands();
// Note: Other application specific actions can be placed here
}
}
void processUsbCommands(void)
{
if(!HIDRxHandleBusy(USBOutHandle))
{
switch(ReceivedDataBuffer[0])
{
// Toggle the LED
case 0x80:
// Toggle the LED0
mStatusLED0_Toggle();
break;
// Read the push switch status
case 0x81:
ToSendDataBuffer[0] = sw0;
// Transmit the response to the host
if(!HIDTxHandleBusy(USBInHandle))
{
USBInHandle = HIDTxPacket(HID_EP,(BYTE*)&ToSendDataBuffer[0],64);
}
break;
}
}
}
//*******************************************************************************************************
// HOST CODE
//*******************************************************************************************************
void CHID_Window_NewDlg::UpdateSwitchState()
{
//Read the data from the device.
//First send the command to the control end point
BYTE commandBuffer[65];
//First byte should be 0.It is reserved for windows
commandBuffer[0] = 0;
//Second byte should be the command id which reads the LED status
commandBuffer[1] = 0x81;
//Write this command to the control end point
WriteData(commandBuffer);
//Now read the status in the input buffer
BYTE* pbInBuffer = NULL;
//Read the data from the device
BOOL bResult = ReadData( pbInBuffer );
//First byte contains the state of the LED
if( pbInBuffer[1] )
{
m_butSwitchState.SetBitmap(m_bmpON);
}
else
{
m_butSwitchState.SetBitmap(m_bmpOFF);
}
}
-
In your original question, you said:
I can continuously poll for the state of the device using HID_GetInputReport.
if that works, your device supports sending reports using control transfers.
You also mentioned using raw input, and that uses reports transferred using interrupt transfers.
-
Sorry about that.
It was a different code I tried.
Now the code what I have shown you is the firmware code I use..
-
If you can get reports using ReadFile, your device supports sending reports using interrupt transfers.