⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbdriver.c

📁 基于ADSP-BF535 USB驱动应用程序
💻 C
📖 第 1 页 / 共 3 页
字号:
*		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 + -