📄 usbdriver.c
字号:
* gActiveEndpointStates
*
* Description:
* This routine is called to handle a Control Request(SETUP) with
* "OUT" data. It allocates a buffer based on the wLength provided
* in the setup request, and arms the endpoint again to recieve the
* setup data.
*
* Returns:
* Nothing.
*
*------------------------------------------------------------*/
void HandleDataOutControlRequest (UCHAR currentEndpoint)
{
//We come here because the host wants to send more data with the control req.
gActiveEndpointStates[currentEndpoint].currentState = EP_STATE_DATA_OUT_PHASE;
gActiveEndpointStates[currentEndpoint].dmaBufferSize = 0;
gActiveEndpointStates[currentEndpoint].dmaBuffer =
AllocDMABlock (gActiveEndpointStates[currentEndpoint].setupData.wLength);
if (!gActiveEndpointStates[currentEndpoint].dmaBuffer)
{
//Should probably stall!
StallEndpoint (currentEndpoint);
GetControlEndpointReady (currentEndpoint);
}
else
{
//The DMA buffer was allocated
gActiveEndpointStates[currentEndpoint].dmaBufferSize = gActiveEndpointStates[currentEndpoint].setupData.wLength;
ArmEndpoint (currentEndpoint, EP_OUT);
} //(!gActiveEndpointStates[currentEndpoint].dmaBuffer)
}
/*------------------------------------------------------------
* HandleDataInControlRequest
*
* Parameters:
* currentEndpoint - most of the time this will be 0
*
* Globals Used:
* gActiveEndpointStates
*
* Description:
* This routine is called to handle a DATA In requset on the control
* endpoint. This happens as part of a control transfer requiring
* data. This routine calls the DispatchDataInControlRequest which
* will either handle the request itself, or call upon the client
* to handle the request.
*
* Returns:
* Nothing.
*
*------------------------------------------------------------*/
void HandleDataInControlRequest (UCHAR currentEndpoint)
{
//We come here because the host wants to get data with the control req.
gActiveEndpointStates[currentEndpoint].currentState = EP_STATE_DATA_IN_PHASE;
gActiveEndpointStates[currentEndpoint].dmaBufferSize = 0;
gActiveEndpointStates[currentEndpoint].dmaBuffer =
AllocDMABlock (gActiveEndpointStates[currentEndpoint].setupData.wLength);
if (!gActiveEndpointStates[currentEndpoint].dmaBuffer)
{
//Should probably stall!
StallEndpoint (currentEndpoint);
GetControlEndpointReady (currentEndpoint);
}
else
{
gActiveEndpointStates[currentEndpoint].dmaBufferSize = gActiveEndpointStates[currentEndpoint].setupData.wLength;
//This could be one of the Get Descriptor requests, let's try to find out, and dispatch
//accordingl
if (DispatchDataInControlRequest (currentEndpoint))
{
ArmEndpoint (currentEndpoint, EP_IN);
}
else
{
//Free the DMA buffer
FreeDMABlock (gActiveEndpointStates[currentEndpoint].dmaBuffer);
gActiveEndpointStates[currentEndpoint].dmaBuffer = nil;
gActiveEndpointStates[currentEndpoint].dmaBufferSize = 0;
//Stall
StallEndpoint (currentEndpoint);
GetControlEndpointReady (currentEndpoint);
}
} //(!gActiveEndpointStates[currentEndpoint].dmaBuffer)
}
/*------------------------------------------------------------
* DispatchDataInControlRequest
*
* Parameters:
* endpointNumber - the endpoint on which the request was received
*
* Globals Used:
* None
*
* Description:
* This routine is called to handle a Control requset
* with a DATA In phase. By the time this routine is called
* the DMA buffer is allocated and all setup to be filled
*
* Returns:
* true if data is filled in, false if not.
*
*------------------------------------------------------------*/
bool DispatchDataInControlRequest (UCHAR endpointNumber)
{
bool sendToClient = true;
bool retVal = false;
PUSB_SETUP_DATA pSetupData = &gActiveEndpointStates[endpointNumber].setupData;
//First see if it is a GET DESCRIPTOR request
if ((endpointNumber == EP0) &&
(USB_CONTROL_REQUEST_GET_DIRECTION (pSetupData->bmRequestType) == USB_CONTROL_REQUEST_TYPE_IN) &&
(USB_CONTROL_REQUEST_GET_TYPE (pSetupData->bmRequestType) == USB_CONTROL_REQUEST_TYPE_STANDARD) &&
(USB_CONTROL_REQUEST_GET_RECIPIENT (pSetupData->bmRequestType) == USB_CONTROL_REQUEST_TYPE_DEVICE) &&
(pSetupData->bRequest == USB_GET_DESCRIPTOR)
)
{
switch (HIBYTE(pSetupData->wValue))
{
case USB_DEVICE_DESCRIPTOR:
//Make sure that the index is 0, and the client has registered a callback for
//get device descriptor
if ((LOBYTE(pSetupData->wValue) == 0) && (gpOnGetDeviceDescriptor))
{
//Dprintf ("Get Device Descriptor");
sendToClient = false;
retVal = (gpOnGetDeviceDescriptor)(gActiveEndpointStates[endpointNumber].dmaBuffer,
&gActiveEndpointStates[endpointNumber].dmaBufferSize);
}
break;
case USB_CONFIGURATION_DESCRIPTOR:
//Make sure that the index is 0, and the client has registered a callback for
//get config descriptor
//Dprintf ("Get Config Descriptor");
if ((LOBYTE(pSetupData->wValue) == 0) && (gpOnGetConfigDescriptor))
{
sendToClient = false;
retVal = (gpOnGetConfigDescriptor)(gActiveEndpointStates[endpointNumber].dmaBuffer,
&gActiveEndpointStates[endpointNumber].dmaBufferSize);
}
break;
case USB_STRING_DESCRIPTOR:
//Make sure that the the client has registered a callback for
//get string descriptor
//Dprintf ("Get String Descriptor");
if (gpOnGetStringDescriptor)
{
sendToClient = false;
retVal = (gpOnGetStringDescriptor)(LOBYTE(pSetupData->wValue), pSetupData->wIndex, gActiveEndpointStates[endpointNumber].dmaBuffer,
&gActiveEndpointStates[endpointNumber].dmaBufferSize);
}
break;
}
}
//Everything else will be caught here!
if (sendToClient)
{
if (gpOnSetupReq)
retVal = ((gpOnSetupReq) (endpointNumber, &gActiveEndpointStates[endpointNumber].setupData,
gActiveEndpointStates[endpointNumber].dmaBuffer, &gActiveEndpointStates[endpointNumber].dmaBufferSize));
}
return(retVal);
}
/*------------------------------------------------------------
* GetControlEndpointReady
*
* Parameters:
*
* Globals Used:
* gActiveEndpointStates
*
* Description:
* This routine gets a control endpoint ready to receive the next
* SETUP request.
*
* Returns:
* TRUE on success, FALSE if cannot allocate dma buffer.
*
*------------------------------------------------------------*/
bool GetControlEndpointReady (UCHAR endpointNumber)
{
//Move to waiting phase
gActiveEndpointStates[endpointNumber].currentState = EP_STATE_WAITING_FOR_SETUP;
//First allocate a buffer
gActiveEndpointStates[endpointNumber].dmaBufferSize = 0;
gActiveEndpointStates[endpointNumber].dmaBuffer = AllocDMABlock (gActiveEndpointStates[endpointNumber].defaultMaxTransferSize);
if (!gActiveEndpointStates[endpointNumber].dmaBuffer)
return(false);
gActiveEndpointStates[endpointNumber].dmaBufferSize = gActiveEndpointStates[endpointNumber].defaultMaxTransferSize;
//Now arm it!
ArmEndpoint (endpointNumber, EP_OUT);
return(true);
}
/*------------------------------------------------------------
* PrepareINEPForXFer
*
* Parameters:
* endpointNumber - endpoint to prepare
* ppDataBuffer - pointer to a location to recevied the allocated
* buffer.
*
* Globals Used:
* gActiveEndpointStates
*
* Description:
* This routine prepares an endpoint for a transfer by setting the
* state variables and allocating a block out of the DMA
* buffer state. The DMA buffer size is determined by
* the defaultMaxTransferSize setup for the endpoint previously
* using ActivateEndpoint.
*
* Returns:
* true on success, false if the dma buffer could not be allocated.
*
*------------------------------------------------------------*/
bool PrepareINEPForXFer (UCHAR endpointNumber, void **ppDataBuffer)
{
//Move to waiting phase
gActiveEndpointStates[endpointNumber].currentState = EP_STATE_WAITING_FOR_IN_TC;
//First allocate a buffer
gActiveEndpointStates[endpointNumber].dmaBufferSize = 0;
gActiveEndpointStates[endpointNumber].dmaBuffer = AllocDMABlock (gActiveEndpointStates[endpointNumber].defaultMaxTransferSize);
if (!gActiveEndpointStates[endpointNumber].dmaBuffer)
return(false);
gActiveEndpointStates[endpointNumber].dmaBufferSize = gActiveEndpointStates[endpointNumber].defaultMaxTransferSize;
*ppDataBuffer = gActiveEndpointStates[endpointNumber].dmaBuffer;
return(true);
}
/*------------------------------------------------------------
* PrepareOUTEPForXFer
*
* Parameters:
* endpointNumber - endpoint to prepare
*
* Globals Used:
* gActiveEndpointStates
*
* Description:
* This routine prepares an endpoint for a transfer by setting the
* state variables and allocating a block out of the DMA
* buffer state. The DMA buffer size is determined by
* the defaultMaxTransferSize setup for the endpoint previously
* using ActivateEndpoint.
*
* Returns:
* true on success, false if the dma buffer could not be allocated.
*
*------------------------------------------------------------*/
bool PrepareOUTEPForXFer (UCHAR endpointNumber)
{
//Move to waiting phase
gActiveEndpointStates[endpointNumber].currentState = EP_STATE_WAITING_FOR_OUT_TC;
//First allocate a buffer
gActiveEndpointStates[endpointNumber].dmaBufferSize = 0;
gActiveEndpointStates[endpointNumber].dmaBuffer = AllocDMABlock (gActiveEndpointStates[endpointNumber].defaultMaxTransferSize);
if (!gActiveEndpointStates[endpointNumber].dmaBuffer)
return(false);
gActiveEndpointStates[endpointNumber].dmaBufferSize = gActiveEndpointStates[endpointNumber].defaultMaxTransferSize;
return(true);
}
/*------------------------------------------------------------
* UnprepareOUTEP
*
* Parameters:
* endpointNumber - endpoint to un-prepare
*
* Globals Used:
* gActiveEndpointStates
*
* Description:
* This routine un-prepares an endpoint for a transfer by setting the
* state variables, and freeing the associated DMA block.
*
* Returns:
* nothing
*
*------------------------------------------------------------*/
void UnprepareEP (UCHAR endpointNumber)
{
//Move to idle state
gActiveEndpointStates[endpointNumber].currentState = EP_STATE_IDLE;
//Dealloc. DMA buffer
if (gActiveEndpointStates[endpointNumber].dmaBufferSize)
{
gActiveEndpointStates[endpointNumber].dmaBufferSize = 0;
FreeDMABlock(gActiveEndpointStates[endpointNumber].dmaBuffer);
}
}
/*------------------------------------------------------------
* StallEndpoint
*
* Parameters:
* endpointToStall - the endpoint to stall
*
* Globals Used:
* None
*
* Description:
* Stalls the specified endpoint!
*
* Returns:
* Nothing
*
*------------------------------------------------------------*/
void StallEndpoint (UCHAR endpointToStall)
{
USBD_CTRL_REG |= (1 << (endpointToStall + 8));
asm("ssync;");
}
/*----------------------------------------------------------------------------------
* $Log: usbdriver.c,v $
* Revision 1.7 2003/01/16 19:10:52 Devendra
* - BugFix: Reset, Suspend, and Resume interrupts were not unmasked.
* - Added support to provide a callback for SOF interrupts.
*
* Revision 1.6 2003/01/15 01:37:20 Devendra
* - Changed the ISR declaration to used workaround specified by ADI dsptools website.
* - Changed the name of UnprepareOUTEP to UnprepareEP
*
* Revision 1.5 2003/01/13 19:54:03 Devendra
* Changed the priorities of interrupts - now SPORT0 is ivg7, USB is ivg8
* Changed the USB ISR to reentrant isr (so that it can be interrupted by SPORT0 int.)
*
* Revision 1.3 2003/01/10 01:53:26 Devendra
* - Added support for doing OUT transfers (including isoch. transfers).
*
* Revision 1.2 2003/01/09 21:46:15 Devendra
* Added a better DMA block heap manager (dmablocks) so that it can be used with isoch. streaming.
*
* Revision 1.1 2003/01/09 01:16:36 Devendra
* First Rev of AudioClass - have the device enumerated as audio device, and the volume control and mute are functional!
*
* Revision 1.2 2003/01/08 01:41:56 Devendra
* - Changes to remove divide operations (to improve DSP cycle utilization).
* - Supressed dprintfs
*
* Revision 1.1 2002/10/31 00:30:59 Devendra
* Moved all files in one folder to avoid IDE related problems.
*
* Revision 1.2 2002/10/30 02:36:40 Devendra
* - Added more abstraction to HIDCLASS. So that it's possible to build
* different devices without making any changes to the HIDCLASS module.
* - Added proper support for handling USB SUSPEND, RESUME, and RESET events.
*
* Revision 1.1 2002/10/22 17:23:39 Devendra
* Rearranged file locations.
*
* Revision 1.5 2002/10/14 01:33:15 Devendra
* Got "custom" device functional with buttons and lights!
*
* Revision 1.4 2002/10/09 17:09:32 Devendra
* - Added support for handling IN endpoints.
* - Added HID descriptors (HID and HID Report)
* - Modified the Interface descriptors to comply to HID Class Spec.
* - Added functionality to use the push-buttons on the Eagle-35 as a mouse (for buttons as well as for movement).
* - The device is now a fully functioning USB Mouse!
*
* Revision 1.3 2002/10/08 20:44:03 Devendra
* - Separated the printf logging to a different c module.
*
* Revision 1.2 2002/10/08 19:57:02 Devendra
* - Added specific callbacks for getting Device, Config, and String descriptors.
* - BugFix: Max. Packet Size was not being set correctly in ArmEndpoint.
* - Added internal buffer based logging to allow real-time "printfs".
* - Added String descriptors.
*
* Revision 1.1 2002/09/20 06:51:30 Devendra
* First Rev.
*
*
*---------------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -