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

📄 subp.c

📁 51单片机与SL811HST做从机的PS3手柄程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <sl811.h>
#include <des.h>
#include <reg51.h>
#include <varial.h>


//--------------------------------
 // wait  usb reset  5ms
 //-------------------------------
void Delay(void)
{
  unsigned char   i,u;
 for(u=40;u>0;u--)
 {
 i=255;
 while(i--);
 }
 }
//*****************************************************************************************
//  unsigned char Read from SL811H
// a = register address
// return = data in register
//*****************************************************************************************
 unsigned char SL811Read( unsigned char a)
{  
	SL811H_ADDR = a;			
	return (SL811H_DATA);
}

//*****************************************************************************************
//  unsigned char Write to SL811H
// a = register address
// d = data to be written to this register address
//*****************************************************************************************
void SL811Write( unsigned char a,  unsigned char d)
{  
	SL811H_ADDR = a;	
	SL811H_DATA = d;
   
}

//*****************************************************************************************
// Buffer Read from SL811H
// addr = buffer start address
// s    = return buffer address where data are to be save/read
// c	= buffer data length
//*****************************************************************************************
void SL811BufRead( unsigned char addr,  unsigned char *s,  unsigned char c)
{	
	SL811H_ADDR = addr;	
   	while (c--) 
		*s++ = SL811H_DATA;
}

//*****************************************************************************************
// Buffer Write  to SL811H
// addr = buffer start address
// s    = buffer address where data are to be written
// c	= buffer data length
//*****************************************************************************************
void SL811BufWrite( unsigned char addr,  unsigned char *s,  unsigned char c)
{//	 unsigned char i;
	SL811H_ADDR = addr;	
	while (c--) 
	SL811H_DATA = *s++;

	// for(i=0;i<c;i++)
    //   SL811H_DATA = *(s+i);
}

//*****************************************************************************************
// Swap high and low  unsigned char 
//*****************************************************************************************
unsigned short WordSwap(unsigned short input)
{
	return(((input&0x00FF)<<8)|((input&0xFF00)>>8));
}

//*****************************************************************************************
// Audio Control Key Scanning Routine 
//*****************************************************************************************
void audio_key_scan(void)
{
	//Audio_Keys = (~P1) & AUDIO_KEYS;				// Mute/Vol Up/Vol Down Keys
//	if(Audio_Keys != Prev_Audio_Keys)				// Detect for any changes
     
//	{   
         key_temp=P1;
  	     if((key_temp&0xff)!=0xff)
		    {  Delay();
			   Delay();
			  key_temp=P1;
              if((key_temp&0xff)!=0xff)
			    { Delay();
			      Delay();
                  switch(~key_temp)
				     {case 1 : ++kc1;
                               if(kc1==1)      key[2]=0x01;
                               else if(kc1==2) key[2]=0x02;
                               else if(kc1==3) key[2]=0x04;
                               else if(kc1==4) key[2]=0x08;
                               else  kc1=0;	     
	                           break; 
					  case 2 : ++kc2;
                               if(kc2==1)      key[2]=0x10;
                               else if(kc2==2) key[2]=0x20;
                               else if(kc2==3) key[2]=0x40;
                               else if(kc2==4) key[2]=0x80;
                               else  kc2=0;
                               break;  
	         	      case 4 : ++kc3;
                               if(kc3==1)      key[3]=0x01;
                               else if(kc3==2) key[3]=0x02;
                               else if(kc3==3) key[3]=0x04;
                               else if(kc3==4) key[3]=0x08;
                               else  kc3=0;
					           break;
		              case 8 : ++kc4;
                               if(kc4==1)      key[3]=0x10;
                               else if(kc4==2) key[3]=0x20;
                               else if(kc4==3) key[3]=0x40;
                               else if(kc4==4) key[3]=0x80;
                               else if(kc4==5) key[4]=0x01;
                               else if(kc4==6) key[4]=0x02;
                               else if(kc4==7) key[4]=0x04;
                               else    kc4=0;
					           break;
					  case 0x10 :  
					           key[6]=0xff;key[7]=0xff;
					           break;
					  case 0x20 :
					            key[6]=0x00;key[7]=0x00;
								break;
					  case 0x40 :key[8]=0xff;key[9]=0xff;
					             break;
					  case 0x80 :key[8]=0x00;key[9]=0x00;
					            break;
					   default:break;
				     }

			   }
			   }
	    
		//SL811Write(EP1A_Slave_Buf,Audio_Keys);		// send bitmap back to host
        SL811BufWrite(EP1A_Slave_Buf,(unsigned char*)key,0x31);
		EP1A_IN_Arm(EP1A_Slave_Buf,0x31,ep1_toggle);	// Arm Ep1 and toggle data
              key[2]=0x00;key[3]=key[4]=0;
			  key[6]=key[7]=key[8]=key[9]=0x80;
//	}    
//	Prev_Audio_Keys = Audio_Keys;					// update previous key states
}

//*****************************************************************************************
// Internet Control Key Scanning Routine
//*****************************************************************************************
/*void internet_key_scan(void)
{
	return;
}
 */
//*****************************************************************************************
// EP1 interrupt service routine 
//*****************************************************************************************
void ep1_isr(void)
//int ep1_isr(void)
{
	SL811Write(IntStatus,EP1_DONE);					// clear EP1 interrupt	
	if(SL811Read(EP1AStatus) & EP_ACK)				// check for ACK bit set
		ep1_toggle = (((SL811Read(EP1AControl)&DATAX)==0) ? 1:0);			
													// toggle DATA sequence		
        audio_key_scan();
													//	return;
}

//*****************************************************************************************
// EP1's IN Token Arming (using Set A)
//*****************************************************************************************
void EP1A_IN_Arm( unsigned char buf_adr,  unsigned char len,  unsigned char seq)
{												
    SL811Write(EP1AAddress,buf_adr); 				// ep1 address buffer start adress
	SL811Write(EP1AXferLen,len);					// max length of transfer allowed
	if(seq)
	    SL811Write(EP1AControl,DATA1_IN);			// armed to transmit to host, DATA1
	else
	    SL811Write(EP1AControl,DATA0_IN);			// armed to transmit to host, DATA0
}

//*****************************************************************************************
// SOF interrupt service routine (act as 1ms timer)
//*****************************************************************************************
//int sof_isr(void)
/*int sof_isr(void)
{
	SL811Write(IntStatus,SOF_DONE);					// clear SOF interrupt		
	sof_cnt++;										// track msec timing

	if(sof_cnt==TIME_OUT)							//5 reset counter on specify 
	{												// time out.				
		sof_cnt	= 0;								
		timeout = 1;								// set timeout flag
	}

	return;
}
*/
//*****************************************************************************************
// EP0 interrupt service routine
//*****************************************************************************************
//int ep0_isr(void)
void  ep0_isr(void)
{
	 unsigned char 	status,  byte_rx, len_xfr;
	 unsigned char	 req_type,data_seq;

	SL811Write(IntStatus,EP0_DONE);	// clear EP0 interrupt	
	status 	= SL811Read(EP0AStatus);							// get packet status
	byte_rx = SL811Read(EP0AXferLen) - SL811Read(EP0ACounter);	// get no. of  unsigned chars received
																// for OUT data from host
	//----------------------------------------------------------------------------------------
	// ACK received 
	//----------------------------------------------------------------------------------------
	if(status & EP_ACK)
	{
		//----------------------------------------------------------------
		// Set newly assigned USB address
		//----------------------------------------------------------------
		if(Slave_USBaddr)								
	    {														// if new USB address was assigned, 
		    SL811Write(USBAddress,Slave_USBaddr);				// communicate all USB transaction	
	     	Slave_USBaddr = 0;									// using this new address.				
		}
        
		//================================================================
		// SETUP's ACKed
		//================================================================
		//status 	= SL811Read(EP0AStatus);
		if(status & EP_SETUP)					
		{
		 
	    	SL811BufRead(EP0A_Slave_Buf, ( unsigned char*)&dReq,  byte_rx); 		// capture SETUP data request
			len_req = WordSwap(dReq.wLength);							// len_req = actual requested length
			in_buffer_idx = 0;											// reset buffer locatio indexing
			IN_NULL = FALSE;											// these are for IN-NULL packet
			IN_EXACT = FALSE;											// transfer condition
			req_type = (dReq.bmRequest&0x60)>>5;						// decode for Std,Class,Vendor type
             
		    switch (req_type)											// Parse bmRequest Type
			{     
				//---------------------------------------------------------------------
				// Standard USB Requests
				//---------------------------------------------------------------------
				case STD_REQUEST:
				    switch (dReq.bRequest)								// Parse bRequest
    				{ 
	    				case GET_DESCRIPTOR:
		           			switch (( unsigned char)dReq.wValue)   				// Parse wValue
	    		 	      	{         
	   	        		 		case DEVICE:
									SL811BufWrite(EP0A_Slave_Buf,( unsigned char*)Dev_Descp,DEV_LEN);	// load Device Descp
									len_req = (len_req>=DEV_LEN) ? DEV_LEN:len_req;			// get exact data length													 
										
									break;

			             		case CONFIGURATION:
									SL811BufWrite(EP0A_Slave_Buf,( unsigned char*)Cfg_Descp,CFG_LEN);	// load Config Descp	
									len_req = (len_req>=CFG_LEN) ? CFG_LEN:len_req;	// get exact data length
			            		   
									break;

			             		case HID_DEV:
									SL811BufWrite(EP0A_Slave_Buf,( unsigned char*)Cfg_Descp+18,HID_LEN);// load HID Class Descp	
									len_req = (len_req>=HID_LEN) ? HID_LEN:len_req;			// get exact data length
			            		   	break;

			             		case HID_REPORT:
									SL811BufWrite(EP0A_Slave_Buf,( unsigned char*)Rep_Descp,REP_LEN);	// load Report Descp	
									len_req = (len_req>=REP_LEN) ? REP_LEN:len_req;			// get exact data length
				        	       	break;

			             		case STRING:
									switch(dReq.wValue>>8)									// get string index
									{
										case 0x00: SL811BufWrite(EP0A_Slave_Buf,( unsigned char*)LangString,LangString[0]);
												   len_req = (len_req>=LangString[0]) ? LangString[0]:len_req;
												  
											    break;				
										case 0x01: SL811BufWrite(EP0A_Slave_Buf,( unsigned char*)MfgString,MfgString[0]);
												   len_req = (len_req>=MfgString[0]) ? MfgString[0]:len_req;
												   break;		
										case 0x02: SL811BufWrite(EP0A_Slave_Buf,( unsigned char*)ProdString,ProdString[0]);
												   len_req = (len_req>=ProdString[0]) ? ProdString[0]:len_req;
												   break;		
									}
									break;	
							}	

							if (len_req == WordSwap(dReq.wLength))					// if requested length is equal to the
								IN_EXACT = TRUE;									// exact length of descriptor, set IN_EXACT
																					// is use during IN-NULL pkt trasnmission
							len_xfr = (len_req>=EP0_LEN) ? EP0_LEN:( unsigned char)len_req;	// get current IN transfer length
							EP0A_IN_Arm(EP0A_Slave_Buf,len_xfr,1);					// Arm IN response, start with DATA1 seq
							in_buffer_idx += len_xfr;								// update to next muliple buffer location
							len_req -= len_xfr;	                                    // update data length for current transfer
						    
							break;

	    				case GET_CONFIG:
							SL811Write(EP0A_Slave_Buf,Slave_ConfigVal);				// load current configuration value
							EP0A_IN_Arm(EP0A_Slave_Buf,1,1);						// send 1  unsigned char data back to host
							len_req = 0;
							break;

	    				case GET_INTERFACE:
							SL811Write(EP0A_Slave_Buf,Slave_IfcAlt[dReq.wIndex>>8]);// load current alternate setting
							EP0A_IN_Arm(EP0A_Slave_Buf,1,1);						// send 1  unsigned char data back to host
							len_req = 0;
							break;

	    				case GET_STATUS:
							switch(dReq.bmRequest&0x03)								// check for recipients
							{
								case RECIPIENT_DEV:									// load current device status
									SL811Write(EP0A_Slave_Buf,(Slave_RemoteWU<<1)|BUS_POWERED);	
									break;
								case RECIPIENT_IFC:							
									SL811Write(EP0A_Slave_Buf,0);					// first  unsigned char = 0
									break;
								case RECIPIENT_ENP:							
									if((dReq.wIndex>>8) & 0x80)						// for IN direction endpoint
									{
										if(Slave_inEPstall & (0x01<<((dReq.wIndex>>8)&0x0F)))	
											SL811Write(EP0A_Slave_Buf,1);			// first  unsigned char = 1 (IN endpoint stall)		
										else
											SL811Write(EP0A_Slave_Buf,0);			// first  unsigned char = 0 (IN endpoint not stall)		
									}
									else									 		// for OUT direction endpoint
									{
										if(Slave_outEPstall & (0x01<<((dReq.wIndex>>8)&0x0F)))	
											SL811Write(EP0A_Slave_Buf,1);			// first  unsigned char = 1 (OUT endpoint stall)		
										else
											SL811Write(EP0A_Slave_Buf,0);			// first  unsigned char = 0 (OUT endpoint not stall)		
									}
									break;

⌨️ 快捷键说明

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