Exemple #1
0
DMP_INLINE(void) USB_Standard_Request(USB_Device *usb)
{
	switch (usb->Setup.bRequest)
	{
		// case 0x00: Get_Status(usb);        break;
		// case 0x01: Clear_Feature(usb);     break;
		// case 0x02: /* Reserved */          break;
		// case 0x03: Set_Feature(usb);       break;
		// case 0x04: /* Reserved */          break;
		case 0x05: Set_Address(usb);       break;
		case 0x06: Get_Descriptor(usb);    break;
		case 0x07: Set_Descriptor(usb);    break;
		case 0x08: Get_Configuration(usb); break;
		case 0x09: Set_Configuration(usb); break;
		case 0x0A: Get_Interface(usb);     break;
		case 0x0B: Set_Interface(usb);     break;
		case 0x0C: Synch_Frame(usb);       break;
		default: break;
	};
}
void handle_Control ( )
{
	unsigned int usb_cnt=0;
	if((EP_STATUS_OUT & 0x01)||(EP_STATUS_IN & 0x01))                                                                                          // 8 byte setup data received
	{     
		EP_STATUS_OUT = 0x01;                                                                                 // write 1 to clear
		EP_STATUS_IN = 0x01;

		EP_STATE[0] = EP_IDLE;    // force EP_STATE[0] to EP_IDLE
		system.usbp0_data.wait_out_report=0;

		if (CNT0 == 8)                // Make sure that EP 0 has an Out Packet of size 8 byte
		{                                
			// added on 2011.5.8 to fix usb set_report error.
			if (EP0_ADDR_DEF==0x21 && EP0_ADDR_DEF_1 == 0x09 )
			{
				USBINT0 = 0xc0;
				Set_Report();
				system.usbp0_data.report_id=EP0_ADDR_DEF_2;
				system.usbp0_data.report_type = EP0_ADDR_DEF_3;
		
				set_ep_rdy(EP_0);			// 1:Endpoint 0 ready for transfer USB data.
			}
			else if(EP0_ADDR_DEF==0x21 && EP0_ADDR_DEF_1 == 0x01 )
			{								// Fix SET_CUR request error
				SET_CUR();
			}
			else
			{
				fifo_Read (EP_0, 8, (UINT8 *) & setup);
				// Get setup Packet off of Fifo,
				// it is currently Big-Endian

				// Compiler Specific - these next three
				// statements swap the bytes of the
				// setup packet words to Big Endian so
				// they can be compared to other 16-bit
				// values elsewhere properly
//				USBINT0 = 0xc0;
//				set_ep_rdy(EP_0);			// 1:Endpoint 0 ready for transfer USB data.
				setup.wValue.i = setup.wValue.c[MSB] + ((int)setup.wValue.c[LSB] << 8);			// High byte and low byte exchange()
				setup.wIndex.i = setup.wIndex.c[MSB] + ( (int)setup.wIndex.c[LSB] << 8);
				setup.wLength.i = setup.wLength.c[MSB] + ( (int)setup.wLength.c[LSB] << 8);

				// Intercept HID class - specific requests
				// Class request.
//				if( (setup.bmRequestType & ~ 0x80) == DSC_HID) 
				if((setup.bmRequestType & cRequestType) == cClassReq)
				{
					#if	0
					switch (setup.bRequest) 
					{
						case GET_REPORT:
							Get_Report ( );
							break;
						case SET_REPORT:
							Set_Report();          
							break;
						case GET_IDLE:
							Get_Idle ( );
							break;
						case SET_IDLE:
							Set_Idle ( );
							break;
						case GET_PROTOCOL:
							Get_Protocol ( );
							break;
						case SET_PROTOCOL:
							Set_Protocol ( );
							break;
						default:
							force_Stall ( );      // Send stall to host if invalid
							break;                 // request
					}
					#endif
					switch(setup.bRequest)
					{
					// bmRequestType, bRequest, bChannelNum.(CN), bControlSelect(CS, include volume, mute etc.), bInterfaceNO, bTerminal/unit ID, wLength.
					// CTL: 21 01 00 02  00 05 02 00
					// DO:  00 00
						case cSET_CUR:
							if(setup.wIndex.c[1] >= 3)		// HID interface.
							{
								Get_Report();
							}
							else
								SET_CUR();
							break;

						case cSET_MIN:
							if(setup.wIndex.c[1] >= 3)		// HID interface.
							{
								Get_Idle();
							}
							else
								SET_MIN();
							break;

						case cSET_MAX:
							SET_MAX();
							break;

						case cSET_RES:
							SET_RES();
							break;

						case cSET_MEM:
							SET_MEM();
							break;

/*
						case GET_REPORT:
							Get_Report();
							break;
*/
						case SET_REPORT:
							Set_Report();          
							break;
/*								
						case GET_IDLE:
							Get_Idle ( );
							break;
*/	
						case SET_IDLE:
							Set_Idle ( );
							break;
								
						case cGET_CUR:
							GET_CUR();
							break;

						case cGET_MIN:
							GET_MIN();
							break;

						case cGET_MAX:
							GET_MAX();
							break;

						case cGET_RES:
							GET_RES();
							break;

						case cGET_MEM:
							GET_MEM();
							break;

						case cGET_STAT:
							GET_STAT();
							break;
							
						default:
							force_Stall ( );      // Send stall to host if invalid
							break;                 // request
					}
					
				} 
				else
				{
					// Standard request.
					switch (setup.bRequest)       // Call correct subroutine to handle
					{                             // each kind of standard request
						case GET_STATUS:
							Get_Status ( );
							break;
						case CLEAR_FEATURE:
							Clear_Feature ( );
							break;
						case SET_FEATURE:
							Set_Feature ( );
							break;
						case SET_ADDRESS:
							Set_Address ( );
							break;
						case GET_DESCRIPTOR:
							Get_Descriptor ( );
							break;
						case GET_CONFIGURATION:
							Get_Configuration ( );
							break;
						case SET_CONFIGURATION:
							Set_Configuration( );
							break;
						case GET_INTERFACE:
							Get_Interface ( );
							break;
						case SET_INTERFACE:		// 01 0b   00 00(wValue)   01 00(wIndex)   00 00
							Set_Interface ( );	// wValue:Interface alternate setting(0x0 is zero bandwith alternate setting, 0x01 is normal isochronous operate)
							break;				// wIndex: Interface number of one of the audiostreaming interface.
						default:
							force_Stall ( );                 // Send stall to host if invalid request
							break;
					}
				}
			}
		}      
		else 
		{
			force_Stall ( );                       // if rec setup data is not 8 byte , protacal stall
		}
	}   
	else if (EP_STATE[0] == EP_SET_ADDRESS)     // Handle Status Phase of Set Address
	{
		FUNCT_ADR = setup.wValue.c[LSB];         // set usb Address SFR
		EP_STATE[0] = EP_IDLE;


	}
	else if (EP_STATE[0] == EP_WAIT_STATUS)
	{
		EP_STATE[0] = EP_IDLE;

		wait_tx_status=0;
	}   
	else if (EP_STATE[0] == EP_RX)              // See if endpoint should transmit
	{  							// Out Token. PC->Device.
		if (DATASIZE >= EP0_PACKET_SIZE)
		{
			fifo_Read(EP_0, EP0_PACKET_SIZE, (unsigned char * )DATAPTR);
			// Advance data pointer
			DATAPTR  += EP0_PACKET_SIZE;
			// Decrement data size
			DATASIZE -= EP0_PACKET_SIZE;
			// Increment data sent counter
			DATASENT += EP0_PACKET_SIZE;            
		}
		else
		{
			// read bytes from FIFO
//			// Report type: 0x01 input, 0x02 output, 0x03 feature report.
			if( system.usbp0_data.wait_out_report && (system.usbp0_data.report_type==PC_SET_REPORT_2) && (system.usbp0_data.report_id==PC_SET_REPORT_1) )
			{
				system.usbp0_data.wait_out_report=0;
				DATAPTR = & EP0_ADDR_DEF;
			
				if(PC_SET_REPORT_1 == DATAPTR[0])
				{
					DATAPTR++;
					DATASIZE--;
				}

				for ( system.usbp0_data.report_cnt = 0;         // read  num = NO  fifo_data;   
					system.usbp0_data.report_cnt< DATASIZE;
					system.usbp0_data.report_cnt ++ )
				{
					system.usbp0_data.set_report_data[system.usbp0_data.report_cnt] = DATAPTR[system.usbp0_data.report_cnt];
				}
				system.usbp0_data.aceept = 1;  
				system.usbp0_data.reday_report_flag = 0;
				set_report_status_phace=1;
			}
			else
			{
				fifo_Read (EP_0, DATASIZE, (UINT8 * ) DATAPTR);
				// KEYBOARD_OUT_REPORT
				if (system.usbp0_data.wait_out_report)
				{
					numlock_sta = system.usbp0_data.out_report[0] & 0x01;
					system.usbp0_data.out_report_index = DATASIZE;
					system.usbp0_data.wait_out_report=0;
					set_report_status_phace=1;
				}

			}

			set_Wait_Status ( );                  // set Endpoint to EP_WAIT_STATUS
		}

		if ( (DATASENT == setup.wLength.i) && (set_report_status_phace==0) )
		{
			set_Wait_Status ( );
		}
		set_report_status_phace=0;
	}   
    
	if (EP_STATE[0] == EP_TX)                                        // See if endpoint should transmit
	{     									// In Token, device->PC

		if ((DATASIZE == 0))// || (DATASENT == setup.wLength.i))   // when all data has been sent over
		{

			set_Wait_Status ( );

		}
		else
		{   
			CFG_EP0_1 = 0xc0; 
			if (DATASIZE >= EP0_PACKET_SIZE)
			{
				// Break Data into multiple packets if larger than Max Packet
				fifo_Write (EP_0, EP0_PACKET_SIZE, (unsigned char*)DATAPTR);
				// Advance data pointer
				DATAPTR  += EP0_PACKET_SIZE;
				// Decrement data size
				DATASIZE -= EP0_PACKET_SIZE;
				// Increment data sent counter
				DATASENT += EP0_PACKET_SIZE;
			}

			else
			{

				// If data is less than Max Packet size or zero
				fifo_Write (EP_0, DATASIZE, (unsigned char*)DATAPTR);
				// Increment data sent counter
				DATASENT += DATASIZE;
				// Decrement data size
				DATASIZE = 0;
				USBINT0 = 0xc0;   
				EP_RDY = 0x01 ;

				// when usb_reset and send ok inttrupt (USBINT0&0x48)!=0 // when setup come (EP_STATUS & 0x01) will set
				 while(((USBINT0 & 0x4C) == 0) && ((EP_STATUS_OUT & 0x01) == 0));   //wait usb_reset, suspend or sending end interrupt  happend, wait setup come
				if((USBINT0&0x40) !=0) 
				{  
					CFG_EP0_1 =0x40;
					EP_RDY = 0x01 ;
					USBINT0 = 0xc0;
					EP_STATE[0]= EP_WAIT_STATUS;

				}
				wait_tx_status = 1; 
				system.usbp0_data.wait_out_report=0;
			} 
		}   
	}


	if (system.usbp0_data.wait_out_report==0 && wait_tx_status ==0)  
	{  
		USBINT0 = 0xc0;
		//   set_ep_rdy(EP_0);   // set ready to receive or send next packet
		EP_RDY = 0x01 ;  
	}
}