📄 control_ep0.c
字号:
/*******************************************************************
*
* DESCRIPTION: M30245 Mit_USB Demonstration Application
*
* AUTHOR: Mitsubishi DEC-E
*
* HISTORY: 0.5 5/30/02 Initial creation for NC30
* 1.0 6/18/02 First official release
* 1.1 6/27/02 Updated ISO routines
* 1.2 8/07/02 Updated for Rev B Starter Kit Board
*
*******************************************************************/
/** include files **/
#include "sfr245.h"
#include "descriptors.h"
#include "extern.h"
// Function Prototypes
void RequestType(void);
void StandardRequest(void);
void VendorRequest(void);
void SendEP0Data(void);
void CmdSetAddress(void);
void CmdGetDescriptor(void);
void CmdGetStatus(void);
void CmdGetInterface(void);
void CmdSetInterface(void);
void CmdGetConfiguration(void);
void CmdSetConfiguration(void);
void CmdClearFeature(void);
void CmdSetFeature(void);
void WriteLEDData(void);
/*
** RequestType
*
* FILENAME: control_ep0.c
*
* PARAMETERS: None
*
* DESCRIPTION: Determines what request type, (standard, class, or vendor) is being
* asked for.
*
* RETURNS: Nothing
*
*/
void RequestType(void){
ep0csr8 = 1; // Since this is a SETUP packet clear flag here
switch( SetupPacket.bmRequestType & 0x60 ) { // Mask off unnecessary bits
case 0x00:
StandardRequest(); // Standard USB request
break;
case 0x20: // Class specific requests
ep0cs = 0x1040; // STALL not supported
break; // Nothing here for this example
case 0x40: // USB vendor request class
VendorRequest();
break;
default:
ep0cs = 0x1040; // STALL any invalid request
}
}
/*
** StandardRequest
*
* FILENAME: control_ep0.c
*
* PARAMETERS: None
*
* DESCRIPTION: Determines what standard chapter 9 USB request is being asked.
*
* RETURNS: Nothing
*
*/
void StandardRequest(void){
switch( SetupPacket.bRequest ) {
case 0:
CmdGetStatus();
break;
case 1:
CmdClearFeature();
break;
case 3:
CmdSetFeature();
break;
case 5:
CmdSetAddress();
break;
case 6:
CmdGetDescriptor();
break;
case 8:
CmdGetConfiguration();
break;
case 9:
CmdSetConfiguration();
break;
case 10:
CmdGetInterface();
break;
case 11:
CmdSetInterface();
break;
default:
ep0cs = 0x1040; // if none of these then STALL request
}
}
/*
** VendorRequest
*
* FILENAME: control_ep0.c
*
* PARAMETERS: None
*
* DESCRIPTION: Processes USB VENDOR requests sent from the HOST
*
* RETURNS: Nothing
*
*/
void VendorRequest(void){
switch (SetupPacket.bRequest){
case 1:
WriteLEDData(); // Update the LED values on the SK board
break;
case 2:
break;
case 4:
DataTransferFlags.SendBulkData = 1; // Set flag so that MAIN can send BULK data
ep0cs = 0x2240; // OBR, DATA_END, and MASK
break;
default:
ep0cs = 0x1040; // if none of these then STALL request
}
}
/*
** CmdSetAddress
*
* FILENAME: control_ep0.c
*
* PARAMETERS: None
*
* DESCRIPTION: Takes address assigned by the HOST and enters it into the USBA
* register. This request is different depending on whether the
* device already has an assigned address or not. Device enters the
* ADDRESSED state at this point.
*
* RETURNS: Nothing
*
*/
void CmdSetAddress(void) {
if ( usba != 0 ){ // Do we have an address yet?
ep0cs = 0x2240; // Set CLR_OUT_BUF_RDY, DATA_END, & DATA_END_MASK
usba = SetupPacket.wValueLow; // Now load our new device address
USBFlags.Addressed = 1; // And set the ADDRESSED state flag
}
else{ // Otherwise we're changing addresses
usba = SetupPacket.wValueLow; // Load our new device address
ep0cs = 0x2240; // clear out_pkt_rdy, data end, & mask
USBFlags.Addressed = 1; // And set a flag showing current state
}
}
/*
** CmdGetDescriptor
*
* FILENAME: control_ep0.c
*
* PARAMETERS: None
*
* DESCRIPTION: Determines what descriptor string is to be returned to the HOST.
* Calls SendEP0Data to transfer data to HOST.
*
* RETURNS: Nothing
*
*/
void CmdGetDescriptor(void) {
ep0csr6 = 1; // Set CLR_OUT_BUF_RDY moving to the DATA stage for these transactions
switch( SetupPacket.wValueHigh ) { // Mask to determine what descriptor is being asked
case 1: // Send Device Descriptor
pStringAddr = DeviceDescriptor; // Pointer to start of string
SendLength = DeviceDescriptor[0]; // Size of string
break;
case 2: // Send Config Descriptor
pStringAddr = ConfigDescriptor; // Pointer to start of string
SendLength = ConfigDescriptor[2]; // Size of string
break;
case 3:
switch( SetupPacket.wValueLow ) { // Send String Descriptor
case 0: // Language ID String
pStringAddr = LangIDString;
break;
case 1: // Manuf. String
pStringAddr = ManfString;
break;
case 2: // Product String
pStringAddr = ProdString;
break;
case 8: // Configuration string
pStringAddr = ConfigString;
break;
case 4: // Alternate Interface 0 String
pStringAddr = AltSet0String;
break;
case 5: // Alternate Interface 1 String
pStringAddr = AltSet1String;
break;
case 6: // Alternate Interface 2 String
pStringAddr = AltSet2String;
break;
case 7: // Product Serial Number String
pStringAddr = SerialNumberString;
break;
default: // None of these
ep0cs = 0x1040; // STALL and return
return;
}
SendLength = pStringAddr[0]; // Get size of string
break;
default: // None of these
ep0cs = 0x1040; // STALL and return
return;
}
if( SendLength > SetupPacket.wLengthLow ){ // If HOST asks for less data then
SendLength = SetupPacket.wLengthLow; // reset SendLength pointer to requested
} // length
SendBufferIndex = 0x00; // Reset string pointer
while ( SendLength != 0 ){ // Call this function until out of data
ep0ic = 0x00; // disable to prevent extra EP0 interrupts
SendEP0Data(); // Call it here
}
}
/*
** SendEP0Data
*
* FILENAME: control_ep0.c
*
* PARAMETERS: None
*
* DESCRIPTION: Loads FIFO and sends out descriptor data to HOST. Called by CmdGetDescriptor.
* Packets sent differently depending on type and length.
*
* RETURNS: Nothing
*
*/
void SendEP0Data(void){
unsigned char SendNullPacket = 0x00;
if ( USBFlags.SetupEndFlag ){
USBFlags.SetupEndFlag = 0; // Debug....
ep0csr11 = 1; // This clears the SETUP_END condition
ir_ep0ic = 0; // ensure that EP0 interrupt is cleared
ep0ic = 0x03; // Enable the EP0 interrupt (level 3)
SendLength = 0x00; // Don't load anymore data to the FIFO
return; // and just return, completing the transaction...
}
if ( SendLength == 8 ){ // If last packet is = to MAXP and not a
SendNullPacket = 1; // STRING descriptor, then device must send a NULL
} // packet to end the transfer per the USB specification.
// STRING descriptors do not need a NULL terminator however.
if ( SendLength > 8 ) { // If more than 8 bytes then break it up
Bytes2Send = 8; // And send since EP0 here is 8 bytes deep
SendLength -= 8; // And subtract this from the total
}
else{ // Otherwise, send it all now
Bytes2Send = SendLength; // Equate our variable
SendLength = 0; // And clear out SendLength
}
for( ; Bytes2Send; Bytes2Send--) { // Now let's load the FIFO
ep0il = pStringAddr[ SendBufferIndex ];
SendBufferIndex++; // And increment string pointer
}
if ( SendLength == 0 ){ // Is this the last packet?
if ( (SendNullPacket == 0x01) && (SetupPacket.wValueHigh != 0x03) ){ // Is NULL packet needed?
ep0csr7 = 1; // Set IN_PKY_RDY
while ( ep0csr1 ){} // and wait for this packet to be taken
ep0cs = 0x2280; // Set DATA_END, IPR, and DATA_END mask (NULL packet)
ir_ep0ic = 0; // ensure that EP0 interrupt is cleared
ep0ic = 0x03; // Enable the EP0 interrupt (level 3)
}
else{ // Otherwise this is a STRING descriptor. no NULL needed
ep0cs = 0x2280; // Set DATA_END, IPR, and DATA_END mask
ir_ep0ic = 0; // ensure that EP0 interrupt is cleared
ep0ic = 0x03; // Enable the EP0 interrupt (level 3)
}
}
else{
ep0csr7 = 1; // Set IN_PKY_RDY
while ( ep0csr1 ){} // and wait for this packet to be taken
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -