USB: The Adventure Begins
The hardware profile selects options to make the USB device bus powered. That means it draws power from the USB bus (in general, the device can't draw more than 100mA, although there are ways to draw more in some cases). Other options allow the device to have its own power, or to use the bus power if its own power isn't available.
You might wonder why the library cares about your power scheme. The USB specification forbids, for example, devices driving the data lines when there is no power on the bus. The library manages all the details if you tell it what scheme you are using and, where needed, specify what digital input pin you use to monitor the power status. With a bus-powered device like this, there's no need to monitor, but you still need to inform the library that the device is bus powered.
The usb_config.h file has more detailed options regarding USB. For example, you can enable or disable the pull up resistors, select the type of USB (high- or full-speed), etc.
The newmain.c file has a fair amount of code that handles callbacks from the Microchip library. But the essence of the file is this while loop:
while(1)
{
// Check bus status and service USB interrupts.
USBDeviceTasks();
// handle I/O including USB data send/receive
ProcessIO();
}//end while
I wanted this to be as simple as possible so I did not use interrupts to deal with the USB port. The USBDeviceTasks call gives the library a chance to do all the required housekeeping.
The ProcessIO call manages any incoming data and sends data based on requests. The main part of that call looks like this:
void ProcessIO(void)
{
if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return;
if(!HIDRxHandleBusy(USBOutHandle))
{
switch(ReceivedDataBuffer[0])
In other words, the code checks to make sure the USB device is connected and active, and then looks to see if any data is available from the host computer. If so, the code examines the first byte of data and vectors to some specific code for that case.
For now, have a look at the source and match up the files with the list above. Next week I'll talk more about what's inside the source files. Consider this code to be version 1. It is based on some of the Microchip examples, so you'll see some similarities to the examples in the USB directory of the Microchip application library. I may make some changes or tweaks to it in future blogs.
Speaking of changes, I did make one change to the hardware circuit I described last week. Since I elected to go with bus power, I added a capacitor across the power and ground buses. This prevents drops caused by other devices from resetting the CPU. Note the USB specification specifies no more than 10uF for this purpose.
To make up for the change, you can find the schematic for the board (above). I also got tired of the rat's nest construction I showed you last week, so I repurposed a general-purpose PIC PC board and cut a USB cable in half to make a more permanent test fixture.
I'll cover more details in the coming weeks: Exactly what's in the main file? What's the deal with the descriptors? How do you communicate with Windows or Linux software? But that's enough for this week.

