//*----------------------------------------------------------------------------
//* ATMEL Microcontroller Software Support - ROUSSET -
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name : descriptor.c
//* Object : USB monitor aplication.
//*
//* 1.0 Jul 31 2002 : ODi Creation
//*----------------------------------------------------------------------------
#include "AT91_SVC_USBCTL.h"
#include "lib_AT91RM9200.h"
#include "AT91_SVC_USBIN.h"
AT91S_SVC_USBIN usbEp3;
/* ================================================================ */
/* ===================== Device configuration ===================== */
/* ================================================================ */
// This is the current configuration.
unsigned char currentConfiguration = 0;
unsigned char currentConnection = 0;
const char deviceDescriptor[] = {
/* Device descriptor */
0x12, // bLength
0x01, // bDescriptorType
0x10, // bcdUSBL
0x01, //
0x02, // bDeviceClass: CDC class code
0x00, // bDeviceSubclass: CDC class sub code
0x00, // bDeviceProtocol: CDC Device protocol
0x08, // bMaxPacketSize0
0xEB, // idVendorL
0x03, //
0x22, // idProductL
0x61, //
0x10, // bcdDeviceL
0x01, //
0x00, // iManufacturer // 0x01
0x00, // iProduct
0x00, // SerialNumber
0x01 // bNumConfigs
};
const char configurationDescriptor[] = {
/* ============== CONFIGURATION 1 =========== */
/* Configuration 1 descriptor */
0x09, // CbLength
0x02, // CbDescriptorType
0x20, // CwTotalLength 2 EP + Control
0x00,
0x01, // CbNumInterfaces
0x01, // CbConfigurationValue
0x00, // CiConfiguration
0xC0, // CbmAttributes 0xA0
0x00, // CMaxPower
/* Data Class Interface Descriptor Requirement */
0x09, // bLength
0x04, // bDescriptorType
0x00, // bInterfaceNumber
0x00, // bAlternateSetting
0x02, // bNumEndpoints
0x00, // bInterfaceClass
0x00, // bInterfaceSubclass
0x00, // bInterfaceProtocol
0x00, // iInterface
/* First alternate setting */
/* Endpoint 1 descriptor */
0x07, // bLength
0x05, // bDescriptorType
0x01, // bEndpointAddress, Endpoint 01 - OUT
0x02, // bmAttributes BULK
0x40, // wMaxPacketSize
0x00,
0x00, // bInterval
/* Endpoint 2 descriptor */
0x07, // bLength
0x05, // bDescriptorType
0x82, // bEndpointAddress, Endpoint 02 - IN
0x02, // bmAttributes BULK
0x40, // wMaxPacketSize
0x00,
0x00 // bInterval
};
/* USB standard request code */
#define STD_GET_STATUS_ZERO 0x0080
#define STD_GET_STATUS_INTERFACE 0x0081
#define STD_GET_STATUS_ENDPOINT 0x0082
#define STD_CLEAR_FEATURE_ZERO 0x0100
#define STD_CLEAR_FEATURE_INTERFACE 0x0101
#define STD_CLEAR_FEATURE_ENDPOINT 0x0102
#define STD_SET_FEATURE_ZERO 0x0300
#define STD_SET_FEATURE_INTERFACE 0x0301
#define STD_SET_FEATURE_ENDPOINT 0x0302
#define STD_SET_ADDRESS 0x0500
#define STD_GET_DESCRIPTOR 0x0680
#define STD_SET_DESCRIPTOR 0x0700
#define STD_GET_CONFIGURATION 0x0880
#define STD_SET_CONFIGURATION 0x0900
#define STD_GET_INTERFACE 0x0A81
#define STD_SET_INTERFACE 0x0B01
#define STD_SYNCH_FRAME 0x0C82
/* CDC Class Specific Request Code */
#define GET_LINE_CODING 0x21A1
#define SET_LINE_CODING 0x2021
#define SET_CONTROL_LINE_STATE 0x2221
//*----------------------------------------------------------------------------
//* \fn AT91F_USB_GetDescriptorDevice
//* \brief Answer to a standard GET DESCRIPTOR request
//*----------------------------------------------------------------------------
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
__inline void AT91F_USB_GetDescriptorDevice(
AT91PS_SVC_USBCTL pUSBCTL)
{
unsigned short wLength = *((unsigned short *) &(pUSBCTL->pSetup[6]));
pUSBCTL->Write(pUSBCTL,
deviceDescriptor,
MIN(sizeof(deviceDescriptor), wLength),
(AT91PF_SVC_USBCTL_RWComplete) 0); // No callback
}
//*----------------------------------------------------------------------------
//* \fn AT91F_USB_GetDescriptorConfiguration
//* \brief Answer to a standard GET DESCRIPTOR request
//*----------------------------------------------------------------------------
__inline void AT91F_USB_GetDescriptorConfiguration(
AT91PS_SVC_USBCTL pUSBCTL)
{
unsigned short wLength = *((unsigned short *) &(pUSBCTL->pSetup[6]));
pUSBCTL->Write(pUSBCTL,
configurationDescriptor,
MIN(sizeof(configurationDescriptor), wLength),
(AT91PF_SVC_USBCTL_RWComplete) 0); // No callback
}
//*----------------------------------------------------------------------------
//* \fn AT91F_USB_SetAddress
//* \brief Answer to a standard SET ADDRESS request
//*----------------------------------------------------------------------------
void AT91F_USB_SetAddressComplete(
AT91PS_SVC_USBCTL pUSBCTL)
{
unsigned char address = pUSBCTL->pSetup[2];
// Set Address
AT91F_UDP_SetAddress(pUSBCTL->pUdp, address);
if (address)
// Move the UDP function to the addressed state
AT91F_UDP_SetState(pUSBCTL->pUdp, AT91C_UDP_FADDEN);
else
// Move the UDP function to the default state
AT91F_UDP_SetState(pUSBCTL->pUdp, 0);
}
__inline void AT91F_USB_SetAddress(
AT91PS_SVC_USBCTL pUSBCTL)
{
// UDP address change must be done once STATUS IN is achieved
pUSBCTL->Write(pUSBCTL, (char *) 0, 0, AT91F_USB_SetAddressComplete);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_USB_SetConfiguration
//* \brief Answer to a standard SET CONFIGURATION request
//*----------------------------------------------------------------------------
void AT91F_USB_SetConfigurationComplete(
AT91PS_SVC_USBCTL pUSBCTL)
{
AT91PS_UDP pUdp = pUSBCTL->pUdp; // Pointer to UDP registers
// Move the UDP function to the configured state
AT91F_UDP_SetState(pUdp, AT91C_UDP_CONFG);
// Enable endpoints
AT91F_UDP_EpSet(pUdp, 1, AT91C_UDP_EPEDS);
AT91F_UDP_EpSet(pUdp, 2, AT91C_UDP_EPEDS);
AT91F_UDP_EpSet(pUdp, 3, AT91C_UDP_EPEDS);
// Enable endpoint 1 & 2 interrupts
AT91F_SVC_USBIN_Open(&usbEp3, AT91C_BASE_UDP, 3, 8, 1);
// AT91F_UDP_EnableIt(pUdp, (AT91C_UDP_EPINT1 | AT91C_UDP_EPINT2 | AT91C_UDP_EPINT3));
}
__inline void AT91F_USB_SetConfiguration(
AT91PS_SVC_USBCTL pUSBCTL)
{
AT91PS_UDP pUdp = pUSBCTL->pUdp; // Pointer to UDP registers
AT91PF_SVC_USBCTL_RWComplete RWComplete = (AT91PF_SVC_USBCTL_RWComplete) 0; // Callback
// Store the current configuration
currentConfiguration = pUSBCTL->pSetup[2];
// Move to the Configured State
if (currentConfiguration) {
// Reset endpoints
AT91F_UDP_ResetEp(pUdp, (AT91C_UDP_EPINT1 | AT91C_UDP_EPINT2 | AT91C_UDP_EPINT3));
AT91F_UDP_ResetEp(pUdp, 0);
//AT91F_UDP_EnableEp(pUdp, (AT91C_UDP_EPINT1 | AT91C_UDP_EPINT2));
// Configure endpoints and enable them
AT91F_UDP_EpSet(pUdp, 1, (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT)); // Endpoint 1 is a bulk out
AT91F_UDP_EpSet(pUdp, 2, (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN)); // Endpoint 2 is a bulk in
AT91F_UDP_EpSet(pUdp, 3, (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_ISO_IN)); // Endpoint 3 is a INT in
// Init the Callback after STATUS IN
RWComplete = AT91F_USB_SetConfigurationComplete;
}
// Move back to the A