PDA

View Full Version : USB HID Stack



i2tzk
17th October 2012, 17:41
Hi guys
i'm trying to use the new USB stack starting from the examples in
C:\Users\Tony\PDS\Samples\New Samples\Proton_USB_HID_Stack
i've disabled the Timer1 usage, commenting the following sentence in HID_Descriptor.inc

'$define USB_SERVICE ' Use the Timer1 low priority interrupt for enumeration and bus servicing

now when running in Isis environment the pgm:

Main: If USB_tAttached = False Then mUSBService() end if GoTo Main

the device comes attached but flag "USB_tAttached" is never changed to True.

Anybody can give me a suggestion how to detect when the usb is attached without
to enable the interrupt Timer1 ?

Thanks

Les
17th October 2012, 18:35
Without the timer, you will need to constantly poll the USB using USB_Service(). Without this happening the flag will never be set and the USB will never enumerate.

Once enumeration has occurred, you will still need to poll the USB in order to keep it alive. That's what the interrupt does. Why did you disable the interrupt?

i2tzk
17th October 2012, 19:05
Hi Les
thanks for answer, in my project Timer1 is used as asynchronous counter to count pulses at pin RC0 (18F4550) this is the reason i cannot use it for auto polling. Of course this way i need to frequently USBpoll in my main loop as you said.

This instruction block is properly working (user manual):

Repeat ' \|
USBPoll ' | Wait for the USB interface to become attached
Until USB_tConnected = 1 Or USB_tConfigured = 1 ' /

but when i try to use the USB Stack (include files from C:\Users\Tony\PDS\Samples\New Samples\Proton_USB_HID_Stack ) i'm not able to test when the device is attached because the same loop:

Repeat
mUSBService()
Until USB_tAttached = 1

seems do not initialize the flag "USB_tAttached".
For sure i've missed someting, but i don't how how to investigate.
Thanks, Tony

ElektroArt
18th October 2012, 14:28
I have tried latest Proton USB stack. Latest Microchip USB Hid stack with c18 already tested.

I think, there are something wrong with this stack! Mouse example may not have this problem.

Try Hid custom device. Device serial number etc missing. windows hid app. cannot read serial number string.
Sometimes "this device may work faster with usb 2.0 port". baloon message appears

So I have returned again(5th times) proton version 3.5.4.5 . Usbout, usbpoll etc used. Now HID custom device works fine as expected!

ElektroArt
21st October 2012, 20:07
2-3 days later. ..

Now Proton v3.5.5.3 HID stack looks normal. Without the timer, Custom hid device works as expected. but modification needed. Serial number, orther strings, no problem

custom device demo
..Samples\New Samples\Proton_USB_HID_Stack\demo.bas:



include "HID_Descriptor.inc" ' Load the USB routines and descriptor into the program
..
for i= 0 to 63
TXReport[i] ="A"
next
while 1 = 1

HID_WriteReport() ; send array

for i = 1 to 100 ; 100 ms delay
mUSBService()
delayus 1000
next

wend



HID_Descriptor.inc



' USB Generic HID descriptor module
'
' Do not change the order of the commands and directives
'
' Place any $defines here. i.e. before the loading of USB_MemAlloc.inc
' See USB_Defs.inc for the defines used
'
...

;$define USB_SERVICE ' Use the Timer1 low priority interrupt for enumeration and bus servicing
$define USB_USE_HID ' Indicate we require to use a HID interface
;$define USB_CONNECT_LED PORTC.3 ' This pin goes high when the USB is in a connected state
$define USB_SELF_POWER ' Indicate that the PICmicro is self powered. i.e. Not powered by the bus
$define HID_EP_OUT_POLLING_MS 1 ' HID - EP01 - 1ms (EP01Out)
$define HID_EP_IN_POLLING_MS 1 ' HID - EP01 - 1ms (EP01In)
'
'---------------------------------------------------------------------------------------------------------
'
include "USB_MemAlloc.inc" ' ** Load the USB Stack and Dual Port RAM variable definitions **
'
'---------------------------------------------------------------------------------------------------------
'
goto OverDescriptorTables ' Jump over the descriptor tables
'
'---------------------------------------------------------------------------------------------------------
'
$define HID_RPT01_SIZE 47 ' Size of "hid_rpt01" table
'
' This section may be modified to suit your requirements
' Do not change any of the label names, or the format of the tables
'
device_dsc:
cdata SizeOf_Table,_ ' Size of this descriptor (in bytes)
USB_DESCRIPTOR_DEVICE,_ ' device descriptor type
$10, $01,_ ' USB Spec Release Number in BCD format (low byte, high byte)
$00,_ ' Class Code
$00,_ ' Subclass code
$00,_ ' Protocol code
USB_EP0_BUFF_SIZE,_ ' Max packet size For EP0
USB_VID & $FF, USB_VID >> 8,_ ' Vendor ID (low byte, byte byte)
USB_PID & $FF, USB_PID >> 8,_ ' Product ID (low byte, high byte)
USB_DEVICE_VERSION & $FF,_ ' Device release number in BCD format (low byte)
USB_DEVICE_VERSION >> 8,_ ' Device release number in BCD format (high byte)
USB_MANUFACTURER_INDEX,_ ' Manufacturer String index
USB_PRODUCT_INDEX,_ ' Product String index
3,_ ' Device serial number String index
$01 ' Number of possible configurations
...

sd003:
cdata byte SizeOf_Table,_ ' Size of this descriptor (in bytes)
byte USB_DESCRIPTOR_STRING,_ ' Descriptor Type
word "1234567" ' Serial string - unicode format
'
...

USB_SD_Pointer:
cdata sd000, sd001, sd002, sd003 ' Create a pointer to the descriptor's sd tables(with serial)

OverDescriptorTables:
include "USB_System.inc" ' ** Load the USB routines into the program **

$ifdef USB_USE_HID
include "USB_UserHID.inc" ' ** Load the User HID routines into the program (if a HID interface is being used)
$endif

i2tzk
22nd October 2012, 16:27
Hi ElektroArt,
I've reverted to v3.5.4.5 because I'm not able to get HID USB stack working as i need.
Probably i'm not enough skilled to obtain:

1. I want to run without timer, this is obtained commenting the row:
;$define USB_SERVICE

2. how should i modify the example "USB HID Keyboard Demo.bas" to get it working ??
it seems to me that the flag "USB_tAttached" wont be never True (timer is disabled) so no HID_Report_In ...etc etc

Main:
Key = 32
Clear HID_Report_In
While 1 = 1


If USB_tAttached = True Then


HID_Report_In[2] = Key
HID_TxReport(HID_Report_In,8)
DelayMS 200
Inc Key
If Key > "Z" Then Key = " "


EndIf

Wend



3. How to know if a new Key has been received? USBIn was able to jump if buffer empty.
I dont want to use a temporary variable to store the current value and test if the new received buffer is equal to the old.
Should i test "If HID_Report_In[0] = 0 then ..." or something like this ??

4. Why the "DelayMs 200" ??? no way to loop testing when Tx has been succesflully completed ??

Any help ??

ElektroArt
22nd October 2012, 16:58
I don't know usb keyboard device how is work.
if you don't use USB_SERVICE , you have to change delayms 200 like this



Key = 32
Clear HID_Report_In
While 1 = 1

repeat
mUSBService()
until USB_tAttached = true

If USB_tAttached = True Then
HID_Report_In[2] = Key
HID_TxReport(HID_Report_In,8)
for i = 1 to 200 ; 200 ms delay
mUSBService()
delayus 1000
next

Inc Key
If Key > "Z" Then Key = " "
EndIf
Wend

i2tzk
22nd October 2012, 17:03
thanks, are u sure that the loop:


repeat
mUSBService()

until USB_tAttached = true

is working ??
my last test was showing that "mUSBService()" never update the flag "USB_tAttached"
may be something's wrong with my installation, could you confirm that is working ?

ElektroArt
22nd October 2012, 17:21
I'M not sure. USB_tAttached ignored my code. but you use this


for i = 1 to 200 ; 200 ms delay
mUSBService()
delayus 1000
next



after 200ms mUSBService bombing, your device becomes attached. ignore USB_tAttached flag.

i2tzk
22nd October 2012, 17:32
not true this is correct.
What about if windows needs to install new driver ?
It could take an unknow time, much more than 200mS to get the device attached...
Why i should ignore the flag ??
I cannot use a Stack not fully working, unless .......... i'm wrong and the flag to be used has a different name.

ElektroArt
22nd October 2012, 19:44
oK. A FEW minutes ago. this demo tested with real hardware!. and works!. Proton 3.5.5.3 used !

USB HID Keyboard Demo.bas

'
' Demonstrate a USB HID Keyboard interface using the Proton BASIC language
'
' The demonstration is configured to use a 12MHz crystal
' This can be changed by altering the fuse setting located in the USB_Defs.inc file
'
device = 18f13k50
'Device = 18F4550
' device = 18F26J50

declare xtal = 48
declare optimiser_level = 3 ' Maximum optimisation
declare dead_code_remove = on ' Squeeze the code further
'
'--------------------------------------------------------------------------
include "Keyboard_Descriptor.inc" ' Load the USB routines and descriptor into the program
'--------------------------------------------------------------------------
'
dim Key as byte
dim i as byte

'--------------------------------------------------------------------------
' The main program loop starts here
Main:
Key = 32
clear HID_Report_In
while 1 = 1

for i = 1 to 200 ; 200 ms delay
mUSBService()
delayus 1000
next

if USB_tAttached = True then
HID_Report_In[2] = Key
HID_TxReport(HID_Report_In,8)
delayms 200
inc Key
if Key > "Z" then Key = " "
endif
wend



My modified Keyboard_Descriptor.inc :

'
' USB HID Keyboard descriptor
'
' Do not change the order of the commands and directives
'
' Place any $defines here. i.e. before the loading of USB_MemAlloc.inc
' See USB_Defs.inc for the defines used
'
$define USB_VID $04D8 ' User VID value
$define USB_PID $0055 ' User PID value
$define HID_BUFFER_SIZE 64 ' USB Buffer Size.
$define USB_BUS_POWER 50 ' Bus power (50 to 250 milliAmps) x2
$define USB_DEVICE_VERSION $0001 ' Device release number in BCD format

;$define USB_SERVICE ' Use the Timer1 low priority interrupt for enumeration and bus servicing
$define USB_USE_HID ' Indicate we want to use a HID interface
;$define USB_CONNECT_LED PORTC.3 ' This pin goes high when the USB is in a connected state
$define USB_SELF_POWER ' Indicate that the PICmicro is self powered. i.e. Not powered by the bus
$define HID_EP_OUT_POLLING_MS 1 ' HID - EP01 - 1ms (EP01Out)
$define HID_EP_IN_POLLING_MS 1 ' HID - EP01 - 1ms (EP01In)

$define HID_INTF_ID $00
$define HID_EP 1 ' Endpoint number
$define HID_INT_OUT_EP_SIZE 8
$define HID_INT_IN_EP_SIZE 8
$define HID_NUM_OF_DSC 1 ' Number of descriptors

$define HID_RPT01_SIZE 63 ' Size of "hid_rpt01" table (in bytes)
'
'---------------------------------------------------------------------------------------------------------
'
include "USB_MemAlloc.inc" ' ** Load the USB Stack and Dual Port RAM variable definitions **
'
'---------------------------------------------------------------------------------------------------------
'
goto OverDescriptorTables ' Jump over the descriptor tables
'
'---------------------------------------------------------------------------------------------------------
'
' This section may be modified to suit your requirements
' Do not change any of the label names, or the format of the tables
'
device_dsc:
cdata $12,_ ' Size of this descriptor IN bytes
USB_DESCRIPTOR_DEVICE,_ ' Device descriptor type
$10, $01,_ ' USB Spec Release Number in BCD format (low byte, high byte)
$00,_ ' Class Code
$00,_ ' Subclass code
$00,_ ' Protocol code
USB_EP0_BUFF_SIZE,_ ' Max packet size For EP0
USB_VID & $FF, USB_VID >> 8,_ ' Vendor ID (low byte, byte byte)
USB_PID & $FF, USB_PID >> 8,_ ' Product ID (low byte, high byte)
$00, $01,_ ' Device release number in BCD format (low byte, high byte)
$01,_ ' Manufacturer String index
$02,_ ' Product String index
$00,_ ' Device serial number String index
$01 ' Number of possible configurations
'
' Configuration Descriptor
'
configDescriptor1:
cdata $09,_ ' Size of this section of the descriptor (in bytes)
USB_DESCRIPTOR_CONFIGURATION,_ ' Configuration descriptor type
SizeOf_Table, $00,_ ' Size Of "configDescriptor1" table - Total length of data (low byte, high byte)
$01,_ ' Number of interfaces in this configuration
$01,_ ' Index value of this configuration
$00,_ ' Configuration string index
_DEFAULT | _SELF,_ ' Attributes, see USB_defs.inc
USB_BUS_POWER,_ ' Max power consumption (2X mA)
'
' Interface descriptor
'
$09,_ ' Size of this section of the descriptor (in bytes)
USB_DESCRIPTOR_INTERFACE,_ ' Interface descriptor type
$00,_ ' Interface Number
$00,_ ' Alternate Setting Number
$02,_ ' Number of endpoints in this intf
HID_INTF,_ ' Class code
$00,_ ' Subclass code
HID_PROTOCOL_KEYBOARD,_ ' Protocol code
$00,_ ' Interface string index
'
' HID class-specific descriptor
'
$09,_ ' Size of this section of the descriptor (in bytes)
DSC_HID,_ ' HID descriptor type
$11, $01,_ ' HID Spec Release Number in BCD format (low byte, high byte)
$00,_ ' Country Code ($00 for Not supported)
HID_NUM_OF_DSC,_ ' Number of class descriptors, see USB_cfg.inc
DSC_RPT,_ ' Report descriptor type
HID_RPT01_SIZE, $00,_ ' Size of "hid_rpt01" table (low byte, high byte)
'
' Endpoint descriptor (IN)
'
$07,_ ' Size of this section of the descriptor (in bytes)
USB_DESCRIPTOR_ENDPOINT,_ ' Endpoint descriptor type
HID_EP | _EP_IN,_ ' Endpoint 1 in
_INTERRUPT,_ ' Interrupt transfers
HID_INT_IN_EP_SIZE, $00,_ ' Maximum packet size (low byte, high byte)
HID_EP_IN_POLLING_MS,_ ' Polling interval (in milliseconds)
'
' Endpoint descriptor (OUT)
'
$07,_ ' Size of this section of the descriptor (in bytes)
USB_DESCRIPTOR_ENDPOINT,_ ' Endpoint Descriptor type
HID_EP | _EP_OUT,_ ' Endpoint Address
_INTERRUPT,_ ' Attributes
HID_INT_OUT_EP_SIZE, $00,_ ' Maximum packet size (low byte, high byte)
HID_EP_OUT_POLLING_MS ' Polling interval (in milliseconds)
'
' Language string - unicode format
'
sd000:
cdata byte SizeOf_Table,_ ' Size of this descriptor in bytes
byte USB_DESCRIPTOR_STRING,_ ' Descriptor Type
word $0904 ' language ID - (high byte, low byte)
'
' Manufacturer string - unicode format
'
sd001:
cdata byte SizeOf_Table,_
byte USB_DESCRIPTOR_STRING,_
word "Crownhill"
'
' Product string - unicode format
'
sd002:
cdata byte SizeOf_Table,_
byte USB_DESCRIPTOR_STRING,_
word "Proton - HID Keyboard"

$ifdef USB_HAVE_SERIAL_STRING
sd003:
cdata byte SizeOf_Table,_ ' Size of this descriptor (in bytes)
byte USB_DESCRIPTOR_STRING,_
word "1234567" ' Serial string - unicode format
$endif
'
' This example report descriptor for a generic HID mouse defines one report of each type.
' Each report contains two bytes of data with a vendor-defined Usage.
'
hid_rpt01:
cdata $05, $01,_ ' USAGE_PAGE (Generic Desktop)
$09, $06,_ ' USAGE (Keyboard)
$a1, $01,_ ' COLLECTION (Application)
$05, $07,_ ' USAGE_PAGE (Keyboard)
$19, $e0,_ ' USAGE_MINIMUM (Keyboard LeftControl)
$29, $e7,_ ' USAGE_MAXIMUM (Keyboard Right GUI)
$15, $00,_ ' LOGICAL_MINIMUM (0)
$25, $01,_ ' LOGICAL_MAXIMUM (1)
$75, $01,_ ' REPORT_SIZE (1)
$95, $08,_ ' REPORT_COUNT (8)
$81, $02,_ ' INPUT (Data,Var,Abs)
$95, $01,_ ' REPORT_COUNT (1)
$75, $08,_ ' REPORT_SIZE (8)
$81, $03,_ ' INPUT (Cnst,Var,Abs)
$95, $05,_ ' REPORT_COUNT (5)
$75, $01,_ ' REPORT_SIZE (1)
$05, $08,_ ' USAGE_PAGE (LEDs)
$19, $01,_ ' USAGE_MINIMUM (Num Lock)
$29, $05,_ ' USAGE_MAXIMUM (Kana)
$91, $02,_ ' OUTPUT (Data,Var,Abs)
$95, $01,_ ' REPORT_COUNT (1)
$75, $03,_ ' REPORT_SIZE (3)
$91, $03,_ ' OUTPUT (Cnst,Var,Abs)
$95, $06,_ ' REPORT_COUNT (6)
$75, $08,_ ' REPORT_SIZE (8)
$15, $00,_ ' LOGICAL_MINIMUM (0)
$25, $65,_ ' LOGICAL_MAXIMUM (101)
$05, $07,_ ' USAGE_PAGE (Keyboard)
$19, $00,_ ' USAGE_MINIMUM (Reserved (no event indicated))
$29, $65,_ ' USAGE_MAXIMUM (Keyboard Application)
$81, $00,_ ' INPUT (Data,Ary,Abs)
$C0 ' End Collection
'
'---------------------------------------------------------------------------------------------------------
'
USB_CD_Pointer:
cdata configDescriptor1 ' Create a pointer to the descriptor's configDescriptor1 table

USB_SD_Pointer:
$ifdef USB_HAVE_SERIAL_STRING
cdata sd000, sd001, sd002, sd003 ' Create a pointer to the descriptor's sd tables(with serial)
$else
cdata sd000, sd001, sd002 ' Create a pointer to the descriptor's sd tables (without serial)
$endif

OverDescriptorTables:
include "USB_System.inc" ' ** Load the USB routines into the program **

$ifdef USB_USE_HID
include "USB_UserHID.inc" ' ** Load the User HID routines into the program (if a HID interface is being used)
$endif



this demo tested with real hardware!,
and works!. Proton 3.5.5.3 used !
Device typed this lines as keyboard to Windows Notepad

z0 *-ğ,i"./*-+
34567890

USB service interrupt not used, device set as Usb 1.1.

johngb
29th January 2013, 12:46
Has anyone managed to get the Serial Number returned from devices using the HID Stack.
The HID_Descriptor contains the serial number but this is not being picked up by the PC.
Is there still an error in the HID_Descriptor file - I cannot see anything obvious.

towlerg
29th January 2013, 13:35
Has anyone managed to get the Serial Number returned from devices using the HID Stack.
The HID_Descriptor contains the serial number but this is not being picked up by the PC.
Is there still an error in the HID_Descriptor file - I cannot see anything obvious.

Try HidD_GetSerialNumberString

towlerg
29th January 2013, 14:52
Sorry I posted without thinking, you obviously know that and your problem is at a much lower level - what a pity I can't turn back time and delete my last post.

johngb
29th January 2013, 14:54
I cannot use HidD_GetSerialNumberString as I have used a Delphi wrapper for the Hid APIs.
However if I connect to other HID devices which return a serial number I am able to read it.
In fact I can read the serial number of devices compiled under the old USB system.
So I have to suspect there is something wrong with the HID_Descriptor.

Before anyone asks I have set $define USB_HAVE_SERIAL_STRING before the HID descriptor.inc include

towlerg
29th January 2013, 16:16
I'm running the risk of making a fool of myself twice in one day but here goes-

Assuming that the problem relates to the unmodified samples, although a serial number is included, the constant USB_SERIAL_INDEX is set to 0 in USB_Defs.inc. This is confirmed if you view the generated assembler

device_dsc
db 18,1,2,0,0,0
db 0,8,216,4,0,0
db 0,3,1,2,0,1

the last but one byte is the serial index.

One confusing thing (did I say one!) is that Mouse_Descriptor.Inc and USB_Defs.inc both seem to have the same information albeit in a different format.

johngb
29th January 2013, 19:21
Thanks for the pointer - you were right about the USB_SERIAL_INDEX.
I can now see the serial number.

johngb
4th February 2013, 11:52
Has anyone managed to get the USB_HID_Stack working in ISIS.
I have a program which works in real hardware but doesn't in ISIS.
I am using the 18F4550 - in ISIS I get the error "illegal opcode Loaded from PC= 0988 executed as a NOP".
From the lst file, location 988 is "0003DC 26E1 02264 Addwf FSR1L,F,0"
Any thoughts?

towlerg
4th February 2013, 22:00
Has anyone managed to get the USB_HID_Stack working in ISIS.
I have a program which works in real hardware but doesn't in ISIS.
I am using the 18F4550 - in ISIS I get the error "illegal opcode Loaded from PC= 0988 executed as a NOP".
From the lst file, location 988 is "0003DC 26E1 02264 Addwf FSR1L,F,0"
Any thoughts?
Can you get the ISIS samples to work? They're under VSM for USB, 2 x HID, CDC, MSD