Description
Source
Call Graph
Start Line: 628
void USBD_InterruptHandler(void)
{
unsigned int status;
int eptnum = 0;
// Get interrupt status
// Some interrupts may get masked depending on the device state
status = AT91C_BASE_UDP->UDP_ISR;
status &= AT91C_BASE_UDP->UDP_IMR;
if (deviceState < USBD_STATE_POWERED) {
status &= AT91C_UDP_WAKEUP | AT91C_UDP_RXRSM;
AT91C_BASE_UDP->UDP_ICR = ~status;
}
// Return immediately if there is no interrupt to service
if (status == 0) {
return;
}
// Toggle USB LED if the device is active
if (deviceState >= USBD_STATE_POWERED) {
LED_Set(USBD_LEDUSB);
}
// Service interrupts
//if (ISSET(dStatus, AT91C_UDP_SOFINT)) {
//
// TRACE_DEBUG("SOF");
//
// // Invoke the SOF callback
// USB_StartOfFrameCallback(pUsb);
//
// // Acknowledge interrupt
// AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_SOFINT;
// dStatus &= ~AT91C_UDP_SOFINT;
//}
// Suspend
// This interrupt is always treated last (hence the '==')
if (status == AT91C_UDP_RXSUSP) {
TRACE_INFO_WP("Susp ");
// Don't do anything if the device is already suspended
if (deviceState != USBD_STATE_SUSPENDED) {
// The device enters the Suspended state
// Enable wakeup
AT91C_BASE_UDP->UDP_IER = AT91C_UDP_WAKEUP | AT91C_UDP_RXRSM;
// Acknowledge interrupt
AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_RXSUSP;
// Switch to the Suspended state
previousDeviceState = deviceState;
deviceState = USBD_STATE_SUSPENDED;
// Invoke the Suspended callback
USBDCallbacks_Suspended();
UDP_DisableTransceiver();
UDP_DisablePeripheralClock();
UDP_DisableUsbClock();
}
}
// Resume
else if ((status & (AT91C_UDP_WAKEUP | AT91C_UDP_RXRSM)) != 0) {
TRACE_INFO_WP("Res ");
// Don't do anything if the device was not suspended
if (deviceState == USBD_STATE_SUSPENDED) {
// The device enters its previous state
UDP_EnablePeripheralClock();
UDP_EnableUsbClock();
// Enable the transceiver if the device was past the Default
// state
deviceState = previousDeviceState;
if (deviceState >= USBD_STATE_DEFAULT) {
UDP_EnableTransceiver();
// Invoke the Resume callback
USBDCallbacks_Resumed();
}
}
// Clear and disable resume interrupts
AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_WAKEUP
| AT91C_UDP_RXRSM
| AT91C_UDP_RXSUSP;
AT91C_BASE_UDP->UDP_IDR = AT91C_UDP_WAKEUP | AT91C_UDP_RXRSM;
}
// End of bus reset
else if ((status & AT91C_UDP_ENDBUSRES) != 0) {
TRACE_INFO_WP("EoBRes ");
// The device enters the Default state
deviceState = USBD_STATE_DEFAULT;
UDP_EnableTransceiver();
UDP_ResetEndpoints();
UDP_DisableEndpoints();
USBD_ConfigureEndpoint(0);
// Flush and enable the Suspend interrupt
AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_WAKEUP
| AT91C_UDP_RXRSM
| AT91C_UDP_RXSUSP;
AT91C_BASE_UDP->UDP_IER = AT91C_UDP_RXSUSP;
//if (pUsb->pCallbacks->startOfFrame != 0) {
//
// AT91C_BASE_UDP->UDP_IER = AT91C_UDP_SOFINT;
//}
// Invoke the Reset callback
USBDCallbacks_Reset();
// Acknowledge end of bus reset interrupt
AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES;
}
// Endpoint interrupts
else {
while (status != 0) {
// Check if endpoint has a pending interrupt
if ((status & (1 << eptnum)) != 0) {
UDP_EndpointHandler(eptnum);
status &= ~(1 << eptnum);
if (status != 0) {
TRACE_INFO_WP("\n\r - ");
}
}
eptnum++;
}
}
// Toggle LED back to its previous state
TRACE_INFO_WP("\n\r");
if (deviceState >= USBD_STATE_POWERED) {
LED_Clear(USBD_LEDUSB);
}
}