?? f34x_usb_standard_requests.c
字號:
//-----------------------------------------------------------------------------
// F34x_USB_Standard_Requests.c
//-----------------------------------------------------------------------------
// Copyright 2005 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 USB_ISR.c and used for
// USB chapter 9 compliance.
//
// How To Test: See Readme.txt
//
//
// FID: 34X000022
// Target: C8051F34x
// Tool chain: Keil C51 7.50 / Keil EVAL C51
// Silicon Laboratories IDE version 2.6
// Command Line: See Readme.txt
// Project Name: F34x_USB_Interrupt
//
//
// Release 1.0
// -Initial Revision (GP)
// -22 NOV 2005
// -Ported from 'F320_USB_Bulk
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include "c8051F340.h"#include "F34x_USB_Register.h"
#include "F34x_USB_Main.h"
#include "F34x_USB_Descriptor.h"
//-----------------------------------------------------------------------------
// Externs
//-----------------------------------------------------------------------------
// These are created in USB_DESCRIPTOR.h
extern device_descriptor DeviceDesc;
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
extern unsigned int DataSize;
extern unsigned int DataSent;
extern BYTE* DataPtr;
extern BYTE Ep_Status[]; // Contains status bytes for EP 0-2
extern BYTE USB_State; // Determines current usb device state
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
// These are response packets used for communication with host
code BYTE ONES_PACKET[2] = {0x01, 0x00};
code BYTE ZERO_PACKET[2] = {0x00, 0x00};
//-----------------------------------------------------------------------------
// Support Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Get_Status
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine returns a two byte status packet to the host
//
//-----------------------------------------------------------------------------
void Get_Status(void)
{
if (Setup.wValue.c[MSB] || Setup.wValue.c[LSB] ||
// If non-zero return length or data length not equal to 2 then send a stall
// indicating invalid request
Setup.wLength.c[MSB] || (Setup.wLength.c[LSB] != 2))
{
Force_Stall();
}
// Determine if recipient was device, interface, or EP
switch(Setup.bmRequestType)
{
// If recipient was device
case OUT_DEVICE:
if (Setup.wIndex.c[MSB] || Setup.wIndex.c[LSB])
{
// Send stall if request is invalid
Force_Stall();
}
else
{
// Otherwise send 0x00, indicating bus power and no
// remote wake-up supported
DataPtr = (BYTE*)&ZERO_PACKET;
DataSize = 2;
}
break;
// See if recipient was interface
case OUT_INTERFACE:
// Only valid if device is configured and non-zero index
if ((USB_State != DEV_CONFIGURED) ||
Setup.wIndex.c[MSB] || Setup.wIndex.c[LSB])
{
// Otherwise send stall to host
Force_Stall();
}
else
{
// Status packet always returns 0x00
DataPtr = (BYTE*)&ZERO_PACKET;
DataSize = 2;
}
break;
// See if recipient was an endpoint
case OUT_ENDPOINT:
// Make sure device is configured and index msb = 0x00
if ((USB_State != DEV_CONFIGURED) || Setup.wIndex.c[MSB])
{
Force_Stall(); // otherwise return stall to host
}
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 = (BYTE*)&ONES_PACKET;
DataSize = 2;
}
else
{
// Otherwise return 0x00,0x00 to indicate endpoint active
DataPtr = (BYTE*)&ZERO_PACKET;
DataSize = 2;
}
}
else
{
// If request is directed to endpoint 2, send either
// 0x01,0x00 if endpoint halted or 0x00,0x00 if endpoint is active
if (Setup.wIndex.c[LSB] == OUT_EP2)
{
if (Ep_Status[2] == EP_HALT)
{
DataPtr = (BYTE*)&ONES_PACKET;
DataSize = 2;
}
else
{
DataPtr = (BYTE*)&ZERO_PACKET;
DataSize = 2;
}
}
else
{
Force_Stall(); // Send stall if unexpected data
}
}
}
break;
default:
Force_Stall();
break;
}
if (Ep_Status[0] != EP_STALL)
{
// Set serviced Setup Packet, Endpoint 0 intransmit mode,
// and reset DataSent counter
POLL_WRITE_BYTE(E0CSR, rbSOPRDY);
Ep_Status[0] = EP_TX;
DataSent = 0;
}
}
//-----------------------------------------------------------------------------
// Clear_Feature
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine can clear Halt Endpoint features on endpoint 1 and 2.
//
//-----------------------------------------------------------------------------
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, 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)
{
// Indicate setup packet has been serviced
POLL_WRITE_BYTE(E0CSR, rbSOPRDY);
}
}
//-----------------------------------------------------------------------------
// Set_Feature
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine will set the EP Halt feature for endpoints 1 and 2
//
//-----------------------------------------------------------------------------
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, 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
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -