2
\$\begingroup\$

I'm integrating the example USB module into my existing app and can only get it to work when I disable interrupts.

I'm working off the mla example installed at the path:

C:/microchip/mla/v2013_12_20/apps/usb/device/bootloaders/firmware/pic18fxxjxx

Details

  • I'm implementing each of USB callback functions exactly as done in the example.
  • USB clock is 48MHz
  • CPU (f_osc) clock is 16MHz
  • pic18f25k50
  • one high-priority interrupt for Timer1 ticks every 250us, everything else happens about every 1s
    • never go to sleep, yet this still seems to reset

Is microchip's USB stack not thread-safe?

Am I not running the USB task fast enough?

while (1)
{
  // Clear the watchdog timer
  ClrWdt();

  // Run the USB task faster than xxxHz?
  USBDeviceTasks();

  // Do stuff
}

// high-priority foreground loop takes ~5us
void high_priority interrupt HighPriorityTasks(void)
{
  // Do stuff quickly, clear sources of interrupts
}

// low-priority foreground loop takes ~5us
void low_priority interrupt LowPriorityTasks(void)
{
  // Do stuff quickly, clear sources of interrupts
}

When it fails, I see device manager continue to refresh accompanied by one of these popups about every 5s in Windows 7: enter image description here

\$\endgroup\$
2
\$\begingroup\$

Try using USB in interrupt mode. USB devices must respond to host requests within a certain time frame. You haven't detailed how long your timer tasks routine takes to execute but from this error it seems that it is taking too long and there is no way for the USB to respond in a timely fashion.

Without specific details of your application, I would suggest running USBDeviceTasks() as the only high priority interrupt task and set the timer and its tasks as lower priority.

This way when the host requests a response from the PIC when it is executing the timer tasks it will pause executing that routine, answer the host, and then return to that routine.

\$\endgroup\$
  • \$\begingroup\$ in this version of the USB stack, I'm not seeing any USB_INTERRUPT macros. it certainly seems to have something to do with timing though \$\endgroup\$ – tarabyte Apr 16 '14 at 21:28
  • \$\begingroup\$ My mistake - opened the wrong library. None the less, you can just move USBDeviceTasks() from main to HighPriorityTasks once the interrupts are configured correctly. \$\endgroup\$ – SomeEE Apr 16 '14 at 21:40
  • \$\begingroup\$ yeah, wasn't sure if it'd be safe to run USBDeviceTasks() in an interrupt. \$\endgroup\$ – tarabyte Apr 16 '14 at 21:42
1
\$\begingroup\$

USB HID class can poll as fast as every 1ms. So, ideally, you want to call USBDeviceTask() more often than every 1ms.

On the side, I have tried calling USBDeviceTask() every 10ms, and it seems to work fine!!

\$\endgroup\$
0
\$\begingroup\$

I have my own powerdown/powerup functions when going in and out of sleep and didn't realize that the default USB suspend callback function put the device to sleep:

void USBCBSuspend(void)
{
  Sleep();         // Go to sleep, wake up when a USB activity event occurs
  //If using the WDT, should go back to sleep if awoke by WDT instead of USBIF
  while((0 == USBIF_FLAG) && (0 == RCONbits.TO))      //If using the WDT, should go back to sleep if awoke by WDT instead of USBIF
  {
    Sleep();     //Entry into sleep clears WDT count, much like executing ClrWdt() instruction
  }

  //After the USB suspend event ends, you should re-configure your I/O pins
  //for normal operation mode (which is allowed to consume more current).
  //However, it is recommended to put this code in the USBCBWakeFromSuspend()
  //function instead of here (so that this function will work with either
  //sleeping or clock switching to a lower frequency).
}

This is certainly something I didn't intend to do, so have this commented out for now.

While a bit of an aside, a do-while loop really provides a more-readable implementation here better anyway:

// USB_onSuspend(void)
// Called when the USB host sends USB suspend signaling
void USBCBSuspend(void) {
  do {
    Sleep();
  } while ((USBIF_FLAG == 0) && (RCONbits.TO == 0));
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.