Hello -

I'm not sure if my first message was properly received, so I have
included it below.  Please read the earlier message first.  Here is my
simple usbhid application.  All I want to do is send 32 bytes to
Report ID #0.

========== hqcthid.c ==========

static void showReports(int fd, unsigned report_type)
{
   struct hiddev_report_info rinfo;
   struct hiddev_field_info finfo;
   struct hiddev_usage_ref uref;
   int i, j, ret;
   unsigned char go_am[] =
"\x00\x18\x30\x40\x0f\x9f\x01\x00\x30\x50\x50\x74\x6f\x6a\x00\x03\x03\x02\x0A\x0c\x01\x01\x00\xa0\x00\x00\x00\x00\x00\x00\x00\x00";

   rinfo.report_type = report_type;
   rinfo.report_id = HID_REPORT_ID_FIRST;
   ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo);

   // Get Reports
   while (ret >= 0)
   {
       printf("HIDIOCGREPORTINFO: report_id=0x%X (%u fields)\n",
           rinfo.report_id, rinfo.num_fields);

       // Get Fields
       for (i = 0; i < rinfo.num_fields; i++)
       {
           finfo.report_type = rinfo.report_type;
           finfo.report_id   = rinfo.report_id;
           finfo.field_index = i;
           ioctl(fd, HIDIOCGFIELDINFO, &finfo);

           printf("HIDIOCGFIELDINFO: field_index=%u maxusage=%u flags=0x%X\n"
               "\tphysical=0x%X logical=0x%X application=0x%X\n"
               "\tlogical_minimum=%d,maximum=%d
physical_minimum=%d,maximum=%d\n",
               finfo.field_index, finfo.maxusage, finfo.flags,
               finfo.physical, finfo.logical, finfo.application,
               finfo.logical_minimum,  finfo.logical_maximum,
               finfo.physical_minimum, finfo.physical_maximum);

           // Get usages
           for (j = 0; j < finfo.maxusage; j++)
           {
               uref.report_type = finfo.report_type;
               uref.report_id   = finfo.report_id;
               uref.field_index = i;
               uref.usage_index = j;
               ioctl(fd, HIDIOCGUCODE, &uref);
               ioctl(fd, HIDIOCGUSAGE, &uref);

               printf(" >> usage_index=%u usage_code=0x%X () value=0x%X\n",
                   uref.usage_index,
                   uref.usage_code,
                   uref.value);

               // Input usage: set a byte.
               if(uref.report_type == HID_REPORT_TYPE_INPUT) {
                   uref.value = go_am[j];
                   printf(" S> Usage_Index=%u Usage_Code=0x%X () Value=0x%X\n",
                       uref.usage_index,
                       uref.usage_code,
                       uref.value);
                   ioctl(fd,HIDIOCSUSAGE,&uref);
               }

           }

           // Input report: send report.
           if( report_type == HID_REPORT_TYPE_INPUT ) {
                   printf(" S> report sent");
                   ioctl(fd,HIDIOCSREPORT,&rinfo);
           }

       }
       printf("\n");

       rinfo.report_id |= HID_REPORT_ID_NEXT;
       ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo);
   }
}


int main (int argc, char **argv) {

   int fd = -1;

   if (argc != 2) {
       fprintf(stderr, "usage: %s hiddevice - probably
/dev/usb/hiddev0\n", argv[0]);
       exit(1);
   }
   if ((fd = open(argv[1], O_RDONLY)) < 0) {
       perror("hiddev open");
       exit(1);
   }

   // Should display the 32 input usages and send a report
   printf("\n*** INPUT:\n"); showReports(fd, HID_REPORT_TYPE_INPUT);

   // Should display 32 output usages.
   printf("\n*** OUTPUT:\n"); showReports(fd, HID_REPORT_TYPE_OUTPUT);

   // Should display 2 features.
   printf("\n*** FEATURE:\n"); showReports(fd, HID_REPORT_TYPE_FEATURE);

   close(fd);

   return 0;
}

========== end hqcthid.c ==========

This program basically lists all the usages of the hid device. Except, if the
report is an input report then it will additionally set the usages and
send a report.  I know a _real_ program would be written more
efficiently, but this gets the point across.  Look at "// Input usage:
set a byte" and "// Input report: send report" for the bulk of the
work.

This is what is displayed for the input report after two consecutive
executions of the program; First issue:
=====================

*** INPUT:
HIDIOCGREPORTINFO: report_id=0x0 (1 fields)
HIDIOCGFIELDINFO: field_index=31 maxusage=32 flags=0x2
       physical=0x0 logical=0x0 application=0xFFA00001
       logical_minimum=0,maximum=65280 physical_minimum=0,maximum=0
>> usage_index=0 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=0 Usage_Code=0xFFA00003 () Value=0x18
>> usage_index=1 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=1 Usage_Code=0xFFA00003 () Value=0x30
>> usage_index=2 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=2 Usage_Code=0xFFA00003 () Value=0x40
>> usage_index=3 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=3 Usage_Code=0xFFA00003 () Value=0xF
>> usage_index=4 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=4 Usage_Code=0xFFA00003 () Value=0x9F
>> usage_index=5 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=5 Usage_Code=0xFFA00003 () Value=0x1
>> usage_index=6 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=6 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=7 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=7 Usage_Code=0xFFA00003 () Value=0x30
>> usage_index=8 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=8 Usage_Code=0xFFA00003 () Value=0x50
>> usage_index=9 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=9 Usage_Code=0xFFA00003 () Value=0x50
>> usage_index=10 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=10 Usage_Code=0xFFA00003 () Value=0x74
>> usage_index=11 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=11 Usage_Code=0xFFA00003 () Value=0x6F
>> usage_index=12 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=12 Usage_Code=0xFFA00003 () Value=0x6A
>> usage_index=13 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=13 Usage_Code=0xFFA00003 () Value=0xD0
>> usage_index=14 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=14 Usage_Code=0xFFA00003 () Value=0x3
>> usage_index=15 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=15 Usage_Code=0xFFA00003 () Value=0x3
>> usage_index=16 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=16 Usage_Code=0xFFA00003 () Value=0x20
>> usage_index=17 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=17 Usage_Code=0xFFA00003 () Value=0xA
>> usage_index=18 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=18 Usage_Code=0xFFA00003 () Value=0xC
>> usage_index=19 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=19 Usage_Code=0xFFA00003 () Value=0x1
>> usage_index=20 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=20 Usage_Code=0xFFA00003 () Value=0x1
>> usage_index=21 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=21 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=22 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=22 Usage_Code=0xFFA00003 () Value=0xA0
>> usage_index=23 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=23 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=24 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=24 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=25 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=25 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=26 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=26 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=27 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=27 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=28 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=28 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=29 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=29 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=30 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=30 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=31 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=31 Usage_Code=0xFFA00003 () Value=0x0
S> sending report
S> report sent

======================
So, the values are all 0x00 initially and we supposedly set the
values. Unfortunately, the radio does not seem to change state. (>> is
existing value and S> is the sent value).

Second issue:
======================
*** INPUT:
HIDIOCGREPORTINFO: report_id=0x0 (1 fields)
HIDIOCGFIELDINFO: field_index=31 maxusage=32 flags=0x2
       physical=0x0 logical=0x0 application=0xFFA00001
       logical_minimum=0,maximum=65280 physical_minimum=0,maximum=0
>> usage_index=0 usage_code=0xFFA00003 () value=0x3E
S> Usage_Index=0 Usage_Code=0xFFA00003 () Value=0x18
>> usage_index=1 usage_code=0xFFA00003 () value=0x2
S> Usage_Index=1 Usage_Code=0xFFA00003 () Value=0x30
>> usage_index=2 usage_code=0xFFA00003 () value=0x7
S> Usage_Index=2 Usage_Code=0xFFA00003 () Value=0x40
>> usage_index=3 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=3 Usage_Code=0xFFA00003 () Value=0xF
>> usage_index=4 usage_code=0xFFA00003 () value=0x1C
S> Usage_Index=4 Usage_Code=0xFFA00003 () Value=0x9F
>> usage_index=5 usage_code=0xFFA00003 () value=0x57
S> Usage_Index=5 Usage_Code=0xFFA00003 () Value=0x1
>> usage_index=6 usage_code=0xFFA00003 () value=0x98
S> Usage_Index=6 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=7 usage_code=0xFFA00003 () value=0xA3
S> Usage_Index=7 Usage_Code=0xFFA00003 () Value=0x30
>> usage_index=8 usage_code=0xFFA00003 () value=0x9
S> Usage_Index=8 Usage_Code=0xFFA00003 () Value=0x50
>> usage_index=9 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=9 Usage_Code=0xFFA00003 () Value=0x50
>> usage_index=10 usage_code=0xFFA00003 () value=0x8
S> Usage_Index=10 Usage_Code=0xFFA00003 () Value=0x74
>> usage_index=11 usage_code=0xFFA00003 () value=0x74
S> Usage_Index=11 Usage_Code=0xFFA00003 () Value=0x6F
>> usage_index=12 usage_code=0xFFA00003 () value=0x3A
S> Usage_Index=12 Usage_Code=0xFFA00003 () Value=0x6A
>> usage_index=13 usage_code=0xFFA00003 () value=0x5
S> Usage_Index=13 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=14 usage_code=0xFFA00003 () value=0x25
S> Usage_Index=14 Usage_Code=0xFFA00003 () Value=0x3
>> usage_index=15 usage_code=0xFFA00003 () value=0x24
S> Usage_Index=15 Usage_Code=0xFFA00003 () Value=0x3
>> usage_index=16 usage_code=0xFFA00003 () value=0xCA
S> Usage_Index=16 Usage_Code=0xFFA00003 () Value=0x20
>> usage_index=17 usage_code=0xFFA00003 () value=0x35
S> Usage_Index=17 Usage_Code=0xFFA00003 () Value=0xA
>> usage_index=18 usage_code=0xFFA00003 () value=0x14
S> Usage_Index=18 Usage_Code=0xFFA00003 () Value=0xC
>> usage_index=19 usage_code=0xFFA00003 () value=0x10
S> Usage_Index=19 Usage_Code=0xFFA00003 () Value=0x1
>> usage_index=20 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=20 Usage_Code=0xFFA00003 () Value=0x1
>> usage_index=21 usage_code=0xFFA00003 () value=0x15
S> Usage_Index=21 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=22 usage_code=0xFFA00003 () value=0x24
S> Usage_Index=22 Usage_Code=0xFFA00003 () Value=0xA0
>> usage_index=23 usage_code=0xFFA00003 () value=0x1
S> Usage_Index=23 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=24 usage_code=0xFFA00003 () value=0x0
S> Usage_Index=24 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=25 usage_code=0xFFA00003 () value=0xE8
S> Usage_Index=25 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=26 usage_code=0xFFA00003 () value=0xC1
S> Usage_Index=26 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=27 usage_code=0xFFA00003 () value=0x1A
S> Usage_Index=27 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=28 usage_code=0xFFA00003 () value=0x23
S> Usage_Index=28 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=29 usage_code=0xFFA00003 () value=0xA5
S> Usage_Index=29 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=30 usage_code=0xFFA00003 () value=0xC0
S> Usage_Index=30 Usage_Code=0xFFA00003 () Value=0x0
>> usage_index=31 usage_code=0xFFA00003 () value=0x8
S> Usage_Index=31 Usage_Code=0xFFA00003 () Value=0x0
S> sending report
S> report sent

======================
This time the values are not equal to 0x00. instead they are some
seemingly random numbers.  Can anyone provide me with some hints or
maybe a decent example driver to reference?

I appreciate your assistance, thanks for supporting a tool as vital as USB.

--Paul


On 5/9/06, Paul Giblock <[EMAIL PROTECTED]> wrote:
Hello -

This is my first post to this newsletter. I have been trying to write
host software to communicate with a low-speed USB PIC Microcontroller.
 The device is configured to send and receive 32 byte reports.  The
designer of the usb project has code writen in Windows Pascal
(Delphi?) to control the device. The code is a rework from the code
generated by EasyHID.  Here is my output of lsusb:

------------------------------------------------------------
llamabox hqct # lsusb -d 04d8:000a -vvvv

Bus 001 Device 002: ID 04d8:000a Microchip Technology, Inc.
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         8
  idVendor           0x04d8 Microchip Technology, Inc.
  idProduct          0x000a
  bcdDevice            0.01
  iManufacturer           1 Datalex
  iProduct                2 Car-Radio
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           41
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0xa0
      Remote Wakeup
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Devices
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.01
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      47
          Report Descriptor: (length is 47)
            Item(Global): Usage Page, data= [ 0xa0 0xff ] 65440
                            (null)
            Item(Local ): Usage, data= [ 0x01 ] 1
                            (null)
            Item(Main  ): Collection, data= [ 0x01 ] 1
                            Application
            Item(Local ): Usage, data= [ 0x03 ] 3
                            (null)
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0x00 0xff ] 65280
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x20 ] 32
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position
Non_Volatile Bitfield
            Item(Local ): Usage, data= [ 0x04 ] 4
                            (null)
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0x00 0xff ] 65280
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x20 ] 32
            Item(Main  ): Output, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position
