📄 usb_std_req.c
字号:
/*
FILENAME: USB_STD_REQ.c
author: DM
11/22/02
This source file contains the subroutines used to handle incoming setup packets.
These are called by Handle_Setup in USB_ISR.c and used for USB chapter 9
compliance.
*/
#include "c8051F320.h"#include "USB_REGISTER.h"
#include "USB_MAIN.h"
#include "USB_DESCRIPTOR.h"
extern device_descriptor DeviceDesc; // These are created in USB_DESCRIPTOR.h
extern configuration_descriptor ConfigDesc;
extern interface_descriptor InterfaceDesc;
extern endpoint_descriptor Endpoint1Desc;
extern endpoint_descriptor Endpoint2Desc;
extern BYTE* StringDescTable[];
extern setup_buffer Setup; // Buffer for current device request information
extern unsigned int DataSize;
extern unsigned int DataSent;
extern BYTE* DataPtr;
extern BYTE Ep_Status[]; // This array contains status bytes for EP 0-2
code BYTE ONES_PACKET[2] = {0x01, 0x00}; // These are response packets used for
code BYTE ZERO_PACKET[2] = {0x00, 0x00}; // communication with host
extern BYTE USB_State; // Determines current usb device state
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
{
DataPtr = (BYTE*)&ZERO_PACKET; // Otherwise send 0x00, indicating bus power and no
DataSize = 2; // remote wake-up supported
}
break;
case OUT_INTERFACE: // See if recipient was interface
if ((USB_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
{
DataPtr = (BYTE*)&ZERO_PACKET; // Status packet always returns 0x00
DataSize = 2;
}
break;
case OUT_ENDPOINT: // See if recipient was an endpoint
if ((USB_State != DEV_CONFIGURED) ||
Setup.wIndex.c[MSB]) // Make sure device is configured and index msb = 0x00
{ // otherwise return stall to host
Force_Stall();
}
else
{
if (Setup.wIndex.c[LSB] == IN_EP1) // Handle case if request is directed to EP 1
{
if (Ep_Status[1] == EP_HALT)
{ // If endpoint is halted, return 0x01,0x00
DataPtr = (BYTE*)&ONES_PACKET;
DataSize = 2;
}
else
{
DataPtr = (BYTE*)&ZERO_PACKET;// Otherwise return 0x00,0x00 to indicate endpoint active
DataSize = 2;
}
}
else
{
if (Setup.wIndex.c[LSB] == OUT_EP2)
// If request is directed to endpoint 2, send either
{ // 0x01,0x00 if endpoint halted or 0x00,0x00 if
if (Ep_Status[2] == EP_HALT) // endpoint is active
{
DataPtr = (BYTE*)&ONES_PACKET;
DataSize = 2;
}
else
{
DataPtr = (BYTE*)&ZERO_PACKET;
DataSize = 2;
}
}
else
{
Force_Stall(); // Send stall if unexpected data encountered
}
}
}
break;
default:
Force_Stall();
break;
}
if (Ep_Status[0] != EP_STALL)
{
POLL_WRITE_BYTE(E0CSR, rbSOPRDY); // Set serviced Setup Packet, Endpoint 0 in
Ep_Status[0] = EP_TX; // transmit mode, and reset DataSent counter
DataSent = 0;
}
}
void Clear_Feature() // This routine can clear Halt Endpoint features
{ // on endpoint 1 and 2.
if ((USB_State != DEV_CONFIGURED) ||// Send procedural stall if device isn't configured
(Setup.bmRequestType == IN_DEVICE) ||// or request is made to host(remote wakeup not supported)
(Setup.bmRequestType == IN_INTERFACE) ||// or request is made to interface
Setup.wValue.c[MSB] || Setup.wIndex.c[MSB]||// or msbs of value or index set to non-zero value
Setup.wLength.c[MSB] || Setup.wLength.c[LSB])// or data length set to non-zero.
{
Force_Stall();
}
else
{
if ((Setup.bmRequestType == IN_ENDPOINT)&&// Verify that packet was directed at an endpoint
(Setup.wValue.c[LSB] == ENDPOINT_HALT) &&// the feature selected was HALT_ENDPOINT
((Setup.wIndex.c[LSB] == IN_EP1) || // and that the request was directed at EP 1 in
(Setup.wIndex.c[LSB] == OUT_EP2))) // or EP 2 out
{
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
{
POLL_WRITE_BYTE (INDEX, 2); // Clear feature endpoint 2 halt
POLL_WRITE_BYTE (EOUTCSR1, rbOutCLRDT);
Ep_Status[2] = EP_IDLE; // Set endpoint 2 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
}
}
void Set_Feature(void) // This routine will set the EP Halt feature for
{ // endpoints 1 and 2
if ((USB_State != DEV_CONFIGURED) ||// Make sure device is configured, setup data
(Setup.bmRequestType == IN_DEVICE) ||// is all valid and that request is directed at
(Setup.bmRequestType == IN_INTERFACE) ||// an endpoint
Setup.wValue.c[MSB] || Setup.wIndex.c[MSB]||
Setup.wLength.c[MSB] || Setup.wLength.c[LSB])
{
Force_Stall(); // Otherwise send stall to host
}
else
{
if ((Setup.bmRequestType == IN_ENDPOINT)&&// Make sure endpoint exists and that halt
(Setup.wValue.c[LSB] == ENDPOINT_HALT) &&// endpoint feature is selected
((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
{
POLL_WRITE_BYTE (INDEX, 2); // Set feature Ep2 halt
POLL_WRITE_BYTE (EOUTCSR1, rbOutSDSTL);
Ep_Status[2] = EP_HALT;
}
}
else
{
Force_Stall(); // Send procedural stall
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -