Wednesday, 20 August 2008
 
  Home arrow PIC arrow USB arrow 18F4550 USB Interface  
Main Menu
Home
Car PC
PIC
Electronics
Brewing
Links
Contact Me
FAQs
Forums
PayPal Donation

Enter Amount:

18F4550 USB Interface PDF Print E-mail
Written by Evan   
Sunday, 06 August 2006
Article Index
18F4550 USB Interface
Page 2 - Burning in the Bootloader
Page 3 - USBDemo PIC Firmware and C# Software
Page 4 - Understanding the Demo Firmware

Just to clarify, the firmware here sets up the PIC as a custom device using the Microchip driver, and configures it as what they refer to as a "generic" class device.  In addition to the required endpoint 0, it also has endpoint 1 enabled as an IN and OUT interrupt endpoint, which is the endpoint that it uses for communication with the functions USBGenRead and USBGenWrite.  These functions, and the initialization function USBGenInitEP, are found in usbgen.c.  By default, endpoint 1 is configured with a bInterval value of 32, or a max latency of 32ms between transfers.

Packet Format

Each packet consists of a command byte (corresponding to any of the commands in the enum in user.h) followed by 0 or more data bytes, depending on the command.  

<COMMAND><DATA><DATA>...etc...

Looking at the switch statement cases in ServiceRequests in user.c, you can see the rather simple method by which received packets are accessed; in general, it is done as a simple byte array, where dataPacket._byte[0] is the command byte, and subsequent indices represent the data bytes (if any).  

To transmit data back to the PC in response to a command, the data is loaded into the same buffer (datPacket._byte[]), the value of the byte variable 'counter' is set to the total number of bytes to be transmitted (including the command and all data bytes) and at the termination of the switch statement, the following code will perform the transmission via USBGenWrite if there is data to be sent:

if(counter != 0)
{
      if(!mUSBGenTxIsBusy())

           USBGenWrite((byte*)&dataPacket,counter);

}//end if

One question you might ask is "what if I want to send data from the PIC to the PC without the PC having to deliberately send it a command to request it?" (in other words, asynchronously sending data from PIC to PC)  Well, this isn't something covered by this demo firmware and software, but is covered in another of my articles.  Suffice it to say that it's not extraordinarily complex, but it can require some work that is beyond the scope of a plain introductory article (such as adding another endpoint, modifying descriptors, and on the PC side, running the asynchronous receive methods in a separate execution thread) 

Software Side

Well, now that I have covered what is happening on the firmware side, I'll give some insight into the software side.  Interfacing with the PIC would be pretty complicated if we had to make low-level access to the device driver, but thankfully microchip supplies a DLL that simplifies this interface, mpusbapi.dll.  Anyone who is competent in C++ should take a look at the source code of it, which is included as part of the MCHPFSUSB software package from Microchip.   

The heart of the interface in my USB Demo C# program is the usb_interface class in the PICUSB.DLL file.  It basically imports the mpusbapi.dll functions, and provides a few methods as a simpler wrapper around them. 

The complete documentation (MSDN-style) of the PICUSB DLL file is available in HTML format , or in a single compiled help file if you prefer to download.

In the interest of making the interface as C#-friendly as possible, I made the function EasyCommand, which accepts and returns more "normal" data types for C#, instead of the pointers and DWORDs of the imported DLL functions.  

public uint EasyCommand(byte Command, int rxlength, byte[] data, out byte[] dataout) 

You pass in the command, data (if any), and it attempts to do a transmit/recieve, returning any response in 'dataout'.  The function return value indicates success or failure.  Note that what is returned in 'dataout' is an array containing the whole packet, including both command and data. 

As far as what is going on in the demo program, you can see that it is quite simple.  When you click button 1, it sends two packets, with the command UPDATE_LED (0x32), followed by the number of one of the LEDs (3 or 4), followed by the desired state, read from the corresponding checkbox.  The resulting code is as simple as:

private void button1_Click(object sender, EventArgs e)
{
       temp = new byte[2];
       byte[] temp2;
       if(checkBox1.Checked){temp[0]=1;}
       if(checkBox2.Checked){temp[1]=1;}
       usbi.EasyCommand(0x32, 1, new byte[] { 3, temp[0] }, out temp2);
       usbi.EasyCommand(0x32, 1, new byte[] { 4, temp[1] }, out temp2);
}

The code for the counter feature is about as simple, albeit slightly more spread out because it's using a timer and a button, but in essence it sends a packet with the command 0x33, which the PIC increments and sends back; it then takes the second byte of the received packet (the data byte) and stores it back into the variable to be sent next time.  The relevant code, located in the timer1_Tick method, is as follows: (see the full code for more detail if you wish)

byte[] temprx;           
usbi.EasyCommand(0x33, 2, temp, out temprx);
temp[0] = temprx[1];

Note that to compile a project using the usb_interface class, you have to enable "allow unsafe code" in the build options.  If anyone more advanced in the use of C# has ideas about any ways to change this (if it is even possible, given the nature of the DLL functions being used), please let me know!
I have now updated the code to use marshalling when importing the Microchip DLL functions, so no unsafe code is necessary. 

{mos_sb_discuss:8} 



Last Updated ( Monday, 02 June 2008 )
 
< Prev
Partner Site
Visit my friends over at Dream-Technology, producing radio controlled and switch adapted toys for children with physical disabilities.
Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.5 License.
For usage outside the terms of this license, contact me by email to discuss.

© 2008 eegeek.net
Joomla! is Free Software released under the GNU/GPL License.

Get The Best Free Joomla Templates at www.joomla-templates.com