Some more info on USB as the above post was a little short
USB works quite differently to your conventional serial data. Information is sent in packets known as 'Reports'. You can't send half a report, the whole report is sent/received regardless of what parts you have populated. Each report is made up of X bytes. The above program is set to
32 Bytes per report.
VB.net Application Notes:While this post just covers the basic use, a full working model can be downloaded from the first post.
mcHID.dll provides a number of useful events such as;
- Code: Select all
Public Sub OnPlugged(ByVal pHandle As Integer)
Public Sub OnUnplugged(ByVal pHandle As Integer)
Public Sub OnRead(ByVal pHandle As Integer)
Download the source code to see how to use each in more detail. The basic guide for connecting to a device;
a) Copy the form "
mcHIDInterface.vb" from the example project to your application.
b) Configure the default parameters (
VendorID,
ProductID,
BufferInSize,
BufferOutSize)
c) Call "
ConnectToHID(Me.Handle)" to catch all messages/events for the desired device.
d) Wait for "
OnPlugged" event to trigger. This means the selected device is physically connected and ready.
e) Handle "
OnRead" events to parse new reports, and send reports as desired.
Of note there is that OnRead will only trigger when a
complete report has been received. The first element of a report is BufferIn(0), it should always = 0, and there for can be omitted when parsing the report data. For example, the first element is skipped and parsing begins from BufferIn(1) in the following code;
- Code: Select all
For i = 1 To BufferInSize
tmpByte = BufferIn(i)
' Do something with the byte...
'
Next
Transmitting reports is a little different, though quite simple. The BufferOut must first be filled and then you can evoke the transmission of the report. For example;
- Code: Select all
BufferOut(0) = 0
For i = 1 To BufferOutSize
BufferOut(i) = CByte(lstReport.Items(i - 1))
Next
' Get the handle and send report
Dim pHandle As Integer
pHandle = hidGetHandle(VendorID, ProductID)
hidWriteEx(VendorID, ProductID, BufferOut(0))
You probably missed it, but to evoke a report transmission you call "hidWriteEx(VendorID, ProductID, BufferOut(0))" after the buffer is populated with data. Note that Buffer(0) will always = 0. The next 32 elements are the report bytes that can be anything.
Once again, a working VB.net solution can be found in the source code.
Swordfish Application Notes:To create a HID compatible program in SF, simply click Plugin > Swordfish > EasyHID and setup the options. By default, there are quite a few different examples of how to use the USB library. Download the pre-made SF iHID program to view a working model.
The first agenda is to setup the in/out buffers. There are two methods of doing this, one is using Arrays and the other is by using the default report buffer RAM allocation. This project focuses on the use of Array type buffers. Consider the setup for BufferOut;
- Code: Select all
Dim BufferOut(32) As Byte Absolute TXReportRAM
Notice the
Absolute keyword followed by TXReportRAM. This will force the compiler to overlay the array at the reports TX report buffer location. Now we can access the report like any other variable
Now ensure the PIC is connected to the USB network;
- Code: Select all
Repeat
Until Attached
The
output report buffer is referred to how it was declared (in this case "Dim BufferOut(32) as Byte"). Here's an example of filling the report Buffer and transmitting it;
- Code: Select all
// connect to USB...
Repeat
Until Attached
While True
For i = 0 To 31
BufferOut(i) = i
Next
WriteArray(BufferOut,32)
DelayMS(1000)
Wend
The
input report buffer is declared in the following format;
- Code: Select all
Dim BufferIn(32) As Byte Absolute RXReportRAM
Once again, notice the
Absolute keyword followed by RXReportRAM. This will force the compiler to overlay the array at the reports RX report buffer location. Now we can access the report like any other variable, for example;
- Code: Select all
Dim BufferIn(32) As Byte Absolute RXReportRAM
.
.
// check for new report
If DataAvailable Then
ReadReport
// send each byte of the report via USART
For i = 0 To 31
DisableISR // disable USB interrupt handling for timing critical events
// note: if more than 1mS elapses then USB will be disconnected.
// call Service() to refresh USB connection before that happens.
USART.Write(DecToStr(BufferIn(i)),13,10)
EnableISR // enable USB interrupt handling
Next
EndIf
The above code brings another very important concept to play. USB is a polled protocol which needs to be serviced
every 1 millisecond or so. This is to ensure the connection between the microcontroller and PC is maintained and any transactions are handled.
If the USB_SERVICE is enabled (which it is by default) then the module will service the USB connection using interrupts. However, you may have a critical section of code that should not be disturbed. For example, a software based serial read or write may will have exact timing requirements. You don't want an interrupt firing during this time, else these timing will be disturbed and the routines may fail. You can temporarily disable interrupt servicing by calling
DisableISR(). When you have finished, enable the interrupt by calling
EnableISR().
USART is very timing specific, especially at 115200 baud, hence the USB interrupt handle was disabled during the above code.