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

📄 control_ep0.c

📁 Mitsubishi M30245 SampleCode
💻 C
📖 第 1 页 / 共 3 页
字号:
/*******************************************************************
 *
 *    DESCRIPTION: M30245 Mit_USB Demonstration Application
 *
 *    AUTHOR: Mitsubishi DEC-E
 *
 *    HISTORY: 0.5 5/30/02 Initial creation for NC30
 *			   1.0 6/18/02 First official release
 *			   1.1 6/27/02 Updated ISO routines
 *			   1.2 8/07/02 Updated for Rev B Starter Kit Board
 *
 *******************************************************************/

/** include files **/

#include "sfr245.h"
#include "descriptors.h"
#include "extern.h"

// Function Prototypes
void RequestType(void);
void StandardRequest(void);
void VendorRequest(void);
void SendEP0Data(void);
void CmdSetAddress(void);
void CmdGetDescriptor(void);
void CmdGetStatus(void);
void CmdGetInterface(void);
void CmdSetInterface(void);
void CmdGetConfiguration(void);
void CmdSetConfiguration(void);
void CmdClearFeature(void);
void CmdSetFeature(void);
void WriteLEDData(void);

/*
 ** RequestType
 *
 *  FILENAME: control_ep0.c 
 *
 *  PARAMETERS: None
 *
 *  DESCRIPTION: Determines what request type, (standard, class, or vendor) is being
 *				 asked for.
 *
 *  RETURNS: Nothing
 *
 */
void RequestType(void){

		ep0csr8 = 1;					// Since this is a SETUP packet clear flag here

		switch( SetupPacket.bmRequestType & 0x60 ) {	// Mask off unnecessary bits

			case 0x00:	
				StandardRequest();		// Standard USB request
				break;

			case 0x20:					// Class specific requests
				ep0cs = 0x1040;			// STALL not supported													
				break;					// Nothing here for this example

			case 0x40:					// USB vendor request class
				VendorRequest();
				break;

			default:
				ep0cs = 0x1040;			// STALL any invalid request													
		}
}

/*
 ** StandardRequest
 *
 *  FILENAME: control_ep0.c 
 *
 *  PARAMETERS: None
 *
 *  DESCRIPTION: Determines what standard chapter 9 USB request is being asked.
 *
 *  RETURNS: Nothing
 *
 */
void StandardRequest(void){

	switch( SetupPacket.bRequest ) {					
		case 0:
		 	CmdGetStatus();
			break;

		case 1:
			CmdClearFeature();
			break;

		case 3:
			CmdSetFeature();
			break;

		case 5:
			CmdSetAddress();
			break;

		case 6:
			CmdGetDescriptor();
			break;

		case 8:
			CmdGetConfiguration();
			break;

		case 9:
			CmdSetConfiguration();
			break;

		case 10:
			CmdGetInterface();
			break;

		case 11:
			CmdSetInterface();
			break;

		default:
			ep0cs = 0x1040;			// if none of these then STALL request
				
	}
}

/*
 ** VendorRequest
 *
 *  FILENAME: control_ep0.c
 *
 *  PARAMETERS: None
 *
 *  DESCRIPTION: Processes USB VENDOR requests sent from the HOST
 *
 *  RETURNS: Nothing
 *
 */
void VendorRequest(void){

	switch (SetupPacket.bRequest){
		case 1:
			WriteLEDData();			// Update the LED values on the SK board
			break;

		case 2:
			break;

		case 4:
			DataTransferFlags.SendBulkData = 1;		// Set flag so that MAIN can send BULK data
			ep0cs = 0x2240;							// OBR, DATA_END, and MASK
			break;

		default:
			ep0cs = 0x1040;							// if none of these then STALL request
	}			 
}

/*
 ** CmdSetAddress
 *
 *  FILENAME: control_ep0.c 
 *
 *  PARAMETERS: None
 *
 *  DESCRIPTION: Takes address assigned by the HOST and enters it into the USBA
 *				 register. This request is different depending on whether the 
 *				 device already has an assigned address or not. Device enters the 
 *				 ADDRESSED state at this point.
 *
 *  RETURNS: Nothing
 *
 */
void CmdSetAddress(void) {

	if ( usba != 0 ){					// Do we have an address yet?
		ep0cs = 0x2240;					// Set CLR_OUT_BUF_RDY, DATA_END, & DATA_END_MASK
		usba = SetupPacket.wValueLow;	// Now load our new device address
		USBFlags.Addressed = 1;			// And set the ADDRESSED state flag
	}

	else{ 								// Otherwise we're changing addresses
		usba = SetupPacket.wValueLow;	// Load our new device address
		ep0cs = 0x2240;					// clear out_pkt_rdy, data end, & mask
		USBFlags.Addressed = 1;			// And set a flag showing current state
	}
}

/*
 ** CmdGetDescriptor
 *
 *  FILENAME: control_ep0.c
 *
 *  PARAMETERS: None
 *
 *  DESCRIPTION: Determines what descriptor string is to be returned to the HOST.
 *				 Calls SendEP0Data to transfer data to HOST.
 *
 *  RETURNS: Nothing
 *
 */
