📄 f34x_msd_usb_std_req.c
字号:
//-----------------------------------------------------------------------------
// F34x_MSD_USB_Std_Req.c
//-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// This source file contains the subroutines used to handle incoming setup
// packets. These are called by Handle_Setup in F34x_USB_ISR.c and used for
// USB chapter 9 compliance.
//
//
//
// How To Test: See Readme.txt
//
//
// FID: 34X000066
// Target: C8051F34x
// Tool chain: Keil
// Command Line: See Readme.txt
// Project Name: F34x_USB_MSD
//
// Release 1.1
// -All changes by PKC
// -09 JUN 2006
// -Replaced SFR definitions file "c8051f320.h" with "c8051f340.h"
//
// Release 1.0
// -Initial Release
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include "c8051f340.h"
#include "F34x_MSD_USB_Register.h"
#include "F34x_MSD_USB_Main.h"
#include "F34x_MSD_USB_Descriptor.h"
#include "F34x_MSD_Msd.h"
extern device_descriptor Device_Desc; // These are created in F34x_USB_Descriptor.h
extern configuration_descriptor Config_Desc;
extern interface_descriptor Interface_Desc;
extern endpoint_descriptor Endpoint1_Desc;
extern endpoint_descriptor Endpoint2_Desc;
extern BYTE* String_Desc_Table[];
extern setup_buffer Setup; // Buffer for current device request information
extern xdata unsigned int Data_Size;
extern xdata unsigned int Data_Sent;
extern BYTE* Data_Ptr;
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 xdata BYTE USB_State; // Determines current USB device state
//----------------------------------------------------------------------------
// Get_Status
//----------------------------------------------------------------------------
//
// This routine returns a two byte status packet
// to the host
//
// Parameters :
// Return Value :
//----------------------------------------------------------------------------
void Get_Status(void)
{
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
{
Data_Ptr = (BYTE*)&ZERO_PACKET; // Otherwise send 0x00, indicating bus power and no
Data_Size = 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
{
Data_Ptr = (BYTE*)&ZERO_PACKET; // Status packet always returns 0x00
Data_Size = 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
Data_Ptr = (BYTE*)&ONES_PACKET;
Data_Size = 2;
}
else
{
Data_Ptr = (BYTE*)&ZERO_PACKET;// Otherwise return 0x00,0x00 to indicate endpoint active
Data_Size = 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
{
Data_Ptr = (BYTE*)&ONES_PACKET;
Data_Size = 2;
}
else
{
Data_Ptr = (BYTE*)&ZERO_PACKET;
Data_Size = 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 Data_Sent counter
Data_Sent = 0;
}
}
//----------------------------------------------------------------------------
// Clear_Feature
//----------------------------------------------------------------------------
//
// This routine can clear Halt Endpoint features
// on endpoint 1 and 2.
//
// Parameters :
// Return Value :
//----------------------------------------------------------------------------
void Clear_Feature()
{
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, EP1_IN_IDX); // 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, EP2_OUT_IDX); // 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, EP0_IDX); // 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
//----------------------------------------------------------------------------
//
// This routine will set the EP Halt feature for
// endpoints 1 and 2
//
// Parameters :
// Return Value :
//----------------------------------------------------------------------------
void Set_Feature(void)
{
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, EP1_IN_IDX); // Set feature endpoint 1 halt
POLL_WRITE_BYTE (EINCSR1, rbInSDSTL);
Ep_Status[1] = EP_HALT;
}
else
{
POLL_WRITE_BYTE (INDEX, EP2_OUT_IDX); // Set feature Ep2 halt
POLL_WRITE_BYTE (EOUTCSR1, rbOutSDSTL);
Ep_Status[2] = EP_HALT;
}
}
else
{
Force_Stall(); // Send procedural stall
}
}
POLL_WRITE_BYTE(INDEX, EP0_IDX);
if (Ep_Status[0] != EP_STALL)
{
POLL_WRITE_BYTE(E0CSR, (rbSOPRDY | rbDATAEND));
// Indicate setup packet has been serviced
}
}
//----------------------------------------------------------------------------
// Set_Address
//----------------------------------------------------------------------------
//
// Set new function address
//
// Parameters :
// Return Value :
//----------------------------------------------------------------------------
void Set_Address(void)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -