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

📄 usbdriver.c

📁 基于ADSP-BF535 USB驱动应用程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*----------------------------------------------------------------------------------
*
* COPYRIGHT (c) 2001 by Singing Electrons, Inc. All rights reserved.
*
*
* Module Name			: C:\se\adi\hidclass\Source\usbdriver.c
*
* Description			: The USB Driver - contains implementation of the low level USB interface.
*
*
* Revision History	: At bottom of the file.
*
*---------------------------------------------------------------------------------*/

/** include files **/
#include <sys/exception.h>
#include <sys/excause.h>
#include <defBF535.h>
#include "dtype.h"
#include "register.h"
#include "usb.h"
#include "usbdriver.h"
#include "dmablocks.h"
#include "dprintf.h"

/** local definitions **/


/* default settings */


typedef struct tagEPSTATE{
	UCHAR currentState;
	USB_SETUP_DATA setupData;
	void *dmaBuffer;
	UINT dmaBufferSize;
	UCHAR endpointType;
	UINT maxPacketSize;
	UINT defaultMaxTransferSize;
} EPSTATE, *PEPSTATE;

//for currentState
enum	{
	EP_STATE_IDLE = 0,
	EP_STATE_WAITING_FOR_SETUP, 
	EP_STATE_DATA_IN_PHASE,
	EP_STATE_DATA_OUT_PHASE,
	EP_STATE_STATUS_PHASE,
	EP_STATE_WAITING_FOR_IN_TC,
	EP_STATE_WAITING_FOR_OUT_TC,
	};


/** external functions **/

/** external data **/

/** internal functions **/

/** public data **/

/** private data **/
static int gNumEPBufsSetup = 0;
static EP_BUF gEndpointBuffers[MAX_EP_BUF];

static EPSTATE gActiveEndpointStates[MAX_PHY_EP];

static PSETUPPROC gpOnSetupReq;

static PGETDEVICEDESCRIPTORPROC gpOnGetDeviceDescriptor;
static PGETCONFIGDESCRIPTORPROC gpOnGetConfigDescriptor;
static PGETSTRINGDESCRIPTORPROC gpOnGetStringDescriptor;

static PINTCPROC gpOnInTC;
static POUTTCPROC gpOnOutTC;
static PMERRPROC gpOnMERR;
static PSUSPENDPROC gpOnSuspend;
static PRESUMEPROC gpOnResume;
static PRESETPROC gpOnReset;
static PCONFIGPROC gpOnConfigurationChange;
static PSOFPROC gpOnSOF;
static USHORT gep_int_mask; //Nothing special


UCHAR *gpControlEPDMABufferOUT;
UCHAR *gpControlEPDMABufferIN;

/** public functions **/
void *AllocDMABlock (int numBytesToAllocate);
void FreeDMABlock (void *blockToDealloc);
void InitDMA (void);

/** private functions **/
#pragma interrupt_reentrant
EX_INTERRUPT_HANDLER (USBDriver_ISR);

bool GetControlEndpointReady (UCHAR endpointNumber);
void HandleNoDataControlRequest (UCHAR currentEndpoint);
void HandleDataOutControlRequest (UCHAR currentEndpoint);
void HandleDataInControlRequest (UCHAR currentEndpoint);
bool DispatchDataInControlRequest (UCHAR endpointNumber);


