at91lib: Add USB MULTI driver (for device with 3 configurations)

This is in anticipation of the future SIMtrace firmware,
where we will have a single device with three configurations.
This commit is contained in:
Harald Welte 2011-07-31 22:36:10 +02:00
parent 29745a4feb
commit db0ddc6ee6
6 changed files with 1285 additions and 0 deletions

View File

@ -0,0 +1,180 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2008, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
//-----------------------------------------------------------------------------
// Headers
//-----------------------------------------------------------------------------
// GENERAL
#include <utility/trace.h>
#include <utility/assert.h>
#include <utility/led.h>
// USB
#include <usb/device/core/USBD.h>
#include <usb/device/core/USBDDriver.h>
//- MULTI
#include "MULTIDriver.h"
#include "MULTIDriverDescriptors.h"
//-----------------------------------------------------------------------------
// Defines
//-----------------------------------------------------------------------------
/// Interface setting spaces (4 byte aligned)
#define NUM_INTERFACES ((2+3)&0xFC)
//-----------------------------------------------------------------------------
// Types
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Internal variables
//-----------------------------------------------------------------------------
/// USBDDriver instance
static USBDDriver usbdDriver;
/// Array for storing the current setting of each interface
static unsigned char multiDriverInterfaces[NUM_INTERFACES];
//-----------------------------------------------------------------------------
// Internal functions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Optional RequestReceived() callback re-implementation
//-----------------------------------------------------------------------------
#if !defined(NOAUTOCALLBACK)
void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
{
MULTIDriver_RequestHandler(request);
}
#endif
//-----------------------------------------------------------------------------
/// Invoked whenever the active setting of an interface is changed by the
/// host. Changes the status of the third LED accordingly.
/// \param interface Interface number.
/// \param setting Newly active setting.
//-----------------------------------------------------------------------------
void USBDDriverCallbacks_InterfaceSettingChanged(unsigned char interface,
unsigned char setting)
{
TRACE_DEBUG("Callback_IntfChg(%u, %u)\n\r", interface, setting);
}
//-----------------------------------------------------------------------------
// ConfigurationChanged() callback re-implementation
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/// Invoked whenever the configuration value of a device is changed by the host
/// \param cfgnum Configuration number.
//-----------------------------------------------------------------------------
void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum)
{
TRACE_DEBUG("Callback_ConfigChg(%u)\n\r", cfgnum);
}
//-----------------------------------------------------------------------------
// Exported functions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/// Initializes the USB device composite device driver.
//-----------------------------------------------------------------------------
void MULTIDriver_Initialize(void)
{
CDCDFunctionDriver_Initialize();
/* CCID nees no initialization */
// Initialize the standard USB driver
USBDDriver_Initialize(&usbdDriver,
&multiDriverDescriptors,
multiDriverInterfaces);
// Initialize the USB driver
USBD_Init();
}
//-----------------------------------------------------------------------------
/// Handles composite-specific USB requests sent by the host, and forwards
/// standard ones to the USB device driver.
/// \param request Pointer to a USBGenericRequest instance.
//-----------------------------------------------------------------------------
void MULTIDriver_RequestHandler(const USBGenericRequest *request)
{
// Check if this is a class request
if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) {
unsigned char rc = 0;
//rc = CCID_RequestHandler(request);
if (!rc) {
TRACE_WARNING(
"MULTIDriver_RequestHandler: Unsupported request (%d)\n\r",
USBGenericRequest_GetRequest(request));
USBD_Stall(0);
}
}
// Check if this is a standard request
else if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) {
unsigned char rc = 0;
// Forward request to the standard handler
if (rc == 0)
USBDDriver_RequestHandler(&(usbdDriver), request);
}
// Unsupported request type
else {
TRACE_WARNING(
"MULTIDriver_RequestHandler: Unsupported request type (%d)\n\r",
USBGenericRequest_GetType(request));
USBD_Stall(0);
}
}
//-----------------------------------------------------------------------------
/// Starts a remote wake-up sequence if the host has explicitely enabled it
/// by sending the appropriate SET_FEATURE request.
//-----------------------------------------------------------------------------
void MULTIDriver_RemoteWakeUp(void)
{
// Remote wake-up has been enabled
if (USBDDriver_IsRemoteWakeUpEnabled(&usbdDriver))
USBD_RemoteWakeUp();
else
TRACE_WARNING("MULTIriver_RemoteWakeUp: not enabled\n\r");
}

View File

@ -0,0 +1,15 @@
#ifndef MULTIDRIVER_H
#define MULTIDRIVER_H
#include <usb/common/core/USBGenericRequest.h>
#include <usb/device/core/USBD.h>
#include "../composite/CDCDFunctionDriver.h"
extern void MULTIDriver_RequestHandler(const USBGenericRequest *request);
extern void MULTIDriver_RemoteWakeUp(void);
extern void MULTIDriver_Initialize(void);
#endif //#ifndef MULTIDDRIVER_H

View File