void CmdGetDescriptor(void) {

	ep0csr6 = 1;		// Set CLR_OUT_BUF_RDY moving to the DATA stage for these transactions

	switch( SetupPacket.wValueHigh ) {		// Mask to determine what descriptor is being asked
		case 1:										// Send Device Descriptor
			pStringAddr = DeviceDescriptor;		// Pointer to start of string
			SendLength = DeviceDescriptor[0];	// Size of string
			break;

		case 2:										// Send Config Descriptor
			pStringAddr = ConfigDescriptor;		// Pointer to start of string
			SendLength = ConfigDescriptor[2];	// Size of string
			break;

		case 3:	
			switch( SetupPacket.wValueLow ) {	// Send String Descriptor
				case 0:							// Language ID String
					pStringAddr = LangIDString;
					break;
				case 1:							// Manuf. String
					pStringAddr = ManfString;
					break;
				case 2:							// Product String
					pStringAddr = ProdString;
					break;
				case 8:							// Configuration string
					pStringAddr = ConfigString;
					break;						
				case 4:							// Alternate Interface 0 String
					pStringAddr = AltSet0String;
					break;
				case 5:							// Alternate Interface 1 String
					pStringAddr = AltSet1String;
					break;
				case 6:							// Alternate Interface 2 String
					pStringAddr = AltSet2String;
					break;
				case 7:							// Product Serial Number String
					pStringAddr = SerialNumberString;
					break;
				default:						// None of these
					ep0cs = 0x1040;				// STALL and return
					return;
			}

			SendLength = pStringAddr[0];		// Get size of string
			break;

		default:								// None of these
			ep0cs = 0x1040;						// STALL and return
			return;
	}

	if( SendLength > SetupPacket.wLengthLow ){	// If HOST asks for less data then 
		SendLength = SetupPacket.wLengthLow;	// reset SendLength pointer to requested 
	}											// length

	SendBufferIndex = 0x00;						// Reset string pointer
	while ( SendLength != 0 ){					// Call this function until out of data
		ep0ic = 0x00;							// disable to prevent extra EP0 interrupts
		SendEP0Data();							// Call it here
	}
}

/*
 ** SendEP0Data
 *
 *  FILENAME: control_ep0.c
 *
 *  PARAMETERS: None
 *
 *  DESCRIPTION: Loads FIFO and sends out descriptor data to HOST. Called by CmdGetDescriptor.
 *				 Packets sent differently depending on type and length.
 *
 *  RETURNS: Nothing
 *
 */

void SendEP0Data(void){
unsigned char SendNullPacket = 0x00;

	if ( USBFlags.SetupEndFlag ){

		USBFlags.SetupEndFlag = 0;		// Debug....
		
		ep0csr11 = 1;			// This clears the SETUP_END condition
	
		ir_ep0ic = 0;			// ensure that EP0 interrupt is cleared
		ep0ic = 0x03;			// Enable the EP0 interrupt (level 3)	

		SendLength = 0x00;		// Don't load anymore data to the FIFO
		return;					// and just return, completing the transaction...
	}

	if ( SendLength == 8 ){		// If last packet is = to MAXP and not a 
		SendNullPacket = 1;		// STRING descriptor, then device must send a NULL
	}							// packet to end the transfer per the USB specification.
								// STRING descriptors do not need a NULL terminator however.

	if ( SendLength > 8 ) {			// If more than 8 bytes then break it up
		Bytes2Send = 8;				// And send since EP0 here is 8 bytes deep
		SendLength -= 8;			// And subtract this from the total
	}
	else{							// Otherwise, send it all now
		Bytes2Send = SendLength;	// Equate our variable
		SendLength = 0;				// And clear out SendLength
	}
	
	for( ; Bytes2Send; Bytes2Send--) {				// Now let's load the FIFO
   		ep0il = pStringAddr[ SendBufferIndex ];
   		SendBufferIndex++;							// And increment string pointer
   	}

	if ( SendLength == 0 ){			// Is this the last packet?
		if ( (SendNullPacket == 0x01) && (SetupPacket.wValueHigh != 0x03) ){ // Is NULL packet needed?
			ep0csr7 = 1;			// Set IN_PKY_RDY
			while ( ep0csr1 ){}		// and wait for this packet to be taken

			ep0cs = 0x2280;			// Set DATA_END, IPR, and DATA_END mask (NULL packet)
	
			ir_ep0ic = 0;			// ensure that EP0 interrupt is cleared
			ep0ic = 0x03;			// Enable the EP0 interrupt (level 3)	
		}
		else{						// Otherwise this is a STRING descriptor. no NULL needed
			ep0cs = 0x2280;			// Set DATA_END, IPR, and DATA_END mask

			ir_ep0ic = 0;			// ensure that EP0 interrupt is cleared
			ep0ic = 0x03;			// Enable the EP0 interrupt (level 3)	
		}
	}
	else{
		ep0csr7 = 1;				// Set IN_PKY_RDY
		while ( ep0csr1 ){}			// and wait for this packet to be taken
	}
}				

⌨️ 快捷键说明

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