📄 control_ep0.c
字号:
* with the SET_CONFIGURATION request.
*
* RETURNS: Nothing
*
*/
void CmdGetConfiguration(void){
unsigned char wValue = SetupPacket.wValueLow | SetupPacket.wValueHigh;
unsigned char wIndex = SetupPacket.wIndexLow | SetupPacket.wIndexHigh;
unsigned char wLength = SetupPacket.wLengthLow | SetupPacket.wLengthHigh;
if ( ((wValue && wIndex) != 0x00) || (wLength != 0x01) ){
ep0cs = 0x1140; // Are these the correct values?
return; // Incorrect values so STALL here
}
if ( !USBFlags.Addressed ){ // If not in DEFAULT state then
ep0cs = 0x1040; // STALL since not defined
return;
}
ep0ic = 0x00; // Disable to remove extra interrupt
if ( !USBFlags.Configured ){ // If not configured then respond
ep0cs = 0x2140; // Clear SETUP and OPR
ep0il = bCurrentConfiguration; // Send Current Config number (should be 0x00)
}
else{
ep0cs = 0x2140; // Clear SETUP and OPR
ep0il = bCurrentConfiguration; // Send the Current Config number
}
ep0cs = 0x2280; // Set IBR and DATA_END
ir_ep0ic = 0;
ep0ic = 0x03; // Enable the EP0 interrupt (level 3)
}
/*
** CmdGetInterface
*
* FILENAME: control_ep0.c
*
* PARAMETERS: None
*
* DESCRIPTION: Returns the correct ALTERNATE_INTERFACE setting of the current
* configuration. Since there is only one config in this example
* there exists only 2 alt interfaces controlling the ISO endpoint.
* If other configurations existed, another level would be needed
* to check to see if that interface was a valid for the specified
* configuration. Here the check is just done on the current interface
* value, makeing the assumption (incorrectly) that the HOST is always
* asking about this interface alone.
*
* RETURNS: Nothing
*
*/
void CmdGetInterface(void){
unsigned char wValue = SetupPacket.wValueLow | SetupPacket.wValueHigh;
unsigned char wIndex = SetupPacket.wIndexLow | SetupPacket.wIndexHigh;
unsigned char wLength = SetupPacket.wLengthLow | SetupPacket.wLengthHigh;
if ( (wValue != 0x00) || (wLength != 0x01) ){
ep0cs = 0x1140; // Are these the correct values?
return; // Incorrect values so STALL here
}
if ( !USBFlags.Addressed || !USBFlags.Configured ){ // If in DEFAULT or ADDRESSED
ep0cs = 0x1140; // state then STALL
return;
}
ep0ic = 0x00; // Disable to prevent extra interrpts
if ( SetupPacket.wIndexLow == bCurrentInterface ){
switch ( SetupPacket.wIndexLow ){ // Determine what interface is being asked for
case 0: // Only one interface in this example
ep0cs = 0x2140; // Clear OBR
ep0il = bAlternateSetting; // Send the current setting number
break;
case 1: // Only one interface in this example
ep0cs = 0x2140; // Clear OBR
ep0il = bAlternateSetting; // Send the current setting number
break;
default:
ep0cs = 0x1140; // STALL since not supported
return;
}
ep0cs = 0x2280; // Set IBR and DATA_END, MASK
}
else{
ep0cs = 0x1140; // STALL since not supported
}
ir_ep0ic = 0;
ep0ic = 0x03; // Enable the EP0 interrupt (level 3)
}
/*
** CmdSetInterface
*
* FILENAME: control_ep0.c
*
* PARAMETERS: None
*
* DESCRIPTION: The HOST uses this command to set the current interface to a different
* (alternate) setting. This interface is a subset of it's configuration
* and allows the HOST to adjust bandwidth or endpoints according to
* bus loading or need. This is necessary for ISO endpoints so that they can
* be shut off if bus loading is too great. Alternate interfaces for
* simple devices (only a few EP's, bulk & interrupts in nature) might
* only have a singular interface and would not have to include an
* alt. interface. In that case, the EP descriptors would simpily follow
* the interface descriptor and both bCurInt and bAltSet would = 0x00.
*
* Alternate interfaces should be described in order of endpoint usage.
* For example, Alt. Int. 0 should describe no endpoints (only EP0 active).
* Alt. Int. 1 can describe the endpoints used and their sizes in increasing size,
* and so on. Endpoint MAXP adjustments and enabling should be made
* here, not with the SET_CONFIGURATION command, as it just specifies
* a configuration to use. This is more advanced that this example, but
* should be noted here for clarity.
*
* RETURNS: Nothing
*
*/
void CmdSetInterface(void){
unsigned char wValue = SetupPacket.wValueLow | SetupPacket.wValueHigh;
unsigned char wIndex = SetupPacket.wIndexLow | SetupPacket.wIndexHigh;
unsigned char wLength = SetupPacket.wLengthLow | SetupPacket.wLengthHigh;
if ( USBFlags.SetupEndFlag ) { // bug...clear bogus SETUP_END
USBFlags.SetupEndFlag = 0;
ep0csr11 = 1;
}
if ( wLength != 0x00 ){
ep0cs = 0x1140; // Are these the correct values?
return; // Incorrect values so STALL here
}
if ( !USBFlags.Configured ){ // If not already configured
ep0cs = 0x1140; // then STALL
return;
}
switch ( SetupPacket.wIndexLow ){ // Determine what interface is being asked for
case 0: // Only one interface in this example
switch ( SetupPacket.wValueLow ){
case 0: // Default Alternate setting, no EP's here
usbie = 0x0100; // Disable all EP interrupts
usbepen = 0x0000; // Disable all EP's
//***********************************
// This needs to be modified in the driver/app so that the
// correct interface is set upon enumeration. alternate setting
// should be 0x01 here to comply with USB spec. Additionally
// these EP's should not be initialized here for this reason.
// Until then this will provide a work around. Also the descriptors
// should reflect this functionallity as well. (2 ALT SET's)
ep1ifc = 0x0040; // Start = 0 size = 128
ep1imp = 0x0040; // MAXP = 64
ep2ifc = 0x0002; // Start = 128 size = 64
ep2imp = 0x0020; // MAXP = 32
ep3ifc = 0x0003; // Start = 192 size = 64
ep3imp = 0x0020; // MAXP = 32
ep1ofc = 0x0045; // Start = 256 size = 128
ep1omp = 0x0040; // MAXP = 64
ep3ofc = 0x0006; // Start = 384 size = 64
ep3omp = 0x0020; // MAXP = 32
usbepen = 0x003b; // Enable EP1 IN/OUT, EP2 IN, EP3 IN/OUT
usbie = 0x0137; // Enable EP2 IN, EP1 OUT, EP1 IN
//**********************************
bCurrentInterface = 0x00;
bAlternateSetting = 0x00;
break;
case 1: // Second alternate setting
ep1ifc = 0x0040; // Start = 0 size = 128
ep1imp = 0x0040; // MAXP = 64
ep2ifc = 0x0002; // Start = 128 size = 64
ep2imp = 0x0020; // MAXP = 32
ep3ifc = 0x0003; // Start = 192 size = 64
ep3imp = 0x0020; // MAXP = 32
ep1ofc = 0x0045; // Start = 256 size = 128
ep1omp = 0x0040; // MAXP = 64
ep3ofc = 0x0006; // Start = 384 size = 64
ep3omp = 0x0020; // MAXP = 32
usbepen = 0x003b; // Enable EP1 IN/OUT, EP2 IN, EP3 IN/OUT
usbie = 0x0137; // Enable EP1 IN/OUT, EP2 IN, EP3 IN/OUT
bCurrentInterface = 0x00;
bAlternateSetting = 0x01;
break;
default:
ep0cs = 0x1040; // STALL , not supported here
return;
}
ep0cs = 0x2240; // Set DATA_END, OPR, SETUP flag
break;
default:
ep0cs = 0x1040; // STALL other interface requests here
}
}
/*
** CmdSetConfiguration
*
* FILENAME: control_ep0.c
*
* PARAMETERS: None
*
* DESCRIPTION: A USB device may consist of several seperate and mutually exclusive
* configurations. This allows a device to change endpoint configurations
* transfer types and the like as the HOST see fit to do so. In an
* UNCONFIGURED state, no endpoints exist, except EP0 and responses to
* numerous requests are STALLed. When the device enters the CONFIGURED
* state, it's base configuration it should reset all previous endpoints
* (if any). A base configuration should only have EP0 active. The
* SET_INTERFACE command is used to enable/size endpoints through the
* use of alternate interfaces.
*
* RETURNS: Nothing
*
*/
void CmdSetConfiguration(void){
unsigned char wValue = SetupPacket.wValueLow | SetupPacket.wValueHigh;
unsigned char wIndex = SetupPacket.wIndexLow | SetupPacket.wIndexHigh;
unsigned char wLength = SetupPacket.wLengthLow | SetupPacket.wLengthHigh;
if ( USBFlags.SetupEndFlag ) { // bug...clear bogus SETUP_END
USBFlags.SetupEndFlag = 0;
ep0csr11 = 1;
}
if ( (wIndex || wLength) != 0x00 || (SetupPacket.wValueHigh != 0x00) ){
ep0cs = 0x1140; // Are these the correct values?
return; // Incorrect values so STALL here
}
if ( !USBFlags.Configured ){ // Must be in ADDRESSED state
switch ( SetupPacket.wValueLow ){ // Determine what configuration is wanted
case 0: // None selected so remain in ADDRESSED state
usbie = 0x0100; // Disable all EP interrupts
usbepen = 0x0000; // Disable all EP's
bCurrentConfiguration = 0x00;
bAlternateSetting = 0x00;
break;
case 1:
//***********************************
// This needs to be modified in the driver/app so that the
// correct interface is set upon enumeration. alternate setting
// should be 0x01 here for the to comply with USB spec. Additionally
// these EP's should not be initialized here for this reason.
// Until then this will provide a work around. Also the descriptors
// should reflect this functionallity as well. (2 ALT SET's)
ep1ifc = 0x0040; // Start = 0 size = 128
ep1imp = 0x0040; // MAXP = 64
ep2ifc = 0x0002; // Start = 128 size = 64
ep2imp = 0x0020; // MAXP = 32
ep3ifc = 0x0003; // Start = 192 size = 64
ep3imp = 0x0020; // MAXP = 32
ep1ofc = 0x0045; // Start = 256 size = 128
ep1omp = 0x0040; // MAXP = 64
ep3ofc = 0x0006; // Start = 384 size = 64
ep3omp = 0x0020; // MAXP = 32
usbepen = 0x003b; // Enable EP2 IN, EP1 OUT, EP1 IN
usbie = 0x0137; // Enable EP2 IN, EP1 OUT, EP1 IN
//**********************************
bCurrentConfiguration = 0x01; // Set the current config value
bAlternateSetting = 0x00;
USBFlags.Configured = 1; // Enter CONFIGURED state
break;
default:
ep0cs = 0x1040; // Not a supported config so STALL
return;
}
ep0cs = 0x2240; // Set DATA_END, OBR, and mask
}
else{ // Must be in CONFIGURED state
switch ( SetupPacket.wValueLow ){ // Determine what configuration is wanted
case 0: // None selected so return to ADDRESSED state
usbie = 0x0100; // Disable all EP interrupts
usbepen = 0x0000; // Disable all EP's
bCurrentConfiguration = 0x00;
bAlternateSetting = 0x00;
USBFlags.Configured = 0; // Leave the CONFIGURED state
break;
case 1:
usbie = 0x0100; // Disable all EP interrupts
usbepen = 0x0000; // Disable all EP's
bCurrentConfiguration = 0x01; // Set the current config value
bAlternateSetting = 0x00;
break;
default:
ep0cs = 0x1040; // Not a supported config so STALL
return;
}
ep0cs = 0x2240; // Set DATA_END, OBR, SETUP flag
}
}
/*
** WriteLEDData
*
* FILENAME: control_ep0.c
*
* PARAMETERS: None
*
* DESCRIPTION: Using VENDOR request, the value of the onboard LED's is updated
* through this control transfer. Data to update value is contained
* in the data packet (data stage) of this transfer.
*
* RETURNS: Nothing
*
*/
void WriteLEDData(void){
ep0ic = 0x00; // Disable the EP0 interrupt here....
ep0cs = 0x0040; // Clear OPR, waiting for next data value
while ( !ep0csr0 ){} // wait for next packet of data
p7 = ep0ol >> 4; // and update the led's
ep0cs = 0x2240; // Set DATA_END, OBR, and mask
ir_ep0ic = 0; // ensure that EP0 interrupt is cleared
ep0ic = 0x03; // Enable the EP0 interrupt (level 3)
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -