简体   繁体   中英

Communication with HID device hangs on read/write (AS3992 RFID reader)

I'm trying to communicate with UHF RFID reader based on AS3992 chip. This device is detected by Windows as standard HID and it works with 3rd party app (I found some UHF RFID Reader GUI by LinkSprite which works, but it seems like some older C++ application).

So I'm trying to integrate this device support into my .NET application. After some research I tried HidLibrary , but when I'm trying to write something to this device (initial sequence in this sample), it hangs on "write".

Does anybody know what I'm doing wrong?

Thank you!

My OS is Win 8.1 x64.

Here's the sample application:

using HidLibrary; namespace HidTest2 { class Program { static void Main(string[] args) { var devices = HidDevices.Enumerate(0x1325); var rfid = devices.First(); rfid.OpenDevice(); rfid.Write(new byte[] { 0x31, 0x03, 0x01 }); // Application hangs here while (true) // I can't get here { Thread.Sleep(50); var result = rfid.Read(); Console.Write(result.Data); } } } }

PS: I also tried HidSharp, but I got same result. HID device detected, but I can't write into it.

PSS: This is the device: Link to ebay

I can't find a datasheet for the AS3229 chip that you mentioned, so I'm guessing here...

The device is probably presenting as a USB keyboard, so you would typically only be able to write LED status bits to it (Caps lock, Num lock, Shift). Is that what you are trying to write to it?

Try removing the write and just wait for the scanned RFID string to come in.

Edit: It looks like this device is presenting as a serial device over USB...I found a description closely matching it here: https://s3.amazonaws.com/linksprite/cuttonwood/datasheet.pdf

If it's the same device you are testing then I would try communicating to it over a COM port API rather than using the relatively lower level HID APIs you have been using.

Because time by time I get an email how and if I solved this issue, here's an answer:

I had to replace original firmware for HID communication by firmware for serial communication (search for "as399x uart 115200 hex" or "as399x uart 9600 hex" on the internet) and then it worked like a sharm. Of course you need proper programmer for C8051Fxxx (about 20$ from China), USB-Serial converter and be familiar with some soldering (You'll have to solder pins on board for JTAG and Serial port).

As mentioned above, the device may not actually be a Hid device. Have you tried enumerating through USB devices instead of Hid devices? Here is some code to enumerate USB or Hid devices. The code is here .

For Hid devices use a ClassGuid of : 4D1E55B2-F16F-11CF-88CB-001111000030

and for Win USB devices use: dee824ef-729b-4a0e-9c14-b7117d33a817

https://github.com/MelbourneDeveloper/Device.Net/blob/master/src/Device.Net/Windows/WindowsDeviceConstants.cs

public async Task<IEnumerable<DeviceDefinition>> GetConnectedDeviceDefinitions(uint? vendorId, uint? productId)
    {
        return await Task.Run<IEnumerable<DeviceDefinition>>(() =>
        {
            var deviceDefinitions = new Collection<DeviceDefinition>();
            var spDeviceInterfaceData = new SpDeviceInterfaceData();
            var spDeviceInfoData = new SpDeviceInfoData();
            var spDeviceInterfaceDetailData = new SpDeviceInterfaceDetailData();
            spDeviceInterfaceData.CbSize = (uint)Marshal.SizeOf(spDeviceInterfaceData);
            spDeviceInfoData.CbSize = (uint)Marshal.SizeOf(spDeviceInfoData);

            var guidString = ClassGuid.ToString();
            var copyOfClassGuid = new Guid(guidString);

            var i = APICalls.SetupDiGetClassDevs(ref copyOfClassGuid, IntPtr.Zero, IntPtr.Zero, APICalls.DigcfDeviceinterface | APICalls.DigcfPresent);

            if (IntPtr.Size == 8)
            {
                spDeviceInterfaceDetailData.CbSize = 8;
            }
            else
            {
                spDeviceInterfaceDetailData.CbSize = 4 + Marshal.SystemDefaultCharSize;
            }

            var x = -1;

            var productIdHex = GetHex(productId);
            var vendorHex = GetHex(vendorId);

            while (true)
            {
                x++;

                var isSuccess = APICalls.SetupDiEnumDeviceInterfaces(i, IntPtr.Zero, ref copyOfClassGuid, (uint)x, ref spDeviceInterfaceData);
                if (!isSuccess)
                {
                    var errorCode = Marshal.GetLastWin32Error();
                    if (errorCode == APICalls.ERROR_NO_MORE_ITEMS)
                    {
                        break;
                    }

                    throw new Exception($"Could not enumerate devices. Error code: {errorCode}");
                }

                isSuccess = APICalls.SetupDiGetDeviceInterfaceDetail(i, ref spDeviceInterfaceData, ref spDeviceInterfaceDetailData, 256, out _, ref spDeviceInfoData);
                WindowsDeviceBase.HandleError(isSuccess, "Could not get device interface detail");

                //Note this is a bit nasty but we can filter Vid and Pid this way I think...
                if (vendorId.HasValue && !spDeviceInterfaceDetailData.DevicePath.ToLower().Contains(vendorHex)) continue;
                if (productId.HasValue && !spDeviceInterfaceDetailData.DevicePath.ToLower().Contains(productIdHex)) continue;

                deviceDefinitions.Add(GetDeviceDefinition(spDeviceInterfaceDetailData.DevicePath));
            }

            APICalls.SetupDiDestroyDeviceInfoList(i);

            return deviceDefinitions;
        });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM