📄 f3xx_usb0_standard_requests.c
字号:
//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
#include "c8051f3xx.h"
#include "F3xx_USB0_Register.h"
#include "F3xx_USB0_InterruptServiceRoutine.h"
#include "F3xx_USB0_Descriptor.h"
#include "F3xx_USB0_ReportHandler.h"
//-----------------------------------------------------------------------------
// Variables
//-----------------------------------------------------------------------------
extern device_descriptor DEVICEDESC; // These are created in F3xx_USB0_Descriptor.h
extern unsigned char* STRINGDESCTABLE[];
// Additional declarations for HID:
extern hid_configuration_descriptor HIDCONFIGDESC;
extern hid_report_descriptor HIDREPORTDESC;
extern setup_buffer SETUP; // Buffer for current device request
// information
extern unsigned int DATASIZE;
extern unsigned int DATASENT;
extern unsigned char* DATAPTR;
// These are response packets used for
code unsigned char ONES_PACKET[2] = {0x01, 0x00};
// communication with host
code unsigned char ZERO_PACKET[2] = {0x00, 0x00};
extern unsigned char USB0_STATE; // Determines current usb device state
//-----------------------------------------------------------------------------
// Definitions
//-----------------------------------------------------------------------------
// Redefine existing variable names to refer to the descriptors within the
// HID configuration descriptor.
// This minimizes the impact on the existing source code.
#define ConfigDesc (HIDCONFIGDESC.hid_configuration_descriptor)
#define InterfaceDesc (HIDCONFIGDESC.hid_interface_descriptor)
#define HidDesc (HIDCONFIGDESC.hid_descriptor)
#define Endpoint1Desc (HIDCONFIGDESC.hid_endpoint_in_descriptor)
#define Endpoint2Desc (HIDCONFIGDESC.hid_endpoint_out_descriptor)
//-----------------------------------------------------------------------------
// Get_Status
//-----------------------------------------------------------------------------
//
// Return Value - None
// Parameters - None
//
// Standard request that should not change for custom HID designs.
//
// ----------------------------------------------------------------------------
void Get_Status (void) // This routine returns a two byte
{ // status packet to the host
if (SETUP.wValue.c[MSB] || SETUP.wValue.c[LSB] ||
// If non-zero return length or data
// length not
SETUP.wLength.c[MSB] || (SETUP.wLength.c[LSB] != 2))
// equal to 2 then send a stall
{ // indicating invalid request
Force_Stall ();
}
switch(SETUP.bmRequestType) // Determine if recipient was device,
{ // interface, or EP
case OUT_DEVICE: // If recipient was device
if (SETUP.wIndex.c[MSB] || SETUP.wIndex.c[LSB])
{
Force_Stall (); // Send stall if request is invalid
}
else
{
// Otherwise send 0x00, indicating bus power and no
// remote wake-up supported
DATAPTR = (unsigned char*)&ZERO_PACKET;
DATASIZE = 2;
}
break;
case OUT_INTERFACE: // See if recipient was interface
if ((USB0_STATE != DEV_CONFIGURED) ||
SETUP.wIndex.c[MSB] || SETUP.wIndex.c[LSB])
// Only valid if device is configured
// and non-zero index
{
Force_Stall (); // Otherwise send stall to host
}
else
{
// Status packet always returns 0x00
DATAPTR = (unsigned char*)&ZERO_PACKET;
DATASIZE = 2;
}
break;
case OUT_ENDPOINT: // See if recipient was an endpoint
if ((USB0_STATE != DEV_CONFIGURED) ||
SETUP.wIndex.c[MSB]) // Make sure device is configured
// and index msb = 0x00
{ // otherwise return stall to host
Force_Stall();
}
else
{
// Handle case if request is directed to EP 1
if (SETUP.wIndex.c[LSB] == IN_EP1)
{
if (EP_STATUS[1] == EP_HALT)
{ // If endpoint is halted,
// return 0x01,0x00
DATAPTR = (unsigned char*)&ONES_PACKET;
DATASIZE = 2;
}
else
{
// Otherwise return 0x00,0x00 to indicate endpoint active
DATAPTR = (unsigned char*)&ZERO_PACKET;
DATASIZE = 2;
}
}
else
{
Force_Stall (); // Send stall if unexpected data
// encountered
}
}
break;
default:
Force_Stall ();
break;
}
if (EP_STATUS[0] != EP_STALL)
{
// Set serviced SETUP Packet, Endpoint 0 in transmit mode, and
// reset DATASENT counter
POLL_WRITE_BYTE (E0CSR, rbSOPRDY);
EP_STATUS[0] = EP_TX;
DATASENT = 0;
}
}
//-----------------------------------------------------------------------------
// Clear_Feature
//-----------------------------------------------------------------------------
//
// Return Value - None
// Parameters - None
//
// Standard request that should not change in custom HID designs.
//
//-----------------------------------------------------------------------------
void Clear_Feature () // This routine can clear Halt Endpoint
{ // features on endpoint 1
// Send procedural stall if device isn't configured
if ( (USB0_STATE != DEV_CONFIGURED) ||
// or request is made to host(remote wakeup not supported)
(SETUP.bmRequestType == IN_DEVICE) ||
// or request is made to interface
(SETUP.bmRequestType == IN_INTERFACE) ||
// or msbs of value or index set to non-zero value
SETUP.wValue.c[MSB] || SETUP.wIndex.c[MSB] ||
// or data length set to non-zero.
SETUP.wLength.c[MSB] || SETUP.wLength.c[LSB])
{
Force_Stall ();
}
else
{
// Verify that packet was directed at an endpoint
if ( (SETUP.bmRequestType == IN_ENDPOINT)&&
// the feature selected was HALT_ENDPOINT
(SETUP.wValue.c[LSB] == ENDPOINT_HALT) &&
// and that the request was directed at EP 1 in
((SETUP.wIndex.c[LSB] == IN_EP1) ) )
{
if (SETUP.wIndex.c[LSB] == IN_EP1)
{
POLL_WRITE_BYTE (INDEX, 1);// Clear feature endpoint 1 halt
POLL_WRITE_BYTE (EINCSR1, rbInCLRDT);
EP_STATUS[1] = EP_IDLE; // Set endpoint 1 status back to idle
}
}
else
{
Force_Stall (); // Send procedural stall
}
}
POLL_WRITE_BYTE (INDEX, 0); // Reset Index to 0
if (EP_STATUS[0] != EP_STALL)
{
POLL_WRITE_BYTE (E0CSR, (rbSOPRDY | rbDATAEND));
// Set Serviced Out packet ready and
// data end to indicate transaction
// is over
}
}
//-----------------------------------------------------------------------------
// Set_Feature
//-----------------------------------------------------------------------------
//
// Return Value - None
// Parameters - None
//
// Standard request that should not change in custom HID designs.
//
//-----------------------------------------------------------------------------
void Set_Feature (void) // This routine will set the EP Halt
{ // feature for endpoint 1
// Make sure device is configured, SETUP data
if ((USB0_STATE != DEV_CONFIGURED) ||
// is all valid and that request is directed at an endpoint
(SETUP.bmRequestType == IN_DEVICE) ||
(SETUP.bmRequestType == IN_INTERFACE) ||
SETUP.wValue.c[MSB] || SETUP.wIndex.c[MSB] ||
SETUP.wLength.c[MSB] || SETUP.wLength.c[LSB])
{
Force_Stall (); // Otherwise send stall to host
}
else
{
// Make sure endpoint exists and that halt
if ( (SETUP.bmRequestType == IN_ENDPOINT)&&
// endpoint feature is selected
(SETUP.wValue.c[LSB] == ENDPOINT_HALT) &&
((SETUP.wIndex.c[LSB] == IN_EP1) ||
(SETUP.wIndex.c[LSB] == OUT_EP2) ) )
{
if (SETUP.wIndex.c[LSB] == IN_EP1)
{
POLL_WRITE_BYTE (INDEX, 1);// Set feature endpoint 1 halt
POLL_WRITE_BYTE (EINCSR1, rbInSDSTL);
EP_STATUS[1] = EP_HALT;
}
}
else
{
Force_Stall (); // Send procedural stall
}
}
POLL_WRITE_BYTE (INDEX, 0);
if (EP_STATUS[0] != EP_STALL)
{
POLL_WRITE_BYTE (E0CSR, (rbSOPRDY | rbDATAEND));
// Indicate SETUP packet has been
// serviced
}
}
//-----------------------------------------------------------------------------
// Set_Address
//-----------------------------------------------------------------------------
//
// Return Value - None
// Parameters - None
//
// Standard request that should not change in custom HID designs.
//
//-----------------------------------------------------------------------------
void Set_Address (void) // Set new function address
{
// Request must be directed to device
if ((SETUP.bmRequestType != IN_DEVICE) ||
// with index and length set to zero.
SETUP.wIndex.c[MSB] || SETUP.wIndex.c[LSB]||
SETUP.wLength.c[MSB] || SETUP.wLength.c[LSB]||
SETUP.wValue.c[MSB] || (SETUP.wValue.c[LSB] & 0x80))
{
Force_Stall (); // Send stall if SETUP data invalid
}
EP_STATUS[0] = EP_ADDRESS; // Set endpoint zero to update
// address next status phase
if (SETUP.wValue.c[LSB] != 0)
{
USB0_STATE = DEV_ADDRESS; // Indicate that device state is now
// address
}
else
{
USB0_STATE = DEV_DEFAULT; // If new address was 0x00, return
} // device to default state
if (EP_STATUS[0] != EP_STALL)
{
POLL_WRITE_BYTE (E0CSR, (rbSOPRDY | rbDATAEND));
// Indicate SETUP packet has
// been serviced
}
}
//-----------------------------------------------------------------------------
// Get_Descriptor
//-----------------------------------------------------------------------------
//
// Return Value - None
// Parameters - None
//
// Standard request that should not change in custom HID designs.
//
//-----------------------------------------------------------------------------
void Get_Descriptor (void) // This routine sets the data pointer
{ // and size to correct descriptor and
// sets the endpoint status to transmit
switch(SETUP.wValue.c[MSB]) // Determine which type of descriptor
{ // was requested, and set data ptr and
case DSC_DEVICE: // size accordingly
DATAPTR = (unsigned char*) &DEVICEDESC;
DATASIZE = DEVICEDESC.bLength;
break;
case DSC_CONFIG:
DATAPTR = (unsigned char*) &ConfigDesc;
// Compiler Specific - The next statement
// reverses the bytes in the configuration
// descriptor for the compiler
DATASIZE = ConfigDesc.wTotalLength.c[MSB] +
256*ConfigDesc.wTotalLength.c[LSB];
break;
case DSC_STRING:
DATAPTR = STRINGDESCTABLE[SETUP.wValue.c[LSB]];
// Can have a maximum of 255 strings
DATASIZE = *DATAPTR;
break;
case DSC_INTERFACE:
DATAPTR = (unsigned char*) &InterfaceDesc;
DATASIZE = InterfaceDesc.bLength;
break;
case DSC_ENDPOINT:
if ( (SETUP.wValue.c[LSB] == IN_EP1) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -