📄 f3xx_usb0_standard_requests.c
字号:
/* Copyright (c) 2007 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is confidential property of
* Nordic Semiconductor. The use, copying, transfer or disclosure
* of such information is prohibited except by express written
* agreement with Nordic Semiconductor.
*/
/** @file
*
* Functions for handling USB Standard Requests. This file is originally a
* template from a SiLabs Application Note. It has been adapted to satisfy
* the needs of this application. Documentation blocks for automatical
* generaion of documentation have not been added. However, the source code has
* useful comments.
*
* @author Runar Kjellhaug
* @author Eirik Midttun
*
* @addtogroup usb_code
* @{
*/
//-----------------------------------------------------------------------------
// F32x_USB0_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:
// Target: C8051F32x
// Tool chain: Keil C51 7.50 / Keil EVAL C51
// Silicon Laboratories IDE version 2.6
// Command Line: See Readme.txt
// Project Name:
//
//
// Release 1.3
// - Changes by PD, GP
// - Modified Descriptors
// - Changed name from USB_Descriptor.c
// - 07 December 2005
// Release 1.0
// -Initial Revision (DM)
// -22 NOV 2002
//
//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
#include <c8051f320.h>
#include "usb_regs.h"
#include "f3xx_usb0_interruptserviceroutine.h"
#include "usb_desc.h"
#include "f3xx_usb0_reporthandler.h"
//-----------------------------------------------------------------------------
// Variables
//-----------------------------------------------------------------------------
extern const uint8_t* code STRINGDESCTABLE[];
extern code const device_desc DEVICEDESC;
extern code const hid_conf_desc HIDCONFIGDESC; // Additional declarations for HID:
extern code const uint8_t HID_REPORT_DESC_MOUSE[]; // HID_REPORT_DESCRIPTOR_SIZE
extern code const uint8_t HID_REPORT_DESC_KEYB[];
extern code const uint8_t HID_REPORT_DESC_RC[];
extern setup_buffer SETUP; // Buffer for current device request information
extern xdata uint16_t DATASIZE;
extern xdata uint16_t DATASENT;
extern xdata uint8_t* DATAPTR;
code uint8_t ONES_PACKET[2] = {0x01, 0x00}; // These are response packets used for
code uint8_t ZERO_PACKET[2] = {0x00, 0x00}; // communication with host
extern uint8_t USB0_STATE; // Determines current usb device state
extern uint8_t EP_STATUS[];
extern xdata BufferStructure in_buffer, out_buffer;
//-----------------------------------------------------------------------------
// 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_conf_desc
#define InterfaceDesc HIDCONFIGDESC.hid_interface_desc
#define HidDesc HIDCONFIGDESC.hid_class_desc
#define Endpoint1Desc HIDCONFIGDESC.hid_ep_in_desc
#define Endpoint2Desc HIDCONFIGDESC.hid_ep_out_desc
//-----------------------------------------------------------------------------
// 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 non-zero return length or data length not equal to 2 then send a stall indicating invalid request
if(SETUP.wValue.c[cMSB] || SETUP.wValue.c[cLSB] || SETUP.wLength.c[cMSB] || (SETUP.wLength.c[cLSB] != 2))
{
Force_Stall();
}
// Determine if recipient was device, interface, or EP
switch(SETUP.bmRequestType)
{
case OUT_DEVICE: // If recipient was device
if(SETUP.wIndex.c[cMSB] || SETUP.wIndex.c[cLSB])
{
Force_Stall(); // Send stall if request is invalid
}
else // Otherwise send 0x00, indicating bus power and no remote wake-up supported
{
DATAPTR = (uint8_t*)&ZERO_PACKET[0];
DATASIZE = 2;
}
break;
case OUT_INTERFACE: // See if recipient was interface
if((USB0_STATE != DEV_CONFIGURED) || SETUP.wIndex.c[cMSB] || SETUP.wIndex.c[cLSB]) // Only valid if device is configured and non-zero index
{
Force_Stall(); // Otherwise send stall to host
}
else // Status packet always returns 0x00
{
DATAPTR = (uint8_t*)&ZERO_PACKET[0];
DATASIZE = 2;
}
break;
case OUT_ENDPOINT: // See if recipient was an endpoint
if((USB0_STATE != DEV_CONFIGURED) || SETUP.wIndex.c[cMSB]) // 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[cLSB] == IN_EP1)
{
if(EP_STATUS[1] == EP_HALT) // If endpoint is halted, return 0x01,0x00
{
DATAPTR = (uint8_t*)&ONES_PACKET[0];
DATASIZE = 2;
}
else // Otherwise return 0x00,0x00 to indicate endpoint active
{
DATAPTR = (uint8_t*)&ZERO_PACKET[0];
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(void) // This routine can clear Halt Endpoint features on endpoint 1
{
if((USB0_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[cMSB] || SETUP.wIndex.c[cMSB] || // or msbs of value or index set to non-zero value
SETUP.wLength.c[cMSB] || SETUP.wLength.c[cLSB]) // 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[cLSB] == ENDPOINT_HALT) && // the feature selected was HALT_ENDPOINT
((SETUP.wIndex.c[cLSB] == IN_EP1))) // and that the request was directed at EP 1 in
{
if(SETUP.wIndex.c[cLSB] == 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) // Set Serviced Out packet ready and data end to indicate transaction is over
{
POLL_WRITE_BYTE (E0CSR, (rbSOPRDY | rbDATAEND));
}
}
//-----------------------------------------------------------------------------
// 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
{
if((USB0_STATE != DEV_CONFIGURED) || // Make sure device is configured, SETUP data
(SETUP.bmRequestType == IN_DEVICE) || // is all valid and that request is directed at an endpoint
(SETUP.bmRequestType == IN_INTERFACE) ||
SETUP.wValue.c[cMSB] || SETUP.wIndex.c[cMSB] ||
SETUP.wLength.c[cMSB] || SETUP.wLength.c[cLSB])
{
Force_Stall(); // Otherwise send stall to host
}
else
{
if((SETUP.bmRequestType == IN_ENDPOINT)&& // Make sure endpoint exists and that halt
(SETUP.wValue.c[cLSB] == ENDPOINT_HALT) && // endpoint feature is selected
((SETUP.wIndex.c[cLSB] == IN_EP1) ||
(SETUP.wIndex.c[cLSB] == OUT_EP2)))
{
if (SETUP.wIndex.c[cLSB] == 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
{
if((SETUP.bmRequestType != IN_DEVICE) || // Request must be directed to device with index and length set to zero.
SETUP.wIndex.c[cMSB] || SETUP.wIndex.c[cLSB]||
SETUP.wLength.c[cMSB] || SETUP.wLength.c[cLSB]||
SETUP.wValue.c[cMSB] || (SETUP.wValue.c[cLSB] & 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[cLSB] != 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[cMSB]) // Determine which type of descriptor
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -