Programming Questions

The intent of this forum is to discuss my DOS TSR programs (available at http://bretjohnson.us), how they work and don't work, new/missing features, status of updates, and anything else related to them that may need to be discussed.

Programming Questions

Postby Dinosaur » Fri Sep 11, 2009 1:56 pm

Hi Brett

In an attempt to take control away from the mouse driver, I realised that I needed the InterfaceNum.
So this code is an attempt to get the interfaceNum.
I used all values as "Dont care"
Code: Select all
   irs.RequestType = .FindRegIntf
   irs.HostIndex   = 255
   irs.HostIndex   = 255
   irs.SearchIndex = 255
   irs.VendorID    = &HFFFF
   irs.ProductID   = &HFFFF
   irs.DvcClass    = &HFF
   irs.DvcSubClass = &HFF
   irs.DvcProtocol = &HFF
   irs.IntfClass   = &HFF
   irs.IntfSubClass = &HFF
   irs.IntfProtocol = &HFF
   .StepNbr = 9
   rval = GetUSB
   If rval Then
       USBErrCheck                             ''
       GoTo ErrEnd                             '' Dont go any further if err.
   EndIf
   .Temp1 = dpmir.h.dl
   .Temp2 = dpmir.h.dh   
   irs.InterfaceNum = dpmir.h.dl
After this usbuhcil fills in detail such as VendorID and ProductID correctly.
Also fills in DvcClass & DvcSubClass as Zero.
However I get an error &H32 "Interface not found"

Using usbDevic I get
Code: Select all
                              DEVICE ADDRESSES
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Host Index:  0  Host Type: UHCI  Bus Type: PCI   IRQ#: 10  Root Hub Ports: 2
Vendor: 1106h = VIA Technologies Inc                       Product: 3038h
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
                DEVICES                                   INTERFACES           
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ  ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
                           L                C  I A                O           
ADRS                       o         P      o  n l                w           
ÍÍÍÍ   (hex)               S         o BUS  n  t t                n           
Test VEND PROD     Sub Pro p USB HUB r POWR f  f I                e     Sub Pro
RWak  ID   ID  Cls Cls col d VER ADR t (mA) g  c n  DESCRIPTION   d Cls Cls col
ÍÍÍÍ ÍÍÍÍ ÍÍÍÍ ÍÍÍ ÍÍÍ ÍÍÍ Í ÍÍÍ ÍÍÍ Í ÍÍÍÍ Í  Í Í ÍÍÍÍÍÍÍÍÍÍÍÍÍÍ Í ÍÍÍ ÍÍÍ ÍÍÍ
  1  1106 3038   9   0   0 . 1.0 ... . s  0 1  0 0*Root Hub       Y   9   0   0
     VIA Technologies Inc                   
ÄÄÄÄ ÄÄÄÄ ÄÄÄÄ ÄÄÄ ÄÄÄ ÄÄÄ Ä ÄÄÄ ÄÄÄ Ä ÄÄÄÄ Ä  Ä Ä ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Ä ÄÄÄ ÄÄÄ ÄÄÄ
  2  D209 1501   0   0   0 . 2.0   1 2  500 1  0 0*USBSUPT1.COM!! .   3   0   0
     Ultimarc?                                 1 0*USBSUPT1.COM!! .   3   0   0
                                               2 0*USBSUPT1.COM!! .   3   0   0
                                               3 0*USBSUPT1.COM!! .   3   1   2
Why would it not report an interfaceNum, even when I fill in the VendorID to &HD209 and ProductID to &H1501 ?
You may notice that the device is not owned according to this printout, so I made a small change to the bootup
cd\usb
usbuhcil
Delay 2
usbmouse
cd\
C:\Dos32\ctmouse
C:\Dos32\LBACache
C:\usb\Delay 3
c:\usb\usbdevic
C:\dos32\HDPMI32
C:\USBTest.exe
c:\usb\usbdevic
This now shows the device is owned before and after the USBTest

Regards

Edit: This is the actual uhci calling routine.(I renamed it from GetUSB)
Code: Select all
Function Calluhci As Integer
   '-------------------------------------
   'Struct fields set by caller.   
   '-------------------------------------
   With irs
      CopyToRM( sel, @irs, 0, 64 )      '' copy Struc to RealMode
      dpmir.x.bx = &h5553               '' set dpmi registers(ax already set)
      dpmir.x.cx = &h4221                 '' prepare registers for
      dpmir.x.ds = seg                    '' call
      dpmir.x.dx = 0                      '' offset of Struc is 0
      asm
          mov ax, 0x300                   '' Simulate Real Mode Interrupt
          mov bl, 0x14                    '' interrupt number (for dpmi)
          lea edi, [dpmir]                '' load address of dpmir registers
          Int 0x31                        '' call dpmi Int
      End Asm   
   End With
   If dpmir.x.flags And CF Then            '' Any errors ?
          Function = dpmir.x.ax           '' send them to caller
       Else
         CopyToPM( sel, 0, @irs, 64 )    '' Get filled in Struc
          Function = 0                    '' No error
   EndIf
End Function
Dinosaur
 
Posts: 70
Joined: Wed Jul 01, 2009 5:54 pm
Location: Salt Lake City USA

Re: Programming Questions

Postby Bret » Sun Sep 13, 2009 12:52 pm

I found a problem with USBUHCI{L} in the "Find Registered Interface" and "Find Unregistered interface" calls. If the Interface was not found, they were returning CX = DX = 0 instead of CX = DX =-1. I just uploaded a new version.

However, there is still a problem with your call. irs.SearchIndex must be 0, not 255. There is not a "Don't Care" value for the SearchIndex. 0 will find the "first" registered Interface, 1 the "second", etc. A SearchIndex of 255 will find the 256th registered Interface (and you don't have anywhere near 256 of them). The value returned in AX (&H32) is valid, though the values returned in CX and DX were not. That should be fixed in the new version.
Bret
 
Posts: 478
Joined: Fri Oct 10, 2008 3:43 am
Location: Rio Rancho, NM

Re: Programming Questions

Postby Dinosaur » Sun Sep 13, 2009 3:28 pm

Hi all

Bret, thanks for the update.
I assumed that with every call, you would update the struct with all the info available.
That is where I picked that bit 0 was set on DvcStatus, with DvcStatStep = 65
Obviously the initialisation of the Ultimarc board hasnt gone smoothly, although it
functions correctly. ?
The trick is to keep an eye on whether the Registers or the Struc has the answers.

I have searched the doc's for a method the find out the .DeviceAddress and cant find any.
Using usbdevic I know what it is, but in the code I would like to specify the VendorID & ProductID and then find
from an Int14 what the DeviceAddress is.

Is there such a function. ?

Regards
Edit: Also plugging in another device, seems to change the order of Device's
Dinosaur
 
Posts: 70
Joined: Wed Jul 01, 2009 5:54 pm
Location: Salt Lake City USA

Re: Programming Questions

Postby Dinosaur » Sun Sep 13, 2009 6:14 pm

Hi all

New question.
So far I am doing the following without getting any errors.
.GetHostHWInfo
.GetHostSWInfo
.GetHostVendInfo
.GetDvcClassInfo
.GetDvcVendInfo
.GetDvcStatus
.FindRegIntf 'Which answers my previous question about Device address
.IntfDontLook
This last call is made with the info accumulated from the other calls, such as Interface, DeviceAddress etc.
Then when I quit my app. and run usbdevic, it still shows both devices owned. ?

As there are 4 interfaces for each device, do I have to .IntfDontLook for each one, or am I using the wrong instructions for
disconnecting a device from an owner ?

Regards

Edit: I will have to stop asking questions for which the very detailed doc's have the answers.
Is it likely that the ctmouse driver will try to reclaim the device if I dont succeed in registering as the new owner
within the "dont Look" time. I imagine in Windows, Yes , but in Dos ?
Dinosaur
 
Posts: 70
Joined: Wed Jul 01, 2009 5:54 pm
Location: Salt Lake City USA

Re: Programming Questions

Postby Bret » Sun Sep 13, 2009 11:56 pm

Dinosaur wrote:Is it likely that the ctmouse driver will try to reclaim the device if I dont succeed in registering as the new owner within the "dont Look" time. I imagine in Windows, Yes , but in Dos ?


Yes, in DOS also. It is actually USBMOUSE, not CTMOUSE, that will reclaim the mouse if you don't register within the "Don't Look" time. So, the amount of don't look time should be enough time for you to determine if you want to register or not, and do it, but not so long that the mouse isn't available to the user for a long time if you end up not registering for some reason.

[quote="Dinosaur"]As there are 4 interfaces for each device, do I have to .IntfDontLook for each one, or am I using the wrong instructions for disconnecting a device from an owner?/quote]

Yes, you must do it separately for each Interface. Remember that what USB calls an Interface is the thing that most directly corresponds to your concept of a "device". What USB calls a Device isn't what you would normally think of as a device. USB's choice of nomenclature is very unfortunate, and causes all kinds of confusion.

EDIT:

Don't worry about questions even if they are already answered in the documentation (hopefully, almost everything is answered somewhere in the documentation). There are a lot of new concepts that you have to understand if you want to use the USB API effectively. The concepts are pretty much second-nature and obvious to me, since I developed some of them and have been working with them for many years now. I know it's going to take some time for anybody coming in from the outside to really understand it. I also think the API is probably very different than anything you've seen before, especially if you're used to Windows. It's a multi-tasking BIOS-level (hardware) API, not an OS-level API, even though it's implemented in the DOS OS.

I must also say I admire your tenacity and attention to detail. You're doing far more than what it takes to simply write your application, but are testing the API and building a FreeBASIC library that can be used for all kinds of programs besides your own. I certainly appreciate it, and hope others will as well.

Bret
Bret
 
Posts: 478
Joined: Fri Oct 10, 2008 3:43 am
Location: Rio Rancho, NM

Re: Programming Questions

Postby Dinosaur » Mon Sep 14, 2009 11:25 am

Hi all

Remember that what USB calls an Interface is the thing that most directly corresponds to your concept of a "device".

I understand the device / Interface concept, but that means I need to find out from the manufacturer, which of the 4 Interfaces
is actually doing the I/O function I am looking for.
Or is it that because Interface 3 is the only one "Owned", that this is the interface needed ? Then what would be the purpose of 4 interfaces
when only one is needed.

Do you have a list of which calls fill in the Struc, and which dont touch it. ?

REgards
Dinosaur
 
Posts: 70
Joined: Wed Jul 01, 2009 5:54 pm
Location: Salt Lake City USA

Re: Programming Questions

Postby Bret » Mon Sep 14, 2009 12:30 pm

Dinosaur wrote:I understand the device / Interface concept, but that means I need to find out from the manufacturer, which of the 4 Interfaces is actually doing the I/O function I am looking for. Or is it that because Interface 3 is the only one "Owned", that this is the interface needed ? Then what would be the purpose of 4 interfaces when only one is needed.


You actually have four different Interfaces on a single Device: an I/O, a joystick, a keyboard, and a mouse, in that order. The I/O function is on Interface 0, the joystick on 1, etc. I determined this from one of the previous threads:

Code: Select all
USBUHCIL 0.08, (C) 2007-2009, Bret E. Johnson.
DOS Driver for a Universal HCI compatible USB Host Controller.
  LITE version (maximum 16 Devices, no Isochronous Transactions).

DEVICE ADDRESS:   2
CONFIGURATION:    1

        DEVICE DESCRIPTOR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 12h  18
Descr Type:                   01h  Device
USB Release:                0200h  2.00
Device Class:                 00h  Look at Interface
Device SubClass:              00h  None
Device Protocol:              00h  None
Max Packet Size EP0:          08h  8
Vendor ID:                  D209h  No Matching Record Found               
Product ID:                 1501h  5,377
Device Release:             0019h  0.19
Manufacturer String:          01h  "Universal Herface Device"
Product String:               01h  "Univers Interface Device"
Serial # String:              05h  "9"
# of Configs:                 01h  1

    CONFIGURATION DESCRIPTOR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 09h  9
Descr Type:                   02h  Configuration
Descr Total Length:         006Dh  109
# of Interfaces:              04h  4
Configuration Value:          01h  1
Configuration String:         01h  "Universal Human Interfaee D"
Attributes:                   80h  Valid Historical Attribute 80h
                                   Bus Powered
                                   No Remote Wakeup
                                   Not Battery Powered
Current Draw / 2:             FAh  250 (500 mA)

      INTERFACE DESCRIPTOR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 09h  9
Descr Type:                   04h  Interface
Interface Number:             00h  0
Alternate Setting:            00h  0
# of End Points:              01h  1
Interface Class:              03h  HID (Human Interface Device)
Interface SubClass:           00h  None
Interface Protocol:           00h  None
Interface String:             01h  "Universal Human Interface Device"

  HUMAN INTERFACE DEVICE DESCR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 09h  9
Descr Type:                   21h  HID (Human Interface Device)
HID Class Release:          0111h  1.11
Country Code:                 00h  None/Not Applicable
# of Classes:                 01h  1
Class Descr Type 1:           22h  Report
Class Descr Size 1:         0021h  33

      END POINT DESCRIPTOR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 07h  7
Descr Type:                   05h  EndPoint
End Point Number:             81h  EndPoint = 1  Direction = In
Attributes:                   03h  Interrupt NonSynchronous Data
Max Packet Size:            0008h  8
Max Poll Interval:            0Ah  10

      INTERFACE DESCRIPTOR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 09h  9
Descr Type:                   04h  Interface
Interface Number:             01h  1
Alternate Setting:            00h  0
# of End Points:              01h  1
Interface Class:              03h  HID (Human Interface Device)
Interface SubClass:           00h  None
Interface Protocol:           00h  None
Interface String:             03h  "UHID Gamepad Device #1"

  HUMAN INTERFACE DEVICE DESCR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 09h  9
Descr Type:                   21h  HID (Human Interface Device)
HID Class Release:          0111h  1.11
Country Code:                 00h  None/Not Applicable
# of Classes:                 01h  1
Class Descr Type 1:           22h  Report
Class Descr Size 1:         0046h  70

      END POINT DESCRIPTOR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 07h  7
Descr Type:                   05h  EndPoint
End Point Number:             82h  EndPoint = 2  Direction = In
Attributes:                   03h  Interrupt NonSynchronous Data
Max Packet Size:            0014h  20
Max Poll Interval:            0Ah  10

      INTERFACE DESCRIPTOR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 09h  9
Descr Type:                   04h  Interface
Interface Number:             02h  2
Alternate Setting:            00h  0
# of End Points:              01h  1
Interface Class:              03h  HID (Human Interface Device)
Interface SubClass:           00h  None
Interface Protocol:           00h  None
Interface String:             04h  "UHID Keyboard Device"

  HUMAN INTERFACE DEVICE DESCR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 09h  9
Descr Type:                   21h  HID (Human Interface Device)
HID Class Release:          0111h  1.11
Country Code:                 00h  None/Not Applicable
# of Classes:                 01h  1
Class Descr Type 1:           22h  Report
Class Descr Size 1:         003Fh  63

      END POINT DESCRIPTOR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 07h  7
Descr Type:                   05h  EndPoint
End Point Number:             83h  EndPoint = 3  Direction = In
Attributes:                   03h  Interrupt NonSynchronous Data
Max Packet Size:            0010h  16
Max Poll Interval:            0Ah  10

      INTERFACE DESCRIPTOR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 09h  9
Descr Type:                   04h  Interface
Interface Number:             03h  3
Alternate Setting:            00h  0
# of End Points:              01h  1
Interface Class:              03h  HID (Human Interface Device)
Interface SubClass:           01h  Boot
Interface Protocol:           02h  Mouse
Interface String:             02h  "UHID Mouse Device"

  HUMAN INTERFACE DEVICE DESCR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 09h  9
Descr Type:                   21h  HID (Human Interface Device)
HID Class Release:          0111h  1.11
Country Code:                 00h  None/Not Applicable
# of Classes:                 01h  1
Class Descr Type 1:           22h  Report
Class Descr Size 1:         0036h  54

      END POINT DESCRIPTOR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 07h  7
Descr Type:                   05h  EndPoint
End Point Number:             84h  EndPoint = 4  Direction = In
Attributes:                   03h  Interrupt NonSynchronous Data
Max Packet Size:            0008h  8
Max Poll Interval:            0Ah  10


Luckily, the vendor included descriptions to help you figure out which interface was which. If they didn't do that, you could still figure it out, but it would be much more difficult. You would need to download and decipher the HID Report Descriptors (which we also did in a previous post), since the first three Interfaces all look exactly the same at the USB level (they are just listed as "Human Interface Devices", which doesn't really tell you anything you really need to know). Interface 3, the mouse, is the only one currently owned because USBMOUSE is the only driver you have installed. If you installed USBKEYB, Interface 2 would also be owned, and if you installed USBJSTIK, Interface 1 would also be owned. None of the Drivers I have made so far will own Interface 0 (the one you want to use), because Interface 0 doesn't look anything like a mouse, keyboard, or joystick -- it's just a bunch of buttons and LEDs.

Dinosaur wrote:Do you have a list of which calls fill in the Struc, and which dont touch it. ?


Calls to the API never change anything in the structure. Everything is returned in the Carry Flag, AX, BX, CX, DX, and, possibly in the future, ES. If the request requires a data address, data will be moved from memory to a USB device or vice versa at some later point in time. If the request requires a code call back address, code will be called at some point in time, usually later (from inside an IRQ), but sometimes before the API call is finished, depending on the nature of the call and the state of the bus.
Bret
 
Posts: 478
Joined: Fri Oct 10, 2008 3:43 am
Location: Rio Rancho, NM

Re: Programming Questions

Postby Dinosaur » Mon Sep 14, 2009 9:17 pm

Hi All

1. If Interface 0 is not owned on a device, can I claim it
without asking owner of Interface 3 to release control. ?

2. When the doc's say that the CallBackAddr should be in CS:IP format and
with the declare as CallBackAddr DD ?
does it mean one long number as in:
Code: Select all
        push    eax
        mov     ax,cx      'cx holds Seg:
        rol     eax,16
        mov     ax,dx      'dx holds Offset
        mov     DataAddr,eax
        pop     eax


3. If the call back addr is incorrect or faulty, will
usbuhcil return an error code ? (if there isnt a GPF)

Basically I have created a CallBackAddr with dpmi,then
irs.RequestType = .RegIntfOwner
irs.HostIndex = .DvcHostIndex
irs.DeviceAddress = .DvcAddress
irs.InterfaceNum = .DvcIntfNum
irs.CallBackAddr = DataAddr
irs.Timeout = 250
rval = Calluhci

All without an error, but in my CallBack routine I have just simply done
Code: Select all
My_CallBack:
        Push    eax
        mov     eax,0xffff
        mov     [FdBack],eax  'has uhci been here ?
        pop     eax
        Sti
        Iret

The result is that usbuhci hasnt been there.

Regards
Dinosaur
 
Posts: 70
Joined: Wed Jul 01, 2009 5:54 pm
Location: Salt Lake City USA

Re: Programming Questions

Postby Bret » Tue Sep 15, 2009 12:00 am

Dinosaur wrote:1. If Interface 0 is not owned on a device, can I claim it without asking owner of Interface 3 to release control. ?


Yes.

Dinosaur wrote:2. When the doc's say that the CallBackAddr should be in CS:IP format and with the declare as CallBackAddr DD ? does it mean one long number as in:


Code: Select all
push    eax
mov     ax,cx      'cx holds Seg:
rol     eax,16
mov     ax,dx      'dx holds Offset
mov     DataAddr,eax
pop     eax


Yes, exactly. Depending on the Syntax allowed by your in-line ASM, you may also be able to do something like this, which is smaller and faster:

Code: Select all
mov  WORD PTR DataAddr[2],CX
mov  WORD PTR DataAddr[0],DX


Dinosaur wrote:3. If the call back addr is incorrect or faulty, will usbuhcil return an error code ? (if there isnt a GPF)


No. It has no way of knowing whether the code address is valid or not. I suppose it could do some simple testing, like for all 0's or all 1's, but it doesn't do anything like that. Similarly, it has no way of knowing whether a data address is valid or not, and there's no way it could do even a simple test for that.

Dinosaur wrote:Basically I have created a CallBackAddr with dpmi,then
irs.RequestType = .RegIntfOwner
irs.HostIndex = .DvcHostIndex
irs.DeviceAddress = .DvcAddress
irs.InterfaceNum = .DvcIntfNum
irs.CallBackAddr = DataAddr
irs.Timeout = 250
rval = Calluhci


That should basically work, except you don't need the irs.Timeout. The last value you need in the call is irs.UserPktID, which is simply a value that is returned during the notification calls in the BX register. If you have different processes going on that call the same code, this can help you identify which one called it. It's just a number that USBUHCIL returns back to you during the notification process, so USBUHCIL doesn't care what it is.

Dinosaur wrote:All without an error, but in my CallBack routine I have just simply done


Code: Select all
My_CallBack:
Push    eax
mov     eax,0xffff
mov     [FdBack],eax  'has uhci been here ?
pop     eax
Sti
Iret


Dinosaur wrote:The result is that usbuhci hasnt been there.


You don't need to save any registers or flags on the stack, since USBUHCIL does that automatically before the code is called. You can do it if you want to, but it's redundant and unnecessary. Also, the code should end in a far return (RETF), not an interrupt return (IRET). Also, the notification code is called with CS = DS = ES = FS = GS, with the values determined by the segment portion of the callback address. Your code assumes that the segment where FdBack is located (DS) is the same as where My_CallBack is located (CS), which may or may not be true -- I'm not sure how FreeBASIC sets up the segments in a case like this. Also, the code is called from 16-bit Real/V86 mode, not 32-bit DPMI protected mode. Even simple operations like "PUSH EAX" have different OpCodes depending on whether the CPU is in 16-bit mode or 32-bit mode, and My_Callback and FdBack must both be in V86 accessible memory (I assume they are, but can't tell for sure).

Lastly, USBUHCIL would only call My_Callback when it had something to tell you, like if the Device was disconnected or reset or the Host was stopped for some reason (see the table on page 10 of USBAPI.DOC for a summary list of all the notification types). To give USBUHCIL a reason to notify you, the simplest thing to do would probably be to unplug the device.

************************************
Also, when you get to the point where you want to test the data transfer from an actual USB device (to test the 1:1 relationship between Linear and Physical memory address), you will want to issue an 14RRTDoBulk request. I can help you with that when the time comes.

EDIT:
I should also point out that if you receive a Device Disconnect notification, it means that the Device does not exist any more, which means that the Interfaces do not exist any more, which means that the Interface Ownership Registration does not exist any more (after the appropriate notification processes have completed), since there is no longer an Interface to own. You will have to redo the whole process from scratch, assuming the device gets reconnected and re-enumerated (and it may have a different Device Address or even get plugged into a different Host the next time, at least in an uncontrolled environment).

I also want to reiterate that in your particular situation, which is a controlled environment, you don't necessarily need to even register as the Interface owner. I think it's good that you're working through the process of how to do it from FreeBASIC/DPMI, because that will ultimately help lots of other people. But you don't actually NEED to do it to accomplish your goal.
Bret
 
Posts: 478
Joined: Fri Oct 10, 2008 3:43 am
Location: Rio Rancho, NM

Re: Programming Questions

Postby Dinosaur » Tue Sep 15, 2009 9:58 am

Hi all

mov WORD PTR DataAddr[2],CX
mov WORD PTR DataAddr[0],DX
Yes, that's allowed.
Your code assumes that the segment where FdBack is located (DS) is the same as where My_CallBack is located (CS

Yes it is, I have done this before to Hook the Timer Tick.
The only purpose of this code was to record if usbuhcil had been there. My understanding is that it should get there at least once after
the ownership call.
Code: Select all
I also want to reiterate that in your particular situation, which is a controlled environment, you don't necessarily need to even register as the Interface owner.

If I dont understand it, I cant trust it, and cant use it. Additionally you can guarantee that 6 months after I have "Taken the shortcut" there will be a need to do other things
and then will have to learn it all over again.
At the moment I am waiting for some equipment to arrive from China for my next big install, and my wife is in the UK for another 2 weeks, so I have time to finish this.
And as my wife says, I have the patience of Jobe.

Regards

Edit:
Lastly, USBUHCIL would only call My_Callback when it had something to tell you, like if the Device was disconnected

I must be making progress, for when I pull the plug, Exception 0D in Ring 0. Probably meaning my callbackaddr is wrong.
Dinosaur
 
Posts: 70
Joined: Wed Jul 01, 2009 5:54 pm
Location: Salt Lake City USA

Re: Programming Questions

Postby Bret » Tue Sep 15, 2009 10:22 am

Dinosaur wrote:The only purpose of this code was to record if usbuhcil had been there. My understanding is that it should get there at least once after the ownership call.


No, it won't get there unless there is something worthwhile to say. To test and make sure it works, you'll need to force something to happen that will make it happen. I will consider adding something like that to the API, though, essentially an automatic "Ownership Confirmed" call, or maybe a specific "Test Interface Owner" call.

Dinosaur wrote:If I dont understand it, I cant trust it, and cant use it. Additionally you can guarantee that 6 months after I have "Taken the shortcut" there will be a need to do other things and then will have to learn it all over again.


You're definitely right about that. Almost without fail, whenever you take a shortcut, especially in programming, it comes back to bite you later.

Dinosaur wrote:At the moment I am waiting for some equipment to arrive from China for my next big install, and my wife is in the UK for another 2 weeks, so I have time to finish this. And as my wife says, I have the patience of Jobe.


Good for you. I'll help you where I can and where I have the time.
Bret
 
Posts: 478
Joined: Fri Oct 10, 2008 3:43 am
Location: Rio Rancho, NM

Re: Programming Questions

Postby Dinosaur » Tue Sep 15, 2009 4:47 pm

Hi all

Still having CallBack problems, but leaving that for a moment (to clear the brain) and trying some transactions.
The supplier of the board supplied me with this info:
The format is a 4-byte packet with the first 2 bytes zero, and the second two are the LEDs, with each bit set lighing one of the 16 LEDs.
The data is sent using a control transfer to endpoint zero on the device.
The VID is D209 and PID is 1501
The problem I have is that the doc's state that
SetupReqData = 8-byte Control Setup Packet to send to Device
(contains embedded Direction & Data Size)

What is the allocation of the top 4 bytes, so that I can set Direction / Size etc.

irs.RequestType = .DoControl
irs.HostIndex = .DvcHostIndex
irs.SearchIndex = 0
irs.VendorID = .DvcVendID
irs.ProductID = .DvcProdID
irs.DvcClass = .DvcClass
irs.DvcSubClass = .DvcSubClass
irs.DvcProtocol = .DvcProtocol
irs.EndPoint = 0
irs.DataSize = 2
irs.TimeOut = 50
irs.UserPktID = .DvcHandle1
irs.Flags = &H80 '' WRITE
CtrlData = &H0000FF00
irs.SetupReqData = CtrlData
rval = Calluhci
Then
Print "TransActHndl =";dpmir.x.cx ie: 4
Print "Closure ID =";dpmir.h.dl ie:201
Then to get confirmation that the write did occurr:
irs.RequestType = .DoControl
irs.HostIndex = .DvcHostIndex
irs.SearchIndex = 0
irs.VendorID = .DvcVendID
irs.ProductID = .DvcProdID
irs.DvcClass = .DvcClass
irs.DvcSubClass = .DvcSubClass
irs.DvcProtocol = .DvcProtocol
irs.EndPoint = 0
irs.DataSize = 2
irs.TimeOut = 500
CtrlData = &H00000000
irs.SetupReqData = CtrlData
irs.UserPktID = .DvcHandle1
irs.Flags = 1 Or &H80 '' READ
rval = Calluhci
If rval Then
USBErrCheck
EndIf
Then
Print "TransActHndl =";dpmir.x.cx ie:5
Print "Closure ID =";dpmir.h.dl ie:202
Print "Control Data =";irs.SetupReqData ie:0
After this call there is obviously an error, as the program hangs (probably trying to goto CallBackAddr(which I havent fixed yet))

Is this the right way to get the data from the Control though ?

Regards
Dinosaur
 
Posts: 70
Joined: Wed Jul 01, 2009 5:54 pm
Location: Salt Lake City USA

Re: Programming Questions

Postby Bret » Tue Sep 15, 2009 11:31 pm

Here is an excerpt from one of my programs for what a Control Setup packet looks like. It is an 8-byte structure, defined in the USB specs.

Code: Select all
  ;----------------------------------------------------------------------------
  ;Device Request is a structure containing data required by a USB Setup Packet
  ;----------------------------------------------------------------------------
  SetupRequest           STRUC     ;Structure for a Standard Setup Pkt
    SRRequestType           DB  ?  ;Request Type
      SRRTOut              EQU 00h ;0=Out (Host to Device)
      SRRTIn               EQU 80h ;1=In (Device to Host)
      SRRTTypeMask         EQU 60h ;Mask for Type
        SRRTTypeStandard   EQU 00h ;Type 0 = Standard
        SRRTTypeClass      EQU 20h ;Type 1 = Class
        SRRTTypeVendor     EQU 40h ;Type 2 = Vendor
                                   ;Type 3 = Reserved
      SRRTRecipientMask    EQU 1Fh ;Mask for Recipient Type
        SRRTRecipDevice    EQU 00h ;Recipient Type 0 = Device
        SRRTRecipInterface EQU 01h ;Recipient Type 1 = Interface
        SRRTRecipEndPoint  EQU 02h ;Recipient Type 2 = EndPoint
        SRRTRecipOther     EQU 03h ;Recipient Type 3 = Other
                                   ;Types 4-31 = Reserved
    SRRequest               DB  ?  ;Specific Request
      SRRQGetStatus        EQU  0  ;Request  0 = Get Status
      SRRQClearFeature     EQU  1  ;Request  1 = Clear Feature
      SRRQGetState         EQU  2  ;Request  2 = Get State
      SRRQSetFeature       EQU  3  ;Request  3 = Set Feature
                                   ;Request  4 = Reserved
      SRRQSetAddress       EQU  5  ;Request  5 = Set Address
      SRRQGetDescriptor    EQU  6  ;Request  6 = Get Descriptor
      SRRQSetDescriptor    EQU  7  ;Request  7 = Set Descriptor
      SRRQGetConfig        EQU  8  ;Request  8 = Get Configuration
      SRRQSetConfig        EQU  9  ;Request  9 = Set Configuration
      SRRQGetAltInterface  EQU 10  ;Request 10 = Get Alternate Interface
      SRRQSetAltInterface  EQU 11  ;Request 11 = Set Alternate Interface
      SRRQSynchFrame       EQU 12  ;Request 12 = Synch Frame
    SRValue                 DW  ?  ;Value depends on Request Type
    SRIndex                 DW  ?  ;Index depends on Request Type
      ;If EndPoint,  Bits 3:0 = EndPoint Number
      ;              Bit    7 = 1 if IN EndPoint, 0 if OUT EndPoint
      ;              All other bits are 0
      ;If Interface, Bits 7:0 = Interface Number (low byte)
      ;              All other bits are 0 (high byte)
    SRLength                DW  ?  ;Length of Data (if there is Data)


The Vendor will need to provide a little bit more information about what needs to go in the Setup Packet. I can take a guess at what some of the values should be, though:

Code: Select all
SRRequestType = SRRTOut + SRRTTypeVendor + SRRecipInterface ;Most likely Recipient = Interface
SRRequest = ? ;This will be defined by the Vendor.  Probably 0?
SRValue   = ? ;This will be defined by the Vendor.  Probably 0?
SRIndex   = 0 ;Low Byte = Interface Number, High Byte = 0 (assuming Recipient = Interface)
SRLength  = 4 ;Number of data bytes to transfer


USBUHCIL will send the Control Setup Packet to the Device, and if the Device accepts it, USBUHCIL will then issue a packet to send the 4 data bytes to the Device. I14RDataAddress in the 64-byte structure contains the memory address where the 4 data bytes to send are stored. For Control Setup Requests, I14RFlagIn and I14RDataSize in the 64-byte structure are ignored, since the direction and size of the data transfer are embedded in the Control Setup Packet. As in our previous discussions, I14RDataAddress must ultimately be translated to a physical memory address, so we still need to work out the linear-to-physical details.
Bret
 
Posts: 478
Joined: Fri Oct 10, 2008 3:43 am
Location: Rio Rancho, NM

Re: Programming Questions

Postby Dinosaur » Sat Sep 19, 2009 1:51 pm

Hi Bret

There appears to be a minor error
The doc's for .DoBulk say
Return (Success):
CF = Clear
AX = 0
BX = FFFFh
CX = Transaction Handle
DL = Closure ID (non-zero)
DH = FFh
However a call to this produces 0x11001001 in DX ( C9h )
Dont know if that means something, but at least you know now.
There were no errors in the call.

Regards
Edit: The callback has a code of 0x0014 for which there is no description in the doc.
Is there a more extensive list ?
The Flags are 0x06 and BX is the correct UserPktId
Edit: OK I see it , 04 for TimeOut Orred with 10 for Short Packet Detected.

Edit: Bret,
Can I ask you to give me an example of a call to call the i/f. I am getting weird results using DoControl.
I am sure the values I set are wrong.
Can I ask for a Descriptor from a device that is not owned by me.?
Trying to prove the DataAddress at the moment.
Dinosaur
 
Posts: 70
Joined: Wed Jul 01, 2009 5:54 pm
Location: Salt Lake City USA

Re: Programming Questions

Postby Bret » Sun Sep 20, 2009 7:22 am

Dinosaur wrote:There appears to be a minor error The doc's for .DoBulk say

Return (Success):
CF = Clear
AX = 0
BX = FFFFh
CX = Transaction Handle
DL = Closure ID (non-zero)
DH = FFh

However a call to this produces 0x11001001 in DX ( C9h )
Dont know if that means something, but at least you know now. There were no errors in the call.


Yes, there are some problems with USBUHCIL in this call, and a few others. I've fixed it in my source code, and will upload a new version some time soon.

What I was doing was returning 0 in DH instead of FFh. FYI, this is a remnant of previous (unreleased) versions of USBUHCIL where I would generally return all 0's in unused registers instead of all 1's. Later on, I decided it would be better to change unused values to all 1's in anticipation of future API upgrades, since a lot of times 0 will have a legitimate meaning for a used field but all 1's usually won't. I thought I had changed that everywhere in the code, but there's a few places I obviously missed (like DoBulk).

The ones I just fixed were all of the packet requests (DoBulk, DoControl, etc.). In your code, you should be able to safely ignore any registers that claim to return -1 (unused) in the spec but actually return 0, though I would obviously like to know if you find any more of them so I can patch the code.

Dinosaur wrote:Edit: The callback has a code of 0x0014 for which there is no description in the doc.
Is there a more extensive list ?
The Flags are 0x06 and BX is the correct UserPktId
Edit: OK I see it , 04 for TimeOut Orred with 10 for Short Packet Detected.


FYI, the callback also returns the actual number of data bytes transferred in CX, so you can tell if the device didn't send any data at all or if it just didn't send as much as you asked it to send. For a Bulk or Control Transaction, if it receives a Short Packet error, USBUHCIL will automatically retry the transaction several times before finally giving up. You can override this behavior by setting the ShortPacketOK flag in the API request flags. If ShortPacketOK is set, the transaction will not be retried automatically if the ONLY error is a short packet and at least some data was transferred. This can be useful in situations where you don't actually know ahead of time how many bytes are supposed to be transferred (such situations are rare in USB, but they do occasionally happen).

Dinosaur wrote:Can I ask for a Descriptor from a device that is not owned by me.?


Yes you can. Although there's no way that USBUHCIL can strictly enforce it, you are not allowed to change anything "operational" about a Device or Interface you don't own. Downloading general descriptors is perfectly OK, though. You can, for example, download the general descriptors for the U-HID device (which includes information for all four interfaces), or download the HID report descriptor for the mouse interface, even though you don't own it.

I should also point at that the USB specs say a device must be able to do things like download descriptors at the same time it is actually be used (like the mouse), though some devices can't actually do it. I used to have a wireless mouse made by Hewlett Packard that would crash when you tried to do it, and it had lots of other problems as well, and I finally got rid of it. The reason I even had the mouse was that a friend gave it to me because it gave him problems in Windows.

Dinosaur wrote:Can I ask you to give me an example of a call to call the i/f. I am getting weird results using DoControl. I am sure the values I set are wrong.


Here is some sample code from USBSUPT1, used to download a String Descriptor from a Device as a foreground process. It has most of the structures and equates it uses for reference also.
Code: Select all
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;EQUATES
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;==============================================================================
;USB Related
;==============================================================================
  ;----------------------------------------------------------------------------
  ;General
  ;----------------------------------------------------------------------------
  Int14RequestSize EQU  64 ;Size of Int 14 USB Request Data Structure
  MaxStrSize       EQU 254 ;Maximum size of a String Descriptor

  ;----------------------------------------------------------------------------
  ;Descriptor Types
  ;Put in High Byte of SRValue for GetDescriptor & SetDescriptor Requests
  ;  (Descriptor Index in low byte)
  ;Returned in DescrType of Descriptor Structures
  ;----------------------------------------------------------------------------
  ;----------------------------------------------------------------------------
  ;USB Descriptor Types
  ;----------------------------------------------------------------------------
  DescrTypeDevice    EQU 01h ;Device
  DescrTypeConfig    EQU 02h ;Configuration
  DescrTypeString    EQU 03h ;String
  DescrTypeInterface EQU 04h ;Interface
  DescrTypeEndPoint  EQU 05h ;EndPoint

  ;Anything higher than 1Fh is Class/Interface/Device/Vendor-Specific,
  ;  which means it is not unique
  DescrTypeHID         EQU 21h ;Human Interface Device
  DescrTypeHIDReport   EQU 22h ;Report (from HID)
  DescrTypeHIDPhysical EQU 23h ;Physical Descriptor (from HID)
  DescrTypeIrDA        EQU 21h ;IrDA Bridge
  DescrTypeHub         EQU 29h ;Hub


;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;STRUCTURES
;±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
;==============================================================================
;USB Related
;==============================================================================
  ;----------------------------------------------------------------------------
  ;This is the format for a request sent to Int 14h to Send/Receive Data
  ;It contains the type of request, etc.
  ;----------------------------------------------------------------------------
  Int14RequestStruc         STRUC      ;Structure for an Int 14 Request
    I14RRequestType            DB   ?  ;Type of Request
      I14RRTHostClass         EQU  00h ;Host/System/OS Class
        I14RRTGetHostSWInfo   EQU  01h ;Get Host Software Info
        I14RRTGetHostHWInfo   EQU  02h ;Get Host Hardware Info
        I14RRTGetHostVendInfo EQU  03h ;Get Host Vendor Info
        I14RRTGetHostStatus   EQU  04h ;Get Current Host Status
        I14RRTHostRun         EQU  08h ;Start/Run/Resume Host
        I14RRTHostStop        EQU  09h ;Stop Host
        I14RRTHostReset       EQU  0Ah ;Reset Host
        I14RRTHostSuspend     EQU  0Bh ;Global Suspend Host
        I14RRTHostResume      EQU  0Ch ;Force Global Resume on Host
      I14RRTTimingClass       EQU  10h ;Frame Timing Class
        I14RRTRegTmgOwner     EQU  11h ;Register as Timing Owner
        I14RRTUnRegTmgOwner   EQU  12h ;UnRegister as Timing Owner
        I14RRTIncTiming       EQU  13h ;Increment (Slow Down) Frame Timing
        I14RRTDecTiming       EQU  14h ;Decrement (Speed Up) Frame Timing
        I14RRTChangeTiming    EQU  15h ;Change Frame Timing (by Large Amount)
      I14RRTHubClass          EQU  20h ;Hub Class
        I14RRTGetDvcHubInfo   EQU  21h ;Get Hub Info for Device
        I14RRTNewDvcConn      EQU  24h ;Hub has Detected new Device
        I14RRTDvcDisc         EQU  25h ;Device has been Disconnected
        I14RRTSendHubChar     EQU  27h ;Send Hub Characteristics to Host
        I14RRTEnableHubPort   EQU  28h ;Enable Device given Hub & Port
        I14RRTDisableHubPort  EQU  29h ;Disable Device given Hub & Port
        I14RRTResetHubPort    EQU  2Ah ;Reset Device given Hub & Port
        I14RRTSuspendHubPort  EQU  2Bh ;Suspend Device given Hub & Port
        I14RRTResumeHubPort   EQU  2Ch ;Resume Device given Hub & Port
        I14RRTPwrOnHubPort    EQU  2Dh ;Power On Device given Hub & Port
        I14RRTPwrOffHubPort   EQU  2Eh ;Power Off Device given Hub & Port
        I14RRTPwrResetHubPort EQU  2Fh ;Power Reset Device given Hub & Port
      I14RRTTPowerClass       EQU  30h ;Power Class
        I14RRTGetDvcPowerInfo EQU  31h ;Get Power Info for Device
        I14RRTGetHubPowerDraw EQU  32h ;Get Power Draw for Hub
        I14RRTPwrOnDevice     EQU  3Dh ;Power On Device given Dvc Addr
        I14RRTPwrOffDevice    EQU  3Eh ;Power Off Device given Dvc Addr
        I14RRTPwrResetDevice  EQU  3Fh ;Power Reset Device given Dvc Addr
      I14RRTDeviceClass       EQU  40h ;Device Class
        I14RRTGetDvcClassInfo EQU  41h ;Get Device Class Info
        I14RRTGetDvcVendInfo  EQU  42h ;Get Device Vendor Info
        I14RRTGetDvcStatus    EQU  43h ;Get Device Status
        I14RRTEnableDevice    EQU  48h ;Enable/Resume Device given Dvc Addr
        I14RRTDisableDevice   EQU  49h ;Disable Device given Dvc Addr
        I14RRTResetDevice     EQU  4Ah ;Reset Device given Dvc Addr
        I14RRTSuspendDevice   EQU  4Bh ;Suspend Device given Dvc Addr
        I14RRTResumeDevice    EQU  4Ch ;Resume Device given Dvc Addr
      I14RRTConfigClass       EQU  50h ;Configuration Class
        I14RRTConfigingIntf   EQU  51h ;Driver is Configuring an Interface
        I14RRTConfigIntfDone  EQU  52h ;Interface Configuration is Complete
        I14RRTSetNewConfig    EQU  58h ;Set/Change Device Config Value
      I14RRTInterfaceClass    EQU  60h ;Interface Class
        I14RRTFindRegIntf     EQU  62h ;Look for Registered Interface
        I14RRTFindUnRegIntf   EQU  63h ;Look for Unregistered Interface
        I14RRTRegIntfOwner    EQU  64h ;Register as Interface Owner
        I14RRTUnRegIntfOwner  EQU  65h ;Unregister as Interface Owner
        I14RRTIntfDontLook    EQU  68h ;Existing Interface Owner Don't Look
      I14RRTAltIntfClass      EQU  70h ;Alternate Interface Class
        I14RRTGetAltIntfInfo  EQU  71h ;Get Alternate Interface Info
      I14RRTEndPointClass     EQU  80h ;End Point Class
        I14RRTGetDataX        EQU  81h ;Get Current DataX Value
        I14RRTIncDataX        EQU  88h ;Increment/Toggle DataX Value
      I14RRTPacketClass       EQU  90h ;Packet Class
        I14RRTDoIsoch         EQU  94h ;Schedule Isochronous Transaction
        I14RRTDoInterruptPer  EQU  95h ;Schedule Periodic Interrupt
        I14RRTDoControl       EQU  96h ;Schedule Control/Setup Request
        I14RRTDoBulk          EQU  97h ;Schedule Bulk Transaction
        I14RRTDoInterrupt1T   EQU  98h ;Schedule One-Time Interrupt
        I14RRTCloseHandle     EQU  9Ch ;Close/Remove Scheduled Transaction
        I14RRTChangeIntPer    EQU  9Dh ;Change Periodicity of Interrupt
        I14RRTGetTransStatus  EQU  9Fh ;Get Status of Packet Transaction
      I14RRTMiscClass         EQU 0A0h ;Miscellaneous Class
        I14RRTLargeCallDone   EQU 0A1h ;Large (Complicated) Call Complete
        I14RRTBeepSpeaker     EQU 0AFh ;Beep the Speaker
      I14RRTInterHostClass    EQU 0E0h ;Inter-Host Communication Class
        I14RRTHostAdded       EQU 0E1h ;New Host Driver has been installed
        I14RRTHostDeleted     EQU 0E2h ;Host Driver is being removed from Mem
        I14RRTRegDvc0Host     EQU 0E3h ;Inform other Hosts of Device 0 Reg
        I14RRTUnRegDvc0Host   EQU 0E4h ;Inform other Hosts of Device 0 UnReg
        I14RRTCopyNDTable     EQU 0E5h ;Copy New Device Onership Table
      I14RRTInternalClass     EQU 0F0h ;Host Internal/Troubleshooting Class
        I14RRTHostDebug       EQU 0FDh ;Put Host Into Debug Mode
        I14RRTHostSingleStep  EQU 0FEh ;SingleStep the Host (Debug Mode)
    I14RFlags                  DB   ?  ;Bit-level flags
      I14RFlagIn              EQU  01h ;In Direction
      I14RFlagLowSpeed        EQU  02h ;Low-Speed Device
      I14RFlagHiSpeed         EQU  04h ;High-Speed Device
      I14RFlagNoRetries       EQU  10h ;No Auto Retries for Control
      I14RFlagShortPktOK      EQU  20h ;No Retries for Short Packets
      I14RFlagSpecificFrame   EQU  40h ;Use Specific Frame Number
      I14RFlagAddrIsPhys      EQU  80h ;Data Address is Physical
    I14RHostIndex              DB   ?  ;Host Index
    I14RDeviceAddress          DB   ?  ;USB Device Address
      I14RHubAddress          EQU (OFFSET I14RDeviceAddress)
    I14REndPoint               DB   ?  ;EndPoint or Port or Alt Interface
      I14RHubPort             EQU (OFFSET I14REndPoint)
      I14RAltInterface        EQU (OFFSET I14REndPoint)
    I14RConfigValue            DB   ?  ;Configuration Value
      I14RCloseID             EQU (OFFSET I14RConfigValue)
      I14RDataX               EQU (OFFSET I14RConfigValue)
    I14RInterfaceNum           DB   ?  ;Interface Number
    I14RSearchIndex            DB   ?  ;Search Index
    I14RVendorID               DW   ?  ;Vendor ID
    I14RProductID              DW   ?  ;Product ID
    I14RDvcClass               DB   ?  ;Device Class
    I14RDvcSubClass            DB   ?  ;Device SubClass
    I14RDvcProtocol            DB   ?  ;Device Protocol
    I14RIntfClass              DB   ?  ;Interface Class
    I14RIntfSubClass           DB   ?  ;Interface SubClass
    I14RIntfProtocol           DB   ?  ;Interface Protocol
    I14RRequestHandle          DW   ?  ;Request Handle Number
    I14RPeriodicity            DW   ?  ;Interrupt Periodicity/Duration
      I14RBeepFrequency       EQU (OFFSET I14RPeriodicity)
    I14RTimeout                DW   ?  ;Transaction Time Out Value
    I14RDataAddress            DD   ?  ;Data Address
    I14RDataSize               DW   ?  ;Size of Data (Bytes)
    I14RCallBackAddr           DD   ?  ;Call Back Address (CS:IP format)
      I14RLargeCallRtnCode    EQU (OFFSET I14RCallBackAddr)
    I14RUserPktID              DW   ?  ;User Packet ID
    I14RSetupReqData           DQ   ?  ;Setup Request Data (8 bytes)
    I14RFrameTiming            DW   ?  ;Frame Timing Value (def = 12000)
      I14RFrameIndex          EQU (OFFSET I14RFrameTiming)
                                       ;Starting Frame of Isoch Schedule
    I14RIsochSchedAddr         DD   ?  ;Address of Isoch Schedule
    I14RFiller  DB (Int14RequestSize-$) DUP (0)
   ENDS

  ;----------------------------------------------------------------------------
  ;Device Request is a structure containing data required by a USB Setup Packet
  ;----------------------------------------------------------------------------
  SetupRequest           STRUC     ;Structure for a Standard Setup Pkt
    SRRequestType           DB  ?  ;Request Type
      SRRTOut              EQU 00h ;0=Out (Host to Device)
      SRRTIn               EQU 80h ;1=In (Device to Host)
      SRRTTypeMask         EQU 60h ;Mask for Type
        SRRTTypeStandard   EQU 00h ;Type 0 = Standard
        SRRTTypeClass      EQU 20h ;Type 1 = Class
        SRRTTypeVendor     EQU 40h ;Type 2 = Vendor
                                   ;Type 3 = Reserved
      SRRTRecipientMask    EQU 1Fh ;Mask for Recipient Type
        SRRTRecipDevice    EQU 00h ;Recipient Type 0 = Device
        SRRTRecipInterface EQU 01h ;Recipient Type 1 = Interface
        SRRTRecipEndPoint  EQU 02h ;Recipient Type 2 = EndPoint
        SRRTRecipOther     EQU 03h ;Recipient Type 3 = Other
                                   ;Types 4-31 = Reserved
    SRRequest               DB  ?  ;Specific Request
      SRRQGetStatus        EQU  0  ;Request  0 = Get Status
      SRRQClearFeature     EQU  1  ;Request  1 = Clear Feature
      SRRQGetState         EQU  2  ;Request  2 = Get State
      SRRQSetFeature       EQU  3  ;Request  3 = Set Feature
                                   ;Request  4 = Reserved
      SRRQSetAddress       EQU  5  ;Request  5 = Set Address
      SRRQGetDescriptor    EQU  6  ;Request  6 = Get Descriptor
      SRRQSetDescriptor    EQU  7  ;Request  7 = Set Descriptor
      SRRQGetConfig        EQU  8  ;Request  8 = Get Configuration
      SRRQSetConfig        EQU  9  ;Request  9 = Set Configuration
      SRRQGetInterface     EQU 10  ;Request 10 = Get Interface
      SRRQSetInterface     EQU 11  ;Request 11 = Set Interface
      SRRQSynchFrame       EQU 12  ;Request 12 = Synch Frame
    SRValue                 DW  ?  ;Value depends on Request Type
    SRIndex                 DW  ?  ;Index depends on Request Type
      ;If EndPoint,  Bits 3:0 = EndPoint Number
      ;              Bit    7 = 1 if IN EndPoint, 0 if OUT EndPoint
      ;              All other bits are 0
      ;If Interface, Bits 7:0 = Interface Number (low byte)
      ;              All other bits are 0 (high byte)
    SRLength                DW  ?  ;Length of Data (if there is Data)
   ENDS
  SetupRequestSize EQU TYPE (SetupRequest)


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;DATA
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;==============================================================================
;USB Related
;==============================================================================
  ;------------------------------------------------------------------------------
  ;Data Structure needed to issue Requests to the USB Host
  ;------------------------------------------------------------------------------
  EVEN 2
  Int14Request:
    DB Int14RequestSize DUP (0)

  ;----------------------------------------------------------------------------
  ;Get String Descriptor
  ;----------------------------------------------------------------------------
  GetStringDescrReq:     DB SRRTIn+SRRTTypeStandard+SRRTRecipDevice
                         DB SRRQGetDescriptor
  GetStringIndex:        DB ?               ;String Index
                         DB DescrTypeString ;Type = String (High Byte of SRValue)
  GetStringLanguageID:   DW 0409h           ;Language ID = English
  GetStringDescrReqSize: DW MaxStrSize      ;Maximum Size

  I14RStringDescrSize EQU I14RSetupReqData.SRLength ;Word

  StringDescrData: DB (MaxStrSize+2) DUP (0) ;Data returned by String Descriptor
  GotStringDescr   DW -1                     ;Flag to monitor when it's done


;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;CODE
;ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
;------------------------------------------------------------------------------
;WRITE THE STRING ASSOCIATED WITH A STRING INDEX FROM A DESCRIPTOR
;Inputs:  AL = String Index
;         Int14Request contains Host Index and Device Address (-1 if invalid)
;         ES = Data area of calling program
;Outputs: Write String, in Quotes, to the Screen (if available)
;         If string is Unavailable, writes "None"
;Changes:
;------------------------------------------------------------------------------
DoGetString:
  PUSH AX,CX,DX,DI,SI,ES             ;Save used registers
  MOV  ES,DS                         ;Point ES at our data area
  CALL ClearStringDescr              ;Zero-out the String Descriptor
  MOV  DI,Int14Request               ;Point at Request
  MOV  SI,StringDescrData            ;Point at String Data
  OR   AL,AL                         ;Valid String Index?
  JZ  >S70                           ;If not, write "None"
  CMP  [DI].I14RHostIndex,-1         ;Valid Host Index?
  JE  >S75                           ;If not, write "Unavailable"
  CMP  [DI].I14RDeviceAddress,-1     ;Valid Host Index??
  JE  >S75                           ;If not, write "Unavailable"
  MOV  GetStringIndex[0],AL          ;Store String Index
  MOV  [DI].I14REndPoint,0           ;End Point 0
  MOV  CX,DS                         ;Put Our Segment in CX
  MOV  W [DI].I14RDataAddress[2],CX  ;Where to store
  MOV  W [DI].I14RDataAddress[0],SI  ;  the String Descriptor
  MOV  W [DI].I14RCallBackAddr[2],CX ;Store our
  MOV  W [DI].I14RCallBackAddr[0],GetStringFarCall
  MOV  W [DI].I14RUserPktID,0        ;User Packet ID
  MOV  [DI].I14RRequestType,I14RRTDoControl
  MOV  CX,GetStringDescrReq          ;Copy the
  CALL CopySetupReqToInt14DI         ;  Setup Request
  OR   [DI].I14RFlags,I14RFlagShortPktOK ;No Retries for Short Packets
  MOV  W [DI].I14RStringDescrSize,2  ;Get the first two bytes of string (size)
  CALL SendStringReq                 ;Send the Request
  JC  >S75                           ;If error, write "Unavailable"
  MOV  AX,[SI]                       ;Get the String Size
  CMP  AX,MaxStrSize                 ;Will it fit in our buffer?
  JBE >S20                           ;If so, continue
  MOV  AX,MaxStrSize                 ;If not, just fill our buffer
S20:                                 ;Size is handled
  MOV  W [DI].I14RStringDescrSize,AX ;Store the Size
  CALL SendStringReq                 ;Send the Request
  JC  >S75                           ;If error, write "Unavailable"
  CALL WriteDoubleQuote              ;Write a Quote
  INC  SI,2                          ;Point DS:[SI] at the String (not Size)
  CALL WriteUniCodeString            ;Write it
  CALL WriteDoubleQuote              ;Write a Quote
  JMP >S90                           ;Done
S70:                                 ;No String to Write
  MOV  DX,NoneMsg                    ;Write the No String Message
  JMP >S78                           ;Done
S75:                                 ;String not available
  MOV  DX,UnAvailMsg                 ;Point at "Unavailable" message
S78:                                 ;DX pointed at correct Message
  CALL WriteItDX                     ;Write the message
S90:                                 ;Done
  AND  [DI].I14RFlags,(NOT I14RFlagShortPktOK) ;Retry for Short Packets again
  POP  ES,SI,DI,DX,CX,AX             ;Restore used registers
  RET

;------------------------------------------------------------------------------
;ZERO OUT THE STRING DESCRIPTOR DATA AREA
;Inputs:  CS = Local Data Area
;         CLD already issued
;Outputs: Sets StringDescrData to all zeroes
;Changes:
;------------------------------------------------------------------------------
ClearStringDescr:
  PUSH AX,CX,DI,ES        ;Save used registers
  XOR  AX,AX              ;Write Zeroes
  MOV  CX,(MaxStrSize/2)  ;Number of Words to Write
  MOV  ES,CS              ;Point ES:[DI] at
  MOV  DI,StringDescrData ;  the string
  REP  STOSW              ;Write the data
  POP  ES,DI,CX,AX        ;Restore used registers
  RET

;------------------------------------------------------------------------------
;SEND A REQUEST TO DOWNLOAD A STRING DESCRIPTOR
;Inputs:  [DI] = Int 14 Request (filled in)
;         [SI] = String pointer
;Outputs: CF = Clear if OK (string downloaded OK)
;            = Set if Error
;Changes:
;------------------------------------------------------------------------------
SendStringReq:
  PUSH AX                   ;Save used registers
  MOV  GotStringDescr,-1    ;Mark flag
  MOV  W [SI],0             ;Mark string as invalid
  CALL DoInt14CallSaveAllDI ;Do it
  JC  >Q70                  ;If error, quit
Q20:                        ;Loop to here to wait for request
  MOV  AX,GotStringDescr    ;Put Error Code in AX
  CMP  AX,-1                ;Got the string yet?
  JE   Q20                  ;If not, keep waiting
  OR   AX,AX                ;Any errors?
  JZ  >Q30                  ;If not, continue
  CMP  AX,TDStsShortPacket  ;If so, is it just a Short Packet?
  JNE >Q70                  ;If not, Error
Q30:                        ;No Packet Errors
  CMP  W [SI],4             ;Is it a valid string size?
  JAE >Q80                  ;If so, it's OK
Q70:                        ;Error
  STC                       ;Set error flag
  JMP >Q90                  ;Done
Q80:                        ;OK
  CLC                       ;Set OK flag
Q90:                        ;Done
  POP  AX                   ;Restore used registers
  RET

GetStringFarCall:
  MOV  GotStringDescr,AX ;Mark as done
  RETF

;------------------------------------------------------------------------------
;COPY A REQUEST (CONTROL) STRUCTURE INTO THE INT14 STRUCTURE
;Inputs:  [CX] = Request Structure to Copy
;         DS = ES = Data Area
;         [DI] = Int14 Request Structure to copy it to
;Outputs:
;Changes: Int14 Structure contains Request Structure Data
;------------------------------------------------------------------------------
CopySetupReqToInt14DI:
  PUSH CX,DI,SI                   ;Save used registers
  ADD  DI,OFFSET I14RSetupReqData ;Point at correct part of structure
  MOV  SI,CX                      ;Point at structure to copy
  MOV  CX,(SetupRequestSize/2)    ;Number of words to copy
  REP  MOVSW                      ;Copy it
  POP  SI,DI,CX                   ;Restore used registers
  RET

;------------------------------------------------------------------------------
;ISSUE AN INT 14 CALL TO THE USB HOST
;Inputs:  DS:[DX] = Int 14 Request (filled with appropriate data)
;      OR DS:[DI]
;Outputs: CF = Set if error (host stalled, etc.)
;            = Clear if OK
;Changes: Sends the appropriate info to the USB Host via Int 14 call
;------------------------------------------------------------------------------
DoInt14CallSaveAllDI:       ;Save all changed registers, [DI] = Int14 Structure
  PUSH DX                   ;Save used registers
  MOV  DX,DI                ;Point DX at the Data Offset
  CALL DoInt14CallSaveAllDX ;Do it
  POP  DX                   ;Restore used registers
  RET

DoInt14CallSaveAllDX: ;Save all changed registers, [DX] = Int14 Structure
  PUSH AX,BX,CX,DX    ;Save registers that Int14 changes!
  CALL DoInt14Call    ;Do it
  POP  DX,CX,BX,AX    ;Restore used registers
  RET

;Int 14 returns various values in AX, BX, CX, & DX
DoInt14Call:
  STI           ;Enable Interrupts
  MOV  AX,5001h ;Set Function
  MOV  BX,'US'  ;Set
  MOV  CX,'B!'  ;  Registers
  STC           ;Preset Error Flag
  INT  14h      ;Do it
  RET
Bret
 
Posts: 478
Joined: Fri Oct 10, 2008 3:43 am
Location: Rio Rancho, NM

Re: Programming Questions

Postby Dinosaur » Sun Sep 20, 2009 9:54 am

Thanks Bret, have to go bush this week, so will have another go next weekend.
Dinosaur
 
Posts: 70
Joined: Wed Jul 01, 2009 5:54 pm
Location: Salt Lake City USA

Re: Programming Questions

Postby Dinosaur » Sun Sep 27, 2009 5:02 pm

Hi Bret

Finally had a chance to get back to it.
One of the issues is to identify the error by using the codes you provided in the doc's.
However, there are Status Codes , Error Codes and Notification Codes.
They all arrive in AX.

I have written three different error handlers, but which one to call is getting tricky.
Correct me if I got this wrong.

Notification Codes can come anytime (if someone messes with the device) ,or after you try to
Register as Interface or Frame timing owner.
-----------------------------------------------------
Status Code comes after you (try)
Schedule iso Transaction
Periodic Int Transaction
Control Transaction
Bulk Transaction
----------------------------------------------------
Error Codes come when the carry Flag is set as a result of an Int14h.

Regards
Dinosaur
 
Posts: 70
Joined: Wed Jul 01, 2009 5:54 pm
Location: Salt Lake City USA

Re: Programming Questions

Postby Bret » Sun Sep 27, 2009 11:41 pm

Thats's essentially it.

Error codes are returned immediately for an INT 14h Request. They are mostly a response to error checking the validity of the numbers in the fields of the 64-byte request structure.

Notification Codes are sent to Owners after they have registered: Device 0 Owners, Interface Owners, and Timing Owners. Notification codes come at random times, and are usually the result of the user "messing" with the device (unplugging, resetting, disabling, etc.).

Transaction Status codes occur at the end of a transaction declared as Schedule or Large in the API specification. Those are processes that either sometimes or always involve bus transactions (actually sending USB packets across the bus to a remote Device). Those processes are scheduled to happen in the background, so you don't need to sit around and wait for them to complete if you don't want to. When the initial INT 14h Request returns (assuming the returned Error code is 0), the Transaction has been scheduled, but may not be completed for several seconds. The Status code is returned when the process is complete, and essentially indicates how the device responded to the packets that were sent to it. If you want to process the transaction as a foreground process instead of a background process, you just have to wait in a loop (with interrupts enabled!) for the Transaction Status code to be returned.

I should also point out that Schedule and Large transactions don't ALWAYS involve sending packets across the bus to a remote device, so they don't always take time to complete. Whether packets actually get sent or not depends on exactly which devices are involved, the specific type of transaction, and the current state of the bus or certain devices on the bus. The reason that this is critical is because sometimes the Status code can actually be returned BEFORE the Error code, if the host driver determines that it doesn't actually need to send packets across the bus to do what you asked it to do. This means that you should initialize the Status code monitoring process BEFORE you issue the INT 14h request, or you can end up in an endless loop waiting for a process that has already completed.

Bret
Bret
 
Posts: 478
Joined: Fri Oct 10, 2008 3:43 am
Location: Rio Rancho, NM

Re: Programming Questions

Postby Dinosaur » Mon Sep 28, 2009 1:50 pm

Hi All

Still having difficulties getting a response from the U-HID board.
The following is what I have done upto Step 15 which does the .DoControl
If any of these steps get an Error, the whole program will abort with a message.

1. Do Installation Check
2. Allocate 64 Byte Struc in RM for Int14
3. Allocate 2nd 64 Byte Data area & Calculate Physical Addr.
4. Allocate a 0x32h Struc for dpmi registers to use.
5. Create CallBack address & save in irs.CallBackAddr
Note: I dont do anything in the CallBack. The registers saved by dpmi
are used to analyze the event.
6. Make a call to uhcil to get Host Detail.
7. Fill in irs.DvcVendID = &HD209 & irs.DvcProdID = &H1502,
and make call to get Device Detail.
8. Register as Interface owner.
9. Confirm our new ownership by .FindRegIntf
10. Now the call where I still get a Short packet error.
I am looking for 4 Bytes.
.StepNbr = 15
Clear_CallBack() ' pre-loaded the 64 bytes with 0xff
irs.RequestType = .DoControl
'irs.HostIndex = already set
'irs.DeviceAddress = already set
'irs.CallBackAddr = already set
irs.EndPoint = 0
irs.DataSize = 4
irs.TimeOut = 50
irs.UserPktID = 746 ' = 0x02EA
'irs.SetupReqData= broken up into
irs.ReqType = &H81 'byte
irs.Request = 0 'byte
irs.Value = 0 'dw
irs.Index = .DvcIntfNum 'dw
irs.Length = 4 'dw
irs.Flags = &H80 Or &H20 ' Read , Short Pkt OK
rval = Calluhci
Immediatly after this call the return registers are:
ax:0 ,bx:ff ,cx:4 ,dx:0xcb
After this call I monitor the dpmi register Struc eax for non-zero.
When it happens, I select the message based upon the Notification code.
These are correct, as unplugging the device causes a response that nominates
"Registered Device Disconnected"
The first callback I get Short Pkt error,but if I change the length to 2 bytes
instead of 4, there is no error.
Looking at the 64 byte Data area, the first 2 bytes are set to zero (regardless of length),
which is correct according to Andy, but the next two bytes should have the inputs.

Did I set the .DoControl up correctly ?

Will ask Andy to have a look at this thread.

Regards
Dinosaur
 
Posts: 70
Joined: Wed Jul 01, 2009 5:54 pm
Location: Salt Lake City USA

Re: Programming Questions

Postby Bret » Mon Sep 28, 2009 11:20 pm

Everything looks basically OK, just a couple of pointers. Because this is a control transaction:
You don't need to set irs.DataSize. The Control packet is always exactly 8 bytes (irs.SetupReqData), and the size of the data stage size in irs.Length.
You didn't show that you set irs.DataAddress, but you obviously did because you are seeing two data bytes (zeroes) being returned.
You don't need to set &80h (IN/Read) In irs.Flags. The control packet itself doesn't have a direction, and the direction of the data stage is embedded in irs.ReqType.

Note that these pointers are true only because it's a Control transaction. For Bulk, Isoch, & Interrupt transactions, you need to appropriately fill in irs.DataSize & the high bit of irs.Flags.

Regarding the actual Control Packet:

Dinosaur wrote:'irs.SetupReqData= broken up into
irs.ReqType = &H81 'byte
irs.Request = 0 'byte
irs.Value = 0 'dw
irs.Index = .DvcIntfNum 'dw
irs.Length = 4 'dw


With:

irs.ReqType = &81 = IN, Standard, Interface
irs.Request = 0 = Get Status

This is a generic USB "Get Interface Status" request, which all USB Devices are required to support. It always returns exactly two byte and the two bytes are always zero (even though "Get Interface Status" is a standard and required USB control request, it never provides any useful information). This is actually good news, since it means that everything is working exactly like it should, including your physical memory address.

You just need to find out from Andy exactly what values need to go in the 8 bytes of the control packet to get the data you're looking for. If the device is even remotely following the USB specs, irs.ReqType won't be Standard, it will be Vendor Specific (bit &40 should be set, so irs.ReqType probably needs to be &C1 instead of &81), and irs.Length definitely needs to be 4. Because it is a vendor-specific request, what needs to be in irs.Request, irs.Value, and irs.Index is up to the Vendor. However, again assuming the USB standards are being followed, if bit 0 (&01) of irs.ReqType is set, indicating that the recipient is an Interface, the low byte of irs.Index must be the Interface number, just as you have it set. What needs to be in the high byte of irs.Index is up to the Vendor (but will probably be 0), and irs.Value is normally 0 when the data direction is IN/Read, but again that's up to the Vendor.
Bret
 
Posts: 478
Joined: Fri Oct 10, 2008 3:43 am
Location: Rio Rancho, NM

Re: Programming Questions

Postby Bret » Tue Sep 29, 2009 10:59 pm

Dinosaur:

I was just thinking of a way to test your code and memory addresses while you are waiting for U-HID to provide information on the correct control request format. You can download the Device Descriptor with the following Control Request:

irs.ReqType = &H80 'byte, Direction = IN/Read, Type = Standard, Recipient = Device
irs.Request = 6 'byte, Get Descriptor
irs.Value = &0100 'word, Low Byte = 0, High Byte = Descriptor Type = Device
irs.Index = 0 'word, unused
irs.Length = &12 'word, length of data
Bret
 
Posts: 478
Joined: Fri Oct 10, 2008 3:43 am
Location: Rio Rancho, NM

Re: Programming Questions

Postby Dinosaur » Thu Oct 01, 2009 9:09 pm

Hi Bret

Was away when your message came through.
I have tested and the following is the result (Byte 18 on the left)
151100522980002012
Will look up in the docs to see what this means.

So unless this is gibberish, I can conclude that Both CallBack Address & Data Address are working fine.

I have concluded that I will change direction away from the U-HID boards as far as general I/O is concerned.
Will keep using them for the Joystick Interface.
Will have to source a board that is specifically designed for I/O and Industrial a2d , and buy one to test.
If you have any links, would appreciate them.

Will test more this weekend, and try to put the basic package together.

Regards
Dinosaur
 
Posts: 70
Joined: Wed Jul 01, 2009 5:54 pm
Location: Salt Lake City USA

Re: Programming Questions

Postby Bret » Thu Oct 01, 2009 11:11 pm

You've only sent 9 bytes of information rather than 18. Anyway, here is the format of the Device Descriptor and what each of the bytes/words means. This specific example is from one of the previous posts for your Nano.

Code: Select all
        DEVICE DESCRIPTOR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 12h  18
Descr Type:                   01h  Device
USB Release:                0200h  2.00
Device Class:                 00h  Look at Interface
Device SubClass:              00h  None
Device Protocol:              00h  None
Max Packet Size EP0:          08h  8
Vendor ID:                  D209h  Ultimarc?               
Product ID:                 1501h  5,377
Device Release:             0019h  0.19
Manufacturer String:          01h
Product String:               01h
Serial # String:              05h
# of Configs:                 01h  1
Bret
 
Posts: 478
Joined: Fri Oct 10, 2008 3:43 am
Location: Rio Rancho, NM

Re: Programming Questions

Postby Bret » Thu Oct 01, 2009 11:54 pm

I was just looking at some old information from the Nano (at least I think it's for the Nano rather than the full U-HID) again, stuff that you sent previously when we were messing with the mouse/joystick stuff. Here is the first section of the main descriptors: Device and Configuration, along with the Interface, HID, and End Point Descriptors for the first Interface (the I/O, as opposed to the Joystick, Keyboard, and Mouse):

Code: Select all
        DEVICE DESCRIPTOR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 12h  18
Descr Type:                   01h  Device
USB Release:                0200h  2.00
Device Class:                 00h  Look at Interface
Device SubClass:              00h  None
Device Protocol:              00h  None
Max Packet Size EP0:          08h  8
Vendor ID:                  D209h  No Matching Record Found               
Product ID:                 1501h  5,377
Device Release:             0019h  0.19
Manufacturer String:          01h  "Universal Herface Device"
Product String:               01h  "Univers Interface Device"
Serial # String:              05h  "9"
# of Configs:                 01h  1

    CONFIGURATION DESCRIPTOR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 09h  9
Descr Type:                   02h  Configuration
Descr Total Length:         006Dh  109
# of Interfaces:              04h  4
Configuration Value:          01h  1
Configuration String:         01h  "Universal Human Interfaee D"
Attributes:                   80h  Valid Historical Attribute 80h
                                   Bus Powered
                                   No Remote Wakeup
                                   Not Battery Powered
Current Draw / 2:             FAh  250 (500 mA)

      INTERFACE DESCRIPTOR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 09h  9
Descr Type:                   04h  Interface
Interface Number:             00h  0
Alternate Setting:            00h  0
# of End Points:              01h  1
Interface Class:              03h  HID (Human Interface Device)
Interface SubClass:           00h  None
Interface Protocol:           00h  None
Interface String:             01h  "Universal Human Interface Device"

  HUMAN INTERFACE DEVICE DESCR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 09h  9
Descr Type:                   21h  HID (Human Interface Device)
HID Class Release:          0111h  1.11
Country Code:                 00h  None/Not Applicable
# of Classes:                 01h  1
Class Descr Type 1:           22h  Report
Class Descr Size 1:         0021h  33

      END POINT DESCRIPTOR
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Descr Length:                 07h  7
Descr Type:                   05h  EndPoint
End Point Number:             81h  EndPoint = 1  Direction = In
Attributes:                   03h  Interrupt NonSynchronous Data
Max Packet Size:            0008h  8
Max Poll Interval:            0Ah  10


And here is the HID Report Descriptor that was downloaded for the Interface:

Code: Select all
              USB HID (HUMAN INTERFACE DEVICE) REPORT DESCRIPTOR               
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
05 01          Usage Page:       Generic Desktop
09 00          Usage:            None/Unknown/Not Applicable
A1 01          Collection:       Application

05 09            Usage Page:       Buttons
19 01            Usage Min:        Button #1 (Primary)
29 20            Usage Max:        0020h
15 00            Logical Min:      00h  0  0
25 01            Logical Max:      01h  1  +1
95 20            Report Count:     32
75 01            Report Size:      1
81 02            INPUT:            Data  Variable  Absolute
                                   No_Wrap  Linear  Preferred_State
                                   No_Null_State  Non_Volatile  Bit_Field

05 08            Usage Page:       LEDs (Light Emitting Diodes)
09 4B            Usage:            Generic Indicator
95 20            Report Count:     32
75 01            Report Size:      1
91 20            OUTPUT:           Data  Array  Absolute
                                   No_Wrap  Linear  No_Preferred_State
                                   No_Null_State  Non_Volatile  Bit_Field

C0               End Collection


Cryptic, I know, but here's what it means. The HID Report Descriptor indicates that the Nano can have up to 32 inputs (it calls them buttons) and 32 outputs (it calls them LEDs). The Interface Descriptor has only one End Point Descriptor underneath it, End Point #1 with Direction = In and maximum polling interval of 10 (that's 10 milliseconds). This means that in order to read the inputs (the "buttons"), you don't issue a Control Request to End Point 0 as you have been doing, but instead you must issue a Bulk or Periodic Interrupt Request to End Point 1. It also means that in order for it to work "properly", you should set up a Periodic Interrupt to read it every 10 milliseconds. For testing purposes, though, you can just issue a DoBulk request, which in this case would act sort of like a "one-time periodic interrupt".

This also means that the device is not configured correctly (according to the HID specs), since it provides no way to control the LEDs. In addition to the In End Point, there should also be an Out End Point (it could also be End Point #1, but it would have to be declared with a separate End Point Descriptor and specifically declared with Direction = Out). It's possible that you control the LED outputs with a Control Request, though based on the Descriptors that the Device is providing you would never know that.
Bret
 
Posts: 478
Joined: Fri Oct 10, 2008 3:43 am
Location: Rio Rancho, NM

Re: Programming Questions

Postby Dinosaur » Fri Oct 02, 2009 11:04 am

Hi Bret

The bytes returned are 18 bytes.
My Struc is 64 bytes and I print the whole struc (pre-filled with &HF).
I thought that perhaps I printed it to Quick, but even after a pause, that is what I get.
...FFFF151100522980002012
Code: Select all
    irs.RequestType  = .DoControl
    irs.ReqType = &H80                          'byte, Direction = IN/Read, Type = Standard, Recipient = Device
    irs.Request = 6                             'byte, Get Descriptor
    irs.Value   = &H0100                        'word, Low Byte = 0, High Byte = Descriptor Type = Device
    irs.Index   = 0                             'word, unused
    irs.Length  = &H12                          'word, length of data   
    irs.UserPktID    = 746
    irs.Flags        = &H80 Or &H20             '' Read , Short Pkt OK
    rval = Calluhci

Edit: My mistake. Printed each value as a single char, meaning that whatever the second char was, it got left off.
12=Descr length
01=It is a device
00=
20=USB Release 0200
00=Class
00=SubClass
00=Protocol
08=Max Pkt size
09
D2=Vendor ID D209
02
15=Product ID 1502 (latest boards)
20
00=Device Release 0020
01=Manufacturing String
01=Product String
05=Serial # String
01=# of Configs
That looks correct.
Dinosaur
 
Posts: 70
Joined: Wed Jul 01, 2009 5:54 pm
Location: Salt Lake City USA

Next

Return to Programs

Who is online

Users browsing this forum: No registered users and 1 guest

cron