@ -0,0 +1,506 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2008, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
#include "MULTIDriver.h"
#include "MULTIDriverDescriptors.h"
#include <board.h>
//- USB Generic
#include <usb/common/core/USBGenericDescriptor.h>
#include <usb/common/core/USBConfigurationDescriptor.h>
#include <usb/common/core/USBInterfaceAssociationDescriptor.h>
#include <usb/common/core/USBEndpointDescriptor.h>
#include <usb/common/core/USBStringDescriptor.h>
#include <usb/common/core/USBGenericRequest.h>
//- CDC
#include <usb/common/cdc/CDCGenericDescriptor.h>
#include <usb/common/cdc/CDCDeviceDescriptor.h>
#include <usb/common/cdc/CDCCommunicationInterfaceDescriptor.h>
#include <usb/common/cdc/CDCDataInterfaceDescriptor.h>
#include <usb/common/cdc/CDCHeaderDescriptor.h>
#include <usb/common/cdc/CDCCallManagementDescriptor.h>
#include <usb/common/cdc/CDCAbstractControlManagementDescriptor.h>
#include <usb/common/cdc/CDCUnionDescriptor.h>
#include "../composite/CDCDFunctionDriverDescriptors.h"
//CCID
#include <usb/device/ccid/cciddriver.h>
#include <usb/device/ccid/cciddriverdescriptors.h>
//-----------------------------------------------------------------------------
// Definitions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Macros
//-----------------------------------------------------------------------------
/// Returns the minimum between two values.
#define MIN(a, b) ((a < b) ? a : b)
//-----------------------------------------------------------------------------
// Internal structures
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/// Audio control header descriptor with one slave interface.
//-----------------------------------------------------------------------------
#ifdef __ICCARM__ // IAR
#pragma pack(1) // IAR
#define __attribute__(...) // IAR
#endif // IAR
//-----------------------------------------------------------------------------
/// Configuration descriptor list for a device implementing a composite driver.
//-----------------------------------------------------------------------------
struct multi_cdc_conf_desc {
/// Standard configuration descriptor.
USBConfigurationDescriptor configuration;
/// IAD 0
USBInterfaceAssociationDescriptor cdcIAD0;
/// Communication interface descriptor
USBInterfaceDescriptor cdcCommunication0;
/// CDC header functional descriptor.
CDCHeaderDescriptor cdcHeader0;
/// CDC call management functional descriptor.
CDCCallManagementDescriptor cdcCallManagement0;
/// CDC abstract control management functional descriptor.
CDCAbstractControlManagementDescriptor cdcAbstractControlManagement0;
/// CDC union functional descriptor (with one slave interface).
CDCUnionDescriptor cdcUnion0;
/// Notification endpoint descriptor.
USBEndpointDescriptor cdcNotification0;
/// Data interface descriptor.
USBInterfaceDescriptor cdcData0;
/// Data OUT endpoint descriptor.
USBEndpointDescriptor cdcDataOut0;
/// Data IN endpoint descriptor.
USBEndpointDescriptor cdcDataIn0;
} __attribute__ ((packed));
struct multi_ccid_conf_desc {
USBConfigurationDescriptor configuration;
USBInterfaceDescriptor interface;
CCIDDescriptor ccid;
USBEndpointDescriptor endpoint[3];
} __attribute__ ((packed));
#ifdef __ICCARM__ // IAR
#pragma pack() // IAR
#endif // IAR
//------------------------------------------------------------------------------
// Exported variables
//------------------------------------------------------------------------------
/// Standard USB device descriptor for the composite device driver
const USBDeviceDescriptor deviceDescriptor = {
.bLength = sizeof(USBDeviceDescriptor),
.bDescriptorType = USBGenericDescriptor_DEVICE,
.bcdUSB = USBDeviceDescriptor_USB2_00,
.bDeviceClass = 0x00,
.bDeviceSubClass = 0x00,
.bDeviceProtocol = 0x00,
.bMaxPacketSize0 = BOARD_USB_ENDPOINTS_MAXPACKETSIZE(0),
.idVendor = 0x16c0,
.idProduct = 0x0762,
.bcdDevice = 0x0090,
.iManufacturer = 1,
.iProduct = 2,
.iSerialNumber = 0,
.bNumConfigurations = 3,
};
#if defined(BOARD_USB_UDPHS)
/// USB device qualifier descriptor.
const USBDeviceQualifierDescriptor qualifierDescriptor = {
sizeof(USBDeviceQualifierDescriptor),
USBGenericDescriptor_DEVICEQUALIFIER,
USBDeviceDescriptor_USB2_00,
#if defined(usb_HIDMSD)
0x00,
0x00,
0x00,
#else
0xEF,// MI
0x02,//
0x01,//
#endif
BOARD_USB_ENDPOINTS_MAXPACKETSIZE(0),
3, // Device has one possible configuration
0 // Reserved
};
#endif
/* Configuration Descriptor for config #0 (SNIFFER) */
const struct multi_cdc_conf_desc sniffer_configurationDescriptors = {
.configuration = {
.bLength = sizeof(USBConfigurationDescriptor),
.bDescriptorType = USBGenericDescriptor_CONFIGURATION,
.wTotalLength = sizeof(struct multi_cdc_conf_desc),
.bNumInterfaces = 2,
.bConfigurationValue = 1,
.iConfiguration = 0,
.bmAttributes = BOARD_USB_BMATTRIBUTES,
.bMaxPower = USBConfigurationDescriptor_POWER(100),
},
.cdcIAD0 = {
.bLength = sizeof(USBInterfaceAssociationDescriptor),
.bDescriptorType = USBGenericDescriptor_INTERFACEASSOCIATION,
.bFirstInterface = 0,
.bInterfaceCount = 2,
.bFunctionClass = CDCCommunicationInterfaceDescriptor_CLASS,
.bFunctionSubClass = CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
.bFunctionProtocol = CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
.iFunction = 0,
},
.cdcCommunication0 = {
.bLength = sizeof(USBInterfaceDescriptor),
.bDescriptorType = USBGenericDescriptor_INTERFACE,
.bInterfaceNumber = 0,
.bAlternateSetting = 0,
.bNumEndpoints = 1,
.bInterfaceClass = CDCCommunicationInterfaceDescriptor_CLASS,
.bInterfaceSubClass = CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
.bInterfaceProtocol = CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
.iInterface = 0,
},
.cdcHeader0 = {
.bFunctionLength = sizeof(CDCHeaderDescriptor),
.bDescriptorType = CDCGenericDescriptor_INTERFACE,
.bDescriptorSubtype = CDCGenericDescriptor_HEADER,
.bcdCDC = CDCGenericDescriptor_CDC1_10,
},
.cdcCallManagement0 = {
.bFunctionLength = sizeof(CDCCallManagementDescriptor),
.bDescriptorType = CDCGenericDescriptor_INTERFACE,
.bDescriptorSubtype = CDCGenericDescriptor_CALLMANAGEMENT,
.bmCapabilities = CDCCallManagementDescriptor_SELFCALLMANAGEMENT,
.bDataInterface = 1,
},
.cdcAbstractControlManagement0 = {
.bFunctionLength = sizeof(CDCAbstractControlManagementDescriptor),
.bDescriptorType = CDCGenericDescriptor_INTERFACE,
.bDescriptorSubtype = CDCGenericDescriptor_ABSTRACTCONTROLMANAGEMENT,
.bmCapabilities = CDCAbstractControlManagementDescriptor_LINE,
},
.cdcUnion0 = {
.bFunctionLength = sizeof(CDCUnionDescriptor),
.bDescriptorType = CDCGenericDescriptor_INTERFACE,
.bDescriptorSubtype = CDCGenericDescriptor_UNION,
.bMasterInterface = 0,
.bSlaveInterface0 = 1,
},
.cdcNotification0 = {
.bLength = sizeof(USBEndpointDescriptor),
.bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
CDCD_Descriptors_NOTIFICATION0),
.bmAttributes = USBEndpointDescriptor_INTERRUPT,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_NOTIFICATION0),
USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
.bInterval = 10,
},
.cdcData0 = {
.bLength = sizeof(USBInterfaceDescriptor),
.bDescriptorType = USBGenericDescriptor_INTERFACE,
.bInterfaceNumber = 1,
.bAlternateSetting = 0,
.bNumEndpoints = 2,
.bInterfaceClass = CDCDataInterfaceDescriptor_CLASS,
.bInterfaceSubClass = CDCDataInterfaceDescriptor_SUBCLASS,
.bInterfaceProtocol = CDCDataInterfaceDescriptor_NOPROTOCOL,
.iInterface = 0,
},
.cdcDataOut0 = {
.bLength = sizeof(USBEndpointDescriptor),
.bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT,
CDCD_Descriptors_DATAOUT0),
.bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAOUT0),
USBEndpointDescriptor_MAXBULKSIZE_FS),
.bInterval = 0,
},
.cdcDataIn0 = {
.bLength = sizeof(USBEndpointDescriptor),
.bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
CDCD_Descriptors_DATAIN0),
.bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(CDCD_Descriptors_DATAIN0),
USBEndpointDescriptor_MAXBULKSIZE_FS),
.bInterval = 0,
},
};
const struct multi_ccid_conf_desc reader_configurationDescriptors = {
.configuration = {
.bLength = sizeof(USBConfigurationDescriptor),
.bDescriptorType = USBGenericDescriptor_CONFIGURATION,
.wTotalLength = sizeof(struct multi_ccid_conf_desc),
.bNumInterfaces = 1,
.bConfigurationValue = 2,
.iConfiguration = 0,
.bmAttributes = BOARD_USB_BMATTRIBUTES,
.bMaxPower = USBConfigurationDescriptor_POWER(100),
},
.interface = {
.bLength = sizeof(USBInterfaceDescriptor),
.bDescriptorType = USBGenericDescriptor_INTERFACE,
.bInterfaceNumber = 0,
.bAlternateSetting = 0,
.bNumEndpoints = 3,
.bInterfaceClass = SMART_CARD_DEVICE_CLASS,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = 0,
},
.ccid = {
.bLength = sizeof(CCIDDescriptor),
.bDescriptorType = CCID_DECRIPTOR_TYPE,
.bcdCCID = CCID1_10,
.bMaxSlotIndex = 0,
.bVoltageSupport = VOLTS_3_0,
.dwProtocols = (1 << PROTOCOL_TO),
.dwDefaultClock = 3580,
.dwMaximumClock = 3580,
.bNumClockSupported = 0,
.dwDataRate = 9600,
.dwMaxDataRate = 9600,
.bNumDataRatesSupported = 0,
.dwMaxIFSD = 0xfe,
.dwSynchProtocols = 0,
.dwMechanical = 0,
.dwFeatures = CCID_FEATURES_AUTO_CLOCK | CCID_FEATURES_AUTO_BAUD |
CCID_FEATURES_AUTO_PCONF | CCID_FEATURES_AUTO_PNEGO |
CCID_FEATURES_EXC_TPDU,
.dwMaxCCIDMessageLength = 0x10f,
.bClassGetResponse = 0xff,
.bClassEnvelope = 0xff,
.wLcdLayout = 0,
.bPINSupport = 0,
.bMaxCCIDBusySlots = 1,
},
.endpoint = {
{
.bLength = sizeof(USBEndpointDescriptor),
.bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT,
CCID_EPT_DATA_OUT),
.bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_OUT),
USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
.bInterval = 0,
},
{
.bLength = sizeof(USBEndpointDescriptor),
.bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
CCID_EPT_DATA_IN),
.bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_IN),
USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
.bInterval = 0,
},
{
.bLength = sizeof(USBEndpointDescriptor),
.bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
CCID_EPT_NOTIFICATION),
.bmAttributes = USBEndpointDescriptor_INTERRUPT,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_NOTIFICATION),
USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
.bInterval = 0x10,
},
},
};
const struct multi_ccid_conf_desc mitm_configurationDescriptors = {
.configuration = {
.bLength = sizeof(USBConfigurationDescriptor),
.bDescriptorType = USBGenericDescriptor_CONFIGURATION,
.wTotalLength = sizeof(struct multi_ccid_conf_desc),
.bNumInterfaces = 1,
.bConfigurationValue = 3,
.iConfiguration = 0,
.bmAttributes = BOARD_USB_BMATTRIBUTES,
.bMaxPower = USBConfigurationDescriptor_POWER(100),
},
.interface = {
.bLength = sizeof(USBInterfaceDescriptor),
.bDescriptorType = USBGenericDescriptor_INTERFACE,
.bInterfaceNumber = 0,
.bAlternateSetting = 0,
.bNumEndpoints = 3,
.bInterfaceClass = SMART_CARD_DEVICE_CLASS,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = 0,
},
.ccid = {
.bLength = sizeof(CCIDDescriptor),
.bDescriptorType = CCID_DECRIPTOR_TYPE,
.bcdCCID = CCID1_10,
.bMaxSlotIndex = 0,
.bVoltageSupport = VOLTS_3_0,
.dwProtocols = (1 << PROTOCOL_TO),
.dwDefaultClock = 3580,
.dwMaximumClock = 3580,
.bNumClockSupported = 0,
.dwDataRate = 9600,
.dwMaxDataRate = 9600,
.bNumDataRatesSupported = 0,
.dwMaxIFSD = 0xfe,
.dwSynchProtocols = 0,
.dwMechanical = 0,
.dwFeatures = CCID_FEATURES_AUTO_CLOCK | CCID_FEATURES_AUTO_BAUD |
CCID_FEATURES_AUTO_PCONF | CCID_FEATURES_AUTO_PNEGO |
CCID_FEATURES_EXC_TPDU,
.dwMaxCCIDMessageLength = 0x10f,
.bClassGetResponse = 0xff,
.bClassEnvelope = 0xff,
.wLcdLayout = 0,
.bPINSupport = 0,
.bMaxCCIDBusySlots = 1,
},
.endpoint = {
{
.bLength = sizeof(USBEndpointDescriptor),
.bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT,
CCID_EPT_DATA_OUT),
.bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_OUT),
USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
.bInterval = 0,
},
{
.bLength = sizeof(USBEndpointDescriptor),
.bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
CCID_EPT_DATA_IN),
.bmAttributes = USBEndpointDescriptor_BULK,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_DATA_IN),
USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
.bInterval = 0,
},
{
.bLength = sizeof(USBEndpointDescriptor),
.bDescriptorType = USBGenericDescriptor_ENDPOINT,
.bEndpointAddress = USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
CCID_EPT_NOTIFICATION),
.bmAttributes = USBEndpointDescriptor_INTERRUPT,
.wMaxPacketSize = MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(CCID_EPT_NOTIFICATION),
USBEndpointDescriptor_MAXINTERRUPTSIZE_FS),
.bInterval = 0x10,
},
},
};
/// String descriptor with the supported languages.
const unsigned char languageIdDescriptor[] = {
USBStringDescriptor_LENGTH(1),
USBGenericDescriptor_STRING,
USBStringDescriptor_ENGLISH_US
};
/// Manufacturer name.
const unsigned char manufacturerDescriptor[] = {
USBStringDescriptor_LENGTH(5),
USBGenericDescriptor_STRING,
USBStringDescriptor_UNICODE('A'),
USBStringDescriptor_UNICODE('t'),
USBStringDescriptor_UNICODE('m'),
USBStringDescriptor_UNICODE('e'),
USBStringDescriptor_UNICODE('l')
};
/// Product name.
const unsigned char productDescriptor[] = {
USBStringDescriptor_LENGTH(10),
USBGenericDescriptor_STRING,
USBStringDescriptor_UNICODE('M'),
USBStringDescriptor_UNICODE('u'),
USBStringDescriptor_UNICODE('l'),
USBStringDescriptor_UNICODE('t'),
USBStringDescriptor_UNICODE('i'),
USBStringDescriptor_UNICODE(' '),
USBStringDescriptor_UNICODE('D'),
USBStringDescriptor_UNICODE('e'),
USBStringDescriptor_UNICODE('m'),
USBStringDescriptor_UNICODE('o')
};
/// Array of pointers to the four string descriptors.
const unsigned char *stringDescriptors[] = {
languageIdDescriptor,
manufacturerDescriptor,
productDescriptor,
};
//------------------------------------------------------------------------------
// Exported variables
//------------------------------------------------------------------------------
/// List of descriptors required by an USB audio speaker device driver.
const USBDDriverDescriptors multiDriverDescriptors = {
&deviceDescriptor,
{ (const USBConfigurationDescriptor *) &sniffer_configurationDescriptors,
(const USBConfigurationDescriptor *) &reader_configurationDescriptors,
(const USBConfigurationDescriptor *) &mitm_configurationDescriptors },
#ifdef BOARD_USB_UDPHS
&qualifierDescriptor,
{ (const USBConfigurationDescriptor *) &sniffer_configurationDescriptors },
&deviceDescriptor,
{ (const USBConfigurationDescriptor *) &sniffer_configurationDescriptors },
&qualifierDescriptor,
{ (const USBConfigurationDescriptor *) &sniffer_configurationDescriptors },
#else
0, { 0 }, 0, { 0 }, 0, { 0 },
#endif
stringDescriptors,
3 // Number of string descriptors
};