Non_Volatile Bitfield
            Item(Local ): Usage, data= [ 0x05 ] 5
                            (null)
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0x00 0xff ] 65280
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x02 ] 2
            Item(Main  ): Feature, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position
Non_Volatile Bitfield
            Item(Main  ): End Collection, data=none
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
------------------------------------------------------------

I originally tried using a HIDDEV device.  I could not figure out how
to write to the device properly. Looking at the source shows that
write() is implemented to return an error. The documentation is too
ambiguous for me to figure out how to write properly... I couldn't get
HIDIOCSREPORT to work properly at all. I have read a good deal of the
USB HID papers even.

I tried writing a kernel module based around usb-skel.c. I was able to
change the state of the device noticibly, but I haven't been able to
recreate it. So, this has only happened once.  I change the skeleton
to write to the interrupt endpoints instead of using bulk transfer
since that is not supported.

I have even tried using libhid and that hasn't worked.  The path I
have tried for writing is:

{ 0xffa00001, 0xffa00003 }

This has not worked, from what I could tell, at all. I have even tried
using three different functions for writing while using the libhid
approach: hid_set_output_report(), usb_interrupt_write(), and
hid_interrupt_write().

I have tried restarting the computer and device between almost every
test. Has anyone been able to communicate with a PIC or a comparable
HID device?  All I want is to send a 32 byte report.

I will post sources if requested, I'm not sure how much they would help though.

Thank you,
Paul

------------------------------------------------------------
llamabox hqct # cat /proc/bus/usb/devices
[...]
T:  Bus=01 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#=  2 Spd=12  MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=04d8 ProdID=000a Rev= 0.01
S:  Manufacturer=Datalex
S:  Product=Car-Radio
C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA
I:  If#= 0 Alt= 0 #EPs= 2 Cls=03(HID  ) Sub=00 Prot=00 Driver=(none)
E:  Ad=81(I) Atr=03(Int.) MxPS=  64 Ivl=1ms
E:  Ad=01(O) Atr=03(Int.) MxPS=  64 Ivl=1ms



-------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid0709&bid&3057&dat1642
_______________________________________________
Linux-usb-users@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-users

Reply via email to