To compile without error, you need to install
the library HID_Lib (file "HID_Lib for PureBasic 4.41.exe" in the
archive).
The example HID joystick was transformed into a
demonstration device and USB thermometer.
Demo - device
Demonstration device allows two-way exchange of
arbitrary information with a computer.
The scheme is shown in Figure.
Scheme
The program has a fairly large size (almost
1000 lines), so will be considered only fragments responsible for the
configuration of the USB driver and the exchange of information. In the
original program was replaced by the HID device descriptor, such as the
joystick, to handle non-standard HID device, which allows exchange of arbitrary
information. There was also activated by the second endpoint and is configured
to receive information from your computer. This tag defines the type of HID
devices. Depends on him, whether the device, keyboard, mouse, joystick, etc. In
this demonstration device, HID descriptor has the form
Data 33 ' Length = 33 bytes
Data &H06 , &H00 , &HFF ' Usage_page(vendor Defined Page 1)
Data &H09 , &H01 ' Usage(vendor Usage 1)
Data &HA1 , &H02 ' Collection(logical)
Data &H09 , &H01 ' Usage(pointer)
Data &H15 , &H00 ' Logical_minimum(0)
Data &H25 , &HFF ' Logical_maximum(255)
Data &H75 , &H08 ' Report_size(8)
Data &H95 , &H01 ' Report_count(1)
Data &H81 , &H02 ' Input(data , Var , Abs)
Data &H09 , &H01 ' Usage(pointer)
Data &H15 , &H00 ' Logical_minimum(0)
Data &H26 , &HFF , 0 ' Logical_maximum(255)
Data &H75 , &H08 ' Report_size(8)
Data &H95 , &H01 ' Report_count(1)
Data &H91 , &H02 ' Output(data , Var , Abs)
Data &HC0 ' End_collection
In the first line, given a number of bytes in
the descriptor.
The second and third line describes the type of
device. In our case, this non-standard HID device.
Next is a description of input and output
endpoints.
Options Logical_minimum and Logical_maximum determine allowable range of values stored in the buffer of the endpoint.
Parameter Report_count determines the number of bytes transmitted or
received for one parcel. The allowable value of 1 ... 8. In a demonstration
device, is transmitted and received, only one byte per parcel
The configuration of the endpoints is performed
by this code.
'Address of optional endpoints (Must be
> 0. comment-out to not use)
Const _usb_endp2addr = 1
Const _usb_endp3addr = 2
'Valid types are 0 for control or
3 for interrupt
Const _usb_endp2type = 3
Const _usb_endp3type = 3
'Directions are: 0=Out, 1=In. Ignored by control endpoints
Const _usb_endp2direction = 1
Const _usb_endp3direction = 0
'Polling interval (ms) for
interrupt endpoints. Ignored by control
endpoints
' (Must be at least 10)
Const _usb_endp2interval = 200
Const _usb_endp3interval = 100
Unique device identifier - Vendor ID and Product ID, set in lines:
Const _usb_vid = &HAAAA
Const _usb_pid = &HEF22
Receive and transmit data, are performed in the
main loop program.
Do
Resetcounter = 0
'Check for reset here
While _usb_pin._usb_dminus = 0
Incr Resetcounter
If Resetcounter = 1000 Then
Call Usb_reset()
End If
Wend
'Check for received data
If _usb_status._usb_rxc = 1 Then
If _usb_status._usb_setup = 1 Then
'Process a setup packet/Control message
Call Usb_processsetup(_usb_tx_status)
Elseif _usb_status._usb_endp1 = 1 Then
' Input data endpoints
Portb = _usb_rx_buffer(2) ' Copy USB data in Portb
End If
'Reset the RXC bit and set the RTR bit
(ready to receive a new packet)
_usb_status._usb_rtr = 1
_usb_status._usb_rxc = 0
End If
Buttons_current = Pinc
Buttons_current = Buttons_current And 3
If Buttons_current <> Buttons_last Then
'Queue data to be sent on endpoint 2 (HID
report)
If _usb_tx_status2._usb_txc = 1 Then
Buttons_last = Buttons_current
_usb_tx_buffer2(2) = Buttons_current
Call Usb_send(_usb_tx_status2 , 1) ' Send data in PC
End If
End If
Loop
End
When new data from the computer will flag set _usb_endp1 in variable _usb_status. Incoming data is stored in an array _usb_rx_buffer.
In the demonstration program, for one parcel, received only a single byte of
data, as described in the HID contango. This byte is copied into Portb microcontroller.
To transfer data from the microcontroller to
the computer, the data stored in an array _usb_tx_buffer2. After this
function is called Usb_send. Her second argument - the number of
transferred bytes. But before that, check the readiness USB driver to transfer
data by checking the flag _usb_txc, variable _usb_tx_status2.
To work with the demonstration device was
developed by a computer program HID_Example_IO.exe
USB thermometer
USB thermometer is based on a package of
demonstration device. Major changes were made in the main program loop.
Config 1wire = Portc.5
Dim 1wire_array(9) As Byte
Dim W_1wire As Word
Dim Dsid1(8) As Byte
Dim Flaginputtermo As Byte
Dim Resetcounter As Word
Dim Idlemode As Byte
Enable Interrupts
W_1wire = 1wirecount()
Dsid1(1) = 1wsearchfirst()
1wreset ' reset the bus
1wwrite &HCC ' skip rom
1wwrite &H44 ' Convert T
Timer1=0
Flaginputtermo = 0
Do
Resetcounter = 0
'Check for reset here
While _usb_pin._usb_dminus = 0
Incr Resetcounter
If Resetcounter = 1000 Then
Call Usb_reset()
End If
Wend
'Check for received data
If _usb_status._usb_rxc = 1 Then
If _usb_status._usb_setup = 1 Then
'Process a setup packet/Control message
Call Usb_processsetup(_usb_tx_status)
Elseif _usb_status._usb_endp1 = 1 Then
' Input data endpoints
End If
'Reset the RXC bit and set the RTR bit
(ready to receive a new packet)
_usb_status._usb_rtr = 1
_usb_status._usb_rxc = 0
End If
If Flaginputtermo = 1 Then
Flaginputtermo = 0
1wverify Dsid1(1)
1wwrite &HBE
1wire_array(1) = 1wread(9)
1wreset ' reset the bus
1wwrite &HCC ' skip rom
1wwrite &H44 ' Convert T
'Queue data to be sent on endpoint 2 (HID
report)
If _usb_tx_status2._usb_txc = 1 Then
_usb_tx_buffer2(2) = 1wire_array(1)
_usb_tx_buffer2(3) = 1wire_Array(2)
Call Usb_send(_usb_tx_status2 , 2) ' Send data
(2 bytes) in PC
End If
End If
Loop
End
From the main loop removed code that takes data
from the computer and added code, the survey sensor DS18B20. The data from the
sensor to read no more than once per 750 milliseconds. In order not to delay
the work of the main loop for a relatively long period of time, we used
variable Flaginputtermo as flag. In interrupts of the timer Timer1,
occurring approximately once per second, the variable is written the number 1,
which is a sign of the need to read data from the sensor. Upon completion of
reading, the data is copied from the array 1wire_array in array _usb_tx_buffer2 and call the function Usb_send, transmitting data (2 bytes) by bus USB
to a computer.
In the HID report was a small change
(highlighted in green color) associated with the need to transfer 2 bytes for
sending.
Data 33 ' Length = 33 bytes
Data &H06 , &H00 , &HFF ' Usage_page(vendor Defined Page 1)
Data &H09 , &H01 ' Usage(vendor Usage 1)
Data &HA1 , &H02 ' Collection(logical)
Data &H09 , &H01 ' Usage(pointer)
Data &H15 , &H00 ' Logical_minimum(0)
Data &H25 , &HFF ' Logical_maximum(255)
Data &H75 , &H08 ' Report_size(8)
Data &H95 , &H02 '
Report_count(2)
Data &H81 , &H02 ' Input(data , Var , Abs)
Data &H09 , &H01 ' Usage(pointer)
Data &H15 , &H00 ' Logical_minimum(0)
Data &H26 , &HFF , 0 ' Logical_maximum(255)
Data &H75 , &H08 ' Report_size(8)
Data &H95 , &H01 ' Report_count(1)
Data &H91 , &H02 ' Output(data , Var , Abs)
Data &HC0 ' End_collection
To display the temperature on the computer
screen, the program is USB_thermometer.exe