Searching \ for '[PIC] Another Microchip USB Stack bug' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: techref.massmind.org/techref/microchip/devices.htm?key=pic
Search entire site for: 'Another Microchip USB Stack bug'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] Another Microchip USB Stack bug'
2011\02\12@194552 by Philip Pemberton

face
flavicon
face
This is a great one...

1) Set the USB stack to interrupt mode (#define USB_INTERRUPT, #undef
   USB_POLLED). Set up for a self-powered (device has own PSU, does not
   use Vbus) device with Vbus sensing.
2) Program your target board.
3) Unplug the PSU and USB.
4) Plug in the power
5) Now plug in the USB cable.

Did the device enumerate? I'll bet it didn't!

Here's why.

#if defined(__18CXX)
void main(void)
#else
int main(void)
#endif
{
    InitializeSystem();

    #if defined(USB_INTERRUPT)
        USBDeviceAttach();
    #endif

    while(1)
    {
        ProcessIO();
    }
}

And what does USBDeviceAttach do?

#if defined(USB_INTERRUPT)
void USBDeviceAttach(void)
{
    //if we are in the detached state
    if(USBDeviceState == DETACHED_STATE)
    {
        if(USB_BUS_SENSE == 1)
        {
               //Initialize registers to known states.
            U1CON = 0;

            // Mask all USB interrupts
            U1IE = 0;

            //Configure things like: pull ups, full/low-speed mode,
            //set the ping pong mode, and set internal transceiver
            SetConfigurationOptions();

            USBEnableInterrupts();

            // Enable module & attach to bus
            while(!U1CONbits.USBEN){U1CONbits.USBEN = 1;}

            //moved to the attached state
            USBDeviceState = ATTACHED_STATE;

            #ifdef  USB_SUPPORT_OTG
                U1OTGCON = USB_OTG_DPLUS_ENABLE | USB_OTG_ENABLE;
            #endif
        }
    }
}

Oh dear... it's responsible for enabling the USB interrupts and booting up the PHY!

So what happens when the USB cable isn't plugged in when the PIC cold-boots? Take a guess.
If you said "It gets stuck in the while loop in main, without ever setting up the USB stack", you're absolutely, one hundred percent right.

And how do we fix this colossal, monumental, astronomical cock-up?

Rewrite main().

#if defined(__18CXX)
void main(void)
#else
int main(void)
#endif
{
    InitializeSystem();

    while(1)
    {
        #if defined(USB_INTERRUPT)
            if (USB_BUS_SENSE) {
              USBDeviceAttach();
            } else {
              USBDeviceDetach();
            }
        #endif

        ProcessIO();
    }
}


Now the code checks the state of the Bus Sense line every time it goes through the while loop, and tells the stack what's going on every step of the way. It costs us about a dozen clock cycles per spin, but it solves the bug quite nicely.

Confirmed on v2.7a, still present in the USB Generic LibUSB demo for v2.8. Oh dear...


The score now stands at:
  Bugs I've found in Microchip appnotes or sample code -- 3
  Bugs I've fixed in Microchip appnotes or sample code -- 2

Happy days.


TTFN,
-- Phil.
spam_OUTpiclistTakeThisOuTspamphilpem.me.uk
http://www.philpem.me.uk

More... (looser matching)
- Last day of these posts
- In 2011 , 2012 only
- Today
- New search...