picture home | pixelblog | qt_tools

omino code blog

We need code. Lots of code.
David Van Brink // Fri 2008.03.7 00:23 // {wbl weird blinking lights}

Retro USB MIDI Device III

Microchip’s Reference USB Implementation

Microchip’s PICDEM FS USB Demo Board comes with several working example projects which use its on-board USB port. (On a side note, I’m relieved that Microchip’s developer product names are not significantly better than those foisted by my own employer, Altera.) The board is based on a PIC 18F4550.

Their demo is not really an API or a platform, but it is a starting point that actually works. To understand their approach, let’s dive right in from the top.

void main(void)
{
    InitializeSystem ();
    while(1)
    {
        USBTasks();         // USB Tasks
        ProcessIO();        // See user\user.c & .h
    } //end while
} //end main

Bravo. That’s just what main should look like!

Two features are immediately clear. First, it is a polled system, and the main loop runs forever. Second, they are using globals to manage their state. (Else, we’d see some kind of arguments passed to the several routines here.) These are both perfectly respectable and traditional approaches for an embedded system.

Their demo communicates with a Windows app:

The demo board sends some analog readings (temperature and trim-pot position) up, periodically, which the app displays. If you click the buttons on the app, the board blinks its LEDs.

Here’s part of ProcessIO, which listens for commands.

void ProcessIO(void)
{
    BlinkUSBStatus();
    if((usb_device_state < CONFIGURED_STATE)||(UCONbits.SUSPND==1)) 
		return;

    ServiceRequests();
}//end ProcessIO

void ServiceRequests(void)
{
    if(USBGenRead((byte*)&dataPacket,sizeof(dataPacket)))
    {
        counter = 0;
        switch(dataPacket.CMD)
        {
...
         case UPDATE_LED:
                // LED1 & LED2 are used as USB event indicators.
                if(dataPacket.led_num == 3)
                {
                    mLED_3 = dataPacket.led_status;
                    counter = 0x01;
                }//end if
                else if(dataPacket.led_num == 4)
                {
                    mLED_4 = dataPacket.led_status;
                    counter = 0x01;
                }//end if else
                break;
...
            case RESET:
                Reset();
                break;

            default:
                break;
        }//end switch()
    }//end if
}//end ServiceRequests

So, blink the lights, and, if the USB connection isn’t not running (to speak as the code is written), check for activity and respond to it.

Neat and easy!

Underbelly

Ok. I’ve glossed it up a bit.

When you first plug in the demo board, running the USB firmware, Windows says, “Found new hardware, Microchip USB Demo Board“, and demands that you install a driver for it. Not the worst thing, but annoying. That’s because the demo uses its own unique and specific protocol to communicate between the app and the board. Nothing wrong with that, it is a perfectly respectable approach for a vertical application.

I was wondering where it got Microchip USB Demo Board. Oddly, searching the source for that text failed. Ah. Ugh:

rom struct{byte bLength;byte bDscType;word string[33];}sd002={
sizeof(sd002),DSC_STR,
'M','i','c','r','o','c','h','i','p',' ','U','S','B',' ','D','e','m','o',' ','B','o','a','r','d',' ','(','C',')',' ','2','0','0','7'};

Yes, you’re seeing it right. This is part of the USB descriptor. It’s little-endian unicode, preceded by a length, and all quite cleverly contrived to sit in ROM ready for spooling straight out to the host.

But no fun at all to edit!

Resisting Perfection

My initial urge is to open up a blank editor, and start implementing a complete general purpose USB platform. That’s what I usually do in my code, create platforms for some domain… but I shall resist in this case. The goal is to get the these old buttons to send musical notes…

device

…and that’s all!

So, I took their 15 C files, and pasted them into usbAll.c. Then I took their 15 H files, and put them into usbAll.h. There. Nice and tidy. I can ignore their ugly globals, and benefit from their 3 years of bug fixes (like “Dont hang if host asks for more data than we said was available”).

I’ll just extract and generalize a little at a time, when it makes my work easier.

Starting with:

   CStringToUsbDescriptor("Omino USB MIDI Controller v0.1");

Next up, Why USB for this project?

oh, i dont know. what do you think?



(c) 2003-2011 omino.com / contact poly@omino.com