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

📄 fw2hid.c

📁 基于sy2100 ez-usb开发板的程序
💻 C
字号:
//-----------------------------------------------------------------------------
//	File:		fw2HID.c (fw.c modified by LTH on 20-Aug-01
//	Contents:	Firmware frameworks task dispatcher and device request parser
//				source.
//
//	Copyright (c) 2001 Cypress Semiconductor, Inc. All rights reserved
//-----------------------------------------------------------------------------
#include "ezusb.h"
#include "ezregs.h"
//-----------------------------------------------------------------------------
// Macros
//-----------------------------------------------------------------------------
#define	min(a,b) (((a)<(b))?(a):(b))
#define	max(a,b) (((a)>(b))?(a):(b))
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
#define	bmRequestType 	0
#define bRequest		1
#define	wValueL		 	2
#define wValueH			3
#define	wIndexL		 	4
#define wIndexH			5
#define	wLengthL		6
#define wLengthH		7
//
#define GET_REPORT		0x01	// HID Request Types
#define SET_REPORT		0x09
#define GET_IDLE		0x02
#define SET_IDLE		0x0A
//
#define rt_INPUT		1		// HID report types
#define rt_OUTPUT		2
#define rt_FEATURE		3		// all others are 'reserved'
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
//volatile BOOL	GotSUD;	// set by SUDAV ISR
//volatile BOOL	Sleep;	// Sleep mode enable flag
BOOL	GotSUD;			// set by SUDAV ISR
BOOL	Sleep;			// Sleep mode enable flag
BOOL	Rwuen;
BOOL	Selfpwr;
BYTE	IdleRate;
//-----------------------------------------------------------------------------
// Prototypes
//-----------------------------------------------------------------------------
void SetupCommand(void);
void TD_Init(void);
void TD_Poll(void);
BOOL TD_Suspend(void);
BOOL TD_Resume(void);

BOOL DR_SetConfiguration(void);
BOOL DR_GetConfiguration(void);
BOOL DR_SetInterface(void);
BOOL DR_GetInterface(void);
BOOL DR_GetStatus(void);
BOOL DR_ClearFeature(void);
BOOL DR_SetFeature(void);

void process_standard_request(void);
void process_class_request(void);
void process_descriptor(void);

//-----------------------------------------------------------------------------
// Descriptors
//-----------------------------------------------------------------------------
extern code	DeviceDescr,ConfigDescr,String0,String1,String2,HIDDescr;
extern code ReportDescr,ReportDescr_end;
//-----------------------------------------------------------------------------
// Code
//-----------------------------------------------------------------------------

// Task dispatcher
void main(void)						// power-on reset takes us here
{
	// Initialize Global States
	Sleep = FALSE;					// Disable sleep mode
	Rwuen = FALSE;					// Disable remote wakeup
	Selfpwr = FALSE;				// Disable self powered
	GotSUD = FALSE;					// Clear "Got setup data" flag

	// Initialize user device
	TD_Init();

	EZUSB_IRQ_ENABLE();					// Enable USB interrupt (INT2)
	EZUSB_ENABLE_RSMIRQ();				// Wake-up interrupt
	PORTCCFG |= 0xc0;					// Turn on r/w lines for external memory (Keil monitor)
	USBBAV = USBBAV | 1 & ~bmBREAK;		// Disable breakpoints and ENABLE autovectoring
	USBIEN |= bmSUDAV | bmSUSP | bmURES;	// Enable selected interrupts
	EA = 1;								// Enable 8051 interrupts

    EZUSB_Discon(TRUE); 				// ReNumerate
 
	// Task Dispatcher
	while(TRUE)							// Main Loop
	{
		if(GotSUD)						// Wait for SUDAV
		{
			SetupCommand();	 			// Service the SETUP request
  			GotSUD = FALSE;				// Clear SUDAV flag--NOTE: clearing GotSUD after calling SetupCommand()
		}								// properly handles multi-packet Get_Descriptor_Report requests
										// (which would generate multiple SUDAV interrupts).
		if (Sleep)						// set to TRUE by the SUSPEND ISR
		    {
    		if(TD_Suspend())			// hook in periph.c to do stuff before suspending
    		    { 
    		    Sleep = FALSE;	   		// Clear the "go to sleep" flag.  Do it here to prevent any race condition between wakeup and the next sleep.
    		    do
    		        {
       			    EZUSB_Susp();		// Place processor in idle mode.
    		        }
                while(!Rwuen && EZUSB_EXTWAKEUP());
                // Must continue to go back into suspend if the host has disabled remote wakeup
                // *and* the wakeup was caused by the external wakeup pin.
                
    			// 8051 activity will resume here due to USB bus or Wakeup# pin activity.
    			EZUSB_Resume();	// If source is the Wakeup# pin, signal the host to Resume.		
    			TD_Resume();
    		    }   
		    }

		TD_Poll();
	} // end while(TRUE)
}

// Device request parser
void SetupCommand(void)
{
	switch(SETUPDAT[bmRequestType] & 0x60)	// 00-std,20-class,40-vendor,60-reserved.
	{
		case SETUP_STANDARD_REQUEST:
			process_standard_request();
		break;
		case SETUP_CLASS_REQUEST:
			process_class_request();
		break;
		default:
 			EZUSB_STALL_EP0();		// we don't handle SETUP_VENDOR_REQUEST or "Reserved".
	}
EP0CS = bmHS;						// Clear the HS-NAK bit by writing '1' to it
}

void process_standard_request(void)
{
	switch(SETUPDAT[bRequest])
	{
		case SC_GET_DESCRIPTOR:		// *** Get Descriptor
			process_descriptor();
		break;
		case SC_GET_INTERFACE:					// *** Get Interface
			DR_GetInterface();
		break;
		case SC_SET_INTERFACE:					// *** Set Interface
			DR_SetInterface();
		break;
		case SC_SET_CONFIGURATION:				// *** Set Configuration
			DR_SetConfiguration();
		break;
		case SC_GET_CONFIGURATION:				// *** Get Configuration
			DR_GetConfiguration();
		break;
		case SC_GET_STATUS:						// *** Get Status
			if(DR_GetStatus())
				switch(SETUPDAT[bmRequestType])
				{
					case GS_DEVICE:				// Device
						IN0BUF[0] = ((BYTE)Rwuen << 1) | (BYTE)Selfpwr;
						IN0BUF[1] = 0;
						EZUSB_SET_EP_BYTES(IN0BUF_ID,2);
					break;
					case GS_INTERFACE:			// Interface
						IN0BUF[0] = 0;
						IN0BUF[1] = 0;
						EZUSB_SET_EP_BYTES(IN0BUF_ID,2);
					break;
					case GS_ENDPOINT:			// End Point
						IN0BUF[0] = EPIO[EPID(SETUPDAT[wIndexL])].cntrl & bmEPSTALL;
						IN0BUF[1] = 0;
						EZUSB_SET_EP_BYTES(IN0BUF_ID,2);
					break;
					default:					// Invalid Command
						EZUSB_STALL_EP0();	
				}
		break;
		case SC_CLEAR_FEATURE:					// *** Clear Feature
			if(DR_ClearFeature())
				switch(SETUPDAT[bmRequestType])
				{
					case FT_DEVICE:				// Device
						if(SETUPDAT[wValueL] == 1)
							Rwuen = FALSE; 		// Disable Remote Wakeup
						else
							EZUSB_STALL_EP0();	// we only recognize '1'
					break;
					case FT_ENDPOINT:			// End Point
						if(SETUPDAT[wValueL] == 0)
                  		{
							EZUSB_UNSTALL_EP(EPID(SETUPDAT[wIndexL]));
                    		EZUSB_RESET_DATA_TOGGLE(SETUPDAT[wIndexL]);
                  		}
						else
							EZUSB_STALL_EP0();
					break;
				}
		break;
		case SC_SET_FEATURE:					// *** Set Feature
			if(DR_SetFeature())
				switch(SETUPDAT[bmRequestType])
				{
					case FT_DEVICE:				// Device
						if(SETUPDAT[wValueL] == 1)
							Rwuen = TRUE;		// Enable Remote Wakeup
						else
							EZUSB_STALL_EP0();
					break;
					case FT_ENDPOINT:			// End Point
						if(SETUPDAT[wValueL] == 0)
							EZUSB_STALL_EP( EPID(SETUPDAT[wIndexL]) );
						else
							EZUSB_STALL_EP0();
					break;
				}
		break;
		default:								// *** Invalid Command
				EZUSB_STALL_EP0();
	} // end switch
} // end process_request()

void process_descriptor()
{
unsigned int	j,k,ReportSize;
	switch(SETUPDAT[wValueH])
	{
		case GD_DEVICE:					// Device
			SUDPTRH = MSB(&DeviceDescr);
			SUDPTRL = LSB(&DeviceDescr);
		break;
		case GD_CONFIGURATION:			// Configuration
			SUDPTRH = MSB(&ConfigDescr);
			SUDPTRL = LSB(&ConfigDescr);
		break;
		case GD_STRING:					// String
			{
			switch(SETUPDAT[wValueL])
				{
				case 0:					// string index 1
					SUDPTRH = MSB(&String0);
					SUDPTRL = LSB(&String0);
				break;
				case 1:					// string index 1
					SUDPTRH = MSB(&String1);
					SUDPTRL = LSB(&String1);
				break;
				case 2:					// string index 2
					SUDPTRH = MSB(&String2);
					SUDPTRL = LSB(&String2);
				break;
				default:				// Invalid string requested
					EZUSB_STALL_EP0();
				} // end switch
			} // end case
		break;
		case GD_HID:					// Get-Descriptor: HID
			SUDPTRH = MSB(&HIDDescr);
			SUDPTRL = LSB(&HIDDescr);
		break;
		case GD_REPORT:					// Get-Descriptor: Report
/*
Note: A HID report does not have a length field which the SIE can read to determine how many
bytes to send using the Setup Data Pointer. Therefore we need to 'manually' send the data.
*/
			ReportSize = (WORD)&ReportDescr_end - (WORD)&ReportDescr;
			AUTOPTRH = MSB(&ReportDescr);
			AUTOPTRL = LSB(&ReportDescr);
			while(ReportSize)
				{
				k = min(ReportSize,64);		// smaller of ReportSize or IN0 Buffer (64 bytes)
				for(j=0;j<k;j++)
					IN0BUF[j]=AUTODATA;
					IN0BC = j;					// arm the IN transfer
					ReportSize = ReportSize-j;
					while(EP0CS & bmIN);		// wait for it to go out and get ACK'd
				}
		break;
 	    default:					// *** Invalid Command
			EZUSB_STALL_EP0();
	} // end switch
} // end function

void process_class_request(void)	// Handle the HID class
{
switch(SETUPDAT[bRequest])
	{
	case SET_REPORT:
		switch(SETUPDAT[wValueH])			// wValueH has report type
			{
			case rt_INPUT:
			break;
			case rt_OUTPUT:
			break;
			case rt_FEATURE:
			break;
			default:
				EZUSB_STALL_EP0();
			}
	break;
	case GET_REPORT:
		switch(SETUPDAT[wValueH])			// wValueH has report type
			{
			case rt_INPUT:
			break;
			case rt_OUTPUT:
			break;
			case rt_FEATURE:
			break;
			default:
				EZUSB_STALL_EP0();
			}
	break;
	case SET_IDLE:
		IdleRate = SETUPDAT[wValueH];
	break;
	case GET_IDLE:
		IN0BUF[0]=IdleRate;
		IN0BC = 1;					// arm the IN transfer
	break;
	default:
			EZUSB_STALL_EP0();		// this includes 'GET/SET_PROTOCOL'
	} // end switch
}

void resume_isr(void) interrupt WKUP_VECT	// Wakeup interrupt handler
{
	EZUSB_CLEAR_RSMIRQ();
}


⌨️ 快捷键说明

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