/*------------------------------------------------------------
*	USBDriver_PreInit
*
*	Parameters:  
*
*	Globals Used:
*		gNumEPBufsSetup
*
*	Description:
*		This routine initializes the global state variables used
*		by the driver, and the USBD hardware. It does not
*		initialize the EPBUFs
*
*	Returns:
*
*
*------------------------------------------------------------*/
bool USBDriver_PreInit (void)
	{
		UINT chipVer;


		gNumEPBufsSetup = 0;
		memset (&gEndpointBuffers, 0, sizeof (gEndpointBuffers));

		memset (&gActiveEndpointStates, 0, sizeof (gActiveEndpointStates));

		InitDMA ();

		//Let's setup the control endpoint, as it should be the same
		//for all devices
		USBDriver_SetupEndpoint (EP0, EP_CONFIG0, EP_IFACE0, EP_ALT0, 0, EP_CTL, 
			CONTROL_PIPE_PACKET_SIZE);

		gpOnSetupReq = nil;
		gpOnGetDeviceDescriptor = nil;
		gpOnGetConfigDescriptor = nil;
		gpOnGetStringDescriptor = nil;
		gpOnInTC = nil;
		gpOnOutTC = nil;
		gpOnMERR = nil;
		gpOnSuspend = nil;
		gpOnResume = nil;
		gpOnReset = nil;
		gpOnConfigurationChange = nil;

		// setup endpint interrpt mask
		gep_int_mask = (USBD_GINTR_EP1INT|USBD_GINTR_EP2INT|USBD_GINTR_EP3INT|
					   USBD_GINTR_EP4INT|USBD_GINTR_EP5INT|USBD_GINTR_EP6INT|
					   USBD_GINTR_EP7INT);

		// install the handler 
		//register_handler(ik_ivg7, USBDriver_ISR);
		register_handler(ik_ivg8, USBDriver_ISR);


		chipVer = 0xf0000000 & chipId_REG;
  
	  
	  if(chipVer) 
	  	{
	    	// rev. 1.0 or higher
		    SIC_IMASK_REG |= SIC_MASK2;
		  } 
		else 
			{
	    	// rev. 0.x
	    	SIC_IMASK_REG &= SIC_UNMASK2;  
	   	}

	  asm("ssync;");

	  //IMASK_REG |= 0x0080; // unmask IVG 7 at core
	  IMASK_REG |= 0x0100; // unmask IVG 8 at core
	  asm("ssync;");



		return (true);
	}



/*------------------------------------------------------------
*	USBDriver_SetupEndpoint
*
*	Parameters:
*		endpointNumber - the endpoint number to be used (EP0..EP7)
*		config - which configuration this setting is to be used for.
*		interface - which interface this setting is to be used for.
*		altSetting - which alt. setting this setting is to be used for.
*		direction - could be EP_IN or EP_OUT
*		ep_type - could be EP_CTL, EP_ISO, EP_BULK, or EP_INTERRUPT
*		maxPacketSize - maximum packet length - could be 8, 16, 32, 
*			64 for Bulk, Int, and Control EPs, or any value from
*			0 to 1023 for Iso. endpoints
*
*	Globals Used:
*		gNumEPBufsSetup
*
*	Description:
*		This routine loads the next EP_BUF array member with the 
*		supplied parameters
*
*	Returns:
*		true on success, false on failure
*
*
*------------------------------------------------------------*/
bool USBDriver_SetupEndpoint (UINT endpointNumber, UCHAR altSetting, 
	UCHAR interface, UCHAR configuration, UCHAR direction, 
	UCHAR ep_type, UINT maxPacketSize)			
	{
		//Make sure we can hold them all!
		if (gNumEPBufsSetup >= MAX_EP_BUF)
			return (false);
			
		gEndpointBuffers[gNumEPBufsSetup].s_ep_buf.ep_bufadrptr = endpointNumber;
		gEndpointBuffers[gNumEPBufsSetup].s_ep_buf.ep_maxpktsize = maxPacketSize;
		gEndpointBuffers[gNumEPBufsSetup].s_ep_buf.ep_dir = direction;
		gEndpointBuffers[gNumEPBufsSetup].s_ep_buf.ep_type = ep_type;
		gEndpointBuffers[gNumEPBufsSetup].s_ep_buf.ep_altsetting = altSetting;
		gEndpointBuffers[gNumEPBufsSetup].s_ep_buf.ep_interface = interface;
		gEndpointBuffers[gNumEPBufsSetup].s_ep_buf.ep_config = configuration;
		gEndpointBuffers[gNumEPBufsSetup].s_ep_buf.epnum = endpointNumber;

		gNumEPBufsSetup++;

		return (true);
		

	}


/*------------------------------------------------------------
*	USBDriver_CompleteInit
*
*	Parameters:  
*
*	Globals Used:
*
*	Description:
*		This routine finishes up the initialization, by installing the
*		callback addresses and loading up the EP bufs, enabling USB, etc..
*
*	Returns:
*
*
*------------------------------------------------------------*/
bool USBDriver_CompleteInit (PSETUPPROC pSetupProc, PGETDEVICEDESCRIPTORPROC pDevDescProc,
	PGETCONFIGDESCRIPTORPROC pCfgDescProc, PGETSTRINGDESCRIPTORPROC pStringDescProc,
	PINTCPROC pInTCProc, POUTTCPROC pOutTCProc, PMERRPROC pMerrProc, PSUSPENDPROC pSuspendProc, PRESUMEPROC pResumeProc,
	PRESETPROC pResetProc, PCONFIGPROC pConfigProc, PSOFPROC pSOFProc, UINT controlEPMaxTransferSize)
	{
		int epBufNumber, epByte, timeout;

		gpOnSetupReq = pSetupProc;
		gpOnGetDeviceDescriptor = pDevDescProc;
		gpOnGetConfigDescriptor = pCfgDescProc;
		gpOnGetStringDescriptor = pStringDescProc;
		gpOnInTC = pInTCProc;
		gpOnOutTC = pOutTCProc;
		gpOnMERR = pMerrProc;
		gpOnSuspend = pSuspendProc;
		gpOnResume = pResumeProc;
		gpOnReset = pResetProc;
		gpOnConfigurationChange = pConfigProc;
		gpOnSOF = pSOFProc;

		// initialize all 64 EP through the USBD_EPBUF
		for (epBufNumber = 0; epBufNumber < MAX_EP_BUF; epBufNumber++)
			{
				for (epByte = EP_BUF_SZ; epByte > 0; epByte--)
					{
						UCHAR byteToDownload = gEndpointBuffers[epBufNumber].a_ep_buf[epByte-1];
						USBD_EPBUF_REG = (USHORT) byteToDownload;

						timeout = NUM_EPBUF_RDY_CHK;
						while	(timeout)
							{
								if((USBD_EPBUF_REG) & USBD_EPBUF_RDY)
									break;
								timeout--;
							}

						if (!timeout)
							break;
						asm("ssync;");
					}
			}

		//See if we're all done!
		if(((USBD_EPBUF_REG) & USBD_EPBUF_CFG))
			{
				asm("ssync;");
				return (false);
			}

		asm("ssync;");

		//=========================================================================
		// setup the USBD_GINTR, USBD_INTRx and DMA USBD_DMACFG
		// interrupt mask !
		//=========================================================================
		// clear all pending interrupts
		USBD_GINTR_REG = (USHORT)0xFFFF; 
		
		// unmask all the EPs interrupt as well 
		USBD_GMASK_REG &= (USHORT)~(USBD_GMASK_EP0MSK|USBD_GMASK_EP1MSK|USBD_GMASK_EP2MSK|
									USBD_GMASK_EP3MSK|USBD_GMASK_EP4MSK|USBD_GMASK_EP5MSK|
									USBD_GMASK_EP6MSK|USBD_GMASK_EP7MSK|USBD_GMASK_CFGM |USBD_GMASK_RSTM|
									USBD_GMASK_SUSPM|USBD_GMASK_RESUMEM | USBD_GMASK_SOFM);

									
		// clear interrupt for all the EPs
		USBD_INTR0_REG |= (USHORT)(USBD_INTR_TC|USBD_INTR_PC|USBD_INTR_BCSTAT|
								   USBD_INTR_SETUP|USBD_INTR_MSETUP|USBD_INTR_MERR);
		USBD_INTR1_REG |= (USHORT)(USBD_INTR_TC|USBD_INTR_PC|USBD_INTR_BCSTAT);
		USBD_INTR2_REG |= (USHORT)(USBD_INTR_TC|USBD_INTR_PC|USBD_INTR_BCSTAT);
		USBD_INTR3_REG |= (USHORT)(USBD_INTR_TC|USBD_INTR_PC|USBD_INTR_BCSTAT);
		USBD_INTR4_REG |= (USHORT)(USBD_INTR_TC|USBD_INTR_PC|USBD_INTR_BCSTAT);
		USBD_INTR5_REG |= (USHORT)(USBD_INTR_TC|USBD_INTR_PC|USBD_INTR_BCSTAT);
		USBD_INTR6_REG |= (USHORT)(USBD_INTR_TC|USBD_INTR_PC|USBD_INTR_BCSTAT);
		USBD_INTR7_REG |= (USHORT)(USBD_INTR_TC|USBD_INTR_PC|USBD_INTR_BCSTAT);

		// Unmask the USBD interrupts
		USBD_MASK0_REG &= (USHORT)~(USBD_MASK_TC|USBD_MASK_PC|USBD_MASK_SETUP|
							USBD_MASK_MSETUP|USBD_MASK_MERR|USBD_MASK_BCSTAT); 

		// Let's try something different: enable only BCSTAT
		// SL	:)
	#if 1
		USBD_MASK1_REG &= (USHORT)~(USBD_MASK_TC|USBD_MASK_PC|USBD_INTR_BCSTAT|USBD_MASK_MERR);
		USBD_MASK2_REG &= (USHORT)~(USBD_MASK_TC|USBD_MASK_PC|USBD_INTR_BCSTAT);
		USBD_MASK3_REG &= (USHORT)~(USBD_MASK_TC|USBD_MASK_PC|USBD_INTR_BCSTAT);
		USBD_MASK4_REG &= (USHORT)~(USBD_MASK_TC|USBD_MASK_PC|USBD_INTR_BCSTAT);
		USBD_MASK5_REG &= (USHORT)~(USBD_MASK_TC|USBD_MASK_PC|USBD_INTR_BCSTAT);
		USBD_MASK6_REG &= (USHORT)~(USBD_MASK_TC|USBD_MASK_PC|USBD_INTR_BCSTAT);
		USBD_MASK7_REG &= (USHORT)~(USBD_MASK_TC|USBD_MASK_PC|USBD_INTR_BCSTAT);
	#else
		USBD_MASK1_REG &= (USHORT)~(USBD_INTR_BCSTAT);
		USBD_MASK2_REG &= (USHORT)~(USBD_INTR_BCSTAT);
		USBD_MASK3_REG &= (USHORT)~(USBD_INTR_BCSTAT);
		USBD_MASK4_REG &= (USHORT)~(USBD_INTR_BCSTAT);
		USBD_MASK5_REG &= (USHORT)~(USBD_INTR_BCSTAT);
		USBD_MASK6_REG &= (USHORT)~(USBD_INTR_BCSTAT);
		USBD_MASK7_REG &= (USHORT)~(USBD_INTR_BCSTAT);
	#endif
		
		// clear the DMA FIFO first. before we use it !
		USBD_DMACFG_REG |= (USHORT)USBD_DMACFG_DMABC;	
		USBD_DMACFG_REG = (USHORT)USBD_DMACFG_DMAEN;

	 	//=========================================================================
		// program the DMA master interface with the USB module's base address
		// USBD_DMABL, USBD_DMABH
		//=========================================================================
		// BUG ! BUG ! BUG !
		// need to do the lower 16 bit first to avoid a compiler bug !
		USBD_DMABL_REG = (USHORT)((ULONG)gDMABuffer&USBD_DMABL_SGMSK);
		USBD_DMABH_REG = (USHORT)((ULONG)gDMABuffer >> 16);

		ActivateEndpoint (EP0, USBD_TYP_CTL, CONTROL_PIPE_PACKET_SIZE, controlEPMaxTransferSize);

		if (!GetControlEndpointReady (EP0))
			return (false);


		// Enable the USBD now
		USBD_CTRL_REG |= (USHORT)USBD_CTRL_ENA;

		asm("ssync;");

		//we're now ready to receive interrupts!
		return(true);

	}



/*------------------------------------------------------------
*	ActivateEndpoint
*
*	Parameters:
*		endpointNumber - endpoint to set the information for.
*		endpointType - type of endpoint - EP_CTL, EP_BULK, EP_INT, or EP_ISO
*		maxPacketSize - the maximum packet size for this endpoint.
*		defaultMaxTransferSize - the max. trasfer size to use by default.
*
*	Globals Used:
*		gActiveEndpointStates
*
*	Description:
*		This routine initializes the active endpoint state for the specified endpoint
*		with the type, max packet size and default max. transfer size for the endpoint.
*		This information is used in other circumstances. This routine should be called
*		once for each endpoint after a new config. has come in effect.
*
*	Returns:
*		Nothing
*
*------------------------------------------------------------*/
void ActivateEndpoint (UCHAR endpointNumber, UCHAR endpointType, UCHAR maxPacketSize, UINT defaultMaxTransferSize)
	{
		gActiveEndpointStates[endpointNumber].endpointType = endpointType;
		gActiveEndpointStates[endpointNumber].maxPacketSize = maxPacketSize;
		gActiveEndpointStates[endpointNumber].defaultMaxTransferSize = defaultMaxTransferSize;
	}



/*------------------------------------------------------------
*	ArmEndpoint
*
*	Parameters:  
*		endpointNumber - endpoint to arm.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -