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

📄 sl811s.c

📁 软件中包含了Cypress的SL811 USB接口芯片的固件程序以及如何51单片机进行操作的例子
💻 C
📖 第 1 页 / 共 2 页
字号:
									}
									break;
							}
							SL811Write(EP0A_Slave_Buf+1,0);							// second byte = 0
							EP0A_IN_Arm(EP0A_Slave_Buf,2,1);						// send 2 bytes data back to host
							len_req = 0;											// reset request length to zero
							break;							

	    				case SET_FEATURE:
	    				case CLEAR_FEATURE:
							switch(dReq.bmRequest&0x03)								// check for recipients
							{
								case RECIPIENT_DEV:
									if((dReq.wValue>>8) == 1)						// feature selector = 1 (remote wakeup)
									{
										if(dReq.bRequest==SET_FEATURE)				// set remote wake up status	
											Slave_RemoteWU = 1;						
										if(dReq.bRequest==CLEAR_FEATURE)			// clear remote wake up status		
											Slave_RemoteWU = 0;						
										EP0A_IN_Arm(0,0,1);							// IN status stage
									}
									else
										SL811Write(EP0AControl,SEND_STALL);			// Stall unsupported requests						
									break;

								case RECIPIENT_ENP:
									if((dReq.wValue>>8) == 0)						// feature selector = 0 (endpoint stall)
									{
										if((dReq.wIndex>>8) & 0x80)					// for IN direction endpoint
										{
											if(dReq.bRequest==SET_FEATURE)			// set endpoint stall (limit to 7 IN's data endpoint)
												Slave_inEPstall |=  (0x01<<((dReq.wIndex>>8)&0x0F)); 
											if(dReq.bRequest==CLEAR_FEATURE)		// clear endpoint stall (limit to 7 IN's data endpoint)
												Slave_inEPstall &=  ~(0x01<<((dReq.wIndex>>8)&0x0F)); 
										}
										else									 	// for OUT direction endpoint
										{
											if(dReq.bRequest==SET_FEATURE)			// set endpoint stall (limit to 7 OUT's data endpoint)
												Slave_outEPstall |=  (0x01<<((dReq.wIndex>>8)&0x0F)); 
											if(dReq.bRequest==CLEAR_FEATURE)		// clear endpoint stall (limit to 7 OUT's data endpoint)
												Slave_outEPstall &=  ~(0x01<<((dReq.wIndex>>8)&0x0F)); 
										}
										EP0A_IN_Arm(0,0,1);							// IN status stage
									}		
									else
										SL811Write(EP0AControl,SEND_STALL);			// Stall unsupported requests						
									break;

								default: 
									SL811Write(EP0AControl,SEND_STALL);				// Stall all unsupported requests
									break;
							}
							break;

			         	case SET_ADDRESS:
							Slave_USBaddr = dReq.wValue>>8;							// update new USB address assigned by host
							EP0A_IN_Arm(0,0,1);										// IN status stage
							break;

				        case SET_CONFIG:
							Slave_ConfigVal = dReq.wValue>>8;						// update configuration value
							EP0A_IN_Arm(0,0,1);										// IN status stage
							if(Slave_ConfigVal)	
								SL811Write(EP1AControl,DATA0_IN_ENABLE);			// Enable EP1 (reponse with NAK)
							else
								SL811Write(EP1AControl,DATA0_IN_DISABLE);			// Disable EP1
							break;

	    				case SET_INTERFACE:											// update alternate setting for					
							Slave_IfcAlt[dReq.wIndex>>8] = dReq.wValue>>8;			// selected interface number
							EP0A_IN_Arm(0,0,1);										// IN status stage
							break;

						default: 
							SL811Write(EP0AControl,SEND_STALL);						// Stall all unsupported requests
							break;
					}
					break;

				//---------------------------------------------------------------------
				// Specific Class Requests (HID)
				//---------------------------------------------------------------------
				case CLASS_REQUEST:
				    switch (dReq.bRequest)											// Parse bRequest
    				{
				        case GET_IDLE:
							SL811Write(EP0A_Slave_Buf,Slave_IdleRate);				// load current idle rate value
							EP0A_IN_Arm(EP0A_Slave_Buf,1,1);						// send 1 byte data back to host
							len_req = 0;
							break;	

				        case GET_PROTOCOL:
							SL811Write(EP0A_Slave_Buf,Slave_Protocol);				// load current protocol state
							EP0A_IN_Arm(EP0A_Slave_Buf,1,1);						// send 1 byte data back to host
							len_req = 0;
							break;	

				        case SET_IDLE:
							Slave_IdleRate = (BYTE)dReq.wValue;						// update Idle Rate (upper byte of wValue)
							EP0A_IN_Arm(0,0,1);										// IN status stage
							break;

				        case SET_PROTOCOL:
							Slave_Protocol = dReq.wValue>>8;						// update protocol value, 0=Boot, 1=report
							EP0A_IN_Arm(0,0,1);										// IN status stage
							break;
				
						default: 
							SL811Write(EP0AControl,SEND_STALL);						// Stall all unsupported requests
							break;
					}
					break;

				//---------------------------------------------------------------------
				// Specific Vendor Requests
				//---------------------------------------------------------------------
				case VENDOR_REQUEST:
					SL811Write(EP0AControl,SEND_STALL);								// Stall all unsupported requests
					break;

				//---------------------------------------------------------------------
				// Unsupported Requests
				//---------------------------------------------------------------------
				default: 
					SL811Write(EP0AControl,SEND_STALL);								// Stall all unsupported requests
					break;
			}
		}		

		//================================================================
		// IN/OUT token received from host
		//================================================================
		else
		{	
			//---------------------------------
			// IN's ACKed
			//---------------------------------
			if(SL811Read(EP0AControl)&DIRECTION)
			{
				if(dev_first==0)										// happens on the first get device descp
				{														// the host terminate IN transfer prematurely
					len_req = 0;										// (if EP0 maxpktsize is only 8 bytes)			
					dev_first = 1;										// reset len_req, end with OUT status stage
				}	

				//--------------------------------------					
				// Continue with next IN if needed
				//--------------------------------------					
				if(len_req)															
				{								
					data_seq = (((SL811Read(EP0AControl)&DATAX)==0) ? 1:0);			// toggle DATA sequence
					len_xfr = (len_req>=EP0_LEN) ? EP0_LEN:(BYTE)len_req;			// get transfer length for EP0
					
					if(!IN_NULL)													// point to correct buffer location
						EP0A_IN_Arm(EP0A_Slave_Buf+in_buffer_idx, len_xfr, data_seq);
					else
						EP0A_IN_Arm(0,0,data_seq);									// transfer zero Null packet 	

					in_buffer_idx += len_xfr;										// update buffer location
					len_req -= len_xfr;												// update remaining data length

					if(len_req==0 && len_xfr==EP0_LEN && !IN_EXACT)					// handles null packet of data length					
					{																// to host is multiple of EP0_LEN, and
						len_req = 1;												// only if host request more than this
						IN_NULL = TRUE;												// value of length, otherwise, the extra
					}																// null pkt is not require.
				}

				//--------------------------------------					
				// Arm Status Stage OUT or new SETUP 								
				//--------------------------------------					
				else																// Arm status OUT or next SETUP requests	
					EP0A_OUT_Arm(EP0_LEN);											// i.e. end of IN status stage.
			}

			//---------------------------------
			// OUT's ACKed
			//---------------------------------
			else 
			{
				if(byte_rx==0)									// zero data packet received
				{
					EP0A_OUT_Arm(EP0_LEN);						// get ready for next SETUP token
					if((BYTE)dReq.wValue == HID_REPORT)			// end of a report descp, indicate
					{
						enum_done = 1;							// end of complete enumeration
						OUTB &=	~ACTIVE_LED;					// Turn on Active LED
					}
				}
			}

		}
	}
	//----------------------------------------------------------------------------------------
	// End of ACK received 
	//----------------------------------------------------------------------------------------

	//----------------------------------------------------------------------------------------
	// If a STALL was sent out by device, it will still interrupt, but
	// STALL bit in status register does not reflect this when in slave mode.
	//----------------------------------------------------------------------------------------
	else if( SL811Read(EP0AControl)&0x20 )			// check for previous stall sent
		EP0A_OUT_Arm(EP0_LEN);						// get ready for next SETUP token				

	return;
}

//*****************************************************************************************
// EP0's IN Token Arming (using Set A)
//*****************************************************************************************
void EP0A_IN_Arm(BYTE buf_adr, BYTE len, BYTE seq)
{												
    SL811Write(EP0AAddress,buf_adr); 				// ep0 address buffer start adress
	SL811Write(EP0AXferLen,len);					// max length of transfer allowed
	if(seq)
	    SL811Write(EP0AControl,DATA1_IN);			// armed to transmit to host, DATA1
	else
	    SL811Write(EP0AControl,DATA0_IN);			// armed to transmit to host, DATA0

}

//*****************************************************************************************
// EP0's SETUP/OUT Token Arming (using Set A)
//*****************************************************************************************
void EP0A_OUT_Arm(BYTE len)
{
    SL811Write(EP0AAddress,EP0A_Slave_Buf); 	// ep0 address buffer start adress
    SL811Write(EP0AXferLen,len);				// max length of transfer allowed
    SL811Write(EP0AControl,DATA0_OUT);			// armed to receive from host
}

//*****************************************************************************************
// SL811S variables initialization
//*****************************************************************************************
void sl811s_init(void)
{
	int i;

	//----------------------------
	// Application-Specific
	//----------------------------
	OUTB |=	ACTIVE_LED;			// Clear Active LED	
	OUTC |= PORTX_LED;			// turn off all LEDs

	flags = 0;					// clear flag
	sof_cnt	= 0;				// sof counter equal zero
	ep1_toggle = 0;				// ep1 toggle state
	Audio_Keys = 0;				// clear Audio Control Keys
	Prev_Audio_Keys = 0;		
	Internet_Keys = 0;			// clear Internet Control Keys
	Prev_Internet_Keys = 0;	

	//----------------------------
	// SL811S-Specific
	//----------------------------
	BUS_POWERED = 1;						// define as a bus powered device
	Slave_USBaddr = 0;						// set to default USB address zero
	Slave_ConfigVal = 0;					// default device config value
	Slave_Protocol = 0;						// HID class default boot protocol
	Slave_IdleRate = 0;						// HID class default idle rate
	Slave_RemoteWU = 0;						// device remote wakeup support
	Slave_inEPstall = 0;					// EP0 ~ EP7's IN
	Slave_outEPstall = 0;					// EP0 ~ EP7's OUT
	for(i=0;i<MAXIFCNUM;i++)				// reset alternate setting
		Slave_IfcAlt[i] = 0;
	for(i=0;i<EP0_LEN;i++)					// clear EP0 Buffer
	    SL811Write(EP0A_Slave_Buf+i,0);
	for(i=0;i<EP1_LEN;i++)					// clear EP1 Buffer
	    SL811Write(EP1A_Slave_Buf+i,0);

    SL811Write(USBAddress,0x00);  			// usb address
    SL811Write(IntEna,0x63);				// enable SOF, EP0, EP1, USB Reset interrupts
    SL811Write(IntStatus,0xFF);				// clear all interrupts
	EP0A_OUT_Arm(EP0_LEN);					// ready to receive from host
}

//*****************************************************************************************
// 8051 variables initialization
//*****************************************************************************************
void uC8051_init(void)
{	
	ISOCTL |= 0x01;							// free up iso endpoints for external data space (1024)
	
	//----------------------------
	// Variable initialization
	//----------------------------
	SL811H_DATA = 0x00;
	SL811H_ADDR = 0x00;

	//----------------------------
	// 8051's I/Os Setup
	//----------------------------
	PORTACFG = 0x00;			// Set to output
	OEA      = 0xFF;			// Set PA7~PA0(Output)
	OUTA     = 0xFF;			// Default output high

	PORTBCFG = 0x20;			// Select i/o function for PB7~PB0, except PB5-INT#5
	OEB      = 0xDF;			// Set PB6(O),PB4(I),PB1(O),PB0(O) - PB2(0),PB3(O),PB5(I),PB7(O)
	OUTB     = 0xDF;			// Default output high

	PORTCCFG = 0xC0;			// Select alternate function nWR(PC6) & nRD(PC7), 
//	OEC      = 0x3F;			// Set PC5~PC0 (Output) For LEDs only
//	OUTC     = 0x3F;			// Default output high
	OEC      = 0x38;			// Set PC5~PC3(Output) For LEDs, PC2~PC0 (Input) For Audio Buttons
	OUTC     = 0x38;			// Default output high

	EA = 1;						// enable 8051 interrupt
	EIEX5 = 1;					// enable INT#5 for toggle switch
	EXIF &= 0x7F;				// clear INT#5 flag


	//----------------------------
	// SL811ST hardware reset
	//----------------------------
	OUTB &= ~nRESET;			// reset SL811HST
	EZUSB_Delay(5);				// for 5ms
	OUTB |= nRESET;				// clear reset

//	OUTB &= ~nHOST_SLAVE_MODE;	// set to Host mode
	OUTB |= nHOST_SLAVE_MODE;	// set to Slave mode

    SL811Write(IntEna,0x40);	// enable USB Reset interrupt
    SL811Write(CtrlReg,0x01);   // enable USB, FullSpeed
    SL811Write(IntStatus,0xFF);	// clear all interrupts
}

//*****************************************************************************************
// Main loop start here
//*****************************************************************************************
void main(void)
{
	BYTE	int_status;

	uC8051_init();									// initialized 8051 uC

	while(TRUE)										// Main Loop
	{
		//--------------------------------------------
		// USB-Specific Tasks
		//--------------------------------------------
		int_status = SL811Read(IntStatus);				
		if(int_status & USB_RESET_DONE)				// wait for USB Reset interrupt
			sl811s_init();		
		else if(int_status & EP0_DONE)				// wait for EP0 interrupt
			ep0_isr();
		else if(int_status & EP1_DONE)				// wait for EP1 interrupt
			ep1_isr();
		else if(int_status & SOF_DONE)				// wait for SOF interrupt
			sof_isr();

		//--------------------------------------------
		// Application-Specific Tasks (every 5msec)
		//--------------------------------------------
		if(timeout && enum_done)					// do some task now
		{	
			audio_key_scan();						// Audio Keys Scan
			internet_key_scan();					// Internet Keys Scan
			timeout = 0;							
		}
	
	}
}


⌨️ 快捷键说明

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