USB driver send standard configuration

One configuration, one Interface, two endpoints (bulk in and out)

We don't need to configure Endpoint 0 which is always the control
endpoint and configured before any descriptor requests take place.

% python usb_enum.py
Found device
  CONFIGURATION 2: 100 mA ==================================
   bLength              :    0x9 (9 bytes)
   bDescriptorType      :    0x2 Configuration
   wTotalLength         :   0x20 (32 bytes)
   bNumInterfaces       :    0x1
   bConfigurationValue  :    0x2
   iConfiguration       :    0x2 SOME
   bmAttributes         :   0x80 Bus Powered
   bMaxPower            :   0x32 (100 mA)
    INTERFACE 0: Vendor Specific ===========================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x0
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x2
     bInterfaceClass    :   0xff Vendor Specific
     bInterfaceSubClass :    0x0
     bInterfaceProtocol :    0x0
     iInterface         :    0x1 SIMTRACE~~~~~
      ENDPOINT 0x1: Bulk OUT ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :    0x1 OUT
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :   0x40 (64 bytes)
       bInterval        :    0x0
      ENDPOINT 0x82: Bulk IN ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x82 IN
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :   0x40 (64 bytes)
       bInterval        :    0x0
diff --git a/sam3s_example/mains/usb_enum.c b/sam3s_example/mains/usb_enum.c
new file mode 100644
index 0000000..60c3508
--- /dev/null
+++ b/sam3s_example/mains/usb_enum.c
@@ -0,0 +1,283 @@
+/* ----------------------------------------------------------------------------
+ *         ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2009, 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 "board.h"
+#include "CDCDSerialDriver.h"
+
+/*----------------------------------------------------------------------------
+ *      Internal variables
+ *----------------------------------------------------------------------------*/
+
+/** Standard USB device descriptor for the CDC serial driver */
+const USBDeviceDescriptor deviceDescriptor = {
+
+    sizeof(USBDeviceDescriptor),
+    USBGenericDescriptor_DEVICE,
+    USBDeviceDescriptor_USB2_00,
+    0xff,
+//    CDCDeviceDescriptor_CLASS,
+    0xff,
+//    CDCDeviceDescriptor_SUBCLASS,
+    0xff,
+//    CDCDeviceDescriptor_PROTOCOL,
+    BOARD_USB_ENDPOINTS_MAXPACKETSIZE(0),
+    ATMEL_VENDOR_ID,
+    SIMTRACE_PRODUCT_ID,
+    1, /* Release number */
+    0, /* No string descriptor for manufacturer */
+    1, /* Index of product string descriptor is #1 */
+    0, /* No string descriptor for serial number */
+    1 /* Device has 1 possible configuration */
+};
+
+typedef struct _SIMTraceDriverConfigurationDescriptors {
+
+    /** Standard configuration descriptor. */
+    USBConfigurationDescriptor configuration;
+    /** Data interface descriptor. */
+    USBInterfaceDescriptor data;
+    /** Data OUT endpoint descriptor. */
+    USBEndpointDescriptor dataOut;
+    /** Data IN endpoint descriptor. */
+    USBEndpointDescriptor dataIn;
+
+} __attribute__ ((packed)) SIMTraceDriverConfigurationDescriptor;
+
+/** Standard USB configuration descriptor for the CDC serial driver */
+const SIMTraceDriverConfigurationDescriptor configurationDescriptorsFS = {
+
+    /* Standard configuration descriptor */
+    {
+        sizeof(USBConfigurationDescriptor),
+        USBGenericDescriptor_CONFIGURATION,
+        sizeof(SIMTraceDriverConfigurationDescriptor),
+        2, /* There are two interfaces in this configuration */
+        2, /* This is configuration #1 */
+        2, /* Second string descriptor for this configuration */
+        USBD_BMATTRIBUTES,
+        USBConfigurationDescriptor_POWER(100)
+    },
+    /* Communication class interface standard descriptor */
+    {
+        sizeof(USBInterfaceDescriptor),
+        USBGenericDescriptor_INTERFACE,
+        0, /* This is interface #0 */
+        0, /* This is alternate setting #0 for this interface */
+        2, /* This interface uses 1 endpoint */
+        //CDCCommunicationInterfaceDescriptor_CLASS,
+        0xff,
+//        CDCCommunicationInterfaceDescriptor_ABSTRACTCONTROLMODEL,
+        0,
+//        CDCCommunicationInterfaceDescriptor_NOPROTOCOL,
+        0,
+        1  /* Second in string descriptor for this interface */
+    },
+    /* Bulk-OUT endpoint standard descriptor */
+#define DATAOUT     1
+    {
+        sizeof(USBEndpointDescriptor),
+        USBGenericDescriptor_ENDPOINT,
+        USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT,
+                                      DATAOUT),
+        USBEndpointDescriptor_BULK,
+        MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(DATAOUT),
+            USBEndpointDescriptor_MAXBULKSIZE_FS),
+        0 /* Must be 0 for full-speed bulk endpoints */
+    },
+    /* Bulk-IN endpoint descriptor */
+#define DATAIN      2
+    {
+        sizeof(USBEndpointDescriptor),
+        USBGenericDescriptor_ENDPOINT,
+        USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
+                                      DATAIN),
+        USBEndpointDescriptor_BULK,
+        MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(DATAIN),
+            USBEndpointDescriptor_MAXBULKSIZE_FS),
+        0 /* Must be 0 for full-speed bulk endpoints */
+    }
+};
+
+const unsigned char someString[] = {
+    USBStringDescriptor_LENGTH(4),
+    USBGenericDescriptor_STRING,
+    USBStringDescriptor_UNICODE('S'),
+    USBStringDescriptor_UNICODE('O'),
+    USBStringDescriptor_UNICODE('M'),
+    USBStringDescriptor_UNICODE('E'),
+};
+
+const unsigned char productStringDescriptor[] = {
+
+    USBStringDescriptor_LENGTH(13),
+    USBGenericDescriptor_STRING,
+    USBStringDescriptor_UNICODE('S'),
+    USBStringDescriptor_UNICODE('I'),
+    USBStringDescriptor_UNICODE('M'),
+    USBStringDescriptor_UNICODE('T'),
+    USBStringDescriptor_UNICODE('R'),
+    USBStringDescriptor_UNICODE('A'),
+    USBStringDescriptor_UNICODE('C'),
+    USBStringDescriptor_UNICODE('E'),
+    USBStringDescriptor_UNICODE('~'),
+    USBStringDescriptor_UNICODE('~'),
+    USBStringDescriptor_UNICODE('~'),
+    USBStringDescriptor_UNICODE('~'),
+    USBStringDescriptor_UNICODE('~')
+};
+
+/** List of string descriptors used by the device */
+const unsigned char *stringDescriptors[] = {
+/* FIXME: Is it true that I can't use the string desc #0, 
+ * because 0 also stands for "no string desc"? */
+    0,
+    productStringDescriptor,
+    someString,
+};
+
+const USBDDriverDescriptors driverDescriptors = {
+
+    &deviceDescriptor,
+    (USBConfigurationDescriptor *) &(configurationDescriptorsFS),   /* full-speed configuration descriptor */
+    0, /* No full-speed device qualifier descriptor */
+    0, /* No full-speed other speed configuration */
+    0, /* No high-speed device descriptor */
+    0, /* No high-speed configuration descriptor */
+    0, /* No high-speed device qualifier descriptor */
+    0, /* No high-speed other speed configuration descriptor */
+    stringDescriptors,
+    3 /* 3 string descriptors in list */
+};
+
+
+
+/**
+ * \brief Configure 48MHz Clock for USB
+ */
+static void _ConfigureUsbClock(void)
+{
+    /* Enable PLLB for USB */
+// FIXME: are these the dividers I actually need?
+// FIXME: I could just use PLLA, since it has a frequ of 48Mhz anyways?
+    PMC->CKGR_PLLBR = CKGR_PLLBR_DIVB(5)
+                    | CKGR_PLLBR_MULB(0xc)  /* MULT+1=0xd*/
+                    | CKGR_PLLBR_PLLBCOUNT_Msk;
+    while((PMC->PMC_SR & PMC_SR_LOCKB) == 0);
+    /* USB Clock uses PLLB */
+    PMC->PMC_USB = PMC_USB_USBDIV(0)       /* /1 (no divider)  */
+                 | PMC_USB_USBS;           /* PLLB */
+}
+
+
+void SIMtraceDriver_Initialize( void )
+{
+    // Get std USB driver
+    USBDDriver *pUsbd = USBD_GetDriver();
+
+    TRACE_DEBUG(".");
+
+    // Initialize standard USB driver
+    USBDDriver_Initialize(pUsbd,
+                          &driverDescriptors,
+// FIXME: 2 interface settings supported in MITM mode
+                          0); // Multiple interface settings not supported
+    
+    USBD_Init();
+    TRACE_DEBUG("%s", "leaving");
+}
+
+/*
+void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum)
+{
+    printf("Configuration change requested: %c\n\r", cfgnum);
+}
+
+void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
+{
+    printf("RequestHandler called %d\n\r", USBGenericRequest_GetType(request));
+}
+*/
+/*----------------------------------------------------------------------------
+ *          Main
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief usb_cdc_serial Application entry point.
+ *
+ * Initializes drivers and start the USB <-> Serial bridge.
+ */
+int main(void)
+{
+    uint8_t isUsbConnected = 0;
+
+    LED_Configure(LED_NUM_GREEN);
+    LED_Set(LED_NUM_GREEN);
+
+    /* Disable watchdog */
+    WDT_Disable( WDT );
+
+    PIO_InitializeInterrupts(0);
+    
+//    NVIC_EnableIRQ(UDP_IRQn);
+
+    /* Enable UPLL for USB */
+//    _ConfigureUsbClock();
+
+    /* CDC serial driver initialization */
+//    CDCDSerialDriver_Initialize(&driverDescriptors);
+    SIMtraceDriver_Initialize();
+//    CCIDDriver_Initialize();
+
+    USBD_Connect();
+
+    NVIC_EnableIRQ( UDP_IRQn );
+
+    printf("**** Start");
+
+    while (1) {
+            /* Device is not configured */
+        if (USBD_GetState() < USBD_STATE_CONFIGURED) {
+
+            if (isUsbConnected) {
+                isUsbConnected = 0;
+//                TC_Stop(TC0, 0);
+            }
+        }
+        else if (isUsbConnected == 0) {
+            printf("USB is now configured\n\r");
+
+            isUsbConnected = 1;
+//            TC_Start(TC0, 0);
+        }    
+    }
+}