View File

@ -0,0 +1,5 @@
#include <board.h>
#include <usb/device/core/USBDDriverDescriptors.h>
extern const USBDDriverDescriptors multiDriverDescriptors;

View File

@ -0,0 +1,173 @@
# ----------------------------------------------------------------------------
# ATMEL Microcontroller Software Support
# ----------------------------------------------------------------------------
# Copyright (c) 2008, Atmel Corporation
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# - Redistributions of source code must retain the above copyright notice,
# this list of conditions and the disclaimer below.
#
# Atmel's name may not be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
# DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# ----------------------------------------------------------------------------
# Makefile for compiling the USB COMPOSITE project
#-------------------------------------------------------------------------------
# User-modifiable options
#-------------------------------------------------------------------------------
# Chip & board used for compilation
# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
CHIP = at91sam7s128
BOARD = simtrace
# Trace level used for compilation
# (can be overriden by adding TRACE_LEVEL=#number to the command-line)
# TRACE_LEVEL_DEBUG 5
# TRACE_LEVEL_INFO 4
# TRACE_LEVEL_WARNING 3
# TRACE_LEVEL_ERROR 2
# TRACE_LEVEL_FATAL 1
# TRACE_LEVEL_NO_TRACE 0
TRACE_LEVEL = 5
# Optimization level, put in comment for debugging
OPTIMIZATION = -Os
# AT91 library directory
AT91LIB = ../at91lib
# Output file basename
OUTPUT = usb-device-multi-project-$(BOARD)-$(CHIP)
# Compile for all memories available on the board (this sets $(MEMORIES))
include $(AT91LIB)/boards/$(BOARD)/board.mak
# Output directories
BIN = bin
OBJ = obj
#-------------------------------------------------------------------------------
# Tools
#-------------------------------------------------------------------------------
# Tool suffix when cross-compiling
CROSS_COMPILE = arm-elf-
# Compilation tools
CC = $(CROSS_COMPILE)gcc
SIZE = $(CROSS_COMPILE)size
OBJCOPY = $(CROSS_COMPILE)objcopy
# Flags
INCLUDES = -I$(AT91LIB)/boards/$(BOARD) -I$(AT91LIB)/peripherals
INCLUDES += -I$(AT91LIB)/components -I$(AT91LIB)/usb/device -I$(AT91LIB)
CFLAGS = -Wall -mlong-calls -ffunction-sections
CFLAGS += -Dusb_CDCHID
CFLAGS += -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -DTRACE_LEVEL=$(TRACE_LEVEL)
ASFLAGS = -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__
LDFLAGS = -g $(OPTIMIZATION) -nostartfiles -Wl,--gc-sections
#-------------------------------------------------------------------------------
# Files
#-------------------------------------------------------------------------------
# Directories where source files can be found
USB = $(AT91LIB)/usb
UTILITY = $(AT91LIB)/utility
PERIPH = $(AT91LIB)/peripherals
BOARDS = $(AT91LIB)/boards
COMP = $(AT91LIB)/components
MEM = $(AT91LIB)/memories
VPATH += $(MEM)
VPATH += $(USB)/device/hid-keyboard $(USB)/common/hid
VPATH += $(USB)/device/multiconf $(USB)/device/composite
VPATH += $(USB)/device/core $(USB)/common/core
VPATH += $(USB)/common/cdc
VPATH += $(UTILITY)
VPATH += $(PERIPH)/dbgu $(PERIPH)/aic $(PERIPH)/usart $(PERIPH)/pio $(PERIPH)/pmc
VPATH += $(PERIPH)/cp15 $(PERIPH)/pit
VPATH += $(BOARDS)/$(BOARD) $(BOARDS)/$(BOARD)/$(CHIP)
# Objects built from C source files
C_OBJECTS = main.o
C_OBJECTS += MULTIDriver.o MULTIDriverDescriptors.o
C_OBJECTS += CDCSetControlLineStateRequest.o CDCLineCoding.o
C_OBJECTS += CDCDFunctionDriver.o
#C_OBJECTS += HIDIdleRequest.o HIDReportRequest.o HIDKeypad.o
#C_OBJECTS += HIDDKeyboardInputReport.o HIDDKeyboardOutputReport.o
#C_OBJECTS += HIDDFunctionDriver.o
C_OBJECTS += USBD_OTGHS.o USBD_UDP.o USBD_UDPHS.o USBDDriver.o
C_OBJECTS += USBDCallbacks_Initialized.o
C_OBJECTS += USBDCallbacks_Reset.o
#C_OBJECTS += USBDCallbacks_Resumed.o
#C_OBJECTS += USBDCallbacks_Suspended.o
#C_OBJECTS += USBDDriverCb_CfgChanged.o
#C_OBJECTS += USBDDriverCb_IfSettingChanged.o
C_OBJECTS += USBSetAddressRequest.o USBGenericDescriptor.o USBInterfaceRequest.o
C_OBJECTS += USBGenericRequest.o USBGetDescriptorRequest.o
C_OBJECTS += USBSetConfigurationRequest.o USBFeatureRequest.o
C_OBJECTS += USBEndpointDescriptor.o USBConfigurationDescriptor.o
C_OBJECTS += led.o string.o stdio.o
C_OBJECTS += aic.o dbgu.o usart.o pio.o pio_it.o pmc.o cp15.o pit.o
C_OBJECTS += board_memories.o board_lowlevel.o
# Objects built from Assembly source files
ASM_OBJECTS = board_cstartup.o
ASM_OBJECTS += cp15_asm.o
# Append OBJ and BIN directories to output filename
OUTPUT := $(BIN)/$(OUTPUT)
#-------------------------------------------------------------------------------
# Rules
#-------------------------------------------------------------------------------
all: $(BIN) $(OBJ) $(MEMORIES)
$(BIN) $(OBJ):
mkdir $@
define RULES
C_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(C_OBJECTS))
ASM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ASM_OBJECTS))
$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1))
$(CC) $(LDFLAGS) -T"$(AT91LIB)/boards/$(BOARD)/$(CHIP)/$$@.lds" -o $(OUTPUT)-$$@.elf $$^
$(OBJCOPY) -O binary $(OUTPUT)-$$@.elf $(OUTPUT)-$$@.bin
$(SIZE) $$^ $(OUTPUT)-$$@.elf
$$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
$(CC) $(CFLAGS) -D$(1) -c -o $$@ $$<
$$(ASM_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.S Makefile $(OBJ) $(BIN)
$(CC) $(ASFLAGS) -D$(1) -c -o $$@ $$<
debug_$(1): $(1)
perl ../resources/gdb/debug.pl $(OUTPUT)-$(1).elf
endef
$(foreach MEMORY, $(MEMORIES), $(eval $(call RULES,$(MEMORY))))
clean:
-rm -f $(OBJ)/*.o $(BIN)/*.bin $(BIN)/*.elf

View File

@ -0,0 +1,406 @@
#include <board.h>
#include <pio/pio.h>
#include <pio/pio_it.h>
#include <aic/aic.h>
#include <usart/usart.h>
#include <utility/trace.h>
#include <pit/pit.h>
#include <usb/common/core/USBConfigurationDescriptor.h>
#include <usb/device/core/USBD.h>
#include <utility/led.h>
#include <pmc/pmc.h>
#include <usb/device/multiconf/MULTIDriver.h>
#include <string.h>
//-----------------------------------------------------------------------------
// Definitions
//-----------------------------------------------------------------------------
#ifndef AT91C_ID_TC0
#if defined(AT91C_ID_TC012)
#define AT91C_ID_TC0 AT91C_ID_TC012
#elif defined(AT91C_ID_TC)
#define AT91C_ID_TC0 AT91C_ID_TC
#else
#error Pb define ID_TC
#endif
#endif
/// Master clock frequency in Hz
#define MCK BOARD_MCK
/// Number of keys used in the example.
#define NUM_KEYS 4
/// Number of non-modifiers keys.
#define NUM_NORMAL_KEYS 3
/// Number of modifier keys.
#define NUM_MODIFIER_KEYS (NUM_KEYS - NUM_NORMAL_KEYS)
/// Num lock LED index.
#define LED_NUMLOCK USBD_LEDOTHER
/// Delay for pushbutton debouncing (ms)
#define DEBOUNCE_TIME 10
/// PIT period value (useconds)
#define PIT_PERIOD 1000
/// Size in bytes of the buffer used for reading data from the USB & USART
#define DATABUFFERSIZE BOARD_USB_ENDPOINTS_MAXPACKETSIZE(2)
/// Use for power management
#define STATE_IDLE 0
/// The USB device is in suspend state
#define STATE_SUSPEND 4
/// The USB device is in resume state
#define STATE_RESUME 5
//-----------------------------------------------------------------------------
// Internal variables
//-----------------------------------------------------------------------------
/// State of USB, for suspend and resume
unsigned char USBState = STATE_IDLE;
//- CDC
/// List of pins that must be configured for use by the application.
static const Pin pinsUsart[] = {PIN_USART0_TXD, PIN_USART0_RXD};
/// Double-buffer for storing incoming USART data.
static unsigned char usartBuffers[2][DATABUFFERSIZE];
/// Current USART buffer index.
static unsigned char usartCurrentBuffer = 0;
/// Buffer for storing incoming USB data.
static unsigned char usbSerialBuffer0[DATABUFFERSIZE];
//static unsigned char usbSerialBuffer1[DATABUFFERSIZE];
#define WAKEUP_CONFIGURE()
#define VBUS_CONFIGURE() USBD_Connect()
//------------------------------------------------------------------------------
/// Put the CPU in 32kHz, disable PLL, main oscillator
/// Put voltage regulator in standby mode
//------------------------------------------------------------------------------
void LowPowerMode(void)
{
// MCK=48MHz to MCK=32kHz
// MCK = SLCK/2 : change source first from 48 000 000 to 18. / 2 = 9M
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
// MCK=SLCK : then change prescaler
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_SLOW_CLK;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
// disable PLL
AT91C_BASE_PMC->PMC_PLLR = 0;
// Disable Main Oscillator
AT91C_BASE_PMC->PMC_MOR = 0;
// Voltage regulator in standby mode : Enable VREG Low Power Mode
AT91C_BASE_VREG->VREG_MR |= AT91C_VREG_PSTDBY;
PMC_DisableProcessorClock();
}
//------------------------------------------------------------------------------
/// Put voltage regulator in normal mode
/// Return the CPU to normal speed 48MHz, enable PLL, main oscillator
//------------------------------------------------------------------------------
void NormalPowerMode(void)
{
// Voltage regulator in normal mode : Disable VREG Low Power Mode
AT91C_BASE_VREG->VREG_MR &= ~AT91C_VREG_PSTDBY;
// MCK=32kHz to MCK=48MHz
// enable Main Oscillator
AT91C_BASE_PMC->PMC_MOR = (( (AT91C_CKGR_OSCOUNT & (0x06 <<8)) | AT91C_CKGR_MOSCEN ));
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS ) );
// enable PLL@96MHz
AT91C_BASE_PMC->PMC_PLLR = ((AT91C_CKGR_DIV & 0x0E) |
(AT91C_CKGR_PLLCOUNT & (28<<8)) |
(AT91C_CKGR_MUL & (0x48<<16)));
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK ) );
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;
// MCK=SLCK/2 : change prescaler first
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
// MCK=PLLCK/2 : then change source
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK ;
while( !( AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY ) );
}
//------------------------------------------------------------------------------
// Callbacks re-implementation
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Invoked when the USB device leaves the Suspended state. By default,
/// configures the LEDs.
//------------------------------------------------------------------------------
void USBDCallbacks_Resumed(void)
{
// Initialize LEDs
LED_Configure(USBD_LEDPOWER);
LED_Set(USBD_LEDPOWER);
LED_Configure(USBD_LEDUSB);
LED_Clear(USBD_LEDUSB);
USBState = STATE_RESUME;
}
//------------------------------------------------------------------------------
/// Invoked when the USB device gets suspended. By default, turns off all LEDs.
//------------------------------------------------------------------------------
void USBDCallbacks_Suspended(void)
{
// Turn off LEDs
LED_Clear(USBD_LEDPOWER);
LED_Clear(USBD_LEDUSB);
USBState = STATE_SUSPEND;
}
//-----------------------------------------------------------------------------
// Internal functions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/// Handles interrupts coming from Timer #0.
//-----------------------------------------------------------------------------
static void ISR_Timer0()
{
unsigned char size;
unsigned int status = AT91C_BASE_TC0->TC_SR;
if ((status & AT91C_TC_CPCS) != 0) {
// Flush PDC buffer
size = DATABUFFERSIZE - AT91C_BASE_US0->US_RCR;
if (size == 0) {
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
return;
}
AT91C_BASE_US0->US_RCR = 0;
// Send current buffer through the USB
while (CDCDSerialDriver_Write(0, usartBuffers[usartCurrentBuffer],
size, 0, 0) != USBD_STATUS_SUCCESS);
// Restart read on buffer
USART_ReadBuffer(AT91C_BASE_US0,
usartBuffers[usartCurrentBuffer],
DATABUFFERSIZE);
usartCurrentBuffer = 1 - usartCurrentBuffer;
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
}
}
//-----------------------------------------------------------------------------
/// Callback invoked when data has been received on the USB.
//-----------------------------------------------------------------------------
static void UsbDataReceived0(unsigned int unused,
unsigned char status,
unsigned int received,
unsigned int remaining)
{
// Check that data has been received successfully
if (status == USBD_STATUS_SUCCESS) {
// Send data through USART
while (!USART_WriteBuffer(AT91C_BASE_US0, usbSerialBuffer0, received));
AT91C_BASE_US0->US_IER = AT91C_US_TXBUFE;
// Check if bytes have been discarded
if ((received == DATABUFFERSIZE) && (remaining > 0)) {
TRACE_WARNING(
"UsbDataReceived: %u bytes discarded\n\r",
remaining);
}
}
else {
TRACE_WARNING("UsbDataReceived: Transfer error\n\r");
}
}
//-----------------------------------------------------------------------------
/// Handles interrupts coming from USART #0.
//-----------------------------------------------------------------------------
static void ISR_Usart0()
{
unsigned int status = AT91C_BASE_US0->US_CSR;
unsigned short serialState;
// If USB device is not configured, do nothing
if (USBD_GetState() != USBD_STATE_CONFIGURED) {
AT91C_BASE_US0->US_IDR = 0xFFFFFFFF;
return;
}
// Buffer has been read successfully
if ((status & AT91C_US_ENDRX) != 0) {
// Disable timer
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
// Send buffer through the USBSerial0
while (CDCDSerialDriver_Write(0, usartBuffers[usartCurrentBuffer],
DATABUFFERSIZE, 0, 0) != USBD_STATUS_SUCCESS);
// Restart read on buffer
USART_ReadBuffer(AT91C_BASE_US0,
usartBuffers[usartCurrentBuffer],
DATABUFFERSIZE);
usartCurrentBuffer = 1 - usartCurrentBuffer;
// Restart timer
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
}
// Buffer has been sent
if ((status & AT91C_US_TXBUFE) != 0) {
// Restart USB read
CDCDSerialDriver_Read(0, usbSerialBuffer0,
DATABUFFERSIZE,
(TransferCallback) UsbDataReceived0,
0);
AT91C_BASE_US0->US_IDR = AT91C_US_TXBUFE;
}
// Errors
serialState = CDCDSerialDriver_GetSerialState(0);
// Overrun
if ((status & AT91C_US_OVER) != 0) {
TRACE_WARNING("ISR_Usart0: Overrun\n\r");
serialState |= CDCD_STATE_OVERRUN;
}
// Framing error
if ((status & AT91C_US_FRAME) != 0) {
TRACE_WARNING("ISR_Usart0: Framing error\n\r");
serialState |= CDCD_STATE_FRAMING;
}
CDCDSerialDriver_SetSerialState(0, serialState);
}
//-----------------------------------------------------------------------------
// Main
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/// Initializes drivers and start the USB composite device.
//-----------------------------------------------------------------------------
int main()
{
TRACE_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
printf("-- USB Multi Device Project %s --\n\r", SOFTPACK_VERSION);
printf("-- %s\n\r", BOARD_NAME);
printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);
// If they are present, configure Vbus & Wake-up pins
PIO_InitializeInterrupts(0);
#if 0
// ----- HID Function Initialize
// Initialize key statuses and configure push buttons
PIO_Configure(pinsPushButtons, PIO_LISTSIZE(pinsPushButtons));
memset(keyStatus, 1, NUM_KEYS);
// Configure LEDs
LED_Configure(LED_NUMLOCK);
// ----- CDC Function Initialize
// Configure USART
PIO_Configure(pinsUsart, PIO_LISTSIZE(pinsUsart));
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_US0;
AT91C_BASE_US0->US_IDR = 0xFFFFFFFF;
USART_Configure(AT91C_BASE_US0,
USART_MODE_ASYNCHRONOUS,
115200,
MCK);
USART_SetTransmitterEnabled(AT91C_BASE_US0, 1);
USART_SetReceiverEnabled(AT91C_BASE_US0, 1);
AIC_ConfigureIT(AT91C_ID_US0, 0, ISR_Usart0);
AIC_EnableIT(AT91C_ID_US0);
// Configure timer 0
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0);
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC0->TC_IDR = 0xFFFFFFFF;
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV5_CLOCK
| AT91C_TC_CPCSTOP
| AT91C_TC_CPCDIS
| AT91C_TC_WAVESEL_UP_AUTO
| AT91C_TC_WAVE;
AT91C_BASE_TC0->TC_RC = 0x00FF;
AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;
AIC_ConfigureIT(AT91C_ID_TC0, 0, ISR_Timer0);
AIC_EnableIT(AT91C_ID_TC0);
#endif
// USB COMPOSITE driver initialization
MULTIDriver_Initialize();
WAKEUP_CONFIGURE();
// connect if needed
VBUS_CONFIGURE();
// Driver loop
while (1) {
// Device is not configured
if (USBD_GetState() < USBD_STATE_CONFIGURED) {
// Connect pull-up, wait for configuration
USBD_Connect();
while (USBD_GetState() < USBD_STATE_CONFIGURED);
#if 0
// Start receiving data on the USART
usartCurrentBuffer = 0;
USART_ReadBuffer(AT91C_BASE_US0, usartBuffers[0], DATABUFFERSIZE);
USART_ReadBuffer(AT91C_BASE_US0, usartBuffers[1], DATABUFFERSIZE);
AT91C_BASE_US0->US_IER = AT91C_US_ENDRX
| AT91C_US_FRAME
| AT91C_US_OVER;
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
// Start receiving data on the USB
CDCDSerialDriver_Read(0, usbSerialBuffer0,
DATABUFFERSIZE,
(TransferCallback) UsbDataReceived0,
0);
}
else {
HIDDKeyboardProcessKeys();
#endif
}
if( USBState == STATE_SUSPEND ) {
TRACE_DEBUG("suspend !\n\r");
//LowPowerMode();
USBState = STATE_IDLE;
}
if( USBState == STATE_RESUME ) {
// Return in normal MODE
TRACE_DEBUG("resume !\n\r");
//NormalPowerMode();
USBState = STATE_IDLE;
}
}
}