⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fw_chap9.c

📁 ATMEL公司的demo程序,USB驱动程序,与识别片上flash,并进行枚举和操作.
💻 C
📖 第 1 页 / 共 2 页
字号:
//  ----------------------------------------------------------------------------
//          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 + -