BaseJpegDeocde exampe program

Dependencies:   BaseJpegDecode Terminal BaseUsbHost mbed mbed-rtos

Fork of BaseJpegDecode by Norimasa Okamoto

Files at this revision

API Documentation at this revision

Comitter:
va009039
Date:
Sun Jan 27 11:15:26 2013 +0000
Parent:
6:95be1cd2bc14
Commit message:
change library uvchost to BaseUsbHost, delete SimpleJpegDecode

Changed in this revision

BaseJpegDecode.lib Show annotated file Show diff for this revision Revisions of this file
BaseUsbHost.lib Show annotated file Show diff for this revision Revisions of this file
FATFileSystem.lib Show diff for this revision Revisions of this file
MyThread/MyThread.h Show annotated file Show diff for this revision Revisions of this file
SimpleJpegDecode.cpp Show diff for this revision Revisions of this file
SimpleJpegDecode.h Show diff for this revision Revisions of this file
UvcCam/UvcCam.cpp Show annotated file Show diff for this revision Revisions of this file
UvcCam/UvcCam.h Show annotated file Show diff for this revision Revisions of this file
bmp24.h Show diff for this revision Revisions of this file
example1_c270.cpp Show diff for this revision Revisions of this file
example_SimpleJpegDecode.cpp Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
msc/msc.cpp Show diff for this revision Revisions of this file
msc/msc.h Show diff for this revision Revisions of this file
uvchost.lib Show diff for this revision Revisions of this file
--- a/BaseJpegDecode.lib	Wed Dec 05 12:41:25 2012 +0000
+++ b/BaseJpegDecode.lib	Sun Jan 27 11:15:26 2013 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/va009039/code/BaseJpegDecode/#e243fa781e5c
+http://mbed.org/users/va009039/code/BaseJpegDecode/#85e99ec2e7b5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BaseUsbHost.lib	Sun Jan 27 11:15:26 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/va009039/code/BaseUsbHost/#d931d24c2f81
--- a/FATFileSystem.lib	Wed Dec 05 12:41:25 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/mbed_official/code/FATFileSystem/#b6669c987c8e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MyThread/MyThread.h	Sun Jan 27 11:15:26 2013 +0000
@@ -0,0 +1,52 @@
+// MyThread.h 2012/12/9
+#ifndef MY_THREAD_H
+#define MY_THREAD_H
+
+#define MAGIC_WORD 0xE25A2EA5
+static void thread_handler(void const *argument);
+
+class MyThread {
+public:
+    MyThread() {
+        m_stack_size = DEFAULT_STACK_SIZE;
+        m_stack_pointer = NULL;
+    }
+    void set_stack(uint32_t stack_size=DEFAULT_STACK_SIZE, uint8_t* stack_pointer = NULL) {
+        m_stack_size = stack_size;
+        m_stack_pointer = stack_pointer;
+    }
+    virtual void run() = 0;
+    Thread* start(osPriority priority=osPriorityNormal) {
+        if (m_stack_pointer == NULL) {
+            m_stack_pointer = reinterpret_cast<uint8_t*>(malloc(m_stack_size));
+        }
+        for(int i = 0; i < m_stack_size-64; i += 4) {
+            *reinterpret_cast<uint32_t*>(m_stack_pointer+i) = MAGIC_WORD;
+        }
+        return th = new Thread(thread_handler, this, priority, m_stack_size, m_stack_pointer);
+    }
+
+    int stack_used() {
+        int i;
+        for(i = 0; i < m_stack_size; i += 4) {
+            if(*reinterpret_cast<uint32_t*>(m_stack_pointer+i) != MAGIC_WORD) {
+                break;
+            }
+        }
+        return m_stack_size - i;       
+    }
+
+    int stack_size() { return m_stack_size; }
+protected:
+    Thread* th;
+    uint32_t m_stack_size;
+    uint8_t* m_stack_pointer;
+};
+static void thread_handler(void const *argument) {
+    MyThread* th = (MyThread*)argument;
+    if (th) {
+        th->run();
+    }    
+}
+
+#endif //MY_THREAD_H
--- a/SimpleJpegDecode.cpp	Wed Dec 05 12:41:25 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-#include "SimpleJpegDecode.h"
-
-#define DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);} while(0);
-#define ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
-
-
-#define _1_4020 45
-#define _0_3441 11
-#define _0_7139 23
-#define _1_7718 57
-#define _0_0012 0
-
-int adjust(int r) {
-    if (r >= 0) {
-        if (r <= 255) {
-            return r;
-        } else {
-            return 255;
-        }
-    } else {
-        return 0;
-    }
-}
-    
-void convYUVtoRGB(uint8_t rgb[], int y, int u, int v)
-{
-    rgb[0] = adjust((y*32             + v*_1_4020)/32 + 128);
-    rgb[1] = adjust((y*32 - u*_0_3441 - v*_0_7139)/32 + 128);
-    rgb[2] = adjust((y*32 + u*_1_7718 - v*_0_0012)/32 + 128);
-}
-
-SimpleJpegDecode::SimpleJpegDecode(uint8_t output_mode)
-{
-    m_output_mode = output_mode;
-    clearOnResult();
-}
-
-
-void SimpleJpegDecode::output(int mcu, int block, int scan, int value)
-{
-    int sc = (block < yblock) ? 0 : 1;
-    inputBLOCK(mcu, block, scan, value * qt[sc][scan]);
-}
-
-void SimpleJpegDecode::outputDC(int mcu, int block, int value)
-{
-    output(mcu, block, 0, value);
-    DC_count++;
-}
-
-void SimpleJpegDecode::outputAC(int mcu, int block, int scan, int value)
-{
-    output(mcu, block, scan, value);
-    AC_count++;
-}
-
-void SimpleJpegDecode::outputMARK(uint8_t c)
-{
-}
-
-void SimpleJpegDecode::format_YUV(int mcu, int block, int8_t* values)
-{
-    if (block < yblock+1) {
-        memcpy(m_block_data[block], values, 64);
-        return;
-    }
-    int mcu_x_count = (width+15)/16;
-    int mcu_x = mcu % mcu_x_count;
-    int mcu_y = mcu / mcu_x_count;
-    uint8_t yuv[3];
-    if (yblock == 2) {
-        for(int y = 0; y < 8; y++) {
-            for(int x = 0; x < 16; x++) {
-                yuv[0] = m_block_data[x/8][y*8+x%8] + 128;
-                yuv[1] = m_block_data[2][y*8+x/2] + 128;
-                yuv[2] = values[y*8+x/2] + 128;
-                onResult(mcu_x * 16 + x, mcu_y * 8 + y, yuv);
-            }
-        }
-    } else if (yblock == 4) {
-        for(int y = 0; y < 16; y++) {
-            for(int x = 0; x < 16; x++) {
-                yuv[0] = m_block_data[(y/8)*2+x/8][(y%8)*8+x%8] + 128;
-                yuv[1] = m_block_data[4][(y/2)*8+x/2] + 128;
-                yuv[2] = values[(y/2)*8+x/2] + 128;
-                onResult(mcu_x * 16 + x, mcu_y * 16 + y, yuv);
-            }
-        }
-    } else {
-        ASSERT(yblock == 2 || yblock == 4);
-    }    
-}
-
-void SimpleJpegDecode::format_RGB24(int mcu, int block, int8_t* values)
-{
-    if (block < yblock+1) {
-        memcpy(m_block_data[block], values, 64);
-        return;
-    }
-    int mcu_x_count = (width+15)/16;
-    int mcu_x = mcu % mcu_x_count;
-    int mcu_y = mcu / mcu_x_count;
-    uint8_t rgb[3];
-    if (yblock == 2) {
-        for(int y = 0; y < 8; y++) {
-            for(int x = 0; x < 16; x++) {
-                int8_t yuv_y = m_block_data[x/8][y*8+x%8];
-                int8_t yuv_u = m_block_data[2][y*8+x/2];
-                int8_t yuv_v = values[y*8+x/2];
-                convYUVtoRGB(rgb, yuv_y, yuv_u, yuv_v);
-                onResult(mcu_x * 16 + x, mcu_y * 8 + y, rgb);
-            }
-        }
-    } else if (yblock == 4) {
-        for(int y = 0; y < 16; y++) {
-            for(int x = 0; x < 16; x++) {
-                int8_t yuv_y = m_block_data[(y/8)*2+x/8][(y%8)*8+x%8];
-                int8_t yuv_u = m_block_data[4][(y/2)*8+x/2];
-                int8_t yuv_v = values[(y/2)*8+x/2];
-                convYUVtoRGB(rgb, yuv_y, yuv_u, yuv_v);
-                onResult(mcu_x * 16 + x, mcu_y * 16 + y, rgb);
-            }
-        }
-    } else {
-        ASSERT(yblock == 2 || yblock == 4);
-    }    
-}
-
-void SimpleJpegDecode::outputBLOCK(int mcu, int block, int8_t* values)
-{
-    BLOCK_count++;
-    if (m_output_mode == YUV) {
-        format_YUV(mcu, block, values);
-    } else if (m_output_mode == RGB24) {
-        format_RGB24(mcu, block, values);
-    } else {
-        ASSERT(m_output_mode == YUV || m_output_mode == RGB24);
-    }    
-}
-
-void SimpleJpegDecode::onResult(int x, int y, uint8_t* yuv)
-{
-  if(m_pCbItem && m_pCbMeth)
-    (m_pCbItem->*m_pCbMeth)(x, y, yuv);
-  else if(m_pCb)
-    m_pCb(x, y, yuv);
-}
-
-void SimpleJpegDecode::setOnResult( void (*pMethod)(int, int, uint8_t*) )
-{
-  m_pCb = pMethod;
-  m_pCbItem = NULL;
-  m_pCbMeth = NULL;
-}
-
-void SimpleJpegDecode::clearOnResult()
-{
-  m_pCb = NULL;
-  m_pCbItem = NULL;
-  m_pCbMeth = NULL;
-}
--- a/SimpleJpegDecode.h	Wed Dec 05 12:41:25 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-#ifndef SIMPLE_JPEG_DECODE_H
-#define SIMPLE_JPEG_DECODE_H
-
-#include "BaseJpegDecode.h"
-#include "inverseDCT.h"
-
-#define YUV   0
-#define RGB24 1
-
-class SimpleJpegDecode : public BaseJpegDecode, public inverseDCT {
-public:
-    SimpleJpegDecode(uint8_t output_mode=RGB24);
-
-    void format_YUV(int mcu, int block, int8_t* values);
-    void format_RGB24(int mcu, int block, int8_t* values);
-
-    void output(int mcu, int block, int scan, int value);
-    virtual void outputDC(int mcu, int block, int value);
-    virtual void outputAC(int mcu, int block, int scan, int value);
-    virtual void outputMARK(uint8_t c);
-    virtual void outputBLOCK(int muc, int block, int8_t* values); // iDCT
-
-    int8_t m_block_data[5][64];
-    int DC_count;
-    int AC_count;
-    int BLOCK_count;
-
-    ///Setups the result callback
-    /**
-     @param pMethod : callback function
-     */
-    void setOnResult( void (*pMethod)(int, int, uint8_t*) );
-  
-    ///Setups the result callback
-    /**
-    @param pItem : instance of class on which to execute the callback method
-    @param pMethod : callback method
-    */
-    class CDummy;
-    template<class T> 
-    void setOnResult( T* pItem, void (T::*pMethod)(int, int, uint8_t*) )
-    {
-        m_pCb = NULL;
-        m_pCbItem = (CDummy*) pItem;
-        m_pCbMeth = (void (CDummy::*)(int, int, uint8_t*)) pMethod;
-    }
-    void clearOnResult();
-protected:
-    void onResult(int x, int y, uint8_t* yuv);
-    CDummy* m_pCbItem;
-    void (CDummy::*m_pCbMeth)(int, int, uint8_t*);
-    void (*m_pCb)(int, int, uint8_t*);
-    uint8_t m_output_mode;
-};
-
-#endif // SIMPLE_JPEG_DECODE_H
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UvcCam/UvcCam.cpp	Sun Jan 27 11:15:26 2013 +0000
@@ -0,0 +1,566 @@
+// UvcCam.cpp 2013/1/25
+#include "mbed.h"
+#include "rtos.h"
+#include "BaseUsbHost.h"
+//#define DEBUG
+#include "BaseUsbHostDebug.h"
+#define TEST
+#include "BaseUsbHostTest.h"
+#include "UvcCam.h"
+
+UvcCam::UvcCam(int formatIndex, int frameIndex, uint32_t interval, ControlEp* ctlEp)
+{
+    uint8_t buf[34];
+    int rc;
+    int alt;
+    int cfg2;
+    
+    if (ctlEp == NULL) { // root hub
+        DBG_OHCI(LPC_USB->HcRhPortStatus1);
+        TEST_ASSERT_FALSE(LPC_USB->HcRhPortStatus1 & 0x200);
+        ctlEp = new ControlEp();
+        TEST_ASSERT_TRUE(ctlEp);
+    }
+    bool r = check(ctlEp);
+    TEST_ASSERT(r);
+    m_ctlEp = ctlEp;
+    
+    UvcCfg* cfg = new UvcCfg(formatIndex, frameIndex, ctlEp);
+    TEST_ASSERT(cfg);
+
+    int param_len = 34;
+    TEST_ASSERT(cfg->bcdUVC >= 0x0100);
+    if (cfg->bcdUVC == 0x0100) { // UVC ver. 1.0
+        param_len = 26;
+    }
+    
+    int addr = m_ctlEp->GetAddr();
+    m_isoEp = new IsochronousEp(addr, cfg->bEndpointAddress, cfg->wMaxPacketSize);
+    TEST_ASSERT_TRUE(m_isoEp);
+
+//#define USE_PROBE
+
+#ifdef USE_PROBE
+    rc = Control(GET_INFO, VS_PROBE_CONTROL, 1, buf, 1);
+    TEST_ASSERT(rc == USB_OK);
+    DBG_BYTES("GET_INFO Prob", buf, 1);
+
+    rc = Control(GET_DEF, VS_PROBE_CONTROL, 1, buf, param_len);
+    TEST_ASSERT(rc == USB_OK);
+    DBG_BYTES("GET_DEF Probe", buf, param_len);
+
+    rc = Control(GET_MIN, VS_PROBE_CONTROL, 1, buf, param_len);
+    TEST_ASSERT(rc == USB_OK);
+    DBG_BYTES("GET_MIN Probe", buf, param_len);
+
+    rc = Control(GET_MAX, VS_PROBE_CONTROL, 1, buf, param_len);
+    TEST_ASSERT(rc == USB_OK);
+    DBG_BYTES("GET_MAX Probe", buf, param_len);
+
+    rc = Control(GET_CUR, VS_PROBE_CONTROL, 1, buf, param_len);
+    TEST_ASSERT(rc == USB_OK);
+    DBG_BYTES("GET_CUR Probe", buf, param_len);
+#endif // USE_PROBE
+
+    rc = Control(GET_INFO, VS_COMMIT_CONTROL, 1, buf, 1);
+    TEST_ASSERT(rc == USB_OK);
+    DBG_BYTES("GET_INFO Commit", buf, 1);
+
+    memset(buf, 0, param_len);
+    buf[2] = cfg->FormatIndex;
+    buf[3] = cfg->FrameIndex;
+    *reinterpret_cast<uint32_t*>(buf+4) = interval;
+    
+    DBG_BYTES("SET_CUR Commit", buf, param_len);
+    rc = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, param_len);
+    TEST_ASSERT(rc == USB_OK);
+
+    rc = Control(GET_CUR, VS_COMMIT_CONTROL, 1, buf, param_len);
+    TEST_ASSERT(rc == USB_OK);
+    TEST_ASSERT_EQUAL(buf[2], cfg->FormatIndex);
+    TEST_ASSERT_EQUAL(buf[3], cfg->FrameIndex);
+    TEST_ASSERT_EQUAL(*reinterpret_cast<uint32_t*>(buf+4), interval);
+    DBG_BYTES("GET_CUR Commit", buf, param_len);
+
+    rc = m_ctlEp->GetConfiguration(&cfg2);
+    TEST_ASSERT_EQUAL(rc, USB_OK);
+    DBG("config: %d\n", cfg2);
+
+    rc = m_ctlEp->SetConfiguration(1);
+    TEST_ASSERT_EQUAL(rc, USB_OK);
+
+    rc = m_ctlEp->GetConfiguration(&cfg2);
+    TEST_ASSERT_EQUAL(rc, USB_OK);
+    DBG("config: %d\n", cfg2);
+    TEST_ASSERT_EQUAL(cfg2, 1);
+
+    rc = m_ctlEp->GetInterface(cfg->bInterface, &alt);
+    TEST_ASSERT_EQUAL(rc, USB_OK);
+    DBG("alt: %d\n", alt);
+
+    rc = m_ctlEp->SetInterfaceAlternate(cfg->bInterface, cfg->bAlternate);
+    TEST_ASSERT_EQUAL(rc, USB_OK);
+
+    rc = m_ctlEp->GetInterface(cfg->bInterface, &alt);
+    TEST_ASSERT_EQUAL(rc, USB_OK);
+    DBG("alt: %d\n", alt);
+    TEST_ASSERT_EQUAL(alt, cfg->bAlternate);
+    delete cfg;
+    
+    for(int i = 0; i < 16; i++) {
+        report_cc_count[i] = 0;
+        report_ps_cc_count[i] = 0;
+    }
+  
+    LPC_USB->HcControl |= OR_CONTROL_PLE; // PeriodicListEnable
+    LPC_USB->HcControl |= OR_CONTROL_IE;  // IsochronousEnable
+}
+
+bool UvcCam::check(ControlEp* ctlEp)
+{
+    if (ctlEp == NULL) {
+        return false;
+    }
+    uint8_t buf[18];
+    int r = ctlEp->GetDescriptor(1, 0, buf, 8);
+    if (r != USB_OK) {
+        return false;
+    }
+    DBG_HEX(buf, 8);
+    const uint8_t desc[] = {0x12,0x01,0x00,0x02,0xef,0x02,0x01};
+    if (memcmp(buf, desc, sizeof(desc)) != 0) {
+        return false;
+    }
+    r = ctlEp->GetDescriptor(1, 0, buf, 18);
+    if (r != USB_OK) {
+        return false;
+    }
+    DBG_HEX(buf, 18);
+    return true;
+}
+
+#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_INTERFACE_ASSOCIATION 0x0b
+
+#define DESCRIPTOR_TYPE_HID          0x21
+#define DESCRIPTOR_TYPE_REPORT       0x22
+#define DESCRIPTOR_TYPE_PHYSICAL     0x23
+#define DESCRIPTOR_TYPE_CS_INTERFACE 0x24
+#define DESCRIPTOR_TYPE_CS_ENDPOINT  0x25
+#define DESCRIPTOR_TYPE_HUB          0x29
+
+#define CLASS_AUDIO 0x02
+#define CLASS_HUB   0x09
+
+#define IF_EQ_THEN_PRINTF(A,B) if (A == B) {VERBOSE("%s\n", #A);
+#define ENDIF }
+
+#define CC_AUDIO 0x01
+#define SC_AUDIOCONTROL   0x01
+#define SC_AUDIOSTREAMING 0x02
+
+#define AC_HEADER          0x01
+#define AC_INPUT_TERMINAL  0x02
+#define AC_OUTPUT_TERMINAL 0x03
+#define AC_FEATURE_UNIT    0x06
+
+// Input Terminal Types
+#define ITT_CAMERA 0x0201
+
+static int LE16(const uint8_t* d)
+{
+    return d[0] | (d[1] << 8);
+}
+
+static int LE24(const uint8_t* d) {
+    return d[0] | (d[1]<<8) | (d[2] << 16);
+}
+
+static int LE32(const uint8_t* d) {
+    return d[0] |(d[1]<<8) | (d[2] << 16) |(d[3] << 24) ;
+}
+
+UvcCfg::UvcCfg(int formatIndex, int frameIndex, ControlEp* ctlEp):wMaxPacketSize(0)
+{
+    TEST_ASSERT(ctlEp);
+    switch(formatIndex) {
+        case UVC_MJPEG: _payload = UVC_MJPEG; break;
+        case UVC_YUY2:  _payload = UVC_YUY2; break;
+        default:        _payload = UVC_MJPEG; break;
+    }
+
+    switch(frameIndex) {
+        case UVC_160x120: _width = 160; _height = 120; break;
+        case UVC_176x144: _width = 176; _height = 144; break;
+        case UVC_320x176: _width = 320; _height = 176; break;
+        case UVC_320x240: _width = 320; _height = 240; break;
+        case UVC_352x288: _width = 352; _height = 288; break;
+        case UVC_432x240: _width = 432; _height = 240; break;
+        case UVC_640x480: _width = 640; _height = 480; break;
+        case UVC_544x288: _width = 544; _height = 288; break;
+        case UVC_640x360: _width = 640; _height = 360; break;
+        case UVC_752x416: _width = 752; _height = 416; break;
+        case UVC_800x448: _width = 800; _height = 448; break;
+        case UVC_800x600: _width = 800; _height = 600; break;
+        default:          _width = 160; _height = 120; break;
+    }
+    int index = 0;
+    uint8_t temp[4];
+    int rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, temp, sizeof(temp));
+    TEST_ASSERT(rc == USB_OK);
+    DBG_BYTES("Config Descriptor 4bytes", temp, sizeof(temp));
+    TEST_ASSERT(temp[0] == 9);
+    TEST_ASSERT(temp[1] == 0x02);
+    int TotalLength = LE16(temp+2);
+    DBG("TotalLength: %d\n", TotalLength);
+
+    uint8_t* buf = new uint8_t[TotalLength];
+    TEST_ASSERT(buf);
+    rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, TotalLength);
+    TEST_ASSERT(rc == USB_OK);
+    if (rc != USB_OK) {
+        delete[] buf;
+        return;
+    }
+    _parserConfigurationDescriptor(buf, TotalLength);
+    delete[] buf;
+}
+
+void UvcCfg::_parserAudioControl(uint8_t* buf, int len) {
+    int subtype = buf[2];
+    IF_EQ_THEN_PRINTF(AC_HEADER, subtype)
+    VERBOSE("ADC: %04x\n", LE16(buf+3));
+    VERBOSE("TotalLength: %d\n", LE16(buf+5));
+    VERBOSE("InCollection: %d\n", buf[7]);
+    for (int n = 1; n <= buf[7]; n++) {
+        VERBOSE("aInterfaceNr(%d): %d\n", n, buf[8+n-1]);
+    }
+    ENDIF
+    IF_EQ_THEN_PRINTF(AC_INPUT_TERMINAL, subtype)
+    VERBOSE("TerminalID: %d\n", buf[3]);
+    VERBOSE("TerminalType: %04X\n", LE16(buf+4));
+    VERBOSE("AssocTermianl: %d\n", buf[6]);
+    VERBOSE("NrChannels: %d\n", buf[7]);
+    ENDIF
+    IF_EQ_THEN_PRINTF(AC_OUTPUT_TERMINAL, subtype)
+    VERBOSE("TerminalID: %d\n", buf[3]);
+    VERBOSE("TerminalType: %04X\n", LE16(buf+4));
+    VERBOSE("AssocTermianl: %d\n", buf[6]);
+    ENDIF
+    IF_EQ_THEN_PRINTF(AC_FEATURE_UNIT, subtype)
+    VERBOSE("UnitID: %d\n", buf[3]);
+    VERBOSE("SourceID: %d\n", buf[4]);
+    VERBOSE("ControlSize: %d\n", buf[5]);
+    ENDIF
+}
+
+#define AS_GENERAL     0x01
+#define AS_FORMAT_TYPE 0x02
+
+void UvcCfg::_parserAudioStream(uint8_t* buf, int len) {
+    int subtype = buf[2];
+    IF_EQ_THEN_PRINTF(AS_GENERAL, subtype)
+    VERBOSE("TerminalLink: %d\n", buf[3]);
+    VERBOSE("Delay: %d\n", buf[4]);
+    VERBOSE("FormatTag: %04x\n", LE16(buf+5));
+    ENDIF
+    IF_EQ_THEN_PRINTF(AS_FORMAT_TYPE, subtype)
+    VERBOSE("FormatType: %d\n", buf[3]);
+    VERBOSE("NrChannels: %d\n", buf[4]);
+    VERBOSE("SubFrameSize: %d\n", buf[5]);
+    VERBOSE("BitResolution: %d\n", buf[6]);
+    VERBOSE("SamFreqType: %d\n", buf[7]);
+    VERBOSE("SamFreq(1): %d\n", LE24(buf+8));
+    ENDIF
+}
+
+#define CC_VIDEO 0x0e
+
+#define SC_VIDEOCONTROL   0x01
+#define SC_VIDEOSTREAMING 0x02
+
+#define VC_HEADER          0x01
+#define VC_INPUT_TERMINAL  0x02
+#define VC_OUTPUT_TERMINAL 0x03
+#define VC_SELECTOR_UNIT   0x04
+#define VC_PROCESSING_UNIT 0x05
+#define VC_EXTENSION_UNIT  0x06
+
+void UvcCfg::_parserVideoControl(uint8_t* buf, int len) {
+    int subtype = buf[2];
+    IF_EQ_THEN_PRINTF(VC_HEADER, subtype)
+        bcdUVC = LE16(buf+3);
+        VERBOSE("UVC: %04x\n", bcdUVC);
+        VERBOSE("TotalLength: %d\n", LE16(buf+5));
+        VERBOSE("ClockFrequency: %d\n", LE32(buf+7));
+        VERBOSE("InCollection: %d\n", buf[11]);
+        VERBOSE("aInterfaceNr(1): %d\n", buf[12]);
+    ENDIF
+    IF_EQ_THEN_PRINTF(VC_INPUT_TERMINAL, subtype)
+        VERBOSE("TerminalID: %d\n", buf[3]);
+        uint16_t tt = LE16(buf+4);
+        VERBOSE("TerminalType: %04X\n", tt);
+        VERBOSE("AssocTerminal: %d\n", buf[6]);
+        VERBOSE("Terminal: %d\n", buf[7]);
+        if (tt == ITT_CAMERA) { // camera
+            int bControlSize = buf[14];
+            VERBOSE("ControlSize: %d\n", bControlSize);
+            for(int i = 0; i < bControlSize; i++) {
+            uint8_t bControls = buf[15+i];
+                VERBOSE("Controls(%d): %02X\n", i, bControls); 
+            }
+        }
+    ENDIF
+    IF_EQ_THEN_PRINTF(VC_OUTPUT_TERMINAL, subtype)
+        VERBOSE("TerminalID: %d\n", buf[3]);
+        VERBOSE("TerminalType: %04X\n", LE16(buf+4));
+        VERBOSE("AssocTerminal: %d\n", buf[6]);
+        VERBOSE("SourceID: %d\n", buf[7]);
+        VERBOSE("Terminal: %d\n", buf[8]);
+    ENDIF
+    IF_EQ_THEN_PRINTF(VC_SELECTOR_UNIT, subtype)
+        VERBOSE("UnitID: %d\n", buf[3]);
+    ENDIF
+    IF_EQ_THEN_PRINTF(VC_PROCESSING_UNIT, subtype)
+        VERBOSE("UnitID: %d\n", buf[3]);
+        VERBOSE("SourceID: %d\n", buf[4]);
+        VERBOSE("MaxMultiplier: %d\n", LE16(buf+5));
+        VERBOSE("ControlSize: %d\n", buf[7]);
+        int pos = 8;
+        for (int n = 1; n <= buf[7]; n++) {
+            VERBOSE("Controls(%d): %02X\n", n , buf[pos]);
+            pos++;
+        }
+        VERBOSE("Processing: %d\n", buf[pos]);
+        pos++;
+        VERBOSE("VideoStanders: %02X\n", buf[pos]);
+    ENDIF
+    IF_EQ_THEN_PRINTF(VC_EXTENSION_UNIT, subtype)
+        VERBOSE("UnitID: %d\n", buf[3]);
+    ENDIF
+}
+
+#define VS_INPUT_HEADER 0x01
+#define VS_STILL_FRAME  0x03
+#define VS_FORMAT_UNCOMPRESSED 0x04
+#define VS_FRAME_UNCOMPRESSED 0x05
+#define VS_FORMAT_MJPEG 0x06
+#define VS_FRAME_MJPEG  0x07
+#define VS_COLOR_FORMAT 0x0d
+
+void UvcCfg::_parserVideoStream(uint8_t* buf, int len) {
+    int subtype = buf[2];
+    IF_EQ_THEN_PRINTF(VS_INPUT_HEADER, subtype)
+        VERBOSE("NumFormats: %d\n", buf[3]);
+        VERBOSE("TotalLength: %d\n", LE16(buf+4));
+        VERBOSE("EndpointAddress: %02X\n", buf[6]);
+        VERBOSE("Info: %02X\n", buf[7]);
+        VERBOSE("TerminalLink: %d\n", buf[8]);
+        VERBOSE("StillCaptureMethod: %d\n", buf[9]);
+        VERBOSE("TriggerSupport: %d\n", buf[10]);
+        VERBOSE("TriggerUsage: %d\n", buf[11]);
+        VERBOSE("ControlSize: %d\n", buf[12]);
+        int pos = 13;
+        for (int n = 1; n <= buf[12]; n++) {
+            VERBOSE("Controls(%d): %02X\n", n, buf[pos]);
+            pos++;
+        }
+        bEndpointAddress = buf[6];
+    ENDIF
+    IF_EQ_THEN_PRINTF(VS_STILL_FRAME, subtype)
+    VERBOSE("EndpointAdress: %02X\n", buf[3]);
+    VERBOSE("NumImageSizePatterns: %d\n", buf[4]);
+    int ptn = buf[4];
+    int pos = 5;
+    for (int n = 1; n <= ptn; n++) {
+        VERBOSE("Width(%d): %d\n", n, LE16(buf+pos));
+        VERBOSE("Height(%d): %d\n", n, LE16(buf+pos+2));
+        pos += 4;
+    }
+    VERBOSE("NumCompressPtn: %d\n", buf[pos]);
+    ptn = buf[pos++];
+    for (int n = 1; n <= ptn; n++) {
+        VERBOSE("Compress(%d): %d\n", n, buf[pos]);
+        pos++;
+    }
+    ENDIF
+    IF_EQ_THEN_PRINTF(VS_FORMAT_UNCOMPRESSED, subtype)
+        VERBOSE("FormatIndex: %d\n", buf[3]);
+        VERBOSE("NumFrameDescriptors: %d\n", buf[4]);
+        uint32_t guid = LE32(buf+5);
+        if (guid == 0x32595559) {
+            VERBOSE("GUID: YUY2\n");
+        } else if (guid == 0x3231564e) {
+            VERBOSE("GUID: NV12\n");
+        } else {
+            VERBOSE("GUID: %08x\n", guid);
+        }
+        VERBOSE("DefaultFrameIndex: %d\n", buf[22]);
+        if (_payload == UVC_YUY2) {
+            FormatIndex = buf[3];
+        }
+    ENDIF
+    IF_EQ_THEN_PRINTF(VS_FRAME_UNCOMPRESSED, subtype)
+        VERBOSE("FrameIndex: %d\n", buf[3]);
+        VERBOSE("Capabilites: %d\n", buf[4]);
+        VERBOSE("Width: %d\n", LE16(buf+5));
+        VERBOSE("Height: %d\n", LE16(buf+7));
+        VERBOSE("MinBitRate: %d\n", LE32(buf+9));
+        VERBOSE("MaxBitRate: %d\n", LE32(buf+13));
+        VERBOSE("MaxVideoFrameBufferSize: %d\n", LE32(buf+17));
+        VERBOSE("DefaultFrameInterval: %d\n", LE32(buf+21));
+        VERBOSE("FrameIntervalType: %d\n", buf[25]);
+        int it = buf[25];
+        uint32_t max_fi = 333333; // 30.0fps
+        if (it == 0) {
+            VERBOSE("FrameMinInterval: %d\n", buf[26]);
+            VERBOSE("FrameMaxInterval: %d\n", buf[30]);
+            VERBOSE("FrameIntervalStep: %d\n", buf[34]);
+        } else {
+            int pos = 26;
+            for (int n = 1; n <= it; n++) {
+                uint32_t fi = LE32(buf+pos);
+                if (fi >= max_fi) {
+                    max_fi = fi;
+                }
+                float fps = 1e+7 / fi;
+                VERBOSE("FrameInterval(%u): %d (%.1f fps)\n", n, fi, fps);
+                pos += 4;
+            }
+        }
+        if (_payload == UVC_YUY2) {
+            if (_width == LE16(buf+5) && _height == LE16(buf+7)) {
+                FrameIndex = buf[3];
+            }
+            if (dwFrameInterval == 0) {
+                dwFrameInterval = max_fi;
+            }
+        }
+    ENDIF
+    IF_EQ_THEN_PRINTF(VS_FORMAT_MJPEG, subtype)
+        VERBOSE("FormatIndex: %d\n", buf[3]);
+        VERBOSE("NumFrameDescriptors: %d\n", buf[4]);
+        VERBOSE("Flags: %d\n", buf[5]);
+        VERBOSE("DefaultFrameIndex: %d\n", buf[6]);
+        if (_payload == UVC_MJPEG) {
+            FormatIndex = buf[3];
+        }
+    ENDIF
+    IF_EQ_THEN_PRINTF(VS_FRAME_MJPEG, subtype)
+        VERBOSE("FrameIndex: %d\n", buf[3]);
+        VERBOSE("Capabilites: %d\n", buf[4]);
+        VERBOSE("Width: %d\n", LE16(buf+5));
+        VERBOSE("Height: %d\n", LE16(buf+7));
+        VERBOSE("MinBitRate: %d\n", LE32(buf+9));
+        VERBOSE("MaxBitRate: %d\n", LE32(buf+13));
+        VERBOSE("MaxVideoFrameBufferSize: %d\n", LE32(buf+17));
+        VERBOSE("DefaultFrameInterval: %d\n", LE32(buf+21));
+        VERBOSE("FrameIntervalType: %d\n", buf[25]);
+        int it = buf[25];
+        uint32_t max_fi = 333333; // 30.0fps
+        if (it == 0) {
+            VERBOSE("FrameMinInterval: %d\n", buf[26]);
+            VERBOSE("FrameMaxInterval: %d\n", buf[30]);
+            VERBOSE("FrameIntervalStep: %d\n", buf[34]);
+        } else {
+            int pos = 26;
+            for (int n = 1; n <= it; n++) {
+                uint32_t fi = LE32(buf+pos);
+                if (fi >= max_fi) {
+                    max_fi = fi;
+                }
+                float fps = 1e+7 / fi;
+                VERBOSE("FrameInterval(%u): %d (%.1f fps)\n", n, fi, fps);
+                pos += 4;
+            }
+        }
+        if (_payload == UVC_MJPEG) {
+            if (_width == LE16(buf+5) && _height == LE16(buf+7)) {
+                FrameIndex = buf[3];
+            }
+            if (dwFrameInterval == 0) {
+                dwFrameInterval = max_fi;
+            }
+        }
+    ENDIF
+    IF_EQ_THEN_PRINTF(VS_COLOR_FORMAT, subtype)
+    ENDIF
+}
+
+void UvcCfg::_parserConfigurationDescriptor(uint8_t* buf, int len) {
+    int pos = 0;
+    _IfClass = 0;
+    _IfSubClass = 0;
+    while (pos < len) {
+        int type = buf[pos+1];
+        //DBG_BYTES(TYPE_Str(type), buf+pos, buf[pos]);
+        IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_CONFIGURATION, type)
+            VERBOSE("NumInterfaces: %d\n", buf[pos+4]);
+        ENDIF
+        IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, type)
+            VERBOSE("FirstInterface: %d\n", buf[pos+2]);
+            VERBOSE("InterfaceCount: %d\n", buf[pos+3]);
+            VERBOSE("FunctionClass: %02X\n", buf[pos+4]);
+            VERBOSE("FunctionSubClass: %02X\n", buf[pos+5]);
+            VERBOSE("FunctionProtocol: %02X\n", buf[pos+6]);
+            VERBOSE("Function: %d\n", buf[pos+7]);
+        ENDIF
+        IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_INTERFACE,type)
+            VERBOSE("InterfaceNumber: %d\n", buf[pos+2]);
+            VERBOSE("AlternateSetting: %d\n", buf[pos+3]);
+            VERBOSE("NumEndpoint: %d\n", buf[pos+4]);
+            VERBOSE("InterfaceClass: %02X\n", buf[pos+5]);
+            VERBOSE("InterfaceSubClass: %02X\n", buf[pos+6]);
+            VERBOSE("InterfaceProtocol: %02X\n", buf[pos+7]);
+            VERBOSE("Interface: %d\n", buf[pos+8]);
+            _If         = buf[pos+2];
+            _Ifalt      = buf[pos+3];
+            _IfClass    = buf[pos+5];
+            _IfSubClass = buf[pos+6];
+        ENDIF
+        IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_ENDPOINT, type)
+            VERBOSE("EndpointAddress: %02X\n", buf[pos+2]);
+            VERBOSE("Attributes: %02X\n", buf[pos+3]);
+            VERBOSE("MaxPacketSize: %d\n", LE16(buf+pos+4));
+            VERBOSE("Interval: %d\n", buf[pos+6]);
+            if (_IfClass == CC_VIDEO && _IfSubClass == SC_VIDEOSTREAMING) {
+                if (bEndpointAddress == buf[pos+2]) {
+                    if (wMaxPacketSize == 0) {
+                        wMaxPacketSize = LE16(buf+pos+4);
+                    }    
+                    if (wMaxPacketSize == LE16(buf+pos+4)) {
+                        bInterface = _If;
+                        bAlternate = _Ifalt;
+                    }
+                }
+            }
+        ENDIF
+        IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_CS_INTERFACE, type)
+            IF_EQ_THEN_PRINTF(CC_VIDEO, _IfClass)
+                IF_EQ_THEN_PRINTF(SC_VIDEOCONTROL, _IfSubClass)
+                    _parserVideoControl(buf+pos, buf[pos]);
+                ENDIF
+                IF_EQ_THEN_PRINTF(SC_VIDEOSTREAMING, _IfSubClass)
+                    _parserVideoStream(buf+pos, buf[pos]);
+                ENDIF
+            ENDIF
+            IF_EQ_THEN_PRINTF(CC_AUDIO, _IfClass)
+                IF_EQ_THEN_PRINTF(SC_AUDIOCONTROL, _IfSubClass)
+                    _parserAudioControl(buf+pos, buf[pos]);
+                ENDIF 
+                IF_EQ_THEN_PRINTF(SC_AUDIOSTREAMING, _IfSubClass)
+                    _parserAudioStream(buf+pos, buf[pos]);
+                ENDIF
+            ENDIF
+        ENDIF
+        IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_HUB, type)
+        ENDIF
+        pos += buf[pos];
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UvcCam/UvcCam.h	Sun Jan 27 11:15:26 2013 +0000
@@ -0,0 +1,55 @@
+// UvcCam.h 2012/12/9
+#ifndef UVC_CAM_H
+#define UVC_CAM_H
+
+#define UVC_160x120 2
+#define UVC_176x144 3
+#define UVC_320x176 4
+#define UVC_320x240 5
+#define UVC_352x288 6
+#define UVC_432x240 7
+#define UVC_640x480 1
+#define UVC_544x288 8
+#define UVC_640x360 9
+#define UVC_752x416 10
+#define UVC_800x448 11
+#define UVC_800x600 12
+
+#define UVC_MJPEG 2
+#define UVC_YUY2  1
+
+#define VERBOSE(...) do{printf(__VA_ARGS__);} while(0);
+
+class UvcCam : public BaseUvc {
+public:
+    UvcCam(int formatIndex = UVC_MJPEG, int frameIndex = UVC_160x120, uint32_t interval = _5FPS, ControlEp* ctlEp = NULL);
+    static bool check(ControlEp* ctlEp);
+};
+
+class UvcCfg {
+public:
+    UvcCfg(int formatIndex, int frameIndex, ControlEp* ctlEp);
+    uint8_t bEndpointAddress; 
+    uint16_t wMaxPacketSize;
+    uint8_t FormatIndex;
+    uint8_t FrameIndex;
+    uint32_t dwFrameInterval;
+    uint8_t bInterface;
+    uint8_t bAlternate;
+    uint16_t bcdUVC;
+protected:
+    void _parserAudioControl(uint8_t* buf, int len);
+    void _parserAudioStream(uint8_t* buf, int len);
+    void _parserVideoControl(uint8_t* buf, int len);
+    void _parserVideoStream(uint8_t* buf, int len);
+    void _parserConfigurationDescriptor(uint8_t* buf, int len);
+    uint16_t _width;
+    uint16_t _height;
+    uint8_t _payload;
+    int _If;
+    int _Ifalt;
+    int _IfClass;
+    int _IfSubClass;
+};
+
+#endif //UVC_CAM_H
--- a/bmp24.h	Wed Dec 05 12:41:25 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-#ifndef BMP24_H
-#define BMP24_H
-
-#define BMP24_WIDTH  (16*4)
-#define BMP24_HEIGHT (16*3)
-
-class bmp24 {
-public:
-    int width;
-    int height;
-
-    bmp24() {
-        width = BMP24_WIDTH;
-        height = BMP24_HEIGHT;
-    }
-    
-    void clear() {
-        memset(m_bitmap, 0, sizeof(m_bitmap));
-    }
-    
-    void point(int x, int y, uint8_t* rgb) {
-        if (x >= 0 && x < width && y >= 0 && y < height) {
-            int pos = y*width*3+x*3;
-            m_bitmap[pos++] = rgb[0];
-            m_bitmap[pos++] = rgb[1];
-            m_bitmap[pos]   = rgb[2];
-        }
-    }
-    
-    void LE32write(uint8_t* buf, int value) {
-        *buf++ = value & 0xff;
-        *buf++ = (value>>8) & 0xff;
-        *buf++ = (value>>16) & 0xff;
-        *buf   = (value>>24) & 0xff;
-    }
-    
-    void writeFile(const char *path) {
-        FILE *fp = fopen(path, "wb");
-        if (fp == NULL) {
-            return;
-        }
-        uint8_t header[] = {
-0x42,0x4d,0x36,0xe1,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x28,0x00,
-0x00,0x00,0xa0,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00};
-        int file_size = sizeof(header) + sizeof(m_bitmap);
-        LE32write(header+2, file_size);
-        LE32write(header+18, width);
-        LE32write(header+22, height);
-        
-        fwrite(header, 1, sizeof(header), fp);
-        for(int y = height-1; y >=0; y--) {
-            for(int x = 0; x < width; x++) {
-                fputc(m_bitmap[y*width*3+x*3+2], fp);
-                fputc(m_bitmap[y*width*3+x*3+1], fp);
-                fputc(m_bitmap[y*width*3+x*3+0], fp);
-            }
-        }    
-        fclose(fp);
-    }
-    
-    uint8_t m_bitmap[BMP24_WIDTH*BMP24_HEIGHT*3];
-};
-
-#endif // BMP24_H
--- a/example1_c270.cpp	Wed Dec 05 12:41:25 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-#if 1
-//
-// simple color tracking
-//
-#include "mbed.h"
-#include "BaseJpegDecode.h"
-#include "uvc.h"
-#include "Terminal.h"
-
-// Logitech C270
-#define WIDTH  320
-//#define HEIGHT 176
-
-// LifeCam
-#define HEIGHT 240
-
-#define THRESHOLD 100
-
-#define ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
-
-DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
-Terminal term(USBTX, USBRX);
-
-class CalcCenter : public BaseJpegDecode {
-public:
-    int y_center, x_center;
-    int m_x_sum, m_y_sum, m_sum;
-    int16_t m_buf[WIDTH/16*HEIGHT/8];
-    virtual void outputDC(int mcu, int block, int value) {
-        if (mcu >= (WIDTH/16*HEIGHT/8)) {
-            return;
-        }
-        if (block == 3) { // 0-1:Y 2:Cb 3:Cr
-            value *= qt[1][0];
-            ASSERT(value < 32367 && value > -32368);
-            m_buf[mcu] = value; // debug
-            if (value >= THRESHOLD) { // red
-                m_x_sum += value*(mcu%(WIDTH/16));
-                m_y_sum += value*(mcu/(WIDTH/16));
-                m_sum += value;
-            }
-        }
-    }
-    virtual void outputAC(int mcu, int block, int scan, int value){};
-    virtual void outputMARK(uint8_t c){
-        if (c == 0xd9) { // EOI
-            if(m_sum == 0) {
-                x_center = y_center = -1; // not found
-            } else {
-                x_center = m_x_sum / m_sum;
-                y_center = m_y_sum / m_sum;
-            }
-            m_x_sum = m_y_sum = m_sum = 0; // reset
-            led2 = !led2;
-        }
-    };
-};
-
-CalcCenter* calc = NULL;
-
-void callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len)
-{
-    if (calc) {
-        calc->input(buf+12, len-12);
-    }
-    led1 = buf[1]&1; // FID
-}
-
-int main() {
-    term.baud(921600);
-    term.printf("%s\n", __FILE__);
-
-    calc = new CalcCenter;
-    ASSERT(calc);
-    uvc* cam = new uvc;
-    ASSERT(cam);
-    cam->SetImageSize(WIDTH, HEIGHT);
-    cam->SetFrameInterval(2000000); // 5.0fps
-    cam->setOnResult(callback_motion_jpeg);
-    ASSERT(cam->setup() >= 0);
-    term.cls();
-    int fg, old_fg = 0xffffff;
-    while(1) {
-        int y;
-        for(y = 0; y < HEIGHT/8; y++) {
-            term.locate(0, y);
-            for(int x = 0; x < WIDTH/16; x++) {
-                int value = calc->m_buf[y*WIDTH/16+x];
-                if (value >= THRESHOLD) {
-                    fg = 0xff0000; // red
-                } else {
-                    fg = 0xffffff; // white
-                }
-                if (fg != old_fg) {
-                    term.foreground(fg);
-                    old_fg = fg;
-                }
-                term.printf("%+4d,", value);
-                cam->poll();
-            }
-        }
-        term.locate(0, y);
-        term.printf("Cr:(%d,%d)", calc->x_center, calc->y_center);
-        cam->wait_ms(500);
-        led3 = !led3;
-    }
-}
-#endif
--- a/example_SimpleJpegDecode.cpp	Wed Dec 05 12:41:25 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-#if 0
-//
-// split jpeg to bmp files
-//
-#include "mbed.h"
-#include "SimpleJpegDecode.h"
-#include "bmp24.h"
-#include "uvc.h"
-#include "msc.h"
-
-#define ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
-
-DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
-Serial pc(USBTX, USBRX);
-
-SimpleJpegDecode* decode = NULL;
-bmp24* bmp = NULL;
-
-int offset_x = 0;
-int offset_y = 0;
-
-void callbackRGB(int x, int y, uint8_t* rgb)
-{
-    led1 = !led1;
-    if (bmp) {
-        bmp->point(x - offset_x, y - offset_y, rgb);
-    }
-}
-
-int main() {
-    pc.baud(921600);
-    printf("%s\n", __FILE__);
-    
-    msc* usb = new msc("usb");
-    int r = usb->setup();
-    ASSERT(r == 0);
-
-    bmp = new bmp24;
-    ASSERT(bmp);
-
-    decode = new SimpleJpegDecode();
-    ASSERT(decode);
-
-    const char* input_file = "/usb/input.jpg";
-
-    FILE *fp = fopen(input_file, "rb");
-    ASSERT(fp != NULL);
-    Timer benchmark_t;
-    benchmark_t.reset();
-    benchmark_t.start();
-    while(!feof(fp)) {
-        int c = fgetc(fp);
-        led2 = !led2;
-    }
-    benchmark_t.stop();
-    fclose(fp);
-    printf("input: %s, %d ms\n", input_file, benchmark_t.read_ms());
-    
-    decode->clear();
-    fp = fopen(input_file, "rb");
-    ASSERT(fp != NULL);
-    benchmark_t.reset();
-    benchmark_t.start();
-    while(!feof(fp)) {
-        int c = fgetc(fp);
-        decode->input(c);
-        led2 = !led2;
-    }
-    benchmark_t.stop();
-    fclose(fp);
-    printf("width: %d, height: %d, yblock: %d, %d ms\n", decode->width, decode->height, 
-                                                         decode->yblock, benchmark_t.read_ms());
-
-    decode->setOnResult(callbackRGB);
-    int n = 0;
-    for(offset_y = 0; offset_y < decode->height; offset_y += bmp->height) {
-        for(offset_x = 0; offset_x < decode->width; offset_x += bmp->width) {
-            bmp->clear();
-            decode->clear();
-            fp = fopen(input_file, "rb");
-            ASSERT(fp != NULL);
-            benchmark_t.reset();
-            benchmark_t.start();
-            while(!feof(fp)) {
-                int c = fgetc(fp);
-                decode->input(c);
-                led2 = !led2;
-            }
-            benchmark_t.stop();
-            fclose(fp);
-            char path[32];
-            sprintf(path, "/usb/output%02d.bmp", n++);
-            printf("offset: (%3d,%3d), size:(%3d,%3d), %s %d ms\n", 
-                offset_x, offset_y, bmp->width, bmp->height, 
-                path, benchmark_t.read_ms());
-            bmp->writeFile(path);
-            led3 = !led3;
-        }
-        led4 = !led4;
-    }
-    printf("done\n");
-    exit(1);     
-}
-#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Jan 27 11:15:26 2013 +0000
@@ -0,0 +1,153 @@
+// BaseJpegDecode_example/main.cpp 2013/1/27
+// simple color tracking
+//
+#include "mbed.h"
+#include "rtos.h"
+#include "BaseUsbHost.h"
+#include "UvcCam.h"
+#include "BaseJpegDecode.h"
+#include "Terminal.h"
+#include "MyThread.h"
+
+#define WIDTH  160
+#define HEIGHT 120
+
+#define THRESHOLD 200
+
+DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
+Terminal term(USBTX, USBRX);
+
+class CalcCenter : public MyThread, public BaseJpegDecode {
+public:
+    int y_center, x_center;
+    int m_x_sum, m_y_sum, m_sum;
+    uint32_t EOI_count;
+    int16_t buf_Cb[WIDTH/16*HEIGHT/8]; // debug
+    int16_t buf_Cr[WIDTH/16*HEIGHT/8]; // debug
+    CalcCenter(BaseUvc* cam) {
+        m_cam = cam;
+        m_cam->setOnResult(this, &CalcCenter::callback_motion_jpeg);
+        EOI_count = 0;
+    }
+protected:
+    void callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len) {
+        input(buf+12, len-12);
+        if (buf[1]&1) { // FID
+            led1 = !led1;
+        }
+    }
+    
+    virtual void outputDC(int mcu, int block, int value) {
+        if (mcu >= (WIDTH/16*HEIGHT/8)) {
+            return;
+        }
+        if (block == 2) {
+            buf_Cb[mcu] = value * qt[1][0];
+        } else if (block == 3) { // 0-1:Y 2:Cb 3:Cr
+            buf_Cr[mcu] = value * qt[1][0];
+            value *= qt[1][0];
+            if (value >= THRESHOLD) { // red
+                m_x_sum += value*(mcu%(WIDTH/16));
+                m_y_sum += value*(mcu/(WIDTH/16));
+                m_sum += value;
+            }
+        }
+    }
+    virtual void outputAC(int mcu, int block, int scan, int value){};
+    virtual void outputMARK(uint8_t c){
+        if (c == 0xd9) { // EOI
+            if(m_sum == 0) {
+                x_center = y_center = -1; // not found
+            } else {
+                x_center = m_x_sum / m_sum;
+                y_center = m_y_sum / m_sum;
+            }
+            m_x_sum = m_y_sum = m_sum = 0; // reset
+            EOI_count++;
+            led3 = !led3;
+        }
+    }
+
+    virtual void run() {
+        while(true) {
+            if (m_cam) {
+                m_cam->poll();
+            }
+        }
+    }
+    BaseUvc* m_cam;
+};
+
+BaseUvc* cam = NULL;
+CalcCenter* calc = NULL;
+
+class display_Thread : public MyThread {
+    virtual void run() {
+        term.cls();
+        int fg, old_fg = 0xffffff;
+        while(1) {
+            int column = 0;
+            for(int y = 0; y < HEIGHT/8; y++) {
+                term.locate(0, column++);
+                for(int x = 0; x < WIDTH/16; x++) {
+                    int value = calc->buf_Cr[y*WIDTH/16+x];
+                    if (value >= THRESHOLD) {
+                        fg = 0xff0000; // red
+                    } else {
+                        fg = 0xffffff; // white
+                    }
+                    if (fg != old_fg) {
+                        term.foreground(fg);
+                        old_fg = fg;
+                    }
+                    term.printf("%+4d,", value);
+                    Thread::yield();
+                }
+            }
+            term.locate(0, column++);
+            term.printf("Cr:(%d,%d)", calc->x_center, calc->y_center);
+
+            term.locate(0, column++);
+            term.printf("width=%d height=%d yblock=%d EOI: %u]\nCC:", 
+                         calc->width, calc->height, calc->yblock, calc->EOI_count);
+            for(int i = 0; i < 16; i++) {
+                term.printf(" %u", cam->report_cc_count[i]); 
+            }
+            term.printf("]\nPS:"); 
+            for(int i = 0; i < 16; i++) {
+                term.printf(" %u", cam->report_ps_cc_count[i]); 
+            }
+            term.printf("]\n");
+            Thread::wait(150);
+            led2 = !led2;
+        }
+    }
+};
+
+void no_memory () {
+  error("Failed to allocate memory!\n");
+}
+
+int main() {
+    term.baud(921600);
+    term.printf("%s\n", __FILE__);
+    set_new_handler(no_memory);
+
+    BaseUsbHost* UsbHost = new BaseUsbHost;
+    ControlEp* ctlEp = new ControlEp; // root hub
+    if (UsbHub::check(ctlEp)) { // hub?
+        UsbHub* hub = new UsbHub(ctlEp);
+        ctlEp = hub->search<UvcCam>();
+    }
+    if (!UvcCam::check(ctlEp)) {
+        error("UVC camera is not connected\n");
+    }
+    cam = new UvcCam(UVC_MJPEG, UVC_160x120, _15FPS, ctlEp); 
+    calc = new CalcCenter(cam);
+    calc->start();
+
+    display_Thread* display_th = new display_Thread;
+    display_th->start(osPriorityBelowNormal);
+
+    Thread::wait(osWaitForever);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Sun Jan 27 11:15:26 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-rtos/#88a1a9c26ae3
--- a/mbed.bld	Wed Dec 05 12:41:25 2012 +0000
+++ b/mbed.bld	Sun Jan 27 11:15:26 2013 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/b60934f96c0c
\ No newline at end of file
+http://mbed.org/users/mbed_official/code/mbed/builds/0954ebd79f59
\ No newline at end of file
--- a/msc/msc.cpp	Wed Dec 05 12:41:25 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,390 +0,0 @@
-#include "msc.h"
-//#define __DEBUG
-#include "mydbg.h"
-#include "Utils.h"
-
-//#define WRITE_PROTECT
-
-msc::msc(const char* name, int drive): FATFileSystem(name)
-{
-    DBG("drive=%d\n", drive);
-    m_name = name;
-    m_drive = drive;
-    DBG_ASSERT(sizeof(CBW) == 31);
-    DBG_ASSERT(sizeof(CSW) == 13);
-    m_numBlocks = 0;
-    m_BlockSize = 0;
-    m_lun = 0;
-    m_interface = 0;
-    m_pDev = NULL;
-    m_pEpBulkIn = NULL;
-    m_pEpBulkOut = NULL;
-}
-
-int msc::disk_initialize()
-{
-    DBG("m_BlockSize=%d\n", m_BlockSize);
-    if (m_BlockSize != 512) {
-        return 1;
-    }
-    return 0;    
-}
-
-int msc::disk_write(const uint8_t *buffer, uint64_t block_number)
-{
-    DBG("buffer=%p block_number=%d\n", buffer, block_number);
-    int ret = MS_BulkSend(block_number, 1, (uint8_t*)buffer);
-    if (ret >= 0) {
-        return 0;
-    }
-    return 1;
-}
-
-int msc::disk_read(uint8_t *buffer, uint64_t block_number)
-{
-    DBG("buffer=%p block_number=%d\n", buffer, block_number);
-    int ret = MS_BulkRecv(block_number, 1, (uint8_t*)buffer);
-    if (ret >= 0) {
-        return 0;
-    }
-    return 1;
-}    
-
-int msc::disk_status()
-{
-    DBG("\n");
-    return 0;
-}
-
-int msc::disk_sync()
-{
-    DBG("\n");
-    return 0;
-}
-
-uint64_t msc::disk_sectors()
-{
-    DBG("m_numBlocks=%d\n", m_numBlocks);
-    return m_numBlocks;
-}
-
-int msc::setup(int timeout)
-{
-    for(int i = 0; i < 2; i++) {
-        m_pDev = m_pHost->getDeviceByClass(0x08, m_drive); // USB Mass Storage Class
-        if (m_pDev || i > 0) {
-            break;
-        }
-        UsbErr rc = Usb_poll();
-        if (rc == USBERR_PROCESSING) {
-            VERBOSE("%p USBERR_PROCESSING\n", this);
-            return -1;
-        }
-    }
-    DBG("m_pDev=%p\n", m_pDev);
-    if (m_pDev == NULL) {
-        VERBOSE("%p MSC DISK(%d) NOT FOUND\n", this, m_drive);
-        return -1;
-    }
-    DBG_ASSERT(m_pDev);
-
-    ParseConfiguration();
-    
-    GetMaxLUN();
-
-    int retry = 0;
-    Timer t;
-    t.start();
-    t.reset();
-    while(t.read_ms() < timeout) {
-        DBG("retry=%d t=%d\n", retry, t.read_ms());
-        if (retry > 80) {
-            return -1;
-        }
-        int rc = TestUnitReady();
-        DBG("TestUnitReady(): %d\n", rc);
-        if (rc == USBERR_OK) {
-            DBG("m_CSW.bCSWStatus: %02X\n", m_CSW.bCSWStatus);
-            if (m_CSW.bCSWStatus == 0x00) {
-                break;
-            }
-        }
-        GetSenseInfo();
-        retry++;
-        wait_ms(50);
-    }
-    if (t.read_ms() >= timeout) {
-        return -1;
-    }
-    ReadCapacity();
-    Inquire();
-    return 0;
-}
-void msc::_test()
-{
-    ReadCapacity();
-
-    uint8_t buf[512];
-    for(int block = 0; block < m_numBlocks; block++) {
-    DBG("block=%d\n", block);
-        disk_read(buf, block);    
-    }
-    exit(1);
-}
-
-int msc::ParseConfiguration()
-{
-  UsbErr rc;
-  uint8_t ConfigDesc[9];
-  int index = 0;
-  DBG_ASSERT(m_pDev);
-  rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc));
-  DBG_ASSERT(rc == USBERR_OK);
-  DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc));
-  DBG_ASSERT(ConfigDesc[0] == 9);
-  DBG_ASSERT(ConfigDesc[1] == 0x02);
-  int wTotalLength = *((uint16_t*)&ConfigDesc[2]);
-  DBG("TotalLength: %d\n", wTotalLength);
-  int bConfigValue = ConfigDesc[5];
-  DBG_ASSERT(bConfigValue == 1);
-  DBG("ConfigValue: %d\n", bConfigValue);
-  DBG("MaxPower: %d mA\n", ConfigDesc[8]*2);   
-
-  uint8_t* buf = new uint8_t[wTotalLength];
-  DBG_ASSERT(buf);
-  rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength);
-  DBG_ASSERT(rc == USBERR_OK);
-  DBG_ASSERT(ConfigDesc[1] == 0x02);
-  for (int pos = 0; pos < wTotalLength; pos += buf[pos]) {
-      DBG_BYTES("CFG", buf+pos, buf[pos]);
-      int type = buf[pos+1];
-      if (USB_DESCRIPTOR_TYPE_INTERFACE == type) { // 0x04
-        DBG("InterfaceNumber: %d\n", buf[pos+2]);
-        DBG("AlternateSetting: %d\n", buf[pos+3]);
-        DBG("NumEndpoint: %d\n", buf[pos+4]);
-        DBG("InterfaceClass: %02X\n", buf[pos+5]);
-        DBG("InterfaceSubClass: %02X\n", buf[pos+6]);
-        DBG("InterfaceProtocol: %02X\n", buf[pos+7]);
-        DBG_ASSERT(buf[pos+6] == 0x06); // SCSI
-        DBG_ASSERT(buf[pos+7] == 0x50); // bulk only
-      } 
-      if (USB_DESCRIPTOR_TYPE_ENDPOINT == type) {
-          DBG_ASSERT(buf[pos] == 7);
-          uint8_t att = buf[pos+3];
-          if (att == 2) { // bulk
-              uint8_t ep = buf[pos+2];
-              bool dir = ep & 0x80; // true=IN
-              uint16_t size = LE16(buf+pos+4);
-              DBG("EndpointAddress: %02X\n", ep);
-              DBG("Attribute: %02X\n", att);
-              DBG("MaxPacketSize: %d\n", size); 
-              UsbEndpoint* pEp = new UsbEndpoint(m_pDev, ep, dir, USB_BULK, size);
-              DBG_ASSERT(pEp);
-              if (dir) {
-                  m_pEpBulkIn = pEp;
-              } else {
-                  m_pEpBulkOut = pEp;
-              } 
-          }
-      }
-  }
-  delete[] buf;
-  DBG_ASSERT(m_pEpBulkIn);
-  DBG_ASSERT(m_pEpBulkOut);
-  return 0;   
-}
-
-int msc::BulkOnlyMassStorageReset()
-{
-    DBG_ASSERT(m_pDev);
-    UsbErr rc = m_pDev->controlReceive(0x21, 0xff, 0x0000, m_interface, NULL, 0); 
-    DBG_ASSERT(rc == USBERR_OK);
-    return rc;
-}
-
-int msc::GetMaxLUN()
-{
-    DBG_ASSERT(m_interface == 0);
-    uint8_t temp[1];
-    DBG_ASSERT(m_pDev);
-    UsbErr rc = m_pDev->controlReceive(0xa1, 0xfe, 0x0000, m_interface, temp, sizeof(temp)); 
-    DBG_ASSERT(rc == USBERR_OK);
-    DBG_BYTES("GetMaxLUN", temp, sizeof(temp));
-    m_MaxLUN = temp[0];
-    DBG_ASSERT(m_MaxLUN <= 15);
-    return rc;
-}
-
-
-int msc::TestUnitReady()
-{
-    const uint8_t cdb[6] = {SCSI_CMD_TEST_UNIT_READY, 0x00, 0x00, 0x00, 0x00, 0x00};
-    m_CBW.dCBWDataTraansferLength = 0;
-    m_CBW.bmCBWFlags = 0x00;
-    CommandTransport(cdb, sizeof(cdb));
-    StatusTransport();
-    return 0;
-}
-
-int msc::GetSenseInfo()
-{
-    const uint8_t cdb[6] = {SCSI_CMD_REQUEST_SENSE, 0x00, 0x00, 0x00, 18, 0x00};
-    m_CBW.dCBWDataTraansferLength = 18;
-    m_CBW.bmCBWFlags = 0x80; // data In
-    CommandTransport(cdb, sizeof(cdb));
-
-    uint8_t buf[18];
-    _bulkRecv(buf, sizeof(buf));
-    DBG_HEX(buf, sizeof(buf));
-
-    StatusTransport();
-    DBG_ASSERT(m_CSW.bCSWStatus == 0x00);
-    return 0;
-}
-
-int msc::ReadCapacity()
-{
-    const uint8_t cdb[10] = {SCSI_CMD_READ_CAPACITY, 0x00, 0x00, 0x00, 0x00, 
-                                               0x00, 0x00, 0x00, 0x00, 0x00};
-    m_CBW.dCBWDataTraansferLength = 8;
-    m_CBW.bmCBWFlags = 0x80; // data In
-    CommandTransport(cdb, sizeof(cdb));
-
-    uint8_t buf[8];
-    int rc = _bulkRecv(buf, sizeof(buf));
-    DBG_ASSERT(rc >= 0);
-    DBG_HEX(buf, sizeof(buf));
-
-    StatusTransport();
-    DBG_ASSERT(m_CSW.bCSWStatus == 0x00);
-    
-    m_numBlocks = BE32(buf);
-    m_BlockSize = BE32(buf+4);
-    DBG("m_numBlocks=%d m_BlockSize=%d\n", m_numBlocks, m_BlockSize);
-    DBG_ASSERT(m_BlockSize == 512);
-    DBG_ASSERT(m_numBlocks > 0);
-    return 0;
-}
-
-int msc::Inquire()
-{
-    const uint8_t cdb[6] = {SCSI_CMD_INQUIRY, 0x00, 0x00, 0x00, 36, 0x00};
-    m_CBW.dCBWDataTraansferLength = 36;
-    m_CBW.bmCBWFlags = 0x80; // data In
-    CommandTransport(cdb, sizeof(cdb));
-
-    uint8_t buf[36];
-    _bulkRecv(buf, sizeof(buf));
-    DBG_HEX(buf, sizeof(buf));
-
-    StatusTransport();
-    return 0;
-}
-
-int msc::MS_BulkRecv(uint32_t block_number, int num_blocks, uint8_t* user_buffer)
-{
-    DBG_ASSERT(m_BlockSize == 512);
-    DBG_ASSERT(num_blocks == 1);
-    DBG_ASSERT(user_buffer);
-    uint8_t cdb[10] = {SCSI_CMD_READ_10, 0x00, 0x00, 0x00, 0x00, 
-                                   0x00, 0x00, 0x00, 0x00, 0x00};
-    BE32(block_number, cdb+2);
-    BE16(num_blocks, cdb+7);
-    uint32_t len = m_BlockSize * num_blocks;
-    DBG_ASSERT(len <= 512);
-    m_CBW.dCBWDataTraansferLength = len;
-    m_CBW.bmCBWFlags = 0x80; // data In
-    CommandTransport(cdb, sizeof(cdb));
-
-    int ret = _bulkRecv(user_buffer, len);
-    //DBG_HEX(user_buffer, len);
-
-    StatusTransport();
-    DBG_ASSERT(m_CSW.bCSWStatus == 0x00);
-    return ret;
-}
-
-int msc::MS_BulkSend(uint32_t block_number, int num_blocks, uint8_t* user_buffer)
-{
-#ifdef WRITE_PROTECT
-    return 0;
-#else
-    DBG_ASSERT(num_blocks == 1);
-    DBG_ASSERT(user_buffer);
-    uint8_t cdb[10] = {SCSI_CMD_WRITE_10, 0x00, 0x00, 0x00, 0x00, 
-                                    0x00, 0x00, 0x00, 0x00, 0x00};
-    BE32(block_number, cdb+2);
-    BE16(num_blocks, cdb+7);
-    uint32_t len = m_BlockSize * num_blocks;
-    DBG_ASSERT(len <= 512);
-    m_CBW.dCBWDataTraansferLength = len;
-    m_CBW.bmCBWFlags = 0x00; // data Out
-    CommandTransport(cdb, sizeof(cdb));
-
-    int ret = _bulkSend(user_buffer, len);
-    //DBG_HEX(user_buffer, len);
-
-    StatusTransport();
-    DBG_ASSERT(m_CSW.bCSWStatus == 0x00);
-    return ret;
-#endif //WRITE_PROTECT    
-}
-
-int msc::CommandTransport(const uint8_t* cdb, int size)
-{
-    DBG_ASSERT(cdb);
-    DBG_ASSERT(size >= 6);
-    DBG_ASSERT(size <= 16);
-    m_CBW.bCBWLUN = m_lun;
-    m_CBW.bCBWCBLength = size;
-    memcpy(m_CBW.CBWCB, cdb, size);
-
-    m_CBW.dCBWSignature = 0x43425355;
-    m_CBW.dCBWTag = m_tag++;
-    m_CBW.bCBWLUN = 0;
-    //DBG_HEX((uint8_t*)&m_CBW, sizeof(CBW));
-    int rc = _bulkSend((uint8_t*)&m_CBW, sizeof(CBW));
-    return rc;
-}
-
-int msc::StatusTransport()
-{
-    DBG_ASSERT(sizeof(CSW) == 13);
-    int rc = _bulkRecv((uint8_t*)&m_CSW, sizeof(CSW));
-    //DBG_HEX((uint8_t*)&m_CSW, sizeof(CSW));
-    DBG_ASSERT(m_CSW.dCSWSignature == 0x53425355);
-    DBG_ASSERT(m_CSW.dCSWTag == m_CBW.dCBWTag);
-    DBG_ASSERT(m_CSW.dCSWDataResidue == 0);
-    return rc;
-}
-
-int msc::_bulkRecv(uint8_t* buf, int size)
-{
-    UsbErr rc = m_pEpBulkIn->transfer(buf, size);
-    DBG_ASSERT(rc == USBERR_PROCESSING);
-    while(m_pEpBulkIn->status() == USBERR_PROCESSING){
-        wait_us(1);
-    }
-    int ret = m_pEpBulkIn->status();
-    if (ret >= 0) {
-        return ret;
-    }
-    DBG("buf=%p size=%d ret=%d\n", buf, size, ret);
-    return ret;
-}
-
-int msc::_bulkSend(uint8_t* buf, int size)
-{
-    DBG_ASSERT(m_pEpBulkOut);
-    UsbErr rc = m_pEpBulkOut->transfer(buf, size);
-    DBG_ASSERT(rc == USBERR_PROCESSING);
-    while(m_pEpBulkOut->status() == USBERR_PROCESSING){
-        wait_us(1);
-    }
-    int ret = m_pEpBulkOut->status();
-    if (ret >= 0) {
-        return ret;
-    }
-    DBG("buf=%p size=%d ret=%d\n", buf, size, ret);
-    return ret;
-}
--- a/msc/msc.h	Wed Dec 05 12:41:25 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-#ifndef MSC_H
-#define MSC_H
-#include "UsbHostMgr.h"
-#include "UsbEndpoint.h"
-#include "UsbBaseClass.h"
-#include "FATFileSystem.h"
-
-#define  SCSI_CMD_REQUEST_SENSE      0x03
-#define  SCSI_CMD_TEST_UNIT_READY    0x00
-#define  SCSI_CMD_INQUIRY            0x12
-#define  SCSI_CMD_READ_10            0x28
-#define  SCSI_CMD_READ_CAPACITY      0x25
-#define  SCSI_CMD_WRITE_10           0x2A
-
-#pragma pack(push,1)
-typedef struct stcbw {
-    uint32_t dCBWSignature;
-    uint32_t dCBWTag;
-    uint32_t dCBWDataTraansferLength;
-    uint8_t bmCBWFlags;
-    uint8_t bCBWLUN;
-    uint8_t bCBWCBLength;
-    uint8_t CBWCB[16];
-} CBW;
-
-typedef struct stcsw {
-    uint32_t dCSWSignature;
-    uint32_t dCSWTag;
-    uint32_t dCSWDataResidue;
-    uint8_t  bCSWStatus;
-} CSW;
-#pragma pack(pop)
-
-class msc : public FATFileSystem, public UsbBaseClass {
-public:
-    msc(const char* name = NULL, int drive = 0);
-    virtual int disk_initialize();
-    virtual int disk_write(const uint8_t *buffer, uint64_t block_number);
-    virtual int disk_read(uint8_t *buffer, uint64_t block_number);    
-    virtual int disk_status();
-    virtual int disk_sync();
-    virtual uint64_t disk_sectors();
-
-    int setup(int timeout = 9000);
-    void _test();
-private:
-    int ParseConfiguration();
-    int BulkOnlyMassStorageReset();
-    int GetMaxLUN();
-    int ReadCapacity();
-    int GetSenseInfo();
-    int TestUnitReady();
-    int Inquire();
-    int MS_BulkRecv(uint32_t block_number, int num_blocks, uint8_t* user_buffer);
-    int MS_BulkSend(uint32_t block_number, int num_blocks, uint8_t* user_buffer);
-    int CommandTransport(const uint8_t* cdb, int size);
-    int StatusTransport();
-    int _bulkRecv(uint8_t* buf, int size);
-    int _bulkSend(uint8_t* buf, int size);
-    const char* m_name;
-    int m_drive;
-    uint32_t m_numBlocks;
-    int m_BlockSize;
-    int m_lun;
-    int m_MaxLUN;
-    int m_interface;
-    uint32_t m_tag;
-    CBW m_CBW;
-    CSW m_CSW;
-    UsbDevice* m_pDev;
-    UsbEndpoint* m_pEpBulkIn;
-    UsbEndpoint* m_pEpBulkOut;
-};
-
-#endif // MSC_H
--- a/uvchost.lib	Wed Dec 05 12:41:25 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/va009039/code/uvchost/#3eb41d749f9a