📄 usb.c
字号:
case 2: /*ENDPOINT */
switch (SetupData.wIndex.ByteValue.Low&0x0F) /*find specific endpoint */
{ /* (strip off dir. bit) */
/*
EPCx中的stalld置1时,当发生下列情况USBN9603将产生STALL handshakes
1. The transmit FIFO is enabled and an IN token is received.
2. The receive FIFO is enabled and an OUT token is received.
*/
case 0:
bitclr(EPC0,STALL);
CLRBIT(stalld,BIT0);
break;
case 1:
bitclr(EPC1,STALL);
CLRBIT(stalld,BIT1);
break;
case 2:
bitclr(EPC2,STALL);
CLRBIT(stalld,BIT2);
break;
case 3:
bitclr(EPC3,STALL);
CLRBIT(stalld,BIT3);
break;
case 4:
bitclr(EPC4,STALL);
CLRBIT(stalld,BIT4);
break;
case 5:
bitclr(EPC5,STALL);
CLRBIT(stalld,BIT5);
break;
case 6:
bitclr(EPC6,STALL);
CLRBIT(stalld,BIT6);
break;
default:
break;
}
break;
default: /*UNDEFINED */
break;
}
}
/*************************/
/* 处理 SET_FEATURE 请求 */
/*************************/
/*以下是Set Feature的叙述:
Feature selector values in wValue must be appropriate to the recipient.
Only device feature selector values may be used when the recipient is a
device;Only interface feature selector values may be used when the recipient
is an interface, and only endpoint feature selecter values may be used when
the recipient is an endpoint.
Refer to following table for a definition of which feature
selector values are defined for which recipientd.
--------------------------------------
|Feature Selector |Recipient|Value|
|====================+=========+======
|DEVICE_REMOTE_WAKEUP|Device | 1 |
|--------------------+---------+-----|
|ENDPOINT_HALT |Endpoint | 0 |
--------------------------------------
A ClearFeature() request that references a feature that cannot be set or
that does not exit,or that refernces an interface or endpoint that does not
exist will cause the device to respond with a Request Error.
*/
void setfeature(void)//OK
{
switch (SetupData.bmRequestType&0x03) /*find request target */
{
case 0: /*DEVICE */
break;
case 1: /*INTERFACE */
break;
case 2: /*ENDPOINT */
switch (SetupData.wIndex.ByteValue.Low&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;
}
}
/**************************/
/* 处理 SET_INTERFACE 请求 */
/**************************/
/*以下是Set Interface的叙述:
This request allows the host to select an alternate setting for the specified interface.
----------------------------------------------------------------
|bmRequestType| bRequest | wValue | wIndex |wLength|Data|
|=============+=============+===========+=========+=======+====|
| 00000001B |SET_INTERFACE|Alternative|Interface| Zero |None|
| | | Setting | | | |
----------------------------------------------------------------
Some USB devices have configuration with interface that have mutually exclusive settings.
This request allows the host to select the desired setting.If a device only support a default
setting for the specified interface,then a STALL may be returned in the Status atage of the
request.
If the interface or the alternative setting does not exist,then the device responds with
a Request Error.If wLength is non-zero,then the behavior of the device is not specified.
*/
void setinterface(void)//OK
{
if(SetupData.wValue.ByteValue.Low) /*if the requested intf!=0*/
bitset(EPC0,STALL); /*stall the endpoint */
}
/************************/
/* 处理 SYNCH_FRAME 请求 */
/************************/
/*以下是Synch Frame的叙述:
This request is used to set and then report an endpoint's synchronization frame.
-------------------------------------------------------------
|bmRequestType| bRequest |wValue| wIndex |wLength| Data |
|=============+===========+======+========+=======+=========|
| 10000010B |SYNCH_FRAME| Zero |Endpoint| Two |FrameNone|
| | | | | | Number |
-------------------------------------------------------------
When an endpoint supports isochronous transfers,the endpoint may also require
per-frame transfers to vary is size according to a specific pattern.The host and the
endpoint must agree on which frame the repeating pattern begins.The number of the frames
in which the pattern began is returned to the first frame of the pattern.
Alternatively,the device may used this request to restart the pattern.In this case,the device
would save the frame number in each SOF and return this value in the Data stage of this transfer
and restart the pattern on each IN of the Data stage.
This value is only used for isochronous data transfers using implicit pattern synchronization.
If wValue is non-zero or wLength is not two,then the behavior of the device is not specified.
If the specified endpoint does not support this request,then the device will respond with a
Request Error.
*/
void synchframe(void)//OK
{
bitset(EPC0,STALL); /*stall the endpoint */
}
/*************************/
/* 处理 SET_ADDRESS 请求 */
/*************************/
/*以下是Set Address的叙述:
This request sets the device address for all future device accesses.
-------------------------------------------------------
|bmRequestType| bRequest |wValue |wIndex|wLength|Data|
|=============+===========+=======+======+=======+====|
| 00000000B |SET_ADDRESS|Device | Zero | Zero |None|
| | |Address| | | |
-------------------------------------------------------
The wValue field specifies the device address to use for all subsequest accesses.
As noted elsewhere,requests actually may result in up to 3 stages.In the first
stage,the Setup packet is sent to the device.In the optional second stage,data is
transferred between the host and the device.In the final stage,status is transferred
between the host and device.The direction of data and status transfer depend on whether
the host is sending data to the device or the device is sending data to the host.The
Status stage transfer is always in the opposite direction of the Data stage.If there is
no Data stage,the Status stage is from the device to host.
Stages after the initial Setup packet assume the same device address as the Setup packet.
The USB device does not changes changes its devices untill after the Status atage of this
request is completed successfully.Note that this is a difference between this request and all
other requests.For all other requests,the operation indicated must be completed before this
Status stage.
If the specified device address is greater than 127,or if wIndex or wLength are non-zero,
then the behavior of the device is not specified.
Device response to SetAddress() with a value of 0 is undefine.
*/
void setaddress(void)//OK
{
/*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 = (SetupData.wValue.ByteValue.Low | AD_EN);
// write_usb(FAR,setaddr); /*load new address */
// setaddr=0; /*clear state */
}
/****************************/
/* 处理 GET_DESCRIPTOR 请求 */
/****************************/
/*以下是Get Descriptor的叙述:
This request returns the specified descriptor is the descriptor exists.
------------------------------------------------------------------------
|bmRequestType| bRequest | wValue | wIndex | wLength | Data |
|=============+==============+==========+========+==========+==========|
| 10000000B |GET_DESCRIPTOR|Descriptor|Zero or |Descriptor|Descriptor|
| | |Type and |Language| Length | |
| | |Descriptor|ID | | |
| | |Index | | | |
------------------------------------------------------------------------
The wValue field specifies the descriptor type in the high byte and
the descriptor index in the low byte.The wIndex field specifies the Language
ID for string descriptors or is reset to zero for other descriptor.The wLength
field specifies the number fo bytes to return. If the descriptor is longer than
the wLength field,only the initial bytes of the descriptor are returned.If the
descriptor is shorter than the wLength field,the device indicates the end of
the control transfer by sending a short packet when further data is requested.
A short packet is define as a packet shorter than the maximum payload size or a
NULL data packet.
The standard request to a device supports 3 types of descriptor:DEVICE,
CONFIGURATION,and STRING.a request for a configuration descriptor returns the
configuration descriptor,all interface descriptor,and endpoint descriptor
for all of the interface in a single request.The first iterface descriptor
follows the configuration descriptor.The endpointer descriptor for the first
interface follow the first interface descriptor.If there are additional interfaces
their interface descriptor and endpoint descriptor follow the first interface's
endpoint descriptor.Class-specific and/or vendor-specific descriptor follow the
standard descriptors they extend or modify.
All devices must provide a device descriptor and at least 1 configuration
descriptor.If a device does not support a requester,it responds with a Request Error.
*/
void getdescriptor(void)//OK
{
SET_GETDESC; /*enter GETDESC mode->GETDESC=1;MLTIPKT=1;*/
desc_typ = SetupData.wValue.ByteValue.High; /*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 = STR_OFFSET[SetupData.wValue.ByteValue.Low];
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 (SetupData.wLength.ByteValue.High==0) /*if less than 256 req'd */
if (desc_sze > SetupData.wLength.ByteValue.Low)
desc_sze = SetupData.wLength.ByteValue.Low;
/*send the first data chunk back */
mlti_pkt(); mlti_pkt(); mlti_pkt(); mlti_pkt();
mlti_pkt(); mlti_pkt(); mlti_pkt(); mlti_pkt();
}
/****************************/
/* 处理 GET_INTERFACE 请求 */
/****************************/
/*以下是Get Interface的叙述:
This request returns the selected alternate setting for the specified interface.
----------------------------------------------------------------
|bmRequestType| bRequest |wValue| wIndex |wLength| Data |
|=============+=============+======+=========+=======+=========|
| 10000001B |GET_INTERFACE| Zero |Interface| One |Alternate|
| | | | | | Setting |
----------------------------------------------------------------
Some USB devices have configurations with interfaces that have mutually exclusive
settings.This request allowings the host to determine the current selected alternative
seting.
If wValue or wLength are not specified above,then the device behavior is not specified.
If the interface specified does not exist,then the device respond with a Request Error.
*/
void getinterface(void)//OK
{
write_usb(TXD0,0); /*load the intf. val */
}
/****************************/
/* 处理 SET_DESCRIPTOR 请求 */
/****************************/
/*以下是Set Descriptor的叙述:
This request may be used to updata existing descriptors or new descriptors may be used.
------------------------------------------------------------------------
|bmRequestType| bRequest | wValue | wIndex | wLength | Data |
|=============+==============+==========+========+==========+==========|
| 00000000B |SET_DESCRIPTOR|Descriptor|Zero or |Descriptor|Descriptor|
| | |Type and |Language| Length | |
| | |Descriptor|ID | | |
| | |Index | | | |
------------------------------------------------------------------------
The wValue field specifies the descriptor type in the high byte and the descriptor index
in the low byte.The wIndex field specifies the Language ID for string descriptor or reset to
zero for other descriptor.The wLength field specifies the number of bytes to transfer from the
host to the device.
If this request is not supported then the device will respond with a Request Error.
*/
void setdescriptor(void)//OK
{}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -