📄 fw_chap9.c
字号:
// ----------------------------------------------------------------------------
// ATMEL Microcontroller Software Support - ROUSSET -
// ----------------------------------------------------------------------------
// DISCLAIMER: CONDITIONS AS PER SIGNED LIMITED LICENSE AGREEMENT (AT91
// SOFTWARE AND USER DOCUMENTATION)
// ALL SOFTWARE IS PROVIDED AS IS, WITH ALL FAULTS, AND WITH NO WARRANTY
// WHATSOEVER. ATMEL EXPRESSLY DISCLAIMS ALL WARRANTIES, EXPRESS, IMPLIED,
// OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.
// ----------------------------------------------------------------------------
// File Name : fw_chap9.c
// Object : 11.24.1 Standard Requests
// (chapter9 of USB spec),class and vendor requests usb_20.pdf
//
// Creation : JCB 27/oct/2002
// Modif : JCB 18/fev/2005
// JCB 18/mar/2005 Device descriptor update
// JCB 27/avr/2005
//----------------------------------------------------------------------------
#include "po_types.h"
#include "trace.h"
#include "fw_usb.h"
#include "po_kernel.h"
#include "ms_device.h"
#include "ms_rbc.h"
//
// Table 11-14. Hub Responses to Standard Device Requests
// 9.4.1 Clear Feature ( CLEAR_FEATURE )
// 9.4.2 Get Configuration ( GET_CONFIGURATION )
// 9.4.3 Get Descriptor ( GET_DESCRIPTOR )
// 9.4.4 Get Interface ( GET_INTERFACE )
// 9.4.5 Get Status ( GET_STATUS )
// 9.4.6 Set Address ( SET_ADDRESS )
// 9.4.7 Set Configuration ( SET_CONFIGURATION )
// //SET_DESCRIPTOR Optional
// 9.4.9 Set Feature ( SET_FEATURE )
// 9.4.10 Set Interface ( SET_INTERFACE )
// //SYNCH_FRAME Undefined. Hubs are not allowed to have isochronous endpoints.
//
#ifndef AT91SAM9265
#define AT91C_EPT_DIR_OUT ((unsigned int) 0x0 << 8) // (UDP_EPT) Direction OUT
#define AT91C_EPT_DIR_IN ((unsigned int) 0x1 << 8) // (UDP_EPT) Direction IN
#endif
USB_DEVICE_DESCRIPTOR fw_device =
{
sizeof(USB_DEVICE_DESCRIPTOR), // Size of this descriptor in bytes
USB_DEVICE_DESCRIPTOR_TYPE, // DEVICE Descriptor Type
0x0200, // USB Specification Release Number in Binary-Coded Decimal
0, // Class code (assigned by the USB-IF).
0, // Subclass code (assigned by the USB-IF).
0, // Protocol code (assigned by the USB-IF).
FW_EP0_MAXPACKET_SIZE, // Maximum packet size for endpoint zero
FW_VENDOR_ID, // Vendor ID (assigned by the USB-IF)
FW_PRODUCT_ID, // Product ID (assigned by the manufacturer)
FW_BCDDEVICE, // Device release number in binary-coded decimal
FW_MANUFACTURER, // Index of string descriptor describing manufacturer
FW_PRODUCT, // Index of string descriptor describing product
FW_SERIALNUMBER, // Index of string descriptor describing the device抯 serial number
FW_NUMCONFIGURATION // Number of possible configurations
};
FW_FULL_CONFIG_DESCRIPTOR fw_config =
{
{ // Standard Configuration Descriptor
sizeof(USB_CONFIGURATION_DESCRIPTOR), // Size of this descriptor in bytes
USB_CONFIGURATION_DESCRIPTOR_TYPE, // CONFIGURATION Descriptor Type
sizeof(FW_FULL_CONFIG_DESCRIPTOR), // Total length of data returned for this configuration.
1, // Number of interfaces supported by this configuration
1, // Value to use as an argument to the SetConfiguration() request to select this configuration
0, // Index of string descriptor describing this configuration
USB_CONFIG_BUS_NOWAKEUP, // attribute : Bus-powered, no wakeup
0x64 // Maximum power consumption (in 2mA unit, so 0x64 =100= 200mA)
},
/* Data interface */
{
// Standard Interface Descriptor
sizeof(USB_INTERFACE_DESCRIPTOR), // Size of this descriptor in bytes
USB_INTERFACE_DESCRIPTOR_TYPE, // INTERFACE Descriptor Type
0x00, // Number of this interface
0, // Value used to select this alternate setting for the interface identified in the prior field
2, // Number of endpoints used by this interface (excluding endpoint zero).
USB_DEVICE_CLASS_MASS_STORAGE_MSC, // Class code (assigned by the USB-IF) : USB Mass Storage
SUBCLASSCODE_SCSI, // Subclass code (assigned by the USB-IF): SCSI transparent command set : usb_msc_overview_1.2.pdf
PROTOCOL_BULK_ONLY_TRANSPORT, // Protocol code (assigned by the USB) : Bulk-Only transport : usb_msc_overview_1.2.pdf
0 // Index of string descriptor describing this interface
},
{
// Standard Endpoint Descriptor
sizeof(USB_ENDPOINT_DESCRIPTOR), // Size of this descriptor in bytes
USB_ENDPOINT_DESCRIPTOR_TYPE, // ENDPOINT Descriptor Type
0x81, // The address of the endpoint on the USB device described by this descriptor : Endpoint 1, direction IN
USB_ENDPOINT_TYPE_BULK, // This field describes the endpoint抯 attributes when it is configured using the bConfigurationValue.
FW_MAIN_EP_MAXPACKET_SIZE, // Maximum packet size this endpoint is capable of sending or receiving when this configuration is selected.
0 // Interval for polling endpoint for data transfers.
},
{
// Standard Endpoint Descriptor
sizeof(USB_ENDPOINT_DESCRIPTOR), // Size of this descriptor in bytes
USB_ENDPOINT_DESCRIPTOR_TYPE, // ENDPOINT Descriptor Type
0x02, // The address of the endpoint on the USB device described by this descriptor : Endpoint 2, direction OUT
USB_ENDPOINT_TYPE_BULK, // This field describes the endpoint抯 attributes when it is configured using the bConfigurationValue.
FW_MAIN_EP_MAXPACKET_SIZE, // Maximum packet size this endpoint is capable of sending or receiving when this configuration is selected.
0 // Interval for polling endpoint for data transfers.
}
};
/* Global variable for have the stall status on endpoint */
UCHAR stallEndpointStatus = 0;
/*****************************************************************
*
* ROUTINE fw_clearFeature
*
*-----------------------------------------------------------------
*
* Purpose :
* 9.4.1 Clear Feature ( CLEAR_FEATURE )
* This request is used to clear or disable a specific feature.
*
* Input parameters : NONE
*
* Output parameters : NONE
*
* Global data : fw_controlData : request to be processed
*
*****************************************************************/
void fw_clearFeature(void)
{
EPx _endp;
UCHAR _bRecipient = fw_controlData.DeviceRequest.bmRequestType & FW_USB_RECIPIENT;
TRACE_DEBUG_H( "clFeat\n\r");
if (_bRecipient == FW_USB_RECIPIENT_ENDPOINT
&& fw_controlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_HALT)
{
_endp = (EPx)(fw_controlData.DeviceRequest.wIndex & (FW_EP_CTRL | FW_EP_BULK_IN | FW_EP_BULK_OUT));
fw_setEndpointStatus(_endp, 0);
stallEndpointStatus &= ~(1<<_endp);
if (fw_controlData.DeviceRequest.wIndex & (UCHAR)USB_ENDPOINT_DIRECTION_MASK)
{
/* clear TX stall for IN on EPn. */
USB_EVENT |= USB_EVENT_MASK_IN_STALL_CLEARED;
/* Reset data toggle */
AT91F_UDP_ResetEp( USBDEV_BASE_UDP, USBDEV_UDP_EP1 ); // FW_EP_BULK_IN
}
else
{
/* clear RX stall for OUT on EPn. */
USB_EVENT |= USB_EVENT_MASK_OUT_STALL_CLEARED;
/* Reset data toggle */
AT91F_UDP_ResetEp( USBDEV_BASE_UDP, USBDEV_UDP_EP2 ); // FW_EP_BULK_OUT
}
AT91F_UDP_EnableEp( USBDEV_BASE_UDP,_endp );
fw_singleTransmit(0, 0);
}
else
{
if(fw_controlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP)
{
stallEndpointStatus &= ~(1<<4);
fw_singleTransmit(0, 0);
}
else
{
TRACE_DEBUG_H( "stall\n\r");
fw_stallEp0();
stallEndpointStatus &= ~(1<<FW_EP_CTRL);
}
}
}
/*****************************************************************
*
* ROUTINE fw_getConfiguration
*
*-----------------------------------------------------------------
*
* Purpose :
* 9.4.2 Get Configuration ( GET_CONFIGURATION )
* This request returns the current device configuration value.
*
* Input parameters : NONE
*
* Output parameters : NONE
*
* Global data : fw_deviceState : bitmap for different device caracteristics
*
*****************************************************************/
void fw_getConfiguration(void)
{
UCHAR _c = fw_deviceState & FW_DS_CONFIG; /* only one configuration */
TRACE_DEBUG_H( "getConf\n\r");
fw_singleTransmit(&_c, 1);
}
/*****************************************************************
*
* ROUTINE fw_getDescriptor
*
*-----------------------------------------------------------------
*
* Purpose :
* 9.4.3 Get Descriptor ( GET_DESCRIPTOR )
* This request returns the specified descriptor if the descriptor exists.
*
* Input parameters : NONE
*
* Output parameters : NONE
*
* Global data : fw_device
* fw_config
* fw_controlData : request to be processed
*
*****************************************************************/
void fw_getDescriptor(void)
{
UCHAR _bDescriptor = fw_controlData.DeviceRequest.wValue >> 8;
if (_bDescriptor == USB_DEVICE_DESCRIPTOR_TYPE)
{
fw_codeTransmit((UCHAR *)&fw_device, sizeof(USB_DEVICE_DESCRIPTOR));
}
else
{
if (_bDescriptor == USB_CONFIGURATION_DESCRIPTOR_TYPE)
{
fw_codeTransmit((UCHAR *)&fw_config, sizeof(FW_FULL_CONFIG_DESCRIPTOR));
}
else
{
TRACE_ERROR( "stalled\n\r");
fw_stallEp0();
}
}
}
/*****************************************************************
*
* ROUTINE fw_getInterface
*
*-----------------------------------------------------------------
*
* Purpose :
* 9.4.4 Get Interface ( GET_INTERFACE )
* This request returns the selected alternate setting for the specified interface.
*
* Input parameters : NONE
*
* Output parameters : NONE
*
*****************************************************************/
void fw_getInterface(void)
{
UCHAR _txdat = 0; /* Only one alternate settings per interface = 0 */
TRACE_DEBUG_H( "getInt\n\r");
fw_singleTransmit(&_txdat, 1);
}
/*****************************************************************
*
* ROUTINE fw_getStatus
*
*-----------------------------------------------------------------
*
* Purpose :
* 9.4.5 Get Status ( GET_STATUS )
* This request returns status for the specified recipient.
*
* Input parameters : NONE
*
* Output parameters : NONE
*
* Global data : fw_controlData : request to be processed
*
*****************************************************************/
void fw_getStatus(void)
{
UCHAR _endp = 0, _txdat[2];
UCHAR _bRecipient = fw_controlData.DeviceRequest.bmRequestType & FW_USB_RECIPIENT;
/* UCHAR _c = 0; */
TRACE_DEBUG_H( "fw_getStatus\n\r");
switch(_bRecipient)
{
case FW_USB_RECIPIENT_DEVICE:
// A GetStatus() request to a device returns the information shown in Figure 9-4.
// DO=1 : Self powered
// D1=1 : Remote Wakeup
_txdat[0] = 0; /* bus powered */
if( (stallEndpointStatus&(1<<4)) == (1<<4) )
{
_txdat[0] = 3; /* remote wakeup */ // jcb
}
_txdat[1] = 0;
fw_singleTransmit(_txdat, 2);
break;
case FW_USB_RECIPIENT_INTERFACE:
// A GetStatus() request to an interface returns the information shown in Figure 9-5.
// All are set to 0
_txdat[0]=0;
_txdat[1]=0;
fw_singleTransmit(_txdat, 2);
break;
case FW_USB_RECIPIENT_ENDPOINT:
// A GetStatus() request to an endpoint returns the information shown in Figure 9-6.
// D0=1 : HALT
_endp = (UCHAR)(fw_controlData.DeviceRequest.wIndex & (FW_EP_CTRL | FW_EP_BULK_IN | FW_EP_BULK_OUT));
_txdat[0] = 0;
if( (1<<_endp) == (stallEndpointStatus&(1<<_endp)) )
{
_txdat[0] = 1;
}
_txdat[1] = 0;
fw_singleTransmit(_txdat, 2);
break;
default:
TRACE_DEBUG_H( "getSt:default\n\r");
fw_stallEp0();
}
}
/*****************************************************************
*
* ROUTINE fw_setAddress
*
*-----------------------------------------------------------------
*
* Purpose :
* 9.4.6 Set Address ( SET_ADDRESS )
* This request sets the device address for all future device accesses.
*
* Input parameters : NONE
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -