📄 subp.c
字号:
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
// EP0A_IN_Arm(0,0,1);
break;
}
break;
//---------------------------------------------------------------------
// Specific Class Requests (HID)
//---------------------------------------------------------------------
case CLASS_REQUEST:
switch (dReq.bRequest) // Parse bRequest
{
case SET_REPORT:
switch(( unsigned char)dReq.wValue)
{
case INPUT:
SL811Write(EP0AControl,SEND_STALL);
break;
case OUTPUT:
bReport=1;
EP0A_OUT_Arm(4);
// SL811Write(EP1AControl,SEND_STALL);
break;
case FEATURE:
SL811Write(EP0AControl,SEND_STALL);
break;
default:
SL811Write(EP0AControl,SEND_STALL);
break;
}
break;
case GET_REPORT:
break;
case GET_IDLE:
SL811Write(EP0A_Slave_Buf,Slave_IdleRate); // load current idle rate value
EP0A_IN_Arm(EP0A_Slave_Buf,1,1); // send 1 unsigned char 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 unsigned char data back to host
len_req = 0;
break;
case SET_IDLE:
Slave_IdleRate = ( unsigned char)dReq.wValue; // update Idle Rate (upper unsigned char 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;
}
} // if(statuse&EP_setup)
//================================================================
// 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 unsigned chars)
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:( unsigned char)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(byte_rx);
// if(bReport==1)
// {
// SL811BufRead(EP0A_Slave_Buf, ( unsigned char*)&dReq, byte_rx);
bReport=0;
// EP0A_IN_Arm(0,0,1);
// }
// SL811Write(EP0AAddress,EP0A_Slave_Buf); // ep0 address buffer start adress after 64 unsigned char
// SL811Write(EP0AXferLen,byte_rx); // max length of transfer allowed
// SL811Write(EP0AControl,DATA1_OUT);
}
else
EP0A_OUT_Arm(EP0_LEN);
}
}
}
//----------------------------------------------------------------------------------------
// 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( unsigned char buf_adr, unsigned char len, unsigned char 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
P35_LED=0; }
else
{ SL811Write(EP0AControl,DATA0_IN); // armed to transmit to host, DATA0
}
}
//*****************************************************************************************
// EP0's SETUP/OUT Token Arming (using Set A)
//*****************************************************************************************
void EP0A_OUT_Arm( unsigned char len)
{
//SL811Write(cDATASet,0);
SL811Write(EP0AAddress,EP0A_Slave_Buf); // ep0 address buffer start adress after 64 unsigned char
SL811Write(EP0AXferLen,len); // max length of transfer allowed
SL811Write(EP0AControl,DATA0_OUT); // armed to receive from host 03
}
//*****************************************************************************************
// SL811S variables initialization
//*****************************************************************************************
void sl811s_init(void)
{
int i;
//----------------------------
// Application-Specific
//----------------------------
P1 |=AUDIO_KEYS ; // Clear Active LED
// P3 |= ACTIVE_LED; //PORTX_LED; // turn off all LEDs
P35_LED=1;
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
// SL811Write(cSOFcnt,0x00);
for(i=0;i<MAXIFCNUM;i++)//8 // 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); //07h on power on and reset usb address set to 00
SL811Write(IntEna,0x63); //06h enable SOF, EP0, EP1, USB Reset interrupts
SL811Write(IntStatus,0xff); //0dh clear all interrupts
SL811Write(CtrlReg,0x21);
EP0A_OUT_Arm(EP0_LEN); // ready to receive from host 64=ep0_len
}
//*****************************************************************************************
// 8051 variables initialization
//*****************************************************************************************
void C51_init(void)
{
// ISOCTL |= 0x01; // free up iso endpoints for external data space (1024)
//----------------------------
// Variable initialization
//----------------------------
SL811H_DATA = 0x00; //FF00
SL811H_ADDR = 0x00; //FE00
//----------------------------
// 8051's I/Os Setup
//----------------------------
//PORTACFG = 0x00; // Set to output
//OEA = 0xFF; // Set PA7~PA0(Output)
P0=0xFF; // Default output high
// PORTBCFG = 0x20; // Select i/o function for PB7~PB0, except PB5-INT#5
// OEB = 0xDF; // Set PB6(0),PB4(I),PB1(O),PB0(O) - PB2(0),PB3(O),PB5(I),PB7(O)
P1=0xFF; // Default output high
P2=0xff;
// 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
P3=0xff; // 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
//----------------------------
// P3 &= ~nRESET; // reset SL811HST
P34_RES=0;
Delay(); // for 5ms
P34_RES=1;
// P3 |= nRESET; // clear reset
// OUTB &= ~nHOST_SLAVE_MODE; // set to Host mode
// P3 |= nHOST_SLAVE_MODE; // set to Slave mode
// P33_SLA=1;
SL811Write(cSOFcnt,0x40); //LowSpeed(0x40),FullSpeed(0x00)
SL811Write(IntEna,0x40); // enable USB Reset interrupt
SL811Write(CtrlReg,0x21); // enable USB, FullSpeed(01);LowSpeed(21h)
SL811Write(IntStatus,0xFF); // clear all interrupts
//EP0A_OUT_Arm(EP0_LEN);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -