This program is for an autonomous robot for the competition at the Hochschule Luzern. http://cruisingcrepe.wordpress.com/ We are one of the 32 teams. http://cruisingcrepe.wordpress.com/ The postition control is based on this Documentation: Control of Wheeled Mobile Robots: An Experimental Overview from Alessandro De Luca, Giuseppe Oriolo, Marilena Vendittelli. For more information see here: http://www.dis.uniroma1.it/~labrob/pub/papers/Ramsete01.pdf

Dependencies:   mbed

Fork of autonomous Robot Android by Christian Burri

Files at this revision

API Documentation at this revision

Comitter:
chrigelburri
Date:
Sat Mar 23 13:52:48 2013 +0000
Parent:
5:48a258f6335e
Child:
7:34be8b3a979c
Commit message:
mit link und rechten Radradius

Changed in this revision

Actuators/Hallsensor.h Show annotated file Show diff for this revision Revisions of this file
Actuators/MaxonESCON.cpp Show annotated file Show diff for this revision Revisions of this file
Actuators/MaxonESCON.h Show annotated file Show diff for this revision Revisions of this file
Android/AndroidAccessory/AndroidAccessory.cpp Show annotated file Show diff for this revision Revisions of this file
Android/AndroidAccessory/AndroidAccessory.h Show annotated file Show diff for this revision Revisions of this file
Android/AndroidAccessory/USBHost/USBHost.cpp Show annotated file Show diff for this revision Revisions of this file
Android/AndroidAccessory/USBHost/USBHost.h Show annotated file Show diff for this revision Revisions of this file
Android/AndroidAccessory/USBHost/USBHost_log.cpp Show annotated file Show diff for this revision Revisions of this file
RobotControl/MotionState.cpp Show annotated file Show diff for this revision Revisions of this file
RobotControl/MotionState.h Show annotated file Show diff for this revision Revisions of this file
RobotControl/RobotControl.cpp Show annotated file Show diff for this revision Revisions of this file
RobotControl/RobotControl.h Show annotated file Show diff for this revision Revisions of this file
StateDefines/State.cpp Show annotated file Show diff for this revision Revisions of this file
StateDefines/State.h Show annotated file Show diff for this revision Revisions of this file
StateDefines/defines.h Show annotated file Show diff for this revision Revisions of this file
Task/Task.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/Actuators/Hallsensor.h	Thu Mar 21 08:56:53 2013 +0000
+++ b/Actuators/Hallsensor.h	Sat Mar 23 13:52:48 2013 +0000
@@ -14,11 +14,30 @@
  * @section DESCRIPTION
  *
  * Interface to count the Hallsensor input from a EC-Motor.
- * 
+ *
  */
 class Hallsensor
 {
 
+private:
+
+    /**
+     * Update the pulse count.
+     * Called on every rising/falling edge of Hall 1-3.
+     * Reads the state of the channels and determines whether a pulse forward
+     * or backward has occured, updating the count appropriately.
+     */
+    void encode(void);
+
+    InterruptIn hall1_;
+    InterruptIn hall2_;
+    InterruptIn hall3_;
+
+    int          prevState_;
+    int          currState_;
+
+    volatile int pulses_;
+
 public:
 
     /**
@@ -52,25 +71,6 @@
      */
     int getRevolutions(void);
 
-private:
-
-    /**
-     * Update the pulse count.
-     * Called on every rising/falling edge of Hall 1-3.
-     * Reads the state of the channels and determines whether a pulse forward
-     * or backward has occured, updating the count appropriately.
-     */
-    void encode(void);
-
-    InterruptIn hall1_;
-    InterruptIn hall2_;
-    InterruptIn hall3_;
-
-    int          prevState_;
-    int          currState_;
-
-    volatile int pulses_;
-
 };
 
 #endif /* Hallsensor_H */
--- a/Actuators/MaxonESCON.cpp	Thu Mar 21 08:56:53 2013 +0000
+++ b/Actuators/MaxonESCON.cpp	Sat Mar 23 13:52:48 2013 +0000
@@ -56,7 +56,7 @@
 
 void MaxonESCON::enable(bool enb)
 {
-    if(enb == false) {
+    if(enb == true) {
         _enb = 1;
     } else {
         _enb = 0;
--- a/Actuators/MaxonESCON.h	Thu Mar 21 08:56:53 2013 +0000
+++ b/Actuators/MaxonESCON.h	Sat Mar 23 13:52:48 2013 +0000
@@ -42,12 +42,12 @@
 public:
 
     /** Create a motor control object.
-       * @param enb DigitalOut, set high for enable
-       * @param isenb DigitalIn, high for enable
-       * @param pwm PwmOut pin, set the velocity
-       * @param actualSpeed AnalogIn filtered signal for ActualSpeed from Motor
-       * @param hall The object of the hallsensor from Motor
-       */
+     * @param enb DigitalOut, set high for enable
+     * @param isenb DigitalIn, high for enable
+     * @param pwm PwmOut pin, set the velocity
+     * @param actualSpeed AnalogIn filtered signal for ActualSpeed from Motor
+     * @param hall The object of the hallsensor from Motor
+     */
     MaxonESCON(PinName enb,
                PinName isenb,
                PinName pwm,
@@ -55,42 +55,43 @@
                Hallsensor *hall);
 
     /** Set the speed of the motor with a pwm for 10%..90%.
-    * 50% PWM is 0rpm.
-    * Caclulate from [1/s] in [1/min] and the Factor of the ESCON.
-    * @param speed The speed of the motor as a normalised value, given in [1/s]
-    */
+     * 50% PWM is 0rpm.
+     * Caclulate from [1/s] in [1/min] and the Factor of the ESCON.
+     * @param speed The speed of the motor as a normalised value, given in [1/s]
+     */
     void setVelocity(float speed);
 
     /**Return the speed from ESCON.
-    * 0 rpm is defined in the Analog input as 1.65V
-    * @return speed of the motor, given in [1/s]
-    */
+     * 0 rpm is defined in the Analog input as 1.65V
+     * @return speed of the motor, given in [1/s]
+     */
     float getActualSpeed(void);
 
     /** Set the period of the pwm duty cycle.
-    * Wrapper for PwmOut::period()
-    * @param period Pwm duty cycle, given in [s].
-    */
+     * Wrapper for PwmOut::period()
+     * @param period Pwm duty cycle, given in [s].
+     */
     void period(float period);
 
     /** Set the Motor to a enable sate.
-    * @param enb <code>false</code> for disable <code>true</code> for enable.
-    */
+     * @param enb <code>false</code> for disable <code>true</code> for enable.
+     */
     void enable(bool enb);
 
     /**Tests if the servo drive is enabled.
-    * @return <code>true</code> if the drive is enabled, <code>false</code> otherwise.
-    */
+     * @return <code>true</code> if the drive is enabled, 
+     * <code>false</code> otherwise.
+     */
     bool isEnabled(void);
 
     /** Return the number of Pulses.
-    * @return Pulses, given in [count]
-    */
+     * @return Pulses, given in [count]
+     */
     int getPulses(void);
 
     /** Set the Pulses of the Motor, given in [count]
-    * @return Pulses, given in [count]
-    */
+     * @return Pulses, given in [count]
+     */
     int setPulses(int setPos);
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Android/AndroidAccessory/AndroidAccessory.cpp	Sat Mar 23 13:52:48 2013 +0000
@@ -0,0 +1,323 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "USBHost.h"
+#include "AndroidAccessory.h"
+#include "mbed.h"
+
+AndroidAccessory* _adk;
+
+void AdkreadCallback(int device, int endpoint, int status, u8* buf, int len, void* userData);
+void AdkwriteCallback(int device, int endpoint, int status, u8* buf, int len, void* userData);
+
+
+
+AndroidAccessory::AndroidAccessory(int rbuffsize,int wbuffsize,
+                                   const char* manufacturer,
+                                   const char *model,
+                                   const char *description,
+                                   const char *version,
+                                   const char *uri,
+                                   const char *serial
+                                  ) {
+
+    _adk=this;
+
+    this->manufacturer=manufacturer;
+    this->model=model;
+    this->description=description;
+    this->version=version;
+    this->uri=uri;
+    this->serial=serial;
+
+    u32 len;
+    u8* p=USBGetBuffer(&len);
+    if (len<(rbuffsize+wbuffsize+255)) {
+        error("buff size too big.please resize max=%d. currentSize=%d\r\n",len,(rbuffsize+wbuffsize+255));
+    }
+
+    _readbuff=p;
+    _readbuffsize=rbuffsize;
+    p+=rbuffsize;
+    _writebuff=p;
+    _writebuffsize=wbuffsize;
+    p+=wbuffsize;
+    _strbuff=p;
+    p+=255;
+
+}
+
+
+
+int AndroidAccessory::write(u8 *buff, int len) {
+    log("AndroidAccessory::write ");
+   // __disable_irq();
+    int ret=USBBulkTransfer(_device,output_ep,buff,len,AdkwriteCallback,this);
+   // __enable_irq();
+    log("--ret=%d \r\n",ret);
+    return ret;
+}
+int AndroidAccessory::writeNC(u8 *buff, int len) {
+    log("AndroidAccessory::write ");
+   // __disable_irq();
+    int ret=USBBulkTransfer(_device,output_ep,buff,len);
+   // __enable_irq();
+    log("--ret=%d \r\n",ret);
+    return ret;
+}
+
+
+
+int AndroidAccessory::read(u8 *buff, int len) {
+   // if(_initok==false)return 0;
+    
+    log("AndroidAccessory::read ");
+   // __disable_irq();
+    int ret=USBBulkTransfer(_device,input_ep|0x80,buff,len);
+   // __enable_irq();
+    log("--ret=%d \r\n",ret);
+    return ret;
+}
+
+
+void AndroidAccessory::init(int device, int configuration, int interfaceNumber) {
+
+    log("AndroidAccessory::init \r\n");
+
+//    _initok=false;
+    _device = device;
+    _configuration = configuration;
+    _interfaceNumber = interfaceNumber;
+    printf("device = %d configuration = %d interfaceNumber = %d\r\n", device, configuration, interfaceNumber);
+    int err;
+
+    u8* buffer=_strbuff;
+    err = GetDescriptor(_device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,4);
+
+    if (err < 0) {
+        log("Failed to get descriptor\r\n");
+        return;
+    }
+
+
+    int len = buffer[2] | (buffer[3] << 8);
+    if (len > 255) {
+        log("config descriptor too large\n");
+        /* might want to truncate here */
+        return;
+    }
+    err = GetDescriptor(_device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,len);
+    u8* p = buffer;
+    input_ep=0;
+    output_ep=0;
+    EndpointDescriptor *epDesc;
+    while (p<(buffer+len)) {
+        u8 descLen  = p[0];
+        u8 descType = p[1];
+        log("descLen=%d,descType=%d\r\n",descLen,descType);
+        switch (descType) {
+            case DESCRIPTOR_TYPE_CONFIGURATION:
+                log("config desc\r\n");
+                break;
+            case DESCRIPTOR_TYPE_INTERFACE:
+                log("interface desc\r\n");
+                break;
+            case DESCRIPTOR_TYPE_ENDPOINT:
+                epDesc=(EndpointDescriptor*)p;
+                if (!input_ep && (epDesc->bEndpointAddress& 0x80)) {
+                    input_ep=epDesc->bEndpointAddress& 0x7f;
+                    //PacketSize drop
+                    log("input Endpoint address=%d,wMaxPacketSize=%d,bmAttributes=%d\r\n",input_ep,epDesc->wMaxPacketSize,epDesc->bmAttributes);
+
+                } else if (!output_ep) {
+                    output_ep=epDesc->bEndpointAddress& 0x7f;
+                    //PacketSize drop
+                    log("output Endpoint address=%d,wMaxPacketSize=%d,bmAttributes=%d\r\n",input_ep,epDesc->wMaxPacketSize,epDesc->bmAttributes);
+                } else {
+                    //other
+                    log("non input,output Endpoint address=%d,wMaxPacketSize=%d,bmAttributes=%d\r\n",input_ep,epDesc->wMaxPacketSize,epDesc->bmAttributes);
+                }
+                break;
+            default:
+                log("unkown desc type(%d) \r\n",descType);
+        }
+        p+=descLen;
+    }
+
+    if (!(input_ep && output_ep)) {
+        log("can't find accessory endpoints\r\n");
+        return;
+    }
+
+    log("SetConfiguration\r\n");
+    err = SetConfiguration(device,configuration);
+    if (err < 0) {
+        log("SetConfiguration error\r\n");
+        return;
+    }
+
+
+    log("interrupt setup\r\n");
+    //interrupt setup
+    if (_readbuff==NULL || _readbuffsize<=0) {
+        error("_readbuffer error please setup buffer call setReadBuffer function\r\n");
+    }
+
+    if (IO_PENDING!=USBBulkTransfer(_device,input_ep|0x80,_readbuff,_readbuffsize,AdkreadCallback,this))
+        return;
+
+
+    log("setupDevice\r\n");
+    this->setupDevice();
+//    _initok=true;
+}
+
+
+
+bool AndroidAccessory::switchDevice(int device) {
+
+    if (1==getProtocol(device)) {
+        log("device supports protocol 1\r\n");
+
+    } else {
+        log("could not read device protocol version\r\n");
+        return false;
+    }
+
+
+    sendString(device,ACCESSORY_STRING_MANUFACTURER,manufacturer);
+    sendString(device,ACCESSORY_STRING_MODEL,model);
+    sendString(device,ACCESSORY_STRING_DESCRIPTION,description);
+    sendString(device,ACCESSORY_STRING_VERSION,version);
+    sendString(device,ACCESSORY_STRING_URI,uri);
+    sendString(device,ACCESSORY_STRING_SERIAL,serial);
+    USBControlTransfer(device,
+                       HOST_TO_DEVICE |REQUEST_TYPE_VENDOR|RECIPIENT_DEVICE,
+                       ACCESSORY_START,
+                       0,//value
+                       0, //index
+                       0,
+                       0,
+                       0,
+                       0 );
+
+    wait_ms(4);
+    //reset usb host
+    USBInit();
+
+    return true;
+
+}
+
+
+int AndroidAccessory::getProtocol(int device) {
+    s16 data=-1;
+    USBControlTransfer(device,
+                       DEVICE_TO_HOST|REQUEST_TYPE_VENDOR|RECIPIENT_DEVICE,
+                       ACCESSORY_GET_PROTOCOL,
+                       0,//value
+                       0, //index
+                       (u8*)&data,
+                       2,
+                       0,
+                       0 );
+    return data;
+
+}
+
+void AndroidAccessory::sendString(const char *str) {
+    sendString(_device,1,str);
+
+}
+
+void AndroidAccessory::sendString(int device, int index, const char *str) {
+
+    LOG("send_string start(%d,%d,%s)  %d \r\n",device,index,str,strlen(str)+1);
+    strcpy((char*)_strbuff,str);
+    //thankyou curryman san
+    USBControlTransfer(device,
+                       HOST_TO_DEVICE|REQUEST_TYPE_VENDOR|RECIPIENT_DEVICE,
+                       ACCESSORY_SEND_STRING,
+                       0,//value
+                       index,
+                       _strbuff,
+                       strlen(str)+1
+                      );
+
+    LOG("send_string end(%d,%d,%s)\r\n",device,index,str);
+
+}
+
+
+/** from USBHost load function. initialize Android device**/
+void OnLoadDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc) {
+    printf("LoadDevice %d %02X:%02X:%02X\r\n",device,interfaceDesc->bInterfaceClass,interfaceDesc->bInterfaceSubClass,interfaceDesc->bInterfaceProtocol);
+    char s[128];
+
+    for (int i = 1; i < 3; i++) {
+        if (GetString(device,i,s,sizeof(s)) < 0)
+            break;
+        printf("%d: %s\r\n",i,s);
+    }
+
+    //for android ADK
+    if ( ( deviceDesc->idVendor != 0x18D1 ||
+            ( deviceDesc->idProduct != 0x2D00 && deviceDesc->idProduct != 0x2D01))
+            &&_adk->switchDevice(device)) {
+
+        printf("  try to change accmode.interfaceDesc->bInterfaceClass=%d\r\n",interfaceDesc->bInterfaceClass);
+        //1th root
+        //accmode_support=true;
+        printf("accessory mode ok.\r\n");
+        return;
+    }
+
+    if (deviceDesc->idVendor == 0x18D1 &&
+            (deviceDesc->idProduct == 0x2D00 || deviceDesc->idProduct == 0x2D01)) {
+        //2th root
+        printf("connecting Android.\r\n");
+        printf("idVender=%x  idProduct=%x  interfaceDesc->bInterfaceClass=%d\r\n",deviceDesc->idVendor,deviceDesc->idProduct,interfaceDesc->bInterfaceClass);
+        _adk->init(device,1,0);
+        //_AdkUSB.loop();
+        return;
+    }
+}
+
+void AdkreadCallback(int device, int endpoint, int status, u8* buf, int len, void* userData) {
+    log("AdkreadCallback(int device=%d, int endpoint=%x, int status=%d, u8* buf=%p, int len=%d, void* userData=%p)\r\n",
+        device,endpoint,status,buf,len,userData);
+//    __disable_irq();
+    AndroidAccessory* t = (AndroidAccessory*)userData;
+    if (status!=0 && status!=8) {
+        log("adk end.\r\n");
+        t->adkEnd();
+//        __enable_irq();
+        USBInit();
+        return;
+    }
+
+
+    //virtual method run
+    t->callbackRead(buf,len);
+
+    USBBulkTransfer(device, endpoint , buf, len, AdkreadCallback, userData);
+
+//    wait_ms(4);
+//    __enable_irq();
+}
+
+
+
+
+void AdkwriteCallback(int device, int endpoint, int status, u8* buf, int len, void* userData) {
+
+    log("AdkwriteCallback(int device=%d, int endpoint=%x, int status=%d, u8* buf=%p, int len=%d, void* userData=%p)\r\n",
+        device,endpoint,status,buf,len,userData);
+    
+    AndroidAccessory* t = (AndroidAccessory*)userData;
+    t->callbackWrite();
+    //wait_ms(4);
+    //USBBulkTransfer(device, endpoint , buf, len, AdkwriteCallback, userData);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Android/AndroidAccessory/AndroidAccessory.h	Sat Mar 23 13:52:48 2013 +0000
@@ -0,0 +1,195 @@
+/* mbed AndroidAccessory Library
+ * Created by p07gbar from work by Makoto Abe
+ *
+ */
+#ifndef ADK_H_INCLUDED
+#define ADK_H_INCLUDED
+
+#include "mbed.h"
+#include "USBHost.h"
+
+
+//#define  ADKLOG 1
+#if ADKLOG
+#define  LOG(...)       printf(__VA_ARGS__)
+#define  Log(...)       printf(__VA_ARGS__)
+#define  log(...)       printf(__VA_ARGS__)
+
+#else
+#define  LOG(...)       do {} while(0)
+#define  Log(...)       do {} while(0)
+#define  log(...)       do {} while(0)
+
+#endif
+
+#define ACCESSORY_STRING_MANUFACTURER   0
+#define ACCESSORY_STRING_MODEL          1
+#define ACCESSORY_STRING_DESCRIPTION    2
+#define ACCESSORY_STRING_VERSION        3
+#define ACCESSORY_STRING_URI            4
+#define ACCESSORY_STRING_SERIAL         5
+
+#define ACCESSORY_GET_PROTOCOL          51
+#define ACCESSORY_SEND_STRING           52
+#define ACCESSORY_START                 53
+
+
+
+/** An AndroidAccessory control class
+ * 
+ * It allows easy creation of a mbed android ADK accessory, with minimal low level fussing.
+ * Base code should have methods resetDevice(), setupDevice(), callbackRead(u8 *buff, int len) and callBackWrite() functions
+ * 
+ */
+
+class AndroidAccessory {
+public:
+
+
+
+/** Create a AndroidAccessory object
+ *
+ * Create a AndroidAccessoryobject with specified buffer sizes and infomation
+ *
+ * @param rbuffsize The size of the read buffer
+ * @param wbuffsize The size of the write buffer
+ * @param manufacturer The manufacturer of the accessory
+ * @param model The model of the accessory
+ * @param description A short description of the accessory
+ * @param version The current version of the accessory
+ * @param uri Some data to go with the accessory (URL or more description)
+ * @param serial The serial number of the accessory
+ */
+    AndroidAccessory(int rbuffsize,int wbuffsize,
+                     const char* manufacturer,
+                     const char *model,
+                     const char *description,
+                     const char *version,
+                     const char *uri,
+                     const char *serial
+                    );
+                    
+ /** Init the device
+ * This is meant to be implimented by the user of the class
+ *
+ * @param device Device number
+ * @param configuration Configuration
+ * @param interfaceNumber Inteface number
+ */
+    virtual void init(int device, int configuration, int interfaceNumber); 
+    
+/** Reset the device
+ * This is meant to be implimented by the user of the class
+ *
+ */
+    virtual void resetDevice()=0;
+        
+/** Setup the device
+ * This is meant to be implimented by the user of the class. Called when the device is first intialised
+ *
+ */
+    virtual void setupDevice()=0;
+    
+ /** Callback on Read
+ * This is meant to be implimented by the user of the class. Called when some data has been read in.
+ *
+ * @param buff The buffered read in data
+ * @param len The length of the packet recived
+ *
+ */
+    virtual int callbackRead(u8 *buff, int len)=0;
+ 
+ /** Callback after Write
+ * This is meant to be implimented by the user of the class. Called when the write has been finished.
+ *
+ */
+    virtual int callbackWrite()=0;
+    
+ /** Write over USB
+ * This sends the data in the buffer over USB in a packet
+ *
+ * @param buff The buffer to write out
+ * @param len The length of the packet to send
+ *
+ */    
+    int write(u8 *buff, int len);
+    
+/** Write over USB
+ * This sends the data in the buffer over USB in a packet, sends _writebuff and _writebuffsize
+ *
+ */    
+    int write() {
+        return write(_writebuff,_writebuffsize);
+    }
+    
+ /** Write over USB with no callback
+ * This sends the data in the buffer over USB in a packet, waits until the packet is sent, rather than doing a callback
+ *
+ * @param buff The buffer to write out
+ * @param len The length of the packet to send
+ *
+ */  
+    int writeNC(u8 *buff, int len);
+    
+ /** Write over USB
+ * This sends the data in the buffer over USB in a packet, waits until the packet is sent, rather than doing a callback, sends _writebuff and _writebuffsize
+ *
+ */    
+    int writeNC() {
+        return writeNC(_writebuff,_writebuffsize);
+    }
+
+ /** Read the buffer USB
+ * This sends the data in the buffer over USB in a packet, waits until the packet is sent, rather than doing a callback
+ *
+ * @param buff The buffer to read into
+ * @param len The length of the packet to read in
+ *
+ * @param returns The number of bytes read
+ *
+ */  
+    int read(u8 *buff, int len);
+
+
+    void adkEnd() {
+       // _initok=false;
+        resetDevice();
+    }; //if connection close
+    bool switchDevice(int device);
+
+    //buffer
+    u8* _readbuff;
+    int _readbuffsize;
+    u8* _writebuff;
+    int _writebuffsize;
+    u8* _strbuff;//255bytes;
+     void sendString(const char *str);
+
+private:
+
+    void sendString(int device, int index, const char *str);
+    int getProtocol(int device);
+
+    const char *manufacturer;
+    const char *model;
+    const char *description;
+    const char *version;
+    const char *uri;
+    const char *serial;
+
+    //endpoints
+    int input_ep;
+    int output_ep;
+
+    int _device;
+    int _configuration;
+    int _interfaceNumber;
+
+    //bool _initok;
+
+};
+
+extern AndroidAccessory* _adk; //declared in cpp
+
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Android/AndroidAccessory/USBHost/USBHost.cpp	Sat Mar 23 13:52:48 2013 +0000
@@ -0,0 +1,1093 @@
+
+/*
+Copyright (c) 2010 Peter Barrett
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+ 
+
+
+#include "mbed.h"
+#include "USBHost.h"
+#ifndef  USBHOST_LOG
+
+
+//    Config (default uses x bytes)
+#define MAX_DEVICES 8                // Max number of devices
+#define MAX_ENDPOINTS_TOTAL 16        // Max number of endpoints total
+#define MAX_ENDPOINTS_PER_DEVICE 8    // Max number of endpoints for any one device
+
+//#define  USBLOG 1
+#if USBLOG
+#define  LOG(...)       printf(__VA_ARGS__)
+#else 
+#define  LOG(...)       do {} while(0)
+#endif
+
+// USB host structures
+
+#define USB_RAM_SIZE 16*1024    // AHB SRAM block 1 TODO MACHINE DEPENDENT
+#define USB_RAM_BASE 0x2007C000
+
+#define TOKEN_SETUP 0
+#define TOKEN_IN  1
+#define TOKEN_OUT 2
+
+//    Status flags from hub
+#define PORT_CONNECTION 0
+#define PORT_ENABLE  1
+#define PORT_SUSPEND  2
+#define PORT_OVER_CURRENT 3
+#define PORT_RESET 4
+#define PORT_POWER 8
+#define PORT_LOW_SPEED 9
+
+#define C_PORT_CONNECTION 16
+#define C_PORT_ENABLE 17
+#define C_PORT_SUSPEND 18
+#define C_PORT_OVER_CURRENT 19
+#define C_PORT_RESET 20
+
+typedef struct {
+    u8 bm_request_type;
+    u8 b_request;
+    u16 w_value;
+    u16 w_index;
+    u16 w_length;
+} Setup;
+
+
+//    Hub stuff is kept private just to keep api simple
+int SetPortFeature(int device, int feature, int index);
+int ClearPortFeature(int device, int feature, int index);
+int SetPortPower(int device, int port);
+int SetPortReset(int device, int port);
+int GetPortStatus(int device, int port, u32* status);
+
+//===================================================================
+//===================================================================
+//    Hardware defines
+
+//    HcControl
+#define PeriodicListEnable    0x00000004
+#define    IsochronousEnable    0x00000008
+#define    ControlListEnable    0x00000010
+#define    BulkListEnable        0x00000020
+#define    OperationalMask        0x00000080
+#define    HostControllerFunctionalState    0x000000C0
+
+//    HcCommandStatus
+#define HostControllerReset    0x00000001
+#define ControlListFilled    0x00000002
+#define BulkListFilled        0x00000004
+
+//    HcInterruptStatus Register
+#define    WritebackDoneHead        0x00000002
+#define    StartofFrame            0x00000004
+#define ResumeDetected            0x00000008
+#define UnrecoverableError        0x00000010
+#define FrameNumberOverflow        0x00000020
+#define RootHubStatusChange        0x00000040
+#define OwnershipChange            0x00000080
+#define MasterInterruptEnable    0x80000000
+
+//    HcRhStatus
+#define SetGlobalPower            0x00010000
+#define DeviceRemoteWakeupEnable    0x00008000
+
+//    HcRhPortStatus (hub 0, port 1)
+#define CurrentConnectStatus    0x00000001
+#define    PortEnableStatus        0x00000002
+#define PortSuspendStatus        0x00000004
+#define PortOverCurrentIndicator    0x00000008
+#define PortResetStatus            0x00000010
+
+#define PortPowerStatus            0x00000100
+#define LowspeedDevice            0x00000200
+#define HighspeedDevice            0x00000400
+
+#define ConnectStatusChange    (CurrentConnectStatus << 16)
+#define PortResetStatusChange    (PortResetStatus << 16)
+
+
+#define  TD_ROUNDING        (u32)0x00040000
+#define  TD_SETUP            (u32)0x00000000
+#define  TD_IN                (u32)0x00100000
+#define  TD_OUT                (u32)0x00080000
+#define  TD_DELAY_INT(x)    (u32)((x) << 21)
+#define  TD_TOGGLE_0        (u32)0x02000000
+#define  TD_TOGGLE_1        (u32)0x03000000
+#define  TD_CC                (u32)0xF0000000
+
+//    HostController EndPoint Descriptor
+typedef struct {
+    volatile u32    Control;
+    volatile u32    TailTd;
+    volatile u32    HeadTd;
+    volatile u32    Next;
+} HCED;
+
+// HostController Transfer Descriptor
+typedef struct {
+    volatile u32    Control;
+    volatile u32    CurrBufPtr;
+    volatile u32    Next;
+    volatile u32    BufEnd;
+} HCTD;
+
+// Host Controller Communication Area
+typedef struct {
+    volatile u32    InterruptTable[32];
+    volatile u16    FrameNumber;
+    volatile u16    FrameNumberPad;
+    volatile u32    DoneHead;
+    volatile u8        Reserved[120];
+} HCCA;
+
+//====================================================================================
+//====================================================================================
+
+class HostController;
+class Endpoint;
+class Device;
+
+//      must be 3*16 bytes long
+class Endpoint
+{
+public:
+    HCED    EndpointDescriptor;    // Pointer to EndpointDescriptor == Pointer to Endpoint
+    HCTD    TDHead;
+
+    enum State
+    {
+        Free,
+        NotQueued,
+        Idle,
+        SetupQueued,
+        DataQueued,
+        StatusQueued,
+        CallbackPending
+    };
+    
+    volatile u8 CurrentState;
+    u8        Flags;            // 0x80 In, 0x03 mask endpoint type
+
+    u16        Length;
+    u8*        Data;
+    USBCallback Callback;     // Must be a multiple of 16 bytes long
+    void*  UserData;
+  
+    int Address()
+    {
+        int ep = (EndpointDescriptor.Control >> 7) & 0xF;
+        if (ep)
+            ep |= Flags & 0x80;
+        return ep;
+    }
+    
+    int Device()
+    {
+        return EndpointDescriptor.Control & 0x7F;
+    }
+
+    int Status()
+    {
+        return (TDHead.Control >> 28) & 0xF;
+    }
+
+    u32 Enqueue(u32 head)
+    {
+        if (CurrentState == NotQueued)
+        {
+            EndpointDescriptor.Next = head;
+            head = (u32)&EndpointDescriptor;
+            CurrentState = Idle;
+        }
+        return head;
+    }
+};
+
+class Device
+{
+public:
+    u8    _endpointMap[MAX_ENDPOINTS_PER_DEVICE*2];
+    u8    Hub;
+    u8    Port;
+    u8    Addr;
+    u8    Pad;
+
+    //    Only if this device is a hub
+    u8    HubPortCount;    // nonzero if this is a hub
+    u8    HubInterruptData;
+    u8    HubMap;
+    u8    HubMask;
+
+    int Flags;        // 1 = Disconnected
+
+    Setup    SetupBuffer;
+
+    // Allocate endpoint zero
+    int Init(DeviceDescriptor* d, int hub, int port, int addr, int lowSpeed)
+    {
+        Hub = hub;
+        Port = port;
+        Addr = addr;
+        Flags = lowSpeed;
+        memset(_endpointMap,0xFF,sizeof(_endpointMap));
+        return 0;
+    }
+
+    int SetEndpointIndex(int ep, int endpointIndex)
+    {
+        for (int i = 0; i < MAX_ENDPOINTS_PER_DEVICE*2; i += 2)
+        {
+            if (_endpointMap[i] == 0xFF)    // Add endpoint to map
+            {
+                _endpointMap[i] = ep;
+                _endpointMap[i+1] = endpointIndex;
+                return 0;
+            }
+        }
+        return ERR_ENDPOINT_NONE_LEFT;
+    }
+
+    int GetEndpointIndex(int ep)
+    {
+        for (int i = 0; i < MAX_ENDPOINTS_PER_DEVICE*2; i += 2)
+        {
+            if (_endpointMap[i] == ep)
+                return _endpointMap[i+1];
+            if (_endpointMap[i] == 0xFF)
+                break;
+        }
+        return -1;
+    }
+};
+
+class HostController
+{
+public:
+    HCCA        CommunicationArea;
+    Endpoint    Endpoints[MAX_ENDPOINTS_TOTAL];    // Multiple of 16
+    
+    Endpoint    EndpointZero;                        // For device enumeration
+    HCTD        _commonTail;
+    Setup        _setupZero;
+    
+    Device    Devices[MAX_DEVICES];
+    u32    _frameNumber;            // 32 bit ms counter
+
+    u8    _callbacksPending;        //    Endpoints with callbacks are pending, set from ISR via ProcessDoneQueue
+    u8    _rootHubStatusChange;    //    Root hub status has changed, set from ISR
+    u8    _unused0;
+    u8    _unused1;
+
+    u8    _connectPending;    //    Reset has initiated a connect
+    u8    _connectCountdown;    //    Number of ms left after reset before we can connect
+    u8    _connectHub;        //    Will connect on this hub
+    u8    _connectPort;        //    ... and this port
+
+    u8    SRAM[0];            // Start of free SRAM
+
+    void Loop()
+    {
+        u16 elapsed = CommunicationArea.FrameNumber - (u16)_frameNumber;    // extend to 32 bits
+        _frameNumber += elapsed;
+
+        // Do callbacks, if any
+        while (_callbacksPending)
+        {
+            for (int i = 0; i < MAX_ENDPOINTS_TOTAL; i++)
+            {
+                Endpoint* endpoint = Endpoints + i;
+                if (endpoint->CurrentState == Endpoint::CallbackPending)
+                {
+                    LOG("Sorting Callbacks %i\n\r",endpoint->CurrentState);
+                    _callbacksPending--;
+                    endpoint->CurrentState = Endpoint::Idle;
+                    LOG("SatusChanged %i\n\r",endpoint->CurrentState);
+                    endpoint->Callback(endpoint->Device(),endpoint->Address(),endpoint->Status(),endpoint->Data,endpoint->Length,endpoint->UserData);
+                }
+            }
+        }
+
+        //    Deal with changes on the root hub
+        if (_rootHubStatusChange)
+        {
+            u32 status = LPC_USB->HcRhPortStatus1;
+            _rootHubStatusChange = 0;
+            if (status >> 16)
+            {
+                HubStatusChange(0,1,status);
+                LPC_USB->HcRhPortStatus1 = status & 0xFFFF0000;    // clear status changes
+            }
+        }
+
+        //    Connect after reset timeout
+        if (_connectCountdown)
+        {
+            if (elapsed >= _connectCountdown)
+            {
+                _connectCountdown = 0;
+                Connect(_connectHub,_connectPort & 0x7F,_connectPort & 0x80);
+            } else
+                _connectCountdown -= elapsed;
+        }
+    }
+
+    //    HubInterrupt - bitmap in dev->HubInterruptData
+    void HubInterrupt(int device)
+    {
+        Device* dev = &Devices[device-1];
+        for (int i = 0; i < dev->HubPortCount; i++)
+        {
+            int port = i+1;
+            if (dev->HubInterruptData & (1 << port))
+            {
+                u32 status = 0;
+                GetPortStatus(device,port,&status);
+                if (status >> 16)
+                {
+                    if (_connectPending && (status & ConnectStatusChange))
+                        continue;    // Don't connect again until previous device has been added and addressed
+
+                    HubStatusChange(device,port,status);
+                    if (status & ConnectStatusChange)
+                        ClearPortFeature(device,C_PORT_CONNECTION,port);
+                    if (status & PortResetStatusChange)
+                        ClearPortFeature(device,C_PORT_RESET,port);
+                }
+            }
+        }
+    }
+
+    static void HubInterruptCallback(int device, int endpoint, int status, u8* data, int len, void* userData)
+    {
+        HostController* controller = (HostController*)userData;
+        if (status == 0)
+            controller->HubInterrupt(device);
+        USBInterruptTransfer(device,endpoint,data,1,HubInterruptCallback,userData);
+    }
+
+    int InitHub(int device)
+    {
+        u8 buf[16];
+        int r= USBControlTransfer(device,DEVICE_TO_HOST | REQUEST_TYPE_CLASS | RECIPIENT_DEVICE,GET_DESCRIPTOR,(DESCRIPTOR_TYPE_HUB << 8),0,buf,sizeof(buf));
+        if (r < 0)
+            return ERR_HUB_INIT_FAILED;
+        
+        //    turn on power on the hubs ports
+        Device* dev = &Devices[device-1];
+        int ports = buf[2];
+        dev->HubPortCount = ports;
+        for (int i = 0; i < ports; i++)
+            SetPortPower(device,i+1);
+        
+        // Enable hub change interrupts
+        return USBInterruptTransfer(device,0x81,&dev->HubInterruptData,1,HubInterruptCallback,this);
+    }
+    
+    int AddEndpoint(int device, int ep, int attributes, int maxPacketSize, int interval)
+    {
+        LOG("AddEndpoint D:%02X A:%02X T:%02X P:%04X I:%02X\r\n",device,ep,attributes,maxPacketSize,interval);
+        Device* dev = &Devices[device-1];
+        Endpoint* endpoint = AllocateEndpoint(device,ep,attributes,maxPacketSize);
+        if (!endpoint)
+            return ERR_ENDPOINT_NONE_LEFT;
+        dev->SetEndpointIndex(ep,endpoint - Endpoints);
+        endpoint->EndpointDescriptor.Control |= dev->Flags; // Map in slow speed
+        return 0;  // TODO ed->bInterval
+    }
+    
+    int AddEndpoint(int device, EndpointDescriptor* ed)
+    {
+        return AddEndpoint(device,ed->bEndpointAddress,ed->bmAttributes,ed->wMaxPacketSize,ed->bInterval);
+    }
+
+    //      allocate a endpoint
+    Endpoint* AllocateEndpoint(int device, int endpointAddress, int type, int maxPacketSize)
+    {
+        for (int i = 0; i < MAX_ENDPOINTS_TOTAL; i++)
+        {
+            Endpoint* ep = &Endpoints[i];
+            if (ep->CurrentState == 0)
+            {
+                //LOG("Allocated endpoint %d to %02X:%02X\r\n",i,device,endpointAddress);
+                ep->Flags = (endpointAddress & 0x80) | (type & 3);
+                ep->CurrentState = Endpoint::NotQueued;
+                ep->EndpointDescriptor.Control = (maxPacketSize << 16) | ((endpointAddress & 0x7F) << 7) | device;
+                return ep;
+            }
+        }
+        return 0;
+    }
+
+    Endpoint* GetEndpoint(int device, int ep)
+    {
+        if (device == 0)
+        {
+            //printf("WARNING: USING DEVICE 0\n");
+            return &EndpointZero;
+        }
+        if (device > MAX_DEVICES)
+            return 0;
+        int i = Devices[device-1].GetEndpointIndex(ep);
+        if (i == -1)
+            return 0;
+        return Endpoints + i;
+    }
+
+    int Transfer(Endpoint* endpoint, int token, u8* data, int len, int state)
+    {
+        //LOG("Transfer %02X T:%d Len:%d S:%d\r\n",endpoint->Address(),token,len,state);
+    
+        int toggle = 0;
+        if (endpoint->Address() == 0)
+            toggle = (token == TOKEN_SETUP) ? TD_TOGGLE_0 : TD_TOGGLE_1;
+
+        if (token != TOKEN_SETUP)
+            token = (token == TOKEN_IN ? TD_IN : TD_OUT);
+
+        HCTD* head = &endpoint->TDHead;
+        HCTD* tail = &_commonTail;
+
+        head->Control = TD_ROUNDING | token | TD_DELAY_INT(0) | toggle | TD_CC; 
+        head->CurrBufPtr = (u32)data;
+        head->BufEnd = (u32)(data + len - 1);
+        head->Next = (u32)tail;
+
+        HCED* ed = &endpoint->EndpointDescriptor;
+        ed->HeadTd = (u32)head | (ed->HeadTd & 0x00000002);    // carry toggle
+        ed->TailTd = (u32)tail;
+        
+        //HCTD* td = head;
+        //LOG("%04X TD %08X %08X %08X Next:%08X\r\n",CommunicationArea.FrameNumber,td->Control,td->CurrBufPtr,td->BufEnd,td->Next);
+        //LOG("%04X ED %08X %08X %08X\r\n",CommunicationArea.FrameNumber,ed->Control,ed->HeadTd,ed->TailTd);
+        
+        switch (endpoint->Flags & 3)
+        {
+            case ENDPOINT_CONTROL:
+                LPC_USB->HcControlHeadED = endpoint->Enqueue(LPC_USB->HcControlHeadED);    // May change state NotQueued->Idle
+                endpoint->CurrentState = state;                                               // Get in before an int
+                LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | ControlListFilled;
+                LPC_USB->HcControl = LPC_USB->HcControl | ControlListEnable;
+                break;
+
+            case ENDPOINT_BULK:
+                LPC_USB->HcBulkHeadED = endpoint->Enqueue(LPC_USB->HcBulkHeadED);
+                endpoint->CurrentState = state;
+                LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | BulkListFilled;
+                LPC_USB->HcControl = LPC_USB->HcControl | BulkListEnable;
+                break;
+
+            case ENDPOINT_INTERRUPT:
+                CommunicationArea.InterruptTable[0] = endpoint->Enqueue(CommunicationArea.InterruptTable[0]);
+                endpoint->CurrentState = state;
+                LPC_USB->HcControl |= PeriodicListEnable;
+                break;
+        }
+        return 0;
+    }
+    
+    //    Remove an endpoint from an active queue
+    bool Remove(HCED* ed, volatile HCED** queue)
+    {
+        if (*queue == 0)
+            return false;
+        if (*queue == (volatile HCED*)ed)
+        {
+            *queue = (volatile HCED*)ed->Next;    // At head of queue
+            return true;
+        }
+
+        volatile HCED* head = *queue;
+        while (head)
+        {
+            if (head->Next == (u32)ed)
+            {
+                head->Next = ed->Next;
+                return true;
+            }
+            head = (volatile HCED*)head->Next;
+        }
+        return false;
+    }
+
+    void Release(Endpoint* endpoint)
+    {
+        if (endpoint->CurrentState == Endpoint::NotQueued)
+        {
+            // Never event used it, nothing to do
+        }
+        else
+        {
+            HCED* ed = (HCED*)endpoint;
+            ed->Control |= 0x4000;    // SKIP
+            switch (endpoint->Flags & 0x03)
+            {
+                case ENDPOINT_CONTROL:
+                    Remove(ed,(volatile HCED**)&LPC_USB->HcControlHeadED);
+                    break;
+                case ENDPOINT_BULK:
+                    Remove(ed,(volatile HCED**)&LPC_USB->HcBulkHeadED);
+                    break;
+                case ENDPOINT_INTERRUPT:
+                    for (int i = 0; i < 32; i++)
+                        Remove(ed,(volatile HCED**)&CommunicationArea.InterruptTable[i]);
+                    break;
+            }
+
+            u16 fn = CommunicationArea.FrameNumber;
+            while (fn == CommunicationArea.FrameNumber)
+                ;    // Wait for next frame
+
+        }
+
+        //    In theory, the endpoint is now dead.
+        //    TODO: Will Callbacks ever be pending? BUGBUG
+        memset(endpoint,0,sizeof(Endpoint));
+    }
+
+    //      Pop the last TD from the list
+    HCTD* Reverse(HCTD* current) 
+    { 
+        HCTD *result = NULL,*temp; 
+        while (current) 
+        { 
+            temp = (HCTD*)current->Next; 
+            current->Next = (u32)result;
+            result = current;
+            current = temp;
+        }
+        return result;
+    }
+
+    //      Called from interrupt...
+    //      Control endpoints use a state machine to progress through the transfers
+    void ProcessDoneQueue(u32 tdList)
+    {
+        HCTD* list = Reverse((HCTD*)tdList);
+        while (list)
+        {
+            Endpoint* endpoint = (Endpoint*)(list-1);
+            list = (HCTD*)list->Next;
+            int ep = endpoint->Address();
+            bool in = endpoint->Flags & 0x80;
+            int status = (endpoint->TDHead.Control >> 28) & 0xF;
+
+            //LOG("ProcessDoneQueue %02X %08X\r\n",ep,endpoint->TDHead.Control);
+
+            if (status != 0)
+            {
+                LOG("ProcessDoneQueue status %02X %d\r\n",ep,status);
+                endpoint->CurrentState = Endpoint::Idle;
+            } else {
+                switch (endpoint->CurrentState)
+                {
+                    case Endpoint::SetupQueued:
+                        if (endpoint->Length == 0)
+                            Transfer(endpoint,in ? TOKEN_OUT : TOKEN_IN,0,0,Endpoint::StatusQueued);    // Skip Data Phase
+                        else
+                            Transfer(endpoint,in ? TOKEN_IN : TOKEN_OUT,endpoint->Data,endpoint->Length, Endpoint::DataQueued);    // Setup is done, now Data
+                        break;
+
+                    case Endpoint::DataQueued:
+                        if (endpoint->TDHead.CurrBufPtr)
+                            endpoint->Length = endpoint->TDHead.CurrBufPtr - (u32)endpoint->Data;
+
+                        if (ep == 0)
+                            Transfer(endpoint,in ? TOKEN_OUT : TOKEN_IN,0,0,Endpoint::StatusQueued);    // Data is done, now Status, Control only
+                        else
+                            endpoint->CurrentState = Endpoint::Idle;
+                        break;
+
+                    case Endpoint::StatusQueued:    // Transaction is done
+                        endpoint->CurrentState = Endpoint::Idle;
+                        break;
+                }
+            }
+
+            //      Complete, flag if we need a callback
+            if (endpoint->Callback && endpoint->CurrentState == Endpoint::Idle)
+            {
+                endpoint->CurrentState = Endpoint::CallbackPending;
+                _callbacksPending++;
+            }
+        }
+    }
+
+    //    Hack to reset devices that don't want to connect
+    int AddDevice(int hub, int port, bool isLowSpeed)
+    {
+        int device = AddDeviceCore(hub,port,isLowSpeed);
+        if (device < 0)
+        {
+            LOG("========RETRY ADD DEVICE========\r\n");    // This will go for ever.. TODO power cycle root?
+            Disconnect(hub,port);    // Could not read descriptor at assigned address, reset this port and try again
+            ResetPort(hub,port);    // Cheap bluetooth dongles often need this on a hotplug
+            return -1;
+        }
+        return device;
+    }
+
+    int AddDeviceCore(int hub, int port, bool isLowSpeed)
+    {
+        int lowSpeed = isLowSpeed ? 0x2000 : 0;
+        DeviceDescriptor desc;
+        EndpointZero.EndpointDescriptor.Control = (8 << 16) | lowSpeed;               // MaxPacketSize == 8
+        int r = GetDescriptor(0,DESCRIPTOR_TYPE_DEVICE,0,(u8*)&desc,8);
+        if (r < 0)
+        {
+            LOG("FAILED TO LOAD DESCRIPTOR FOR DEVICE 0\r\n");
+            return r;
+        }
+
+        EndpointZero.EndpointDescriptor.Control = (desc.bMaxPacketSize << 16) | lowSpeed;     // Actual MaxPacketSize
+        r = GetDescriptor(0,DESCRIPTOR_TYPE_DEVICE,0,(u8*)&desc,sizeof(desc));
+        if (r < 0)
+            return r;
+
+        LOG("\nClass %02X found %04X:%04X\r\n",desc.bDeviceClass,desc.idVendor,desc.idProduct);
+
+        //      Now assign the device an address, move off EndpointZero
+        int device = 0;
+        for (int i = 0; i < MAX_DEVICES; i++)
+        {
+            if (Devices[i].Port == 0)
+            {
+                device = i+1;
+                break;
+            }
+        }
+        if (!device)
+            return ERR_DEVICE_NONE_LEFT;
+
+        r = SetAddress(0,device);
+        if (r)
+            return r;
+        DelayMS(2);
+        
+        // Now at a nonzero address, create control endpoint
+        Device* dev = &Devices[device-1];
+        dev->Init(&desc,hub,port,device,lowSpeed);
+        AddEndpoint(device,0,ENDPOINT_CONTROL,desc.bMaxPacketSize,0);
+        _connectPending = 0;
+
+        //    Verify this all works
+        r = GetDescriptor(device,DESCRIPTOR_TYPE_DEVICE,0,(u8*)&desc,sizeof(desc));
+        if (r < 0)
+            return r;
+
+        //    Set to interface 0 by default
+        //    Calls LoadDevice if interface is found
+        r = SetConfigurationAndInterface(device,1,0,&desc);
+
+        if (desc.bDeviceClass == CLASS_HUB)
+            InitHub(device);            // Handle hubs in this code
+
+        return device;
+    }
+
+    // Walk descriptors and create endpoints for a given device
+    // TODO configuration !=1, alternate settings etc.
+    int SetConfigurationAndInterface(int device, int configuration, int interfaceNumber, DeviceDescriptor* desc)
+    {
+        u8 buffer[255];
+        int err = GetDescriptor(device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,sizeof(buffer));
+        if (err < 0)
+            return err;
+
+        err = SetConfiguration(device,configuration);
+        if (err < 0)
+            return err;
+
+        //    Add the endpoints for this interface
+        int len = buffer[2] | (buffer[3] << 8);
+        u8* d = buffer;
+        u8* end = d + len;
+        InterfaceDescriptor* found = 0;
+        while (d < end)
+        {
+            if (d[1] == DESCRIPTOR_TYPE_INTERFACE)
+            {
+                InterfaceDescriptor* id = (InterfaceDescriptor*)d;
+                if (id->bInterfaceNumber == interfaceNumber)
+                {
+                    found = id;
+                    d += d[0];
+                    while (d < end && d[1] != DESCRIPTOR_TYPE_INTERFACE)
+                    {
+                        switch (d[1])
+                        {
+                            case DESCRIPTOR_TYPE_ENDPOINT:
+                                AddEndpoint(device,(EndpointDescriptor*)d);
+                                break;
+                            default:
+                                LOG("Skipping descriptor %02X (%d bytes)\r\n",d[1],d[0]);
+                        }
+                        d += d[0];
+                    }
+                }
+            }
+            d += d[0];
+        }
+
+        if (!found)
+            return ERR_INTERFACE_NOT_FOUND;
+        OnLoadDevice(device,desc,found);
+        return 0;
+    }
+
+    void Init()
+    {
+        LOG("USB INIT (Controller is %d bytes)\r\n",sizeof(*this));
+        memset(this,0,sizeof(HostController));
+        EndpointZero.CurrentState = Endpoint::NotQueued;
+        HWInit(&CommunicationArea);
+        DelayMS(10);
+    }
+
+    void ResetPort(int hub, int port)
+    {        
+        LOG("ResetPort Hub:%d Port:%d\r\n",hub,port);
+        _connectPending++;            // Only reset/add 1 device at a time
+        if (hub == 0)
+            LPC_USB->HcRhPortStatus1 = PortResetStatus;    // Reset Root Hub, port 1
+        else
+            SetPortReset(hub,port);    // or reset other hub
+    }
+
+    void Disconnect(int hub, int port)
+    {
+        LOG("Disconnect Hub:%d Port:%d\r\n",hub,port);    // Mark a device for destruction
+        for (int i = 0; i < MAX_DEVICES; i++)
+        {
+            Device* dev = Devices + i;
+            if (dev->Port == port && dev->Hub == hub)
+            {
+                //    Disconnect everything that is attached to this device if it is a hub
+                for (int p = 0; p < dev->HubPortCount; p++)
+                    Disconnect(i+1,p+1);
+
+                //    Now release endpoints
+                for (int j = 1; j < MAX_ENDPOINTS_PER_DEVICE*2; j += 2)
+                {
+                    u8 endpointIndex = dev->_endpointMap[j];
+                    if (endpointIndex != 0xFF)
+                        Release(Endpoints + endpointIndex);
+                }
+                dev->Port = 0;    // Device is now free
+                dev->Flags = 0;
+                return;
+            }
+        }
+    }
+
+    // called after reset
+    void Connect(int hub, int port, bool lowspeed)
+    {
+        LOG("Connect Hub:%d Port:%d %s\r\n",hub,port,lowspeed ? "slow" : "full");
+        AddDevice(hub,port,lowspeed);
+    }
+
+    // Called from interrupt
+    void HubStatusChange(int hub, int port, u32 status)
+    {
+        LOG("HubStatusChange Hub:%d Port:%d %08X\r\n",hub,port,status);
+        if (status & ConnectStatusChange)
+        {
+            if (status & CurrentConnectStatus)    // Connecting
+                ResetPort(hub,port);            // Reset to initiate connect (state machine?)
+            else
+                Disconnect(hub,port);
+        }
+
+        if (status & PortResetStatusChange)
+        {
+            if (!(status & PortResetStatus))
+            {
+                _connectCountdown = 200;        // Schedule a connection in 200ms
+                if (status & LowspeedDevice)
+                    port |= 0x80;
+                _connectHub = hub;
+                _connectPort = port;
+            }
+        }
+    }
+
+    #define HOST_CLK_EN        (1<<0)
+    #define PORTSEL_CLK_EN    (1<<3)
+    #define AHB_CLK_EN        (1<<4)
+    #define CLOCK_MASK        (HOST_CLK_EN | PORTSEL_CLK_EN | AHB_CLK_EN)
+
+    #define  FRAMEINTERVAL        (12000-1)    // 1ms
+    #define  DEFAULT_FMINTERVAL    ((((6 * (FRAMEINTERVAL - 210)) / 7) << 16) | FRAMEINTERVAL)
+
+    void DelayMS(int ms)
+    {
+        u16 f = ms + CommunicationArea.FrameNumber;
+        while (f != CommunicationArea.FrameNumber)
+            ;
+    }
+
+    static void HWInit(HCCA* cca)
+    {
+        NVIC_DisableIRQ(USB_IRQn);
+        
+        // turn on power for USB
+        LPC_SC->PCONP        |= (1UL<<31);
+        // Enable USB host clock, port selection and AHB clock
+        LPC_USB->USBClkCtrl |= CLOCK_MASK;
+        // Wait for clocks to become available
+        while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK)
+            ;
+        
+        //    We are a Host
+        LPC_USB->OTGStCtrl |= 1;
+        LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN;                // we don't need port selection clock until we do OTG
+        
+        // configure USB pins
+        LPC_PINCON->PINSEL1 &= ~((3<<26)|(3<<28));    
+        LPC_PINCON->PINSEL1 |=    ((1<<26)|(1<<28));            // USB D+/D-
+            
+        LPC_PINCON->PINSEL3 &= ~((3 << 6) | (3 << 22));        // USB_PPWR, USB_OVRCR
+        LPC_PINCON->PINSEL3 |= ((2 << 6) | (2 << 22));
+        
+        LPC_PINCON->PINSEL4 &= ~(3 << 18);                    // USB_CONNECT
+        LPC_PINCON->PINSEL4 |= (1 << 18);
+
+        //    Reset OHCI block
+        LPC_USB->HcControl         = 0;
+        LPC_USB->HcControlHeadED = 0;
+        LPC_USB->HcBulkHeadED     = 0;
+        
+        LPC_USB->HcCommandStatus = HostControllerReset;
+        LPC_USB->HcFmInterval     = DEFAULT_FMINTERVAL;
+        LPC_USB->HcPeriodicStart = FRAMEINTERVAL*90/100;
+
+        LPC_USB->HcControl    = (LPC_USB->HcControl & (~HostControllerFunctionalState)) | OperationalMask;
+        LPC_USB->HcRhStatus = SetGlobalPower;
+        
+        LPC_USB->HcHCCA = (u32)cca;
+        LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus;
+        LPC_USB->HcInterruptEnable = MasterInterruptEnable | WritebackDoneHead | RootHubStatusChange | FrameNumberOverflow;
+
+        NVIC_SetPriority(USB_IRQn, 0);
+        NVIC_EnableIRQ(USB_IRQn);
+        while (cca->FrameNumber < 10)
+            ;    // 10ms delay before diving in
+    }
+};
+
+//====================================================================================
+//====================================================================================
+//      Host controller instance and Interrupt handler
+
+static HostController _controller __attribute__((at(USB_RAM_BASE)));
+
+extern "C" void USB_IRQHandler(void) __irq;
+void USB_IRQHandler (void) __irq
+{
+    u32 int_status = LPC_USB->HcInterruptStatus;
+
+    if(int_status & UnrecoverableError) //Error
+    {
+      LOG("USB_IRQHandler UnrecoverableError Please reset\r\n");
+    }
+
+
+    if (int_status & RootHubStatusChange)    //    Root hub status change
+        _controller._rootHubStatusChange++;    //    Just flag the controller, will be processed in USBLoop
+
+    u32 head = 0;
+    if (int_status & WritebackDoneHead)
+    {
+        head = _controller.CommunicationArea.DoneHead;        // Writeback Done
+        _controller.CommunicationArea.DoneHead = 0;
+    }             
+    LPC_USB->HcInterruptStatus = int_status;
+
+    if (head)
+       _controller.ProcessDoneQueue(head);     // TODO - low bit can be set BUGBUG
+}
+
+//====================================================================================
+//====================================================================================
+//      API Methods
+
+void USBInit()
+{
+    return _controller.Init();
+}
+
+void USBLoop()
+{
+    
+    return _controller.Loop();
+    
+}
+
+u8* USBGetBuffer(u32* len)
+{
+    *len = USB_RAM_SIZE - sizeof(HostController);
+    return _controller.SRAM;
+}
+
+static Setup* GetSetup(int device)
+{
+    if (device == 0)
+        return &_controller._setupZero;
+    
+    if (device < 1 || device > MAX_DEVICES)
+        return 0;
+    return &_controller.Devices[device-1].SetupBuffer;
+}
+
+//    Loop until IO on endpoint is complete
+static int WaitIODone(Endpoint* endpoint)
+{
+    LOG("Waiting\n\r");
+    if (endpoint->CurrentState == Endpoint::NotQueued)
+        return 0;
+    while (endpoint->CurrentState != Endpoint::Idle)
+        //LOG("Loopz");
+        USBLoop();    // May generate callbacks, mount or unmount devices etc
+    int status = endpoint->Status();
+    if (status == 0)
+        return endpoint->Length;
+        LOG("DATA SENT\n\r");
+    return -status;
+}
+
+int USBTransfer(int device, int ep, u8 flags, u8* data, int length, USBCallback callback, void* userData)
+{
+    Endpoint* endpoint = _controller.GetEndpoint(device,ep);
+    if (!endpoint)
+        return ERR_ENDPOINT_NOT_FOUND;
+        
+    WaitIODone(endpoint);
+    LOG("before ep=%x,callback=%p\r\n",endpoint,endpoint->Callback);
+    endpoint->Flags = flags;
+    endpoint->Data = data;
+    endpoint->Length = length;
+    endpoint->Callback = callback;
+    endpoint->UserData = userData;
+    LOG("ep=%x,callback=%p\r\n",ep,callback);
+    if (ep == 0)
+        _controller.Transfer(endpoint,TOKEN_SETUP,(u8*)GetSetup(device),8,Endpoint::SetupQueued);
+    else
+        _controller.Transfer(endpoint,flags & 0x80 ? TOKEN_IN : TOKEN_OUT,data,length,Endpoint::DataQueued);
+    if (callback)
+        return IO_PENDING;
+    return WaitIODone(endpoint);
+}
+
+int USBControlTransfer(int device, int request_type, int request, int value, int index, u8* data, int length, USBCallback callback, void * userData)
+{
+    Setup* setup = GetSetup(device);
+    if (!setup)
+        return ERR_DEVICE_NOT_FOUND;
+        
+    // Async control calls may overwrite setup buffer of previous call, so we need to wait before setting up next call
+    WaitIODone(_controller.GetEndpoint(device,0));
+    
+    setup->bm_request_type = request_type;
+    setup->b_request = request;
+    setup->w_value = value;
+    setup->w_index = index;
+    setup->w_length = length;
+    return USBTransfer(device,0,request_type & DEVICE_TO_HOST,data,length,callback,userData);
+}
+
+int  USBInterruptTransfer(int device, int ep, u8* data, int length, USBCallback callback, void* userData)
+{
+    return USBTransfer(device,ep,(ep & 0x80) | ENDPOINT_INTERRUPT,data,length,callback,userData);
+}
+
+int  USBBulkTransfer(int device, int ep, u8* data, int length, USBCallback callback, void* userData)
+{
+    return USBTransfer(device,ep,(ep & 0x80) | ENDPOINT_BULK,data,length,callback,userData);
+}
+
+int GetDescriptor(int device, int descType,int descIndex, u8* data, int length)
+{
+    return USBControlTransfer(device,DEVICE_TO_HOST | RECIPIENT_DEVICE, GET_DESCRIPTOR,(descType << 8)|(descIndex), 0, data, length, 0);
+}
+
+int GetString(int device, int index, char* dst, int length)
+{
+    u8 buffer[255];
+    int le = GetDescriptor(device,DESCRIPTOR_TYPE_STRING,index,buffer,sizeof(buffer));
+    if (le < 0)
+        return le;
+    if (length < 1)
+        return -1;
+    length <<= 1;
+    if (le > length)
+        le = length;
+    for (int j = 2; j < le; j += 2)
+        *dst++ = buffer[j];
+    *dst = 0;
+    return (le>>1)-1;
+}
+
+int SetAddress(int device, int new_addr)
+{
+    return USBControlTransfer(device,HOST_TO_DEVICE | RECIPIENT_DEVICE, SET_ADDRESS, new_addr, 0, 0, 0, 0);
+}
+
+int SetConfiguration(int device, int configNum)
+{
+    return USBControlTransfer(device,HOST_TO_DEVICE | RECIPIENT_DEVICE, SET_CONFIGURATION, configNum, 0, 0, 0, 0);
+}
+
+int SetInterface(int device, int ifNum, int altNum)
+{
+    return USBControlTransfer(device,HOST_TO_DEVICE | RECIPIENT_INTERFACE, SET_INTERFACE, altNum, ifNum, 0, 0, 0);
+}
+
+//    HUB stuff
+int SetPortFeature(int device, int feature, int index)
+{
+    return USBControlTransfer(device,HOST_TO_DEVICE | REQUEST_TYPE_CLASS | RECIPIENT_OTHER,SET_FEATURE,feature,index,0,0);
+}
+
+int ClearPortFeature(int device, int feature, int index)
+{
+    return USBControlTransfer(device,HOST_TO_DEVICE | REQUEST_TYPE_CLASS | RECIPIENT_OTHER,CLEAR_FEATURE,feature,index,0,0);
+}
+
+int SetPortPower(int device, int port)
+{
+    int r = SetPortFeature(device,PORT_POWER,port);
+    _controller.DelayMS(20);    // 80ms to turn on a hubs power... DESCRIPTOR? todo
+    return r;
+}
+
+int SetPortReset(int device, int port)
+{
+    return SetPortFeature(device,PORT_RESET,port);
+}
+
+int GetPortStatus(int device, int port, u32* status)
+{
+    return USBControlTransfer(device,DEVICE_TO_HOST | REQUEST_TYPE_CLASS | RECIPIENT_OTHER,GET_STATUS,0,port,(u8*)status,4);
+}
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Android/AndroidAccessory/USBHost/USBHost.h	Sat Mar 23 13:52:48 2013 +0000
@@ -0,0 +1,221 @@
+
+/*
+Copyright (c) 2010 Peter Barrett
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+
+#ifndef USBHOST_H
+#define USBHOST_H
+
+//log mode on off
+//#define USBHOST_LOG
+
+
+#ifndef u8
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned long u32;
+
+typedef char s8;
+typedef short s16;
+typedef char s32;
+#endif
+
+#define ENDPOINT_CONTROL 0
+#define ENDPOINT_ISOCRONOUS 1
+#define ENDPOINT_BULK 2
+#define ENDPOINT_INTERRUPT 3
+
+#define  DESCRIPTOR_TYPE_DEVICE            1
+#define  DESCRIPTOR_TYPE_CONFIGURATION    2
+#define  DESCRIPTOR_TYPE_STRING            3
+#define  DESCRIPTOR_TYPE_INTERFACE        4
+#define  DESCRIPTOR_TYPE_ENDPOINT        5
+
+#define DESCRIPTOR_TYPE_HID         0x21
+#define DESCRIPTOR_TYPE_REPORT      0x22
+#define DESCRIPTOR_TYPE_PHYSICAL    0x23
+#define DESCRIPTOR_TYPE_HUB         0x29
+
+enum USB_CLASS_CODE
+{
+    CLASS_DEVICE,
+    CLASS_AUDIO,
+    CLASS_COMM_AND_CDC_CONTROL,
+    CLASS_HID,
+    CLASS_PHYSICAL = 0x05,
+    CLASS_STILL_IMAGING,
+    CLASS_PRINTER,
+    CLASS_MASS_STORAGE,
+    CLASS_HUB,
+    CLASS_CDC_DATA,
+    CLASS_SMART_CARD,
+    CLASS_CONTENT_SECURITY = 0x0D,
+    CLASS_VIDEO = 0x0E,
+    CLASS_DIAGNOSTIC_DEVICE = 0xDC,
+    CLASS_WIRELESS_CONTROLLER = 0xE0,
+    CLASS_MISCELLANEOUS = 0xEF,
+    CLASS_APP_SPECIFIC = 0xFE,
+    CLASS_VENDOR_SPECIFIC = 0xFF
+};
+
+#define  DEVICE_TO_HOST         0x80
+#define  HOST_TO_DEVICE         0x00
+#define  REQUEST_TYPE_STANDARD     0x00
+#define  REQUEST_TYPE_CLASS     0x20
+#define  REQUEST_TYPE_VENDOR     0x40
+#define  RECIPIENT_DEVICE       0x00
+#define  RECIPIENT_INTERFACE    0x01
+#define  RECIPIENT_ENDPOINT        0x02
+#define  RECIPIENT_OTHER        0x03
+
+#define  GET_STATUS                0
+#define  CLEAR_FEATURE            1
+#define  SET_FEATURE            3
+#define  SET_ADDRESS            5
+#define  GET_DESCRIPTOR            6
+#define  SET_DESCRIPTOR            7
+#define  GET_CONFIGURATION        8
+#define  SET_CONFIGURATION        9
+#define  GET_INTERFACE            10
+#define  SET_INTERFACE            11
+#define  SYNCH_FRAME            11
+
+/* HID Request Codes */ 
+#define HID_REQUEST_GET_REPORT          0x01 
+#define HID_REQUEST_GET_IDLE            0x02 
+#define HID_REQUEST_GET_PROTOCOL        0x03 
+#define HID_REQUEST_SET_REPORT          0x09 
+#define HID_REQUEST_SET_IDLE            0x0A 
+#define HID_REQUEST_SET_PROTOCOL        0x0B 
+ 
+/* HID Report Types */ 
+#define HID_REPORT_INPUT                0x01 
+#define HID_REPORT_OUTPUT               0x02 
+#define HID_REPORT_FEATURE              0x03 
+
+
+//        -5 is nak
+/*
+0010 ACK Handshake
+1010 NAK Handshake
+1110 STALL Handshake
+0110 NYET (No Response Yet)
+*/
+
+#define IO_PENDING -100
+#define ERR_ENDPOINT_NONE_LEFT -101
+#define ERR_ENDPOINT_NOT_FOUND -102
+#define ERR_DEVICE_NOT_FOUND -103
+#define ERR_DEVICE_NONE_LEFT -104
+#define ERR_HUB_INIT_FAILED -105
+#define ERR_INTERFACE_NOT_FOUND -106
+
+typedef struct
+{
+    u8    bLength;
+    u8    bDescriptorType;
+    u16 bcdUSB;
+    u8 bDeviceClass;
+    u8 bDeviceSubClass;
+    u8 bDeviceProtocol;
+    u8 bMaxPacketSize;
+    u16 idVendor;
+    u16 idProduct;
+    u16 bcdDevice;    // version
+    u8 iManufacturer;
+    u8 iProduct;
+    u8 iSerialNumber;
+    u8 bNumConfigurations;
+} DeviceDescriptor;    // 16 bytes
+
+typedef struct
+{
+    u8    bLength;
+    u8    bDescriptorType;
+    u16    wTotalLength;
+    u8    bNumInterfaces;
+    u8    bConfigurationValue;    // Value to use as an argument to select this configuration
+    u8    iConfiguration;            // Index of String Descriptor describing this configuration
+    u8    bmAttributes;            // Bitmap D7 Reserved, set to 1. (USB 1.0 Bus Powered),D6 Self Powered,D5 Remote Wakeup,D4..0 = 0
+    u8    bMaxPower;                // Maximum Power Consumption in 2mA units
+} ConfigurationDescriptor;
+
+typedef struct
+{
+    u8    bLength;
+    u8    bDescriptorType;
+    u8  bInterfaceNumber;
+    u8    bAlternateSetting;
+    u8    bNumEndpoints;
+    u8    bInterfaceClass;
+    u8    bInterfaceSubClass;
+    u8    bInterfaceProtocol;
+    u8    iInterface;                // Index of String Descriptor Describing this interface
+} InterfaceDescriptor;
+
+typedef struct
+{
+    u8    bLength;
+    u8    bDescriptorType;
+    u8    bEndpointAddress;    // Bits 0:3 endpoint, Bits 7 Direction 0 = Out, 1 = In (Ignored for Control Endpoints)
+    u8    bmAttributes;        // Bits 0:1 00 = Control, 01 = Isochronous, 10 = Bulk, 11 = Interrupt
+    u16 wMaxPacketSize;
+    u8    bInterval;            // Interval for polling endpoint data transfers.
+} EndpointDescriptor;
+
+typedef struct {
+  u8    bLength;
+  u8    bDescriptorType;
+  u16   bcdHID;
+  u8    bCountryCode;
+  u8    bNumDescriptors;
+  u8    bDescriptorType2;
+  u16   wDescriptorLength;
+} HIDDescriptor;
+
+//============================================================================
+//============================================================================
+
+
+void USBInit();
+void USBLoop();
+u8* USBGetBuffer(u32* len);
+
+//    Optional callback for transfers, called at interrupt time
+typedef void (*USBCallback)(int device, int endpoint, int status, u8* data, int len, void* userData);
+
+//    Transfers
+int USBControlTransfer(int device, int request_type, int request, int value, int index, u8* data, int length, USBCallback callback = 0, void* userData = 0);
+int USBInterruptTransfer(int device, int ep, u8* data, int length, USBCallback callback = 0, void* userData = 0);
+int USBBulkTransfer(int device, int ep, u8* data, int length, USBCallback callback = 0, void* userData = 0);
+
+//    Standard Device methods
+int GetDescriptor(int device, int descType, int descIndex, u8* data, int length);
+int GetString(int device, int index, char* dst, int length);
+int SetAddress(int device, int new_addr);
+int SetConfiguration(int device, int configNum);
+int SetInterface(int device, int ifNum, int altNum);
+
+//    Implemented to notify app of the arrival of a device
+void OnLoadDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc);
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Android/AndroidAccessory/USBHost/USBHost_log.cpp	Sat Mar 23 13:52:48 2013 +0000
@@ -0,0 +1,1175 @@
+
+/*
+Copyright (c) 2010 Peter Barrett
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+
+#include "mbed.h"
+#include "USBHost.h"
+//#define USBHOST_LOG
+#ifdef  USBHOST_LOG
+
+//    Config (default uses x bytes)
+#define MAX_DEVICES 8                // Max number of devices
+#define MAX_ENDPOINTS_TOTAL 16        // Max number of endpoints total
+#define MAX_ENDPOINTS_PER_DEVICE 8    // Max number of endpoints for any one device
+
+//#define  USBLOG 1
+#if USBLOG
+#define  LOG(...)       printf(__VA_ARGS__)
+#else 
+#define  LOG(...)       do {} while(0)
+#endif
+
+// USB host structures
+
+#define USB_RAM_SIZE 16*1024    // AHB SRAM block 1 TODO MACHINE DEPENDENT
+#define USB_RAM_BASE 0x2007C000
+
+#define TOKEN_SETUP 0
+#define TOKEN_IN  1
+#define TOKEN_OUT 2
+
+//    Status flags from hub
+#define PORT_CONNECTION 0
+#define PORT_ENABLE  1
+#define PORT_SUSPEND  2
+#define PORT_OVER_CURRENT 3
+#define PORT_RESET 4
+#define PORT_POWER 8
+#define PORT_LOW_SPEED 9
+
+#define C_PORT_CONNECTION 16
+#define C_PORT_ENABLE 17
+#define C_PORT_SUSPEND 18
+#define C_PORT_OVER_CURRENT 19
+#define C_PORT_RESET 20
+
+typedef struct {
+    u8 bm_request_type;
+    u8 b_request;
+    u16 w_value;
+    u16 w_index;
+    u16 w_length;
+} Setup;
+
+
+//    Hub stuff is kept private just to keep api simple
+int SetPortFeature(int device, int feature, int index);
+int ClearPortFeature(int device, int feature, int index);
+int SetPortPower(int device, int port);
+int SetPortReset(int device, int port);
+int GetPortStatus(int device, int port, u32* status);
+
+//===================================================================
+//===================================================================
+//    Hardware defines
+
+//    HcControl
+#define PeriodicListEnable    0x00000004
+#define    IsochronousEnable    0x00000008
+#define    ControlListEnable    0x00000010
+#define    BulkListEnable        0x00000020
+#define    OperationalMask        0x00000080
+#define    HostControllerFunctionalState    0x000000C0
+
+//    HcCommandStatus
+#define HostControllerReset    0x00000001
+#define ControlListFilled    0x00000002
+#define BulkListFilled        0x00000004
+
+//    HcInterruptStatus Register
+#define    WritebackDoneHead        0x00000002
+#define    StartofFrame            0x00000004
+#define ResumeDetected            0x00000008
+#define UnrecoverableError        0x00000010
+#define FrameNumberOverflow        0x00000020
+#define RootHubStatusChange        0x00000040
+#define OwnershipChange            0x00000080
+#define MasterInterruptEnable    0x80000000
+
+//    HcRhStatus
+#define SetGlobalPower            0x00010000
+#define DeviceRemoteWakeupEnable    0x00008000
+
+//    HcRhPortStatus (hub 0, port 1)
+#define CurrentConnectStatus    0x00000001
+#define    PortEnableStatus        0x00000002
+#define PortSuspendStatus        0x00000004
+#define PortOverCurrentIndicator    0x00000008
+#define PortResetStatus            0x00000010
+
+#define PortPowerStatus            0x00000100
+#define LowspeedDevice            0x00000200
+#define HighspeedDevice            0x00000400
+
+#define ConnectStatusChange    (CurrentConnectStatus << 16)
+#define PortResetStatusChange    (PortResetStatus << 16)
+
+
+#define  TD_ROUNDING        (u32)0x00040000
+#define  TD_SETUP            (u32)0x00000000
+#define  TD_IN                (u32)0x00100000
+#define  TD_OUT                (u32)0x00080000
+#define  TD_DELAY_INT(x)    (u32)((x) << 21)
+#define  TD_TOGGLE_0        (u32)0x02000000
+#define  TD_TOGGLE_1        (u32)0x03000000
+#define  TD_CC                (u32)0xF0000000
+
+//    HostController EndPoint Descriptor
+typedef struct {
+    volatile u32    Control;
+    volatile u32    TailTd;
+    volatile u32    HeadTd;
+    volatile u32    Next;
+} HCED;
+
+// HostController Transfer Descriptor
+typedef struct {
+    volatile u32    Control;
+    volatile u32    CurrBufPtr;
+    volatile u32    Next;
+    volatile u32    BufEnd;
+} HCTD;
+
+// Host Controller Communication Area
+typedef struct {
+    volatile u32    InterruptTable[32];
+    volatile u16    FrameNumber;
+    volatile u16    FrameNumberPad;
+    volatile u32    DoneHead;
+    volatile u8        Reserved[120];
+} HCCA;
+
+//====================================================================================
+//====================================================================================
+
+class HostController;
+class Endpoint;
+class Device;
+
+//      must be 3*16 bytes long
+class Endpoint
+{
+public:
+    HCED    EndpointDescriptor;    // Pointer to EndpointDescriptor == Pointer to Endpoint
+    HCTD    TDHead;
+
+    enum State
+    {
+        Free,
+        NotQueued,
+        Idle,
+        SetupQueued,
+        DataQueued,
+        StatusQueued,
+        CallbackPending
+    };
+    
+    volatile u8 CurrentState;
+    u8        Flags;            // 0x80 In, 0x03 mask endpoint type
+
+    u16        Length;
+    u8*        Data;
+    USBCallback Callback;     // Must be a multiple of 16 bytes long
+    void*  UserData;
+  
+    int Address()
+    {
+        int ep = (EndpointDescriptor.Control >> 7) & 0xF;
+        if (ep)
+            ep |= Flags & 0x80;
+        return ep;
+    }
+    
+    int Device()
+    {
+        return EndpointDescriptor.Control & 0x7F;
+    }
+
+    int Status()
+    {
+        return (TDHead.Control >> 28) & 0xF;
+    }
+
+    u32 Enqueue(u32 head)
+    {
+        if (CurrentState == NotQueued)
+        {
+            EndpointDescriptor.Next = head;
+            head = (u32)&EndpointDescriptor;
+            CurrentState = Idle;
+        }
+        return head;
+    }
+};
+
+class Device
+{
+public:
+    u8    _endpointMap[MAX_ENDPOINTS_PER_DEVICE*2];
+    u8    Hub;
+    u8    Port;
+    u8    Addr;
+    u8    Pad;
+
+    //    Only if this device is a hub
+    u8    HubPortCount;    // nonzero if this is a hub
+    u8    HubInterruptData;
+    u8    HubMap;
+    u8    HubMask;
+
+    int Flags;        // 1 = Disconnected
+
+    Setup    SetupBuffer;
+
+    // Allocate endpoint zero
+    int Init(DeviceDescriptor* d, int hub, int port, int addr, int lowSpeed)
+    {
+        Hub = hub;
+        Port = port;
+        Addr = addr;
+        Flags = lowSpeed;
+        memset(_endpointMap,0xFF,sizeof(_endpointMap));
+        return 0;
+    }
+
+    int SetEndpointIndex(int ep, int endpointIndex)
+    {
+        for (int i = 0; i < MAX_ENDPOINTS_PER_DEVICE*2; i += 2)
+        {
+            if (_endpointMap[i] == 0xFF)    // Add endpoint to map
+            {
+                _endpointMap[i] = ep;
+                _endpointMap[i+1] = endpointIndex;
+                return 0;
+            }
+        }
+        return ERR_ENDPOINT_NONE_LEFT;
+    }
+
+    int GetEndpointIndex(int ep)
+    {
+        for (int i = 0; i < MAX_ENDPOINTS_PER_DEVICE*2; i += 2)
+        {
+            if (_endpointMap[i] == ep)
+                return _endpointMap[i+1];
+            if (_endpointMap[i] == 0xFF)
+                break;
+        }
+        return -1;
+    }
+};
+
+class HostController
+{
+public:
+    HCCA        CommunicationArea;
+    Endpoint    Endpoints[MAX_ENDPOINTS_TOTAL];    // Multiple of 16
+    
+    Endpoint    EndpointZero;                        // For device enumeration
+    HCTD        _commonTail;
+    Setup        _setupZero;
+    
+    Device    Devices[MAX_DEVICES];
+    u32    _frameNumber;            // 32 bit ms counter
+
+    u8    _callbacksPending;        //    Endpoints with callbacks are pending, set from ISR via ProcessDoneQueue
+    u8    _rootHubStatusChange;    //    Root hub status has changed, set from ISR
+    u8    _unused0;
+    u8    _unused1;
+
+    u8    _connectPending;    //    Reset has initiated a connect
+    u8    _connectCountdown;    //    Number of ms left after reset before we can connect
+    u8    _connectHub;        //    Will connect on this hub
+    u8    _connectPort;        //    ... and this port
+
+    u8    SRAM[0];            // Start of free SRAM
+
+    void Loop()
+    {
+   // printf("Enter Loop \r\n");
+        u16 elapsed = CommunicationArea.FrameNumber - (u16)_frameNumber;    // extend to 32 bits
+        _frameNumber += elapsed;
+
+        // Do callbacks, if any
+        while (_callbacksPending)
+        {
+            for (int i = 0; i < MAX_ENDPOINTS_TOTAL; i++)
+            {
+                Endpoint* endpoint = Endpoints + i;
+                if (endpoint->CurrentState == Endpoint::CallbackPending)
+                {
+                    _callbacksPending--;
+                    endpoint->CurrentState = Endpoint::Idle;
+                    LOG("CurrentState Change  Idle  endpoint(%d) currentState =%d\r\n",endpoint->Address(),endpoint->CurrentState);
+                    endpoint->Callback(endpoint->Device(),endpoint->Address(),endpoint->Status(),endpoint->Data,endpoint->Length,endpoint->UserData);
+                }
+            }
+        }
+
+        //    Deal with changes on the root hub
+        if (_rootHubStatusChange)
+        {
+            u32 status = LPC_USB->HcRhPortStatus1;
+            _rootHubStatusChange = 0;
+            if (status >> 16)
+            {
+                HubStatusChange(0,1,status);
+                LPC_USB->HcRhPortStatus1 = status & 0xFFFF0000;    // clear status changes
+            }
+        }
+
+        //    Connect after reset timeout
+        if (_connectCountdown)
+        {
+            if (elapsed >= _connectCountdown)
+            {
+                _connectCountdown = 0;
+                Connect(_connectHub,_connectPort & 0x7F,_connectPort & 0x80);
+            } else
+                _connectCountdown -= elapsed;
+        }
+    
+   // printf("Outer Loop \r\n");
+    }
+
+    //    HubInterrupt - bitmap in dev->HubInterruptData
+    void HubInterrupt(int device)
+    {
+        Device* dev = &Devices[device-1];
+        for (int i = 0; i < dev->HubPortCount; i++)
+        {
+            int port = i+1;
+            if (dev->HubInterruptData & (1 << port))
+            {
+                u32 status = 0;
+                GetPortStatus(device,port,&status);
+                if (status >> 16)
+                {
+                    if (_connectPending && (status & ConnectStatusChange))
+                        continue;    // Don't connect again until previous device has been added and addressed
+
+                    HubStatusChange(device,port,status);
+                    if (status & ConnectStatusChange)
+                        ClearPortFeature(device,C_PORT_CONNECTION,port);
+                    if (status & PortResetStatusChange)
+                        ClearPortFeature(device,C_PORT_RESET,port);
+                }
+            }
+        }
+    }
+
+    static void HubInterruptCallback(int device, int endpoint, int status, u8* data, int len, void* userData)
+    {
+        HostController* controller = (HostController*)userData;
+        if (status == 0)
+            controller->HubInterrupt(device);
+        USBInterruptTransfer(device,endpoint,data,1,HubInterruptCallback,userData);
+    }
+
+    int InitHub(int device)
+    {
+        u8 buf[16];
+        int r= USBControlTransfer(device,DEVICE_TO_HOST | REQUEST_TYPE_CLASS | RECIPIENT_DEVICE,GET_DESCRIPTOR,(DESCRIPTOR_TYPE_HUB << 8),0,buf,sizeof(buf));
+        if (r < 0)
+            return ERR_HUB_INIT_FAILED;
+        
+        //    turn on power on the hubs ports
+        Device* dev = &Devices[device-1];
+        int ports = buf[2];
+        dev->HubPortCount = ports;
+        for (int i = 0; i < ports; i++)
+            SetPortPower(device,i+1);
+        
+        // Enable hub change interrupts
+        return USBInterruptTransfer(device,0x81,&dev->HubInterruptData,1,HubInterruptCallback,this);
+    }
+    
+    int AddEndpoint(int device, int ep, int attributes, int maxPacketSize, int interval)
+    {
+        LOG("AddEndpoint D:%02X A:%02X T:%02X P:%04X I:%02X\r\n",device,ep,attributes,maxPacketSize,interval);
+        Device* dev = &Devices[device-1];
+        Endpoint* endpoint = AllocateEndpoint(device,ep,attributes,maxPacketSize);
+        if (!endpoint)
+            return ERR_ENDPOINT_NONE_LEFT;
+        dev->SetEndpointIndex(ep,endpoint - Endpoints);
+        endpoint->EndpointDescriptor.Control |= dev->Flags; // Map in slow speed
+        return 0;  // TODO ed->bInterval
+    }
+    
+    int AddEndpoint(int device, EndpointDescriptor* ed)
+    {
+        return AddEndpoint(device,ed->bEndpointAddress,ed->bmAttributes,ed->wMaxPacketSize,ed->bInterval);
+    }
+
+    //      allocate a endpoint
+    Endpoint* AllocateEndpoint(int device, int endpointAddress, int type, int maxPacketSize)
+    {
+        for (int i = 0; i < MAX_ENDPOINTS_TOTAL; i++)
+        {
+            Endpoint* ep = &Endpoints[i];
+            if (ep->CurrentState == 0)
+            {
+                //LOG("Allocated endpoint %d to %02X:%02X\r\n",i,device,endpointAddress);
+                ep->Flags = (endpointAddress & 0x80) | (type & 3);
+                ep->CurrentState = Endpoint::NotQueued;
+                ep->EndpointDescriptor.Control = (maxPacketSize << 16) | ((endpointAddress & 0x7F) << 7) | device;
+                return ep;
+            }
+        }
+        return 0;
+    }
+
+    Endpoint* GetEndpoint(int device, int ep)
+    {
+        if (device == 0)
+        {
+            //printf("WARNING: USING DEVICE 0\n");
+            return &EndpointZero;
+        }
+        if (device > MAX_DEVICES)
+            return 0;
+        int i = Devices[device-1].GetEndpointIndex(ep);
+        if (i == -1)
+            return 0;
+        return Endpoints + i;
+    }
+
+    int Transfer(Endpoint* endpoint, int token, u8* data, int len, int state)
+    {
+        //Makoto edit comment out 
+       // LOG("Transfer start\r\n");
+        LOG("Transfer ep=%02X Token:%d Len:%d State:%d\r\n",endpoint->Address(),token,len,state);
+    
+        int toggle = 0;
+        if (endpoint->Address() == 0)
+            toggle = (token == TOKEN_SETUP) ? TD_TOGGLE_0 : TD_TOGGLE_1;
+
+        if (token != TOKEN_SETUP)
+            token = (token == TOKEN_IN ? TD_IN : TD_OUT);
+
+        HCTD* head = &endpoint->TDHead;
+        HCTD* tail = &_commonTail;
+
+        head->Control = TD_ROUNDING | token | TD_DELAY_INT(0) | toggle | TD_CC; 
+        head->CurrBufPtr = (u32)data;
+        head->BufEnd = (u32)(data + len - 1);
+        head->Next = (u32)tail;
+
+        HCED* ed = &endpoint->EndpointDescriptor;
+        ed->HeadTd = (u32)head | (ed->HeadTd & 0x00000002);    // carry toggle
+        ed->TailTd = (u32)tail;
+        
+        //HCTD* td = head;
+        //LOG("%04X TD %08X %08X %08X Next:%08X\r\n",CommunicationArea.FrameNumber,td->Control,td->CurrBufPtr,td->BufEnd,td->Next);
+        //LOG("%04X ED %08X %08X %08X\r\n",CommunicationArea.FrameNumber,ed->Control,ed->HeadTd,ed->TailTd);
+        
+        //LOG("Transfer run01\r\n");
+        switch (endpoint->Flags & 3)
+        {
+            case ENDPOINT_CONTROL:
+                LOG("Transfer run ENDPOINT_CONTROL\r\n");
+                LPC_USB->HcControlHeadED = endpoint->Enqueue(LPC_USB->HcControlHeadED);    // May change state NotQueued->Idle
+                //LOG("Transfer run02\r\n");
+                LOG("endpoint->CurrentState change %d->%d\r\n",endpoint->CurrentState,state);
+                endpoint->CurrentState = state;                                               // Get in before an int
+                LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | ControlListFilled;
+                LPC_USB->HcControl = LPC_USB->HcControl | ControlListEnable;
+                
+                break;
+
+            case ENDPOINT_BULK:
+                LOG("Transfer run ENDPOINT_BULK\r\n");
+                LPC_USB->HcBulkHeadED = endpoint->Enqueue(LPC_USB->HcBulkHeadED);
+                LOG("endpoint->CurrentState change %d->%d\r\n",endpoint->CurrentState,state);
+                endpoint->CurrentState = state;
+                LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | BulkListFilled;
+                LPC_USB->HcControl = LPC_USB->HcControl | BulkListEnable;
+                break;
+
+            case ENDPOINT_INTERRUPT:
+                LOG("Transfer run ENDPOINT_INTERRUPT\r\n");
+                CommunicationArea.InterruptTable[0] = endpoint->Enqueue(CommunicationArea.InterruptTable[0]);
+                LOG("endpoint->CurrentState change %d->%d\r\n",endpoint->CurrentState,state);
+                endpoint->CurrentState = state;
+                LPC_USB->HcControl |= PeriodicListEnable;
+                break;
+        }
+        
+        LOG("Transfer end\r\n");
+        return 0;
+    }
+    
+    //    Remove an endpoint from an active queue
+    bool Remove(HCED* ed, volatile HCED** queue)
+    {
+        if (*queue == 0)
+            return false;
+        if (*queue == (volatile HCED*)ed)
+        {
+            *queue = (volatile HCED*)ed->Next;    // At head of queue
+            return true;
+        }
+
+        volatile HCED* head = *queue;
+        while (head)
+        {
+            if (head->Next == (u32)ed)
+            {
+                head->Next = ed->Next;
+                return true;
+            }
+            head = (volatile HCED*)head->Next;
+        }
+        return false;
+    }
+
+    void Release(Endpoint* endpoint)
+    {
+        if (endpoint->CurrentState == Endpoint::NotQueued)
+        {
+            // Never event used it, nothing to do
+        }
+        else
+        {
+            HCED* ed = (HCED*)endpoint;
+            ed->Control |= 0x4000;    // SKIP
+            switch (endpoint->Flags & 0x03)
+            {
+                case ENDPOINT_CONTROL:
+                    Remove(ed,(volatile HCED**)&LPC_USB->HcControlHeadED);
+                    break;
+                case ENDPOINT_BULK:
+                    Remove(ed,(volatile HCED**)&LPC_USB->HcBulkHeadED);
+                    break;
+                case ENDPOINT_INTERRUPT:
+                    for (int i = 0; i < 32; i++)
+                        Remove(ed,(volatile HCED**)&CommunicationArea.InterruptTable[i]);
+                    break;
+            }
+
+            u16 fn = CommunicationArea.FrameNumber;
+            while (fn == CommunicationArea.FrameNumber)
+                ;    // Wait for next frame
+
+        }
+
+        //    In theory, the endpoint is now dead.
+        //    TODO: Will Callbacks ever be pending? BUGBUG
+        memset(endpoint,0,sizeof(Endpoint));
+    }
+
+    //      Pop the last TD from the list
+    HCTD* Reverse(HCTD* current) 
+    { 
+        HCTD *result = NULL,*temp; 
+        while (current) 
+        { 
+            temp = (HCTD*)current->Next; 
+            current->Next = (u32)result;
+            result = current;
+            current = temp;
+        }
+        return result;
+    }
+
+    //      Called from interrupt...
+    //      Control endpoints use a state machine to progress through the transfers
+    void ProcessDoneQueue(u32 tdList)
+    {
+    
+    LOG("<<ProcessDoneQueue enter>>\r\n");
+        HCTD* list = Reverse((HCTD*)tdList);
+        while (list)
+        {
+            Endpoint* endpoint = (Endpoint*)(list-1);
+            list = (HCTD*)list->Next;
+            int ep = endpoint->Address();
+            bool in = endpoint->Flags & 0x80;
+            int status = (endpoint->TDHead.Control >> 28) & 0xF;
+
+            //LOG("ProcessDoneQueue %02X %08X\r\n",ep,endpoint->TDHead.Control);
+
+            if (status != 0)
+            {
+                LOG("ProcessDoneQueue status %02X %d\r\n",ep,status);
+                LOG("CurrentState Change  Idle endpoint(%d) currentState =%d\r\n",endpoint->Address(),endpoint->CurrentState);
+                endpoint->CurrentState = Endpoint::Idle;
+                
+                
+            } else {
+                switch (endpoint->CurrentState)
+                {
+                    case Endpoint::SetupQueued:
+                        if (endpoint->Length == 0)
+                        {
+                            LOG("ProcessDoneQueue endpoint->Length == 0 endpoint->CurrentState=%d\r\n",endpoint->CurrentState);
+                            Transfer(endpoint,in ? TOKEN_OUT : TOKEN_IN,0,0,Endpoint::StatusQueued);    // Skip Data Phase
+                        }
+                        else
+                        {
+                            LOG("ProcessDoneQueue endpoint->Length != 0 endpoint->CurrentState=%d\r\n",endpoint->CurrentState);
+                            Transfer(endpoint,in ? TOKEN_IN : TOKEN_OUT,endpoint->Data,endpoint->Length, Endpoint::DataQueued);    // Setup is done, now Data
+                        }
+                        break;
+
+                    case Endpoint::DataQueued:
+                        if (endpoint->TDHead.CurrBufPtr)
+                            endpoint->Length = endpoint->TDHead.CurrBufPtr - (u32)endpoint->Data;
+
+                        if (ep == 0)
+                        {
+                            LOG("ProcessDoneQueue ep == 0 endpoint->CurrentState=%d\r\n",endpoint->CurrentState);
+                            Transfer(endpoint,in ? TOKEN_OUT : TOKEN_IN,0,0,Endpoint::StatusQueued);    // Data is done, now Status, Control only
+                        }
+                        else
+                        {
+                        
+                            LOG("ProcessDoneQueue ep != 0 endpoint->CurrentState=%d\r\n",endpoint->CurrentState);
+                            endpoint->CurrentState = Endpoint::Idle;
+                            LOG("CurrentState Change  Idle endpoint(%d) currentState =%d\r\n",endpoint->Address(),endpoint->CurrentState);
+                        }
+                        break;
+
+                    case Endpoint::StatusQueued:    // Transaction is done
+                        LOG("CurrentState Change  Idle endpoint(%d) currentState =%d\r\n",endpoint->Address(),endpoint->CurrentState);
+                        endpoint->CurrentState = Endpoint::Idle;
+                        break;
+                }
+            }
+
+            //      Complete, flag if we need a callback
+            if (endpoint->Callback && endpoint->CurrentState == Endpoint::Idle)
+            {
+                endpoint->CurrentState = Endpoint::CallbackPending;
+                _callbacksPending++;
+            }
+        }
+        LOG("<<ProcessDoneQueue out>>\r\n");
+    }
+
+    //    Hack to reset devices that don't want to connect
+    int AddDevice(int hub, int port, bool isLowSpeed)
+    {
+        int device = AddDeviceCore(hub,port,isLowSpeed);
+        if (device < 0)
+        {
+            LOG("========RETRY ADD DEVICE========\r\n");    // This will go for ever.. TODO power cycle root?
+            Disconnect(hub,port);    // Could not read descriptor at assigned address, reset this port and try again
+            ResetPort(hub,port);    // Cheap bluetooth dongles often need this on a hotplug
+            return -1;
+        }
+        return device;
+    }
+
+    int AddDeviceCore(int hub, int port, bool isLowSpeed)
+    {
+        int lowSpeed = isLowSpeed ? 0x2000 : 0;
+        DeviceDescriptor desc;
+        EndpointZero.EndpointDescriptor.Control = (8 << 16) | lowSpeed;               // MaxPacketSize == 8
+        int r = GetDescriptor(0,DESCRIPTOR_TYPE_DEVICE,0,(u8*)&desc,8);
+        if (r < 0)
+        {
+            LOG("FAILED TO LOAD DESCRIPTOR FOR DEVICE 0\r\n");
+            return r;
+        }
+
+        EndpointZero.EndpointDescriptor.Control = (desc.bMaxPacketSize << 16) | lowSpeed;     // Actual MaxPacketSize
+        r = GetDescriptor(0,DESCRIPTOR_TYPE_DEVICE,0,(u8*)&desc,sizeof(desc));
+        if (r < 0)
+            return r;
+
+        LOG("\nClass %02X found %04X:%04X\r\n",desc.bDeviceClass,desc.idVendor,desc.idProduct);
+
+        //      Now assign the device an address, move off EndpointZero
+        int device = 0;
+        for (int i = 0; i < MAX_DEVICES; i++)
+        {
+            if (Devices[i].Port == 0)
+            {
+                device = i+1;
+                break;
+            }
+        }
+        if (!device)
+            return ERR_DEVICE_NONE_LEFT;
+
+        r = SetAddress(0,device);
+        if (r)
+            return r;
+        DelayMS(2);
+        
+        // Now at a nonzero address, create control endpoint
+        Device* dev = &Devices[device-1];
+        dev->Init(&desc,hub,port,device,lowSpeed);
+        AddEndpoint(device,0,ENDPOINT_CONTROL,desc.bMaxPacketSize,0);
+        _connectPending = 0;
+
+        //    Verify this all works
+        r = GetDescriptor(device,DESCRIPTOR_TYPE_DEVICE,0,(u8*)&desc,sizeof(desc));
+        if (r < 0)
+            return r;
+
+        //    Set to interface 0 by default
+        //    Calls LoadDevice if interface is found
+        r = SetConfigurationAndInterface(device,1,0,&desc);
+
+        if (desc.bDeviceClass == CLASS_HUB)
+            InitHub(device);            // Handle hubs in this code
+
+        return device;
+    }
+
+    // Walk descriptors and create endpoints for a given device
+    // TODO configuration !=1, alternate settings etc.
+    int SetConfigurationAndInterface(int device, int configuration, int interfaceNumber, DeviceDescriptor* desc)
+    {
+        u8 buffer[255];
+        int err = GetDescriptor(device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,sizeof(buffer));
+        if (err < 0)
+            return err;
+
+        err = SetConfiguration(device,configuration);
+        if (err < 0)
+            return err;
+
+        //    Add the endpoints for this interface
+        int len = buffer[2] | (buffer[3] << 8);
+        u8* d = buffer;
+        u8* end = d + len;
+        InterfaceDescriptor* found = 0;
+        while (d < end)
+        {
+            if (d[1] == DESCRIPTOR_TYPE_INTERFACE)
+            {
+                InterfaceDescriptor* id = (InterfaceDescriptor*)d;
+                if (id->bInterfaceNumber == interfaceNumber)
+                {
+                    found = id;
+                    d += d[0];
+                    while (d < end && d[1] != DESCRIPTOR_TYPE_INTERFACE)
+                    {
+                        switch (d[1])
+                        {
+                            case DESCRIPTOR_TYPE_ENDPOINT:
+                                AddEndpoint(device,(EndpointDescriptor*)d);
+                                break;
+                            default:
+                                LOG("Skipping descriptor %02X (%d bytes)\r\n",d[1],d[0]);
+                        }
+                        d += d[0];
+                    }
+                }
+            }
+            d += d[0];
+        }
+
+        if (!found)
+            return ERR_INTERFACE_NOT_FOUND;
+        OnLoadDevice(device,desc,found);
+        return 0;
+    }
+
+    void Init()
+    {
+        LOG("USB INIT (Controller is %d bytes)\r\n",sizeof(*this));
+        memset(this,0,sizeof(HostController));
+        EndpointZero.CurrentState = Endpoint::NotQueued;
+        HWInit(&CommunicationArea);
+        DelayMS(10);
+    }
+
+    void ResetPort(int hub, int port)
+    {
+        LOG("ResetPort Hub:%d Port:%d\r\n",hub,port);
+        _connectPending++;            // Only reset/add 1 device at a time
+        if (hub == 0)
+            LPC_USB->HcRhPortStatus1 = PortResetStatus;    // Reset Root Hub, port 1
+        else
+            SetPortReset(hub,port);    // or reset other hub
+    }
+
+    void Disconnect(int hub, int port)
+    {
+        LOG("Disconnect Hub:%d Port:%d\r\n",hub,port);    // Mark a device for destruction
+        for (int i = 0; i < MAX_DEVICES; i++)
+        {
+            Device* dev = Devices + i;
+            if (dev->Port == port && dev->Hub == hub)
+            {
+                //    Disconnect everything that is attached to this device if it is a hub
+                for (int p = 0; p < dev->HubPortCount; p++)
+                    Disconnect(i+1,p+1);
+
+                //    Now release endpoints
+                for (int j = 1; j < MAX_ENDPOINTS_PER_DEVICE*2; j += 2)
+                {
+                    u8 endpointIndex = dev->_endpointMap[j];
+                    if (endpointIndex != 0xFF)
+                        Release(Endpoints + endpointIndex);
+                }
+                dev->Port = 0;    // Device is now free
+                dev->Flags = 0;
+                return;
+            }
+        }
+    }
+
+    // called after reset
+    void Connect(int hub, int port, bool lowspeed)
+    {
+        LOG("Connect Hub:%d Port:%d %s\r\n",hub,port,lowspeed ? "slow" : "full");
+        AddDevice(hub,port,lowspeed);
+    }
+
+    // Called from interrupt
+    void HubStatusChange(int hub, int port, u32 status)
+    {
+        LOG("HubStatusChange Hub:%d Port:%d %08X\r\n",hub,port,status);
+        if (status & ConnectStatusChange)
+        {
+            if (status & CurrentConnectStatus)    // Connecting
+                ResetPort(hub,port);            // Reset to initiate connect (state machine?)
+            else
+                Disconnect(hub,port);
+        }
+
+        if (status & PortResetStatusChange)
+        {
+            if (!(status & PortResetStatus))
+            {
+                _connectCountdown = 200;        // Schedule a connection in 200ms
+                if (status & LowspeedDevice)
+                    port |= 0x80;
+                _connectHub = hub;
+                _connectPort = port;
+            }
+        }
+    }
+
+    #define HOST_CLK_EN        (1<<0)
+    #define PORTSEL_CLK_EN    (1<<3)
+    #define AHB_CLK_EN        (1<<4)
+    #define CLOCK_MASK        (HOST_CLK_EN | PORTSEL_CLK_EN | AHB_CLK_EN)
+
+    #define  FRAMEINTERVAL        (12000-1)    // 1ms
+    #define  DEFAULT_FMINTERVAL    ((((6 * (FRAMEINTERVAL - 210)) / 7) << 16) | FRAMEINTERVAL)
+
+    void DelayMS(int ms)
+    {
+        u16 f = ms + CommunicationArea.FrameNumber;
+        while (f != CommunicationArea.FrameNumber)
+            ;
+    }
+
+    static void HWInit(HCCA* cca)
+    {
+        NVIC_DisableIRQ(USB_IRQn);
+        
+        // turn on power for USB
+        LPC_SC->PCONP        |= (1UL<<31);
+        // Enable USB host clock, port selection and AHB clock
+        LPC_USB->USBClkCtrl |= CLOCK_MASK;
+        // Wait for clocks to become available
+        while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK)
+            ;
+        
+        //    We are a Host
+        LPC_USB->OTGStCtrl |= 1;
+        LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN;                // we don't need port selection clock until we do OTG
+        
+        // configure USB pins
+        LPC_PINCON->PINSEL1 &= ~((3<<26)|(3<<28));    
+        LPC_PINCON->PINSEL1 |=    ((1<<26)|(1<<28));            // USB D+/D-
+            
+        LPC_PINCON->PINSEL3 &= ~((3 << 6) | (3 << 22));        // USB_PPWR, USB_OVRCR
+        LPC_PINCON->PINSEL3 |= ((2 << 6) | (2 << 22));
+        
+        LPC_PINCON->PINSEL4 &= ~(3 << 18);                    // USB_CONNECT
+        LPC_PINCON->PINSEL4 |= (1 << 18);
+
+        //    Reset OHCI block
+        LPC_USB->HcControl         = 0;
+        LPC_USB->HcControlHeadED = 0;
+        LPC_USB->HcBulkHeadED     = 0;
+        
+        LPC_USB->HcCommandStatus = HostControllerReset;
+        LPC_USB->HcFmInterval     = DEFAULT_FMINTERVAL;
+        LPC_USB->HcPeriodicStart = FRAMEINTERVAL*90/100;
+
+        LPC_USB->HcControl    = (LPC_USB->HcControl & (~HostControllerFunctionalState)) | OperationalMask;
+        LPC_USB->HcRhStatus = SetGlobalPower;
+        
+        LPC_USB->HcHCCA = (u32)cca;
+        LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus;
+        LPC_USB->HcInterruptEnable = MasterInterruptEnable | WritebackDoneHead | RootHubStatusChange | FrameNumberOverflow;
+
+        NVIC_SetPriority(USB_IRQn, 0);
+        NVIC_EnableIRQ(USB_IRQn);
+        while (cca->FrameNumber < 10)
+            ;    // 10ms delay before diving in
+    }
+};
+
+//====================================================================================
+//====================================================================================
+//      Host controller instance and Interrupt handler
+
+static HostController _controller __attribute__((at(USB_RAM_BASE)));
+
+extern "C" void USB_IRQHandler(void) __irq;
+void USB_IRQHandler (void) __irq
+{
+LOG("USB_IRQHandler start \r\n");
+    u32 int_status = LPC_USB->HcInterruptStatus;
+    LOG("USB_IRQHandler int_status=%0x\r\n",int_status);
+    
+    if(int_status & UnrecoverableError) //Error
+    {
+      LOG("USB_IRQHandler UnrecoverableError Please reset\r\n");
+    }
+
+    if(int_status & MasterInterruptEnable)
+    {
+      LOG("USB_IRQHandler MasterInterruptEnable\r\n");
+    }
+    
+    if(int_status &OwnershipChange)
+    {
+      LOG("USB_IRQHandler OwnershipChange\r\n");
+    }
+
+    if(int_status &FrameNumberOverflow)
+    {
+      LOG("USB_IRQHandler FrameNumberOverflow\r\n");
+    }
+    if(int_status&ResumeDetected)
+    {
+      LOG("USB_IRQHandler ResumeDetected\r\n");
+    }
+    if(int_status&StartofFrame)
+    {
+      LOG("USB_IRQHandler StartofFrame\r\n");
+    }
+
+
+    if (int_status & RootHubStatusChange)    //    Root hub status change
+    {
+      LOG("USB_IRQHandler _rootHubStatusChange %0x->%0x \r\n", _controller._rootHubStatusChange, _controller._rootHubStatusChange+1);
+        _controller._rootHubStatusChange++;    //    Just flag the controller, will be processed in USBLoop
+    }
+
+    u32 head = 0;
+    if (int_status & WritebackDoneHead)
+    {
+        head = _controller.CommunicationArea.DoneHead;        // Writeback Done
+        _controller.CommunicationArea.DoneHead = 0;
+         LOG("USB_IRQHandler head=%0x\r\n",head);
+    }             
+    LPC_USB->HcInterruptStatus = int_status;
+
+    if (head)
+       _controller.ProcessDoneQueue(head);     // TODO - low bit can be set BUGBUG
+LOG("USB_IRQHandler end \r\n");
+}
+
+//====================================================================================
+//====================================================================================
+//      API Methods
+
+void USBInit()
+{
+    return _controller.Init();
+}
+
+void USBLoop()
+{
+    return _controller.Loop();
+}
+
+u8* USBGetBuffer(u32* len)
+{
+    *len = USB_RAM_SIZE - sizeof(HostController);
+    return _controller.SRAM;
+}
+
+static Setup* GetSetup(int device)
+{
+    if (device == 0)
+        return &_controller._setupZero;
+    
+    if (device < 1 || device > MAX_DEVICES)
+        return 0;
+    return &_controller.Devices[device-1].SetupBuffer;
+}
+
+//    Loop until IO on endpoint is complete
+static int WaitIODone(Endpoint* endpoint)
+{
+    LOG("WaitIODone start\r\n");
+    if (endpoint->CurrentState == Endpoint::NotQueued)
+        return 0;
+    while (endpoint->CurrentState != Endpoint::Idle)
+    {
+       LOG("WaitIODone goto  USBloop  endpoint->CurrentState =%d \r\n",endpoint->CurrentState);
+        USBLoop();    // May generate callbacks, mount or unmount devices etc
+    }
+    int status = endpoint->Status();
+    
+    LOG("WaitIODone end\r\n");
+    if (status == 0)
+        return endpoint->Length;
+    return -status;
+}
+
+int USBTransfer(int device, int ep, u8 flags, u8* data, int length, USBCallback callback, void* userData)
+{
+   //LOG("USBTRANSFER start\r\n");
+    Endpoint* endpoint = _controller.GetEndpoint(device,ep);
+    if (!endpoint)
+    {
+        LOG("USBTRANSFER error Endpoint not found!!\r\n");
+        return ERR_ENDPOINT_NOT_FOUND;
+    }
+  
+   //LOG("USBTRANSFER run01\r\n");      
+    WaitIODone(endpoint);
+    endpoint->Flags = flags;
+    endpoint->Data = data;
+    endpoint->Length = length;
+    endpoint->Callback = callback;
+    endpoint->UserData = userData;
+    //LOG("USBTRANSFER run02\r\n");
+    if (ep == 0)
+    {
+      LOG("USBTRANSFER ep == 0(Setup) ------------------------------\r\n");
+        _controller.Transfer(endpoint,TOKEN_SETUP,(u8*)GetSetup(device),8,Endpoint::SetupQueued);
+    }
+    else
+    {
+      LOG("USBTRANSFER ep != 0\r\n");
+        _controller.Transfer(endpoint,flags & 0x80 ? TOKEN_IN : TOKEN_OUT,data,length,Endpoint::DataQueued);
+    }
+    if (callback)
+    {
+       LOG("USBTRANSFER end io_pending\r\n");
+        return IO_PENDING;
+    }
+    LOG("USBTRANSFER end wait io done \r\n");
+    return WaitIODone(endpoint);
+}
+
+int USBControlTransfer(int device, int request_type, int request, int value, int index, u8* data, int length, USBCallback callback, void * userData)
+{
+    Setup* setup = GetSetup(device);
+    if (!setup)
+        return ERR_DEVICE_NOT_FOUND;
+        
+    // Async control calls may overwrite setup buffer of previous call, so we need to wait before setting up next call
+    WaitIODone(_controller.GetEndpoint(device,0));
+    
+    setup->bm_request_type = request_type;
+    setup->b_request = request;
+    setup->w_value = value;
+    setup->w_index = index;
+    setup->w_length = length;
+    LOG("USBControlTransfer(device=%d,reqtype=%d,req=%d,value=%d,index=%d,data=%p,len=%d,callbak=%p,udata=%p)\r\n",
+        device,request_type,request,value,index,data,length,callback,userData);
+    return USBTransfer(device,0,request_type & DEVICE_TO_HOST,data,length,callback,userData);
+}
+
+int  USBInterruptTransfer(int device, int ep, u8* data, int length, USBCallback callback, void* userData)
+{
+    return USBTransfer(device,ep,(ep & 0x80) | ENDPOINT_INTERRUPT,data,length,callback,userData);
+}
+
+int  USBBulkTransfer(int device, int ep, u8* data, int length, USBCallback callback, void* userData)
+{
+    return USBTransfer(device,ep,(ep & 0x80) | ENDPOINT_BULK,data,length,callback,userData);
+}
+
+int GetDescriptor(int device, int descType,int descIndex, u8* data, int length)
+{
+    return USBControlTransfer(device,DEVICE_TO_HOST | RECIPIENT_DEVICE, GET_DESCRIPTOR,(descType << 8)|(descIndex), 0, data, length, 0);
+}
+
+int GetString(int device, int index, char* dst, int length)
+{
+    u8 buffer[255];
+    int le = GetDescriptor(device,DESCRIPTOR_TYPE_STRING,index,buffer,sizeof(buffer));
+    if (le < 0)
+        return le;
+    if (length < 1)
+        return -1;
+    length <<= 1;
+    if (le > length)
+        le = length;
+    for (int j = 2; j < le; j += 2)
+        *dst++ = buffer[j];
+    *dst = 0;
+    return (le>>1)-1;
+}
+
+int SetAddress(int device, int new_addr)
+{
+    return USBControlTransfer(device,HOST_TO_DEVICE | RECIPIENT_DEVICE, SET_ADDRESS, new_addr, 0, 0, 0, 0);
+}
+
+int SetConfiguration(int device, int configNum)
+{
+    return USBControlTransfer(device,HOST_TO_DEVICE | RECIPIENT_DEVICE, SET_CONFIGURATION, configNum, 0, 0, 0, 0);
+}
+
+int SetInterface(int device, int ifNum, int altNum)
+{
+    return USBControlTransfer(device,HOST_TO_DEVICE | RECIPIENT_INTERFACE, SET_INTERFACE, altNum, ifNum, 0, 0, 0);
+}
+
+//    HUB stuff
+int SetPortFeature(int device, int feature, int index)
+{
+    return USBControlTransfer(device,HOST_TO_DEVICE | REQUEST_TYPE_CLASS | RECIPIENT_OTHER,SET_FEATURE,feature,index,0,0);
+}
+
+int ClearPortFeature(int device, int feature, int index)
+{
+    return USBControlTransfer(device,HOST_TO_DEVICE | REQUEST_TYPE_CLASS | RECIPIENT_OTHER,CLEAR_FEATURE,feature,index,0,0);
+}
+
+int SetPortPower(int device, int port)
+{
+    int r = SetPortFeature(device,PORT_POWER,port);
+    _controller.DelayMS(20);    // 80ms to turn on a hubs power... DESCRIPTOR? todo
+    return r;
+}
+
+int SetPortReset(int device, int port)
+{
+    return SetPortFeature(device,PORT_RESET,port);
+}
+
+int GetPortStatus(int device, int port, u32* status)
+{
+    return USBControlTransfer(device,DEVICE_TO_HOST | REQUEST_TYPE_CLASS | RECIPIENT_OTHER,GET_STATUS,0,port,(u8*)status,4);
+}
+
+#endif
\ No newline at end of file
--- a/RobotControl/MotionState.cpp	Thu Mar 21 08:56:53 2013 +0000
+++ b/RobotControl/MotionState.cpp	Sat Mar 23 13:52:48 2013 +0000
@@ -16,7 +16,11 @@
 }
 
 
-MotionState::MotionState(float xposition, float yposition, float theta, float speed, float omega)
+MotionState::MotionState(float xposition,
+                         float yposition,
+                         float theta,
+                         float speed,
+                         float omega)
 {
     this->xposition = xposition;
     this->yposition = yposition;
@@ -32,7 +36,11 @@
 
 }
 
-void MotionState::setState(float xposition, float yposition, float theta, float speed, float omega)
+void MotionState::setState(float xposition,
+                           float yposition,
+                           float theta,
+                           float speed,
+                           float omega)
 {
     this->xposition = xposition;
     this->yposition = yposition;
@@ -120,7 +128,9 @@
     return thetaAcceleration;
 }
 
-void MotionState::increment(float desiredSpeed, float desiredOmega, float period)
+void MotionState::increment(float desiredSpeed,
+                            float desiredOmega,
+                            float period)
 {
     float acceleration = (desiredSpeed-speed)/period;
     if (acceleration < -this->acceleration) acceleration = -this->acceleration;
--- a/RobotControl/MotionState.h	Thu Mar 21 08:56:53 2013 +0000
+++ b/RobotControl/MotionState.h	Sat Mar 23 13:52:48 2013 +0000
@@ -36,7 +36,7 @@
     float yposition;
     /** The &theta; of this motion state. */
     float theta;
-    /** The &theta; of this motion state from the compass. */      
+    /** The &theta; of this motion state from the compass. */
     float thetaCompass;
     /** The speed value of this motion state. */
     float speed;
@@ -50,127 +50,141 @@
     MotionState();
 
     /**
-    * Creates a <code>MotionState</code> object with given values for position and speed.
-    * @param xposition the initial position value of this motion state, given in [m]
-    * @param yposition the initial position value of this motion state, given in [m]
-    * @param theta the initial &theta; value of this motion state, given in [rad]
-    * @param speed the initial speed value of this motion state, given in [m/s]
-    * @param omega the initial &omega; speed value of this motion state, given in [rad/s]
-    */
-    MotionState(float xposition, float yposition, float theta, float speed, float omega);
+     * Creates a <code>MotionState</code> object with given values for position and speed.
+     * @param xposition the initial position value of this motion state, given in [m]
+     * @param yposition the initial position value of this motion state, given in [m]
+     * @param theta the initial &theta; value of this motion state, given in [rad]
+     * @param speed the initial speed value of this motion state, given in [m/s]
+     * @param omega the initial &omega; speed value of this motion state, given in [rad/s]
+     */
+    MotionState(float xposition,
+                float yposition,
+                float theta,
+                float speed,
+                float omega);
 
     /**
-    * Destructor of the Object to destroy the Object.
-    **/
+     * Destructor of the Object to destroy the Object.
+     **/
     virtual     ~MotionState();
 
     /**
-    * Sets the values for xPosition, yPostion and &theta;.
-    * @param xposition the initial position value of this motion state, given in [m]
-    * @param yposition the initial position value of this motion state, given in [m]
-    * @param theta the initial &theta; value of this motion state, given in [rad]
-    * @param speed the initial speed value of this motion state, given in [m/s]
-    * @param omega the initial &omega; speed value of this motion state, given in [rad/s]
-    */
-    void        setState(float xposition, float yposition, float theta, float speed, float omega);
+     * Sets the values for xPosition, yPostion and &theta;.
+     * @param xposition the initial position value of this motion state, given in [m]
+     * @param yposition the initial position value of this motion state, given in [m]
+     * @param theta the initial &theta; value of this motion state, given in [rad]
+     * @param speed the initial speed value of this motion state, given in [m/s]
+     * @param omega the initial &omega; speed value of this motion state, given in [rad/s]
+     */
+    void        setState(float xposition,
+                         float yposition,
+                         float theta,
+                         float speed,
+                         float omega);
 
     /**
-    * Sets the values for X-Position, Y-Postion and &theta;.
-    * @param motionState another <code>MotionState</code> object to copy the state values from
-    */
+     * Sets the values for X-Position, Y-Postion and &theta;.
+     * @param motionState another <code>MotionState</code> object to copy the state values from
+     */
     void        setState(MotionState* motionState);
 
     /**
-    * Sets the X-position value.
-    * @param xposition the desired xposition value of this motion state, given in [m]
-    */
+     * Sets the X-position value.
+     * @param xposition the desired xposition value of this motion state, given in [m]
+     */
     void        setxPosition(float xposition);
 
     /**
-    * Gets the X-position value.
-    * @return the xposition value of this motion state, given in [m]
-    */
+     * Gets the X-position value.
+     * @return the xposition value of this motion state, given in [m]
+     */
     float       getxPosition();
 
     /**
-    * Sets the Y-position value.
-    * @param yposition the desired yposition value of this motion state, given in [m]
-    */
+     * Sets the Y-position value.
+     * @param yposition the desired yposition value of this motion state, given in [m]
+     */
     void        setyPosition(float yposition);
 
     /**
-    * Gets the Y-position value.
-    * @return the xposition value of this motion state, given in [m]
-    */
+     * Gets the Y-position value.
+     * @return the xposition value of this motion state, given in [m]
+     */
     float       getyPosition();
 
     /**
-    * Sets the &theta; value.
-    * @param theta the desired &theta; value of this motion state, given in [rad]
-    */
+     * Sets the &theta; value.
+     * @param theta the desired &theta; value of this motion state, given in [rad]
+     */
     void        setTheta(float theta);
 
     /**
-    * Gets the &theta; value.
-    * @return the &theta; value of this motion state, given in [rad]
-    */
+     * Gets the &theta; value.
+     * @return the &theta; value of this motion state, given in [rad]
+     */
     float       getTheta();
 
     /**
-    * Sets the speed value.
-    * @param speed the desired speed value of this motion state, given in [m/s]
-    */
+     * Sets the speed value.
+     * @param speed the desired speed value of this motion state, given in [m/s]
+     */
     void        setSpeed(float speed);
 
     /**
-    * Gets the speed value.
-    * @return the speed value of this motion state, given in [m/s]
-    */
+     * Gets the speed value.
+     * @return the speed value of this motion state, given in [m/s]
+     */
     float       getSpeed();
 
     /**
-    * Sets the &omega; value.
-    * @param omega the desired &omega; value of this motion state, given in [rad/s]
-    */
+     * Sets the &omega; value.
+     * @param omega the desired &omega; value of this motion state, given in [rad/s]
+     */
     void        setOmega(float omega);
 
     /**
-    * Gets the &omega; value.
-    * @return the &omega; value of this motion state, given in [rad/s]
-    */
+     * Gets the &omega; value.
+     * @return the &omega; value of this motion state, given in [rad/s]
+     */
     float       getOmega();
 
     /**
-    * Sets the maximum acceleration value.
-    * @param acceleration the maximum acceleration value to use for the calculation of the motion trajectory, given in [m/s<SUP>2</SUP>]
-    */
+     * Sets the maximum acceleration value.
+     * @param acceleration the maximum acceleration value to use for
+     * the calculation of the motion trajectory, given in [m/s<SUP>2</SUP>]
+     */
     void        setAcceleration(float acceleration);
 
     /**
-    * Gets the maximum acceleration value.
-    * @return the maximum acceleration value used for the calculation of the motion trajectory, given in [m/s<SUP>2</SUP>]
-    */
+     * Gets the maximum acceleration value.
+     * @return the maximum acceleration value used for the calculation
+     * of the motion trajectory, given in [m/s<SUP>2</SUP>]
+     */
     float       getAcceleration();
 
     /**
-    * Sets the maximum acceleration value of rotation.
-    * @param thetaAcceleration the maximum acceleration value to use for the calculation of the motion trajectory, given in [rad/<SUP>2</SUP>]
-    */
+     * Sets the maximum acceleration value of rotation.
+     * @param thetaAcceleration the maximum acceleration value to use for
+     * the calculation of the motion trajectory, given in [rad/<SUP>2</SUP>]
+     */
     void        setThetaAcceleration(float thetaAcceleration);
 
     /**
-    * Gets the maximum acceleration value of rotation.
-    * @return the maximum acceleration value used for the calculation of the motion trajectory, given in [rad/<SUP>2</SUP>]
-    */
+     * Gets the maximum acceleration value of rotation.
+     * @return the maximum acceleration value used for the calculation of
+     *  the motion trajectory, given in [rad/<SUP>2</SUP>]
+     */
     float       getThetaAcceleration();
 
     /**
-    * Increments the current motion state towards a given desired speed.
-    * @param desiredSpeed the desired speed given in [m/s].
-    * @param desiredOmega the desired &omega; given in [rad/s].
-    * @param period the time period to increment the motion state for, given in [s]
-    */
-    void        increment(float desiredSpeed, float desiredOmega, float period);
+     * Increments the current motion state towards a given desired speed.
+     * @param desiredSpeed the desired speed given in [m/s].
+     * @param desiredOmega the desired &omega; given in [rad/s].
+     * @param period the time period to increment the motion state for, given in [s]
+     */
+    void        increment(float desiredSpeed,
+                          float desiredOmega,
+                          float period);
 };
 
 #endif
--- a/RobotControl/RobotControl.cpp	Thu Mar 21 08:56:53 2013 +0000
+++ b/RobotControl/RobotControl.cpp	Sat Mar 23 13:52:48 2013 +0000
@@ -2,7 +2,10 @@
 
 using namespace std;
 
-RobotControl::RobotControl(MaxonESCON* motorControllerLeft, MaxonESCON* motorControllerRight, /*HMC6352* compass,*/ float period) : Task(period)
+RobotControl::RobotControl(MaxonESCON* motorControllerLeft,
+                           MaxonESCON* motorControllerRight,
+                           /*HMC6352* compass,*/
+                           float period) : Task(period)
 {
     /* get peripherals */
     this->motorControllerLeft = motorControllerLeft;
@@ -91,7 +94,9 @@
     return Desired.theta;
 }
 
-void RobotControl::setDesiredPositionAndAngle(float xposition, float yposition, float theta)
+void RobotControl::setDesiredPositionAndAngle(float xposition,
+        float yposition,
+        float theta)
 {
     setDesiredxPosition(xposition);
     setDesiredyPosition(yposition);
@@ -161,35 +166,16 @@
 float RobotControl::getThetaErrorToGoal()
 {
     return PiRange(atan2(getyPositionError(),getxPositionError()) - getActualTheta());
-    /*float temp;
-    temp = atan2(getyPositionError(),getxPositionError()) - getActualTheta();
-
-    if(temp <= -PI) {
-        temp  += 2*  PI;
-    } else if (temp > PI) {
-        temp  -= 2*  PI;
-    } else {
-        //nothing
-    }
-    return temp;*/
 }
 
 float RobotControl::getThetaGoal()
 {
     return PiRange(atan2(getyPositionError(),getxPositionError()) - getTheta());
-
-    /*
-    if(temp <= -PI) {
-        temp  += 2*  PI;
-    } else if (temp > PI) {
-        temp  -= 2*  PI;
-    } else {
-        //nothing
-    }
-    return temp;*/
 }
 
-void RobotControl::setAllToZero(float xZeroPos, float yZeroPos, float theta)
+void RobotControl::setAllToZero(float xZeroPos,
+                                float yZeroPos,
+                                float theta)
 {
     Actual.setState(xZeroPos, yZeroPos, theta, 0.0f, 0.0f);
     Desired.setState(0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
@@ -219,8 +205,10 @@
     /* position calculation */
 
     /* Set the state of speed from Left und Right Wheel*/
-    stateLeft.speed = motorControllerLeft->getActualSpeed() * 2.0f * WHEEL_RADIUS * PI * GEAR;
-    stateRight.speed = - motorControllerRight->getActualSpeed() * 2.0f * WHEEL_RADIUS * PI * GEAR;
+    stateLeft.speed = motorControllerLeft->getActualSpeed() *
+                      2.0f * WHEEL_RADIUS_LEFT * PI * GEAR;
+    stateRight.speed = - motorControllerRight->getActualSpeed() *
+                       2.0f * WHEEL_RADIUS_RIGHT * PI * GEAR;
 
     /* translational speed of the Robot (average) */
     Actual.speed = ( stateRight.speed + stateLeft.speed ) / 2.0f;
@@ -231,15 +219,7 @@
     /* rotational theta of the Robot integrate the omega with the time*/
     Actual.theta += Actual.omega * period;
     Actual.theta = PiRange(Actual.theta);
-    /*
-        if(Actual.theta <= -PI) {
-            Actual.theta  += 2*  PI;
-        } else if (Actual.theta > PI) {
-            Actual.theta  -= 2*  PI;
-        } else {
-            //nothing
-        }
-    */
+
     /* translational X and Y Position. integrate the speed with the time */
     Actual.xposition += (Actual.speed * period * cos(Actual.theta));
     Actual.yposition += (Actual.speed * period * sin(Actual.theta));
@@ -256,10 +236,13 @@
 
         speed = K1 * getDistanceError() * cos( getThetaErrorToGoal() );
         omega = K2 * getThetaErrorToGoal() +
-                K1 * ( ( sin(getThetaErrorToGoal()) * cos(getThetaErrorToGoal()) ) / (getThetaErrorToGoal()) ) * ( getThetaErrorToGoal() + K3 * getThetaGoal() );
+                K1 * ( ( sin(getThetaErrorToGoal()) * cos(getThetaErrorToGoal()) ) /
+                       (getThetaErrorToGoal()) ) * ( getThetaErrorToGoal() + K3 * getThetaGoal() );
 
-        motorControllerLeft->setVelocity( ( ( (2 * speed) - (WHEEL_DISTANCE * omega) ) / 2 ) / (2 * WHEEL_RADIUS * PI * GEAR) );
-        motorControllerRight->setVelocity(-( ( (2 * speed) + (WHEEL_DISTANCE * omega) ) / 2) / (2 * WHEEL_RADIUS * PI * GEAR) );
+        motorControllerLeft->setVelocity( ( ( (2 * speed) - (WHEEL_DISTANCE * omega) ) / 2 ) /
+                                          (2 * WHEEL_RADIUS_LEFT * PI * GEAR) );
+        motorControllerRight->setVelocity(-( ( (2 * speed) + (WHEEL_DISTANCE * omega) ) / 2) /
+                                          (2 * WHEEL_RADIUS_RIGHT * PI * GEAR) );
 
     } else {
 
@@ -279,4 +262,3 @@
         return theta;
     }
 }
-
--- a/RobotControl/RobotControl.h	Thu Mar 21 08:56:53 2013 +0000
+++ b/RobotControl/RobotControl.h	Sat Mar 23 13:52:48 2013 +0000
@@ -45,103 +45,125 @@
     float               speed;
     float               omega;
 
+    /**
+     * Add &plusmn;2&pi; when the range of
+     * the radian is over +&pi; or under -&pi;.
+     * @param theta to check the value
+     * @return the value in the range from -&pi; to +&pi;
+     */
+    float        PiRange(float theta);
+
 public:
 
     /**
-     * Creates a <code>Robot Control</code> object and initializes all private
-     * state variables.
-     * @param motorControllerLeft a reference to the servo drive for the left motor
-     * @param motorControllerRight a reference to the servo drive for the right motor
+     * Creates a <code>Robot Control</code> object and
+     * initializes all private state variables.
+     * @param motorControllerLeft a reference to the servo
+     * drive for the left motor
+     * @param motorControllerRight a reference to the servo
+     *  drive for the right motor
      * @param compass Modul HMC5883L
-     * @param period the sampling period of the run loop of this controller, given in [s]
+     * @param period the sampling period of the run loop of 
+     * this controller, given in [s]
      */
-    RobotControl(MaxonESCON* motorControllerLeft, MaxonESCON* motorControllerRight, /*HMC6352* compass,*/ float period);
+    RobotControl(MaxonESCON* motorControllerLeft,
+                 MaxonESCON*
+                 motorControllerRight,
+                 /*HMC6352* compass,*/
+                 float period);
 
     /**
-    * Destructor of the Object to destroy the Object.
-    **/
+     * Destructor of the Object to destroy the Object.
+     **/
     virtual     ~RobotControl();
 
     /**
-    * Enables or disables the servo drives of the motors.
-    * @param enable if <code>true</code> enables the drives, <code>false</code> otherwise
-    * the servo drives are shut down.
-    */
+     * Enables or disables the servo drives of the motors.
+     * @param enable if <code>true</code> enables the drives,
+     * <code>false</code> otherwise
+     * the servo drives are shut down.
+     */
     void        setEnable(bool enable);
 
     /**
-    * Tests if the servo drives of the motors are enabled.
-    * @return <code>true</code> if the drives are enabled, <code>false</code> otherwise
-    */
+     * Tests if the servo drives of the motors are enabled.
+     * @return <code>true</code> if the drives are enabled,
+     * <code>false</code> otherwise
+     */
     bool        isEnabled();
 
     /**
-    * Sets the maximum acceleration value.
-    * @param acceleration the maximum acceleration value to use for the calculation of the motion trajectory, given in [m/s<SUP>2</SUP>]
-    */
+     * Sets the maximum acceleration value.
+     * @param acceleration the maximum acceleration value to use
+     * for the calculation of the motion trajectory, given in [m/s<SUP>2</SUP>]
+     */
     void        setAcceleration(float acceleration);
 
     /**
-    * Sets the maximum acceleration value of rotation.
-    * @param acceleration the maximum acceleration value to use for the calculation of the motion trajectory, given in [rad/s<SUP>2</SUP>]
-    */
+     * Sets the maximum acceleration value of rotation.
+     * @param acceleration the maximum acceleration value
+     * to use for the calculation of the motion trajectory,
+     * given in [rad/s<SUP>2</SUP>]
+     */
     void        setThetaAcceleration(float acceleration);
 
     /**
-    * Sets the desired translational speed of the robot.
-    * @param speed the desired speed, given in [m/s]
-    */
+     * Sets the desired translational speed of the robot.
+     * @param speed the desired speed, given in [m/s]
+     */
     void        setDesiredSpeed(float speed);
 
     /**
-    * Sets the desired rotational speed of the robot.
-    * @param omega the desired rotational speed, given in [rad/s]
-    */
+     * Sets the desired rotational speed of the robot.
+     * @param omega the desired rotational speed, given in [rad/s]
+     */
     void        setDesiredOmega(float omega);
 
     /**
-    * Sets the desired X-position of the robot.
-    * @param xposition the desired position, given in [m]
-    */
+     * Sets the desired X-position of the robot.
+     * @param xposition the desired position, given in [m]
+     */
     void        setDesiredxPosition(float xposition);
 
     /**
-    * Sets the desired Y-position of the robot.
-    * @param yposition the desired position, given in [m]
-    */
+     * Sets the desired Y-position of the robot.
+     * @param yposition the desired position, given in [m]
+     */
     void        setDesiredyPosition(float yposition);
 
     /**
-    * Sets the desired &theta; of the robot.
-    * @param theta the desired &theta;, given in [rad]
-    */
+     * Sets the desired &theta; of the robot.
+     * @param theta the desired &theta;, given in [rad]
+     */
     void        setDesiredTheta(float theta);
-    
-        /**
-    * Get the desired X-position of the robot.
-    * @return xposition the desired position, given in [m]
-    */
+
+    /**
+     * Get the desired X-position of the robot.
+     * @return xposition the desired position, given in [m]
+     */
     float        getDesiredxPosition();
 
     /**
-    * Get the desired Y-position of the robot.
-    * @return yposition the desired position, given in [m]
-    */
+     * Get the desired Y-position of the robot.
+     * @return yposition the desired position, given in [m]
+     */
     float        getDesiredyPosition();
 
     /**
-    * Get the desired &theta; of the robot.
-    * @return theta the desired &theta;, given in [rad]
-    */
+     * Get the desired &theta; of the robot.
+     * @return theta the desired &theta;, given in [rad]
+     */
     float        getDesiredTheta();
 
     /**
-    * Sets the desired Position and &theta;.
-    * @param xposition the desired position, given in [m]
-    * @param yposition the desired position, given in [m]
-    * @param theta the desired &theta;, given in [rad]
-    */
-    void        setDesiredPositionAndAngle(float xposition, float yposition, float theta);
+     * Sets the desired Position and &theta;.
+     * @param xposition the desired position, given in [m]
+     * @param yposition the desired position, given in [m]
+     * @param theta the desired &theta;, given in [rad]
+     */
+    void        setDesiredPositionAndAngle(float xposition,
+                                           float yposition,
+                                           float theta);
 
     /**
      * Gets the desired &theta; of the goal point.
@@ -162,85 +184,82 @@
     float       getActualSpeed();
 
     /**
-    * Gets the desired rotational speed of the robot.
-    * @return the desired speed, given in [rad/s]
-    */
+     * Gets the desired rotational speed of the robot.
+     * @return the desired speed, given in [rad/s]
+     */
     float       getDesiredOmega();
 
     /**
-    * Gets the actual rotational speed of the robot.
-    * @return the desired speed, given in [rad/s]
-    */
+     * Gets the actual rotational speed of the robot.
+     * @return the desired speed, given in [rad/s]
+     */
     float       getActualOmega();
 
     /**
-    * Gets the actual translational X-position of the robot.
-    * @return the actual position, given in [m]
-    */
+     * Gets the actual translational X-position of the robot.
+     * @return the actual position, given in [m]
+     */
     float       getxActualPosition();
 
     /**
-    * Gets the X-position following error of the robot.
-    * @return the position following error, given in [m]
-    */
+     * Gets the X-position following error of the robot.
+     * @return the position following error, given in [m]
+     */
     float       getxPositionError();
 
     /**
-    * Gets the actual translational Y-position of the robot.
-    * @return the actual position, given in [m]
-    */
+     * Gets the actual translational Y-position of the robot.
+     * @return the actual position, given in [m]
+     */
     float       getyActualPosition();
 
     /**
-    * Gets the Y-position following error of the robot.
-    * @return the position following error, given in [m]
-    */
+     * Gets the Y-position following error of the robot.
+     * @return the position following error, given in [m]
+     */
     float       getyPositionError();
 
     /**
-    * Gets the actual orientation of the robot.
-    * @return the orientation, given in [rad]
-    */
+     * Gets the actual orientation of the robot.
+     * @return the orientation, given in [rad]
+     */
     float       getActualTheta();
 
     /**
-    * Gets the orientation following error of the robot.
-    * @return the orientation following error, given in [rad]
-    */
+     * Gets the orientation following error of the robot.
+     * @return the orientation following error, given in [rad]
+     */
     float       getThetaError();
 
     /**
-    * Gets the distance to disired point. Calculate with pythagoras.
-    * @return distance to goal, given in [m]
-    */
+     * Gets the distance to disired point. Calculate with pythagoras.
+     * @return distance to goal, given in [m]
+     */
     float       getDistanceError();
 
     /**
-    * Gets the &theta; ot the pointing vector to the goal right the unicycle axis from actual point.
-    * @return theta to goal, given in [rad]
-    */
+     * Gets the &theta; ot the pointing vector to the goal right
+     * the unicycle axis from actual point.
+     * @return theta to goal, given in [rad]
+     */
     float       getThetaErrorToGoal();
 
     /**
-    * Gets the &theta; ot the pointing vector to the goal right the unicycle main axis.
-    * @return theta from the goal, given in [rad]
-    */
+     * Gets the &theta; ot the pointing vector to the goal right the unicycle main axis.
+     * @return theta from the goal, given in [rad]
+     */
     float       getThetaGoal();
 
     /**
-    * Set all state to zero, except the X-position, y-position and &theta;.
-    * @param xZeroPos Sets the start X-position, given in [m]
-    * @param yZeroPos Sets the start y-position, given in [m]
-    * @param theta Sets the start &theta;, given in [rad]
-    */
-    void        setAllToZero(float xZeroPos, float yZeroPos, float theta);
+     * Set all state to zero, except the X-position, y-position and &theta;.
+     * @param xZeroPos Sets the start X-position, given in [m]
+     * @param yZeroPos Sets the start y-position, given in [m]
+     * @param theta Sets the start &theta;, given in [rad]
+     */
+    void        setAllToZero(float xZeroPos,
+                             float yZeroPos,
+                             float theta);
 
-    /**
-    * Add &plusmn;2&pi; when the range of the radian is over +&pi; or under -&pi;.
-    * @param theta to check the value
-    * @return the value in the range from -&pi; to +&pi;
-    */
-    float        PiRange(float theta);
 
     void        run();
 };
--- a/StateDefines/State.cpp	Thu Mar 21 08:56:53 2013 +0000
+++ b/StateDefines/State.cpp	Sat Mar 23 13:52:48 2013 +0000
@@ -62,7 +62,8 @@
 {
     char buf[256];
 
-    sprintf(buf,"%d\t%f\t%d\t%d\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%d\t%f\t%f\t%f",
+    sprintf(buf,"%d\t%f\t%d\t%d\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t"
+            "%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%d\t%f\t%f\t%f",
             s.millis,
             s.voltageBattery,
             s.leftPulses,
@@ -149,8 +150,10 @@
     s->voltageBattery = readBattery();
     s->leftPulses = - motorControllerLeft->getPulses();
     s->rightPulses = motorControllerRight->getPulses();
-    s->leftVelocity = motorControllerLeft->getActualSpeed() * 2.0f * WHEEL_RADIUS * PI;
-    s->rightVelocity = - motorControllerRight->getActualSpeed()* 2.0f * WHEEL_RADIUS * PI;
+    s->leftVelocity = motorControllerLeft->getActualSpeed() *
+                      2.0f * WHEEL_RADIUS_LEFT * PI;
+    s->rightVelocity = - motorControllerRight->getActualSpeed()*
+                       2.0f * WHEEL_RADIUS_RIGHT * PI;
     s->velocity = robotControl->getActualSpeed();
     s->omega =  robotControl->getActualOmega();
     s->xAxis = robotControl->getxActualPosition();
@@ -171,5 +174,4 @@
     setBatteryBit();
     setEnableLeftBit();
     setEnableRightBit();
-
 }
--- a/StateDefines/State.h	Thu Mar 21 08:56:53 2013 +0000
+++ b/StateDefines/State.h	Sat Mar 23 13:52:48 2013 +0000
@@ -22,7 +22,7 @@
  *
  * State is the main mechanism for communicating current realtime system state to
  * the rest of the system for logging etc.
- * 
+ *
  */
 
 class State : public Task
@@ -34,12 +34,11 @@
     RobotControl*       robotControl;
     MaxonESCON*         motorControllerLeft;
     MaxonESCON*         motorControllerRight;
-  //  HMC6352*            compass;
+    //  HMC6352*            compass;
     AnalogIn*           battery;
     Timer               timer;
     float               period;
-
-    float               magout[3];
+    //float               magout[3];
 
 public:
 
@@ -53,28 +52,34 @@
      * @param battery Analog Input Battery Voltage input
      * @param period the sampling period of the run loop of this controller, given in [s]
      */
-    State(state_t* s, RobotControl* robotControl, MaxonESCON* motorControllerLeft, MaxonESCON* motorControllerRight, /*HMC6352* compass,*/ AnalogIn* battery, float period);
+    State(state_t* s,
+          RobotControl* robotControl,
+          MaxonESCON* motorControllerLeft,
+          MaxonESCON* motorControllerRight,
+          /*HMC6352* compass,*/
+          AnalogIn* battery,
+          float period);
 
     /**
-    * Destructor of the Object to destroy the Object.
-    **/
+     * Destructor of the Object to destroy the Object.
+     **/
     virtual     ~State();
-    
+
     /**
      * Initzialize the File. Open the File plots.txt and set the title at first line.
      */
     void initPlotFile(void);
 
     /**
-    * Save the char to the file.
-    * For example at the end.
-    * Don't forget the \n at first.
-    */
+     * Save the char to the file.
+     * For example at the end.
+     * Don't forget the \n at first.
+     */
     void savePlotText(char text[]);
 
     /**
-    * Close the File.
-    */
+     * Close the File.
+     */
     void closePlotFile(void);
 
     /**
@@ -84,15 +89,15 @@
      */
     float readBattery();
 
-     /**
+    /**
      * Starts the timer from zero.
      * The timer is for the logging Time.
      */
     void startTimerFromZero();
 
     /**
-    * Save the new state to a new line.
-    */
+     * Save the new state to a new line.
+     */
     void savePlotFile(state_t s);
 
     void        run();
--- a/StateDefines/defines.h	Thu Mar 21 08:56:53 2013 +0000
+++ b/StateDefines/defines.h	Sat Mar 23 13:52:48 2013 +0000
@@ -9,11 +9,12 @@
 // maxon motor #339282 EC 45 flat 30W and GEAR 
 #define POLE_PAIRS            8u            // Number of of pole pairs
 #define GEAR                  1/11.6f       // Gear on the motor 1/11.6f
-#define PULSES_PER_STEP       6u            // Pulses per step Hallsensor have 6 steps
+#define PULSES_PER_STEP       6u            // Pulses per electrical step Hallsensor, have 6 steps
 
 // Physical Dimension of the car
-#define WHEEL_RADIUS          0.043f        // radius of the wheel, given in [m]
-#define WHEEL_DISTANCE        0.18f         // Distance of the wheel, given in [m] 
+#define WHEEL_RADIUS_LEFT     0.043f        // radius of the left wheel, given in [m]
+#define WHEEL_RADIUS_RIGHT     0.043f        // radius of the left wheel, given in [m]
+#define WHEEL_DISTANCE        0.1865f       // Distance of the wheel, given in [m] 
 
 // State Bits of the car
 #define STATE_STOP            1u            // Bit0 = stop pressed 
@@ -37,8 +38,8 @@
 #define GAIN                  0.30f         // Main Gain
 #define K1                    1.0f * GAIN
 #define K2                    3.0f * GAIN
-#define K3                    2.0f * GAIN
-#define MIN_DISTANCE_ERROR    0.03          // min. Distance to switch the position controller off. Because when Distance Error goes to zero the ATAN2 is not define, given in [m]                 
+#define K3                    5.0f * GAIN   // deafult 2.0f
+#define MIN_DISTANCE_ERROR    -0.02f         // min. Distance to switch the position controller off. Because when Distance Error goes to zero the ATAN2 is not define, given in [m]                 
 
 // LiPo Batterie
 #define BAT_MULTIPLICATOR     21.633333333f // R2 / (R1 + R2) = 0.153    R2= 10k , R1 = 1.8k 1/0.153 = 6.555  ---> 3.3 * 6.555 = 21.6333333f
@@ -64,7 +65,11 @@
 #define COMP_Z_MAX            -237.855042f  // Maximum Z-Range not used in this side      
 #define COMP_X_MIN            -169.952530f  // Minimum X-Range      
 #define COMP_Y_MIN            -247.647675f  // Minimum Y-Range      
-#define COMP_Z_MIN            -385.915009f  // Minimun Z-Range not used in this side  
+#define COMP_Z_MIN            -385.915009f  // Minimun Z-Range not used in this side 
+
+// Android Buffer Size for communication
+#define OUTL 100
+#define INBL 100 
 
     /**
     * struct state
--- a/Task/Task.h	Thu Mar 21 08:56:53 2013 +0000
+++ b/Task/Task.h	Sat Mar 23 13:52:48 2013 +0000
@@ -10,7 +10,7 @@
  *
  * Copyright &copy; 2013 HSLU Pren Team #1 Cruising Crêpe
  * All rights reserved.
- * 
+ *
  * @section DESCRIPTION
  * The <code>Task</code> class allows to install periodic, time-triggered
  * tasks. An example of a simple user-defined task is given below:
@@ -40,17 +40,19 @@
 
     /** specifiying the interval in seconds */
     float       period;
-    /** The Ticker interface is used to setup a recurring interrupt to repeatedly call a function at a specified rate. */
+    /** The Ticker interface is used to setup a recurring interrupt to
+     *  repeatedly call a function at a specified rate.
+     */
     Ticker      ticker;
 
 public:
 
-    /**    
+    /**
      * Creates a task object with a given period.
      * @param period the period of this task in seconds.
      */
     Task(float period);
-    
+
     virtual ~Task();
 
     /**
--- a/main.cpp	Thu Mar 21 08:56:53 2013 +0000
+++ b/main.cpp	Sat Mar 23 13:52:48 2013 +0000
@@ -1,4 +1,6 @@
 /**
+ * \mainpage Index Page
+ * 
  * @file main.cpp
  * @author Christian Burri
  *
@@ -34,6 +36,10 @@
 #include "RobotControl.h"
 #include "Ping.h"
 #include "PowerControl/EthernetPowerControl.h"
+//#include "android.h"
+
+//Android
+//AdkTerm AdkTerm;
 
 // LiPo Batterie
 AnalogIn battery(p15);           // Battery check
@@ -66,7 +72,6 @@
 
 DigitalOut myled(LED1);
 
-//float magout[3] = {0};
 
 // LiPo Batterie
 float batterie_voltage;
@@ -89,10 +94,11 @@
 
     robotControl.start();
     robotControl.setEnable(false);
-    wait(0.01);
+    wait(0.1);
     robotControl.setEnable(true);
-    wait(0.01);
-    robotControl.setAllToZero(START_X_OFFSET, START_Y_OFFSET, PI/2 );
+    wait(0.1);
+    robotControl.setAllToZero(0, 0, PI/2 );
+  //  robotControl.setAllToZero(START_X_OFFSET, START_Y_OFFSET, PI/2 );
 
     leftMotor.setPulses(0);
     rightMotor.setPulses(0);
@@ -100,44 +106,163 @@
     state.startTimerFromZero();
     state.start();
 
-    robotControl.setDesiredPositionAndAngle(START_X_OFFSET, START_Y_OFFSET, PI/2);
+   // robotControl.setDesiredPositionAndAngle(START_X_OFFSET, START_Y_OFFSET, PI/2);
+  //  robotControl.setDesiredPositionAndAngle(0, 0, PI/2);
     wait(0.1);
+    
+    //////////////////////////////////////////
+    
+            robotControl.setDesiredPositionAndAngle(0.0f, 1.0f,  PI);
+        while(!(robotControl.getDistanceError() <= 0.1)) {
+            state.savePlotFile(s);
+        };
 
-    robotControl.setDesiredPositionAndAngle(-1.20f, 1.50f,  3*PI/4);
-    while(!(robotControl.getDistanceError() <= 0.4)) {
-        state.savePlotFile(s);
-    };
+        robotControl.setDesiredPositionAndAngle(-1.00f, 1.0f,  -PI/2);
+        while(!(robotControl.getDistanceError() <= 0.1)) {
+            state.savePlotFile(s);
+        };
+
+        robotControl.setDesiredPositionAndAngle(-1.0f, 0.0f,  0);
+        while(!(robotControl.getDistanceError() <= 0.1)) {
+            state.savePlotFile(s);
+        };
 
-    robotControl.setDesiredPositionAndAngle(-1.20f, 2.5f,  PI/4);
-    while(!(robotControl.getDistanceError() <= 0.4)) {
-        state.savePlotFile(s);
-    };
+        robotControl.setDesiredPositionAndAngle(0.0, 0.0f,  PI/2);
+        while(!(s.millis >= 55000)) {
+            state.savePlotFile(s);
+        };
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    ////////////////////////////////////////////////////////////////////////
+    
+    
 
-    robotControl.setDesiredPositionAndAngle(-0.45f, 3.2f,  3*PI/4);
-    while(!(robotControl.getDistanceError() <= 0.4)) {
+    //Zum Umfang einstellen
+    /*
+    robotControl.setDesiredPositionAndAngle(0.0f, 1.0f,  PI/2);
+    while(!(s.millis >= 20000)) {
         state.savePlotFile(s);
     };
+    
 
-    robotControl.setDesiredPositionAndAngle(-1.0f, 3.6f,  PI);
-    while(!(robotControl.getDistanceError() <= 0.2)) {
-        state.savePlotFile(s);
-    };
+*/
+
+    ///////////////oder//////////////////
+
+
+    // Zum radabstand einstellen
+      
+    /*
+    int sek = 1000;
+    int step = 1000;
+    int i = 0;
+    int totalTurns = 5;
+
+    while(i >= totalTurns) {
+        robotControl.setDesiredPositionAndAngle(0.0f, 0.0f,  PI);
+        while(!(s.millis >= sek)) {
+            state.savePlotFile(s);
+        };
+        sek += step;
+
+        robotControl.setDesiredPositionAndAngle(0.0f, 0.0f,  -PI/2);
+        while(!(s.millis >= sek)) {
+            state.savePlotFile(s);
+        };
+        sek += step;
 
-    robotControl.setDesiredPositionAndAngle(-1.5f, 3.6f,  PI);
-    while(!(robotControl.getDistanceError() <= 0.03)) {
-        state.savePlotFile(s);
-    };
+        robotControl.setDesiredPositionAndAngle(0.0f, 0.0f,  0);
+        while(!(s.millis >= sek)) {
+            state.savePlotFile(s);
+        };
+        sek += step;
+
+        robotControl.setDesiredPositionAndAngle(0.0f, 0.0f,  PI/2);
+        while(!(s.millis >= sek)) {
+            state.savePlotFile(s);
+        };
+        sek += step;
+
+        i++;
+    }
+*/
+
+
+////////////////////////////////////////////////////////
+
+
+
+    //  Epä Parkour fahrä
+/*
+        robotControl.setDesiredPositionAndAngle(START_X_OFFSET, START_Y_OFFSET, PI/2);
+        wait(0.1);
 
-    robotControl.setDesiredPositionAndAngle(-2.5f, 3.0f,  -PI/2);
-    while(!(robotControl.getDistanceError() <= 0.4)) {
-        state.savePlotFile(s);
-    };
+        robotControl.setDesiredPositionAndAngle(-1.20f, 1.50f,  3*PI/4);
+        while(!(robotControl.getDistanceError() <= 0.4)) {
+            state.savePlotFile(s);
+        };
+
+        robotControl.setDesiredPositionAndAngle(-1.20f, 2.5f,  PI/4);
+        while(!(robotControl.getDistanceError() <= 0.4)) {
+            state.savePlotFile(s);
+        };
+
+        robotControl.setDesiredPositionAndAngle(-0.45f, 3.2f,  3*PI/4);
+        while(!(robotControl.getDistanceError() <= 0.4)) {
+            state.savePlotFile(s);
+        };
+
+        robotControl.setDesiredPositionAndAngle(-1.0f, 3.6f,  PI);
+        while(!(robotControl.getDistanceError() <= 0.2)) {
+            state.savePlotFile(s);
+        };
+
+        robotControl.setDesiredPositionAndAngle(-1.5f, 3.6f,  PI);
+        while(!(robotControl.getDistanceError() <= 0.1)) {
+            state.savePlotFile(s);
+        };
 
-    robotControl.setDesiredPositionAndAngle(-1.75f, 1.30f,  -PI/2);
-    while(!(robotControl.getDistanceError() <= 0.04)) {
-        state.savePlotFile(s);
-    };
+        robotControl.setDesiredPositionAndAngle(-2.5f, 3.0f,  -PI/2);
+        while(!(robotControl.getDistanceError() <= 0.4)) {
+            state.savePlotFile(s);
+        };
+
+        robotControl.setDesiredPositionAndAngle(-1.75f, 1.30f,  -PI/2);
+        while(!(robotControl.getDistanceError() <= 0.06)) {
+            state.savePlotFile(s);
+        };
+        
 
+    */
+    
+    
+    
+    
+    /*
+        printf("here we go... \n");
+        AdkTerm.setupDevice();
+        printf("Android Development Kit: start\r\n");
+        USBInit();
+        while (!(s.millis >= 60000)) {
+            USBLoop();
+
+            printf("x: %f y: %f theta: %f", AdkTerm.getx(), AdkTerm.getx(), AdkTerm.getx() )
+
+            if( AdkTerm.getx() == 99) {
+                break;
+            }
+        }
+    */
 
     state.savePlotFile(s);
     state.closePlotFile();