📄 usb.c
字号:
/**********************************************************************/
/* The GET_DESCRIPTOR request is done here. */
/**********************************************************************/
void getdescriptor(void)
{
SET_GETDESC; /*enter GETDESC mode */
desc_typ = usb_buf[3]; /*store the type requested*/
/*select descriptor size and starting index */
switch (desc_typ)
{
case DEVICE:
desc_idx = 0;
desc_sze = DEV_DESC_SIZE;
break;
case CONFIGURATION:
desc_idx = 0;
desc_sze = CFG_DESC_SIZE;
break;
case XSTRING:
desc_idx = usb_buf[2];
desc_sze = STR_DATA[desc_idx];
break;
case HID:
/*valid if we have only one int: revisit if this changes */
desc_idx = CFG_LENGTH+INT_LENGTH;
desc_sze = CFG_DESC[(CFG_LENGTH+INT_LENGTH)];
break;
case HIDREPORT:
desc_idx = 0;
desc_sze = RPT_DESC_SIZE;
break;
default: /*UNDEFINED */
desc_idx = 0;
desc_sze = 0;
break;
}
/*adjust size, if the host has asked for less than we want to */
/*send. Note that we only check the low order byte of the */
/*wlength field. If we ever need to send back descriptors */
/*longer than 256 bytes, we'll need to revisit this */
if (usb_buf[7]==0) /*if less than 256 req'd */
if (desc_sze > usb_buf[6]) desc_sze = usb_buf[6];
/*send the first data chunk back */
mlti_pkt(); mlti_pkt(); mlti_pkt(); mlti_pkt();
mlti_pkt(); mlti_pkt(); mlti_pkt(); mlti_pkt();
}
/**********************************************************************/
/* The GET_STATUS request is done here */
/**********************************************************************/
void getstatus(void)
{
switch (usb_buf[0]&0x03) /*find request target */
{
case 0: /*DEVICE */
write_usb(TXD0,0); /*first byte is reserved */
break;
case 1: /*INTERFACE */
write_usb(TXD0,0); /*first byte is reserved */
break;
case 2: /*ENDPOINT */
switch (usb_buf[4]&0x0F) /*find specific endpoint */
{ /* (strip off dir. bit) */
case 0: EPSTATUS(BIT0);
case 1: EPSTATUS(BIT1);
case 2: EPSTATUS(BIT2);
case 3: EPSTATUS(BIT3);
case 4: EPSTATUS(BIT4);
case 5: EPSTATUS(BIT5);
case 6: EPSTATUS(BIT6);
default:
break;
}
break;
default: /*UNDEFINED */
write_usb(TXD0,0); /*first byte is reserved */
break;
}
write_usb(TXD0,0); /*second byte is reserved */
}
/**********************************************************************/
/* The SET_CONFIGURATION request is done here */
/**********************************************************************/
void setconfiguration(void)
{
usb_cfg = usb_buf[2]; /*set the configuration # */
if (usb_buf[2]!=0) /*set the configuration */
{
dtapid = 0; /*FIRST PID is DATA0 */
stalld = 0; /*nothing stalled */
FLUSHTX1; /*flush TX1 and disable */
write_usb(EPC1,EP_EN+01); /*enable EP1 at adr 1 */
FLUSHRX1; /*flush RX1 and disable */
write_usb(EPC2,EP_EN+02); /*enable EP2 at adr 2 */
write_usb(RXC1,RX_EN); /*enable RX1 */
FLUSHTX3; /*flush TX1 and disable */
write_usb(EPC5,EP_EN+05); /*enable EP5 at adr 5 */
FLUSHRX3; /*flush RX3 and disable */
write_usb(EPC6,EP_EN+06); /*enable EP6 at adr 6 */
write_usb(RXC3,RX_EN); /*enable RX3 */
}
else /*unconfigure the device */
{
write_usb(EPC1,0); /*disable EP1 */
write_usb(EPC2,0); /*disable EP2 */
write_usb(EPC5,0); /*disable EP5 */
write_usb(EPC6,0); /*disable EP6 */
}
}
/**********************************************************************/
/* The SET_FEATURE request is done here */
/**********************************************************************/
void setfeature(void)
{
switch (usb_buf[0]&0x03) /*find request target */
{
case 0: /*DEVICE */
break;
case 1: /*INTERFACE */
break;
case 2: /*ENDPOINT */
switch (usb_buf[4]&0x0F) /*find specific endpoint */
{ /* (strip off dir. bit) */
case 0:
/*control pipes must accept setup requests even if */
/*stalled, so we log the stall here, but don't */
/*actually do it */
/*bitset(EPC0,STALL);*/
SETBIT(stalld,BIT0);
break;
case 1:
bitset(EPC1,STALL);
SETBIT(stalld,BIT1);
break;
case 2:
bitset(EPC2,STALL);
SETBIT(stalld,BIT2);
break;
case 3:
bitset(EPC3,STALL);
SETBIT(stalld,BIT3);
break;
case 4:
bitset(EPC4,STALL);
SETBIT(stalld,BIT4);
break;
case 5:
bitset(EPC5,STALL);
SETBIT(stalld,BIT5);
break;
case 6:
bitset(EPC6,STALL);
SETBIT(stalld,BIT6);
break;
default:
break;
}
break;
default: /*UNDEFINED */
break;
}
}
/**********************************************************************/
/* The HID class specific GET_REPORT request is done here */
/**********************************************************************/
void getreport(void)
{
desc_typ = usb_buf[3]; /*store the type requested*/
queue_rpt(TXD0); /*queue up the report */
}
/**********************************************************************/
/* The HID class specific SET_REPORT request is done here */
/**********************************************************************/
void setreport(void)
{
desc_typ = usb_buf[3]; /*store the report req'd */
}
/**********************************************************************/
/* The HID class specific GET_IDLE request is done here */
/**********************************************************************/
void getidle(void)
{
write_usb(TXD0,usb_idl); /*send back idle value */
}
/**********************************************************************/
/* The HID class specific SET_IDLE request is done here */
/**********************************************************************/
void setidle(void)
{
usb_idl = usb_buf[3]; /*store the idle value */
}
/**********************************************************************/
/* This subroutine handles RX events for FIFO0 (endpoint 0) */
/**********************************************************************/
void rx_0(void)
{
rxstat=read_usb(RXS0); /*get receiver status */
/*is this a setup packet? ***************************************/
if(rxstat & SETUP_R)
{
/*read data payload into buffer then flush/disble the RX ****/
for(desc_idx=0; desc_idx<8; desc_idx++)
usb_buf[desc_idx] = read_usb(RXD0);
FLUSHRX0; /*make sure the RX is off */
FLUSHTX0; /*make sure the TX is off */
bitclr(EPC0,STALL); /*turn off stall */
switch (usb_buf[0]&0x60) /*decode request type */
{
case 0x00: /*standard request */
switch (usb_buf[1]) /*decode request code */
{
case CLEAR_FEATURE:
clrfeature();
break;
case GET_CONFIGURATION:
write_usb(TXD0,usb_cfg);/*load the config val */
break;
case GET_DESCRIPTOR:
getdescriptor();
break;
case GET_INTERFACE:
write_usb(TXD0,0); /*load the intf. val */
break;
case GET_STATUS:
getstatus();
break;
case SET_ADDRESS:
/*save the new address, but don't actually store*/
/*it into FAR until later (when status handshake*/
/*completes during tx_0). Note that the 9602 */
/*has a DEF bit in EPC0 designed for this purp- */
/*ose, but it only works if the default address */
/*is initially in effect. Therefore it can't */
/*be used for multiple SET_ADDRESS commands in */
/*sequence. This will work regardless of init- */
/*ial address. */
setaddr = (usb_buf[2] | AD_EN);
break;
case SET_CONFIGURATION:
setconfiguration();
break;
case SET_FEATURE:
setfeature();
break;
case SET_INTERFACE:
if(usb_buf[2]) /*if the requested intf!=0*/
bitset(EPC0,STALL); /*stall the endpoint */
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -