Simple USBHost WebCam test program

Dependencies:   F401RE-USBHost mbed

Fork of KL46Z-USBHostC270_example by Norimasa Okamoto

WebカメラからJPEG画像を読み取るテストプログラムです。
使い方はKL46Z-USBHostC270_exampleと同じです。
動作確認カメラ: Logitech C270, Logitech C210, Logitech Q200R(Qcam Orbit AF), LifeCam VX-500
/media/uploads/va009039/f401re-c270-1.jpg /media/uploads/va009039/k64f-c270.jpg

Files at this revision

API Documentation at this revision

Comitter:
va009039
Date:
Tue Jan 28 06:54:16 2014 +0000
Parent:
0:a72d9b047d8d
Child:
2:2a40888db9fc
Commit message:
support Logitech C210 Q200R, LifeCam VX-700(VX-500), Sonix Camera.

Changed in this revision

KL46Z-USBHost.lib Show annotated file Show diff for this revision Revisions of this file
KL46Z-USBHostC270/BaseUvc.cpp Show diff for this revision Revisions of this file
KL46Z-USBHostC270/BaseUvc.h Show diff for this revision Revisions of this file
KL46Z-USBHostC270/USBHostC270.cpp Show diff for this revision Revisions of this file
KL46Z-USBHostC270/USBHostC270.h Show diff for this revision Revisions of this file
KL46Z-USBHostC270/decodeMJPEG.cpp Show diff for this revision Revisions of this file
KL46Z-USBHostC270/decodeMJPEG.h Show diff for this revision Revisions of this file
KL46Z_USBHostC270/BaseUvc.cpp Show annotated file Show diff for this revision Revisions of this file
KL46Z_USBHostC270/BaseUvc.h Show annotated file Show diff for this revision Revisions of this file
KL46Z_USBHostC270/CamInfo.cpp Show annotated file Show diff for this revision Revisions of this file
KL46Z_USBHostC270/USBHostC270.cpp Show annotated file Show diff for this revision Revisions of this file
KL46Z_USBHostC270/USBHostC270.h Show annotated file Show diff for this revision Revisions of this file
KL46Z_USBHostC270/USBHostCam.cpp Show annotated file Show diff for this revision Revisions of this file
KL46Z_USBHostC270/USBHostCam.h Show annotated file Show diff for this revision Revisions of this file
KL46Z_USBHostC270/decodeMJPEG.cpp Show annotated file Show diff for this revision Revisions of this file
KL46Z_USBHostC270/decodeMJPEG.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/KL46Z-USBHost.lib	Mon Jan 27 11:07:34 2014 +0000
+++ b/KL46Z-USBHost.lib	Tue Jan 28 06:54:16 2014 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/va009039/code/KL46Z-USBHost/#10bfc10afcc8
+http://mbed.org/users/va009039/code/KL46Z-USBHost/#9a20482c9a7a
--- a/KL46Z-USBHostC270/BaseUvc.cpp	Mon Jan 27 11:07:34 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-// BaseUvc.cpp
-#include "USBHostConf.h"
-#include "USBHost.h"
-//#include "USBIsochronous.h"
-#include "BaseUvc.h"
-
-void BaseUvc::poll()
-{
-    uint8_t buf[ep_iso_in.getSize()];
-    int result = host->IsochronousRead(&ep_iso_in, buf, sizeof(buf));
-    if (result >= 0) {
-        uint16_t frame = 0;
-        onResult(frame, buf, result);
-    }
-}
-
-USB_TYPE BaseUvc::Control(int req, int cs, int index, uint8_t* buf, int size)
-{
-    if (req == SET_CUR) {    
-        return host->controlWrite(dev,
-                    USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, 
-                    req, cs<<8, index, buf, size);
-    }
-    return host->controlRead(dev,
-                USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, 
-                req, cs<<8, index, buf, size);
-}
-
-USB_TYPE BaseUvc::setInterfaceAlternate(uint8_t intf, uint8_t alt)
-{
-    return host->controlWrite(dev, USB_HOST_TO_DEVICE | USB_RECIPIENT_INTERFACE,
-                                   SET_INTERFACE, alt, intf, NULL, 0);
-}
-
-void BaseUvc::onResult(uint16_t frame, uint8_t* buf, int len)
-{
-  if(m_pCbItem && m_pCbMeth)
-    (m_pCbItem->*m_pCbMeth)(frame, buf, len);
-  else if(m_pCb)
-    m_pCb(frame, buf, len);
-}
-
-void BaseUvc::setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) )
-{
-    m_pCb = pMethod;
-    m_pCbItem = NULL;
-    m_pCbMeth = NULL;
-}
-    
-void BaseUvc::clearOnResult()
-{
-    m_pCb = NULL;
-    m_pCbItem = NULL;
-    m_pCbMeth = NULL;
-}
-
--- a/KL46Z-USBHostC270/BaseUvc.h	Mon Jan 27 11:07:34 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-// BaseUvc.h
-//#include "USBIsochronous.h"
-#pragma once
-
-// --- UVC --------------------------------------------------
-#define _30FPS  333333
-#define _25FPS  400000
-#define _20FPS  500000
-#define _15FPS  666666
-#define _10FPS 1000000
-#define _5FPS  2000000
-#define _1FPS 10000000
-
-#define SET_CUR  0x01
-#define GET_CUR  0x81
-#define GET_MIN  0x82
-#define GET_MAX  0x83
-#define GET_RES  0x84
-#define GET_LEN  0x85
-#define GET_INFO 0x86
-#define GET_DEF  0x87
-
-#define VS_PROBE_CONTROL  0x01
-#define VS_COMMIT_CONTROL 0x02
-
-class BaseUvc {
-public:
-    void poll();
-    USB_TYPE Control(int req, int cs, int index, uint8_t* buf, int size);
-    USB_TYPE setInterfaceAlternate(uint8_t intf, uint8_t alt);
-    //IsochronousEp* m_isoEp;
-    // callback
-    void onResult(uint16_t frame, uint8_t* buf, int len);
-    void setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) );
-    class CDummy;
-    template<class T> 
-    void setOnResult( T* pItem, void (T::*pMethod)(uint16_t, uint8_t*, int) )
-    {
-        m_pCb = NULL;
-        m_pCbItem = (CDummy*) pItem;
-        m_pCbMeth = (void (CDummy::*)(uint16_t, uint8_t*, int)) pMethod;
-    }
-    void clearOnResult();
-    CDummy* m_pCbItem;
-    void (CDummy::*m_pCbMeth)(uint16_t, uint8_t*, int);
-    void (*m_pCb)(uint16_t, uint8_t*, int);
-protected:
-    USBHost * host;
-    USBDeviceConnected * dev; // dummy
-    USBEndpoint ep_iso_in;
-};
--- a/KL46Z-USBHostC270/USBHostC270.cpp	Mon Jan 27 11:07:34 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-#include "USBHostC270.h"
-//#include "dbg.h"
-
-#define C270_DEBUG 1
-#ifdef C270_DEBUG
-#define C270_DBG(x, ...) std::printf("[%s:%d]"x"\r\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
-#else
-#define C270_DBG(...)  while(0);
-#endif
-
-USBHostC270::USBHostC270(int formatIndex, int frameIndex, uint32_t interval) {
-    _formatIndex = formatIndex;
-    _frameIndex = frameIndex;
-    _interval = interval;
-    clearOnResult();
-    host = USBHost::getHostInst();
-    report = &host->report;
-    setup();
-}
-
-void USBHostC270::setup() {
-    ep_iso_in.setAddress(C270_EN);
-    ep_iso_in.setSize(C270_MPS);
-    uint8_t buf[26];
-    memset(buf, 0, sizeof(buf));
-    buf[2] = _formatIndex;
-    buf[3] = _frameIndex;
-    *reinterpret_cast<uint32_t*>(buf+4) = _interval;
-    USB_TYPE res = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, sizeof(buf));
-    if (res != USB_TYPE_OK) {
-         C270_DBG("SET_CUR VS_COMMIT_CONTROL FAILED");
-    }
-    res = setInterfaceAlternate(1, C270_IF_ALT); // alt=1 packet size = 192
-    if (res != USB_TYPE_OK) {
-         C270_DBG("SET_INTERFACE FAILED");
-    }
-}
-
-#define SEQ_READ_IDOL 0
-#define SEQ_READ_EXEC 1
-#define SEQ_READ_DONE 2
-
-int USBHostC270::readJPEG(uint8_t* buf, int size, int timeout_ms) {
-    _buf = buf;
-    _pos = 0;
-    _size = size;
-    _seq = SEQ_READ_IDOL;
-    setOnResult(this, &USBHostC270::callback_motion_jpeg);
-    Timer timeout_t;
-    timeout_t.reset();
-    timeout_t.start();
-    while(timeout_t.read_ms() < timeout_ms && _seq != SEQ_READ_DONE) {
-        poll();
-    } 
-    return _pos;
-}
-
-/* virtual */ void USBHostC270::outputJPEG(uint8_t c, int status) { // from decodeMJPEG
-    if (_seq == SEQ_READ_IDOL) {
-        if (status == JPEG_START) {
-            _pos = 0;
-            _seq = SEQ_READ_EXEC;
-        }
-    }
-    if (_seq == SEQ_READ_EXEC) {
-        if (_pos < _size) {
-            _buf[_pos++] = c;  
-        }  
-        if (status == JPEG_END) {
-            _seq = SEQ_READ_DONE;
-        }
-    }
-}
-
-void USBHostC270::callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len) {
-        inputPacket(buf, len);
-}
--- a/KL46Z-USBHostC270/USBHostC270.h	Mon Jan 27 11:07:34 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-// Simple USBHost Logtigech C270 for FRDM-KL46Z
-#include "USBHost.h"
-#include "BaseUvc.h"
-#include "decodeMJPEG.h"
-
-// Logitech C270
-#define C270_VID 0x046d
-#define C270_PID 0x0825
-#define C270_160x120 2
-#define C270_176x144 3
-#define C270_320x176 4
-#define C270_320x240 5
-#define C270_352x288 6
-#define C270_432x240 7
-#define C270_640x480 1
-#define C270_544x288 8
-#define C270_640x360 9
-#define C270_752x416 10
-#define C270_800x448 11
-#define C270_800x600 12
-
-#define C270_MJPEG 2
-#define C270_YUV2  1
-
-#define C270_EN  0x81
-#define C270_MPS  192
-#define C270_IF_ALT 1
-
-class USBHostC270 : public BaseUvc, public decodeMJPEG {
-public:
-    USBHostC270(int formatIndex = C270_MJPEG, int frameIndex = C270_160x120, uint32_t interval = _5FPS);
-    /**
-     * read jpeg image
-     *
-     * @param buf read buffer 
-     * @param size buffer size 
-     * @param timeout_ms timeout default 15sec
-     * @return jpeg size if read success else -1
-     */
-    int readJPEG(uint8_t* buf, int size, int timeout_ms = 15*1000);
-
-    Report* report;
-
-private:
-    int _formatIndex;
-    int _frameIndex;
-    uint32_t _interval;
-    uint8_t _seq;
-    uint8_t* _buf;
-    int _pos;
-    int _size;
-
-    void setup();
-    virtual void outputJPEG(uint8_t c, int status); // from decodeMJPEG
-    void callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len);
-};
-
--- a/KL46Z-USBHostC270/decodeMJPEG.cpp	Mon Jan 27 11:07:34 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +0,0 @@
-// decodeMJPEG.cpp 2012/12/8
-// decode motion-jpeg to jpeg
-#include "mbed.h"
-#include "decodeMJPEG.h"
-
-#define MARK_SOF0 0xc0
-#define MARK_DHT  0xc4
-#define MARK_RST0 0xd0
-#define MARK_RST7 0xd7
-#define MARK_SOI  0xd8
-#define MARK_EOI  0xd9
-#define MARK_SOS  0xda
-#define MARK_DQT  0xdb
-#define MARK_DRI  0xdd
-#define MARK_APP  0xe0
- 
-#define SEQ_INIT      0
-#define SEQ_SOI       1
-#define SEQ_FRAME     2
-#define SEQ_MARK      3
-#define SEQ_SEG_LEN   4
-#define SEQ_SEG_LEN2  5
-#define SEQ_SEG_BODY  6
-#define SEQ_SOS       7
-#define SEQ_SOS2      8
-
-static const uint8_t dht[] = {
-0xFF,0xC4,0x01,0xA2,0x00,0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,
-0x0B,0x01,0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
-0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x10,0x00,
-0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D,0x01,
-0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,
-0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,0x24,
-0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,0x29,
-0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,
-0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
-0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,
-0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,
-0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,0xC6,
-0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,0xE3,
-0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
-0xFA,0x11,0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,
-0x02,0x77,0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,
-0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,
-0x52,0xF0,0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,
-0x1A,0x26,0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,
-0x47,0x48,0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,
-0x67,0x68,0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85,
-0x86,0x87,0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,
-0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,
-0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,
-0xD9,0xDA,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,
-0xF7,0xF8,0xF9,0xFA,
-};
-
-decodeMJPEG::decodeMJPEG()
-{
-    m_seq = SEQ_INIT;
-}
-
-void decodeMJPEG::inputPacket(const uint8_t* buf, int len)
-{
-    for(int i = 12; i < len; i++) {
-        input(buf[i]);
-    }    
-}
-
-void decodeMJPEG::input(uint8_t c)
-{
-    switch(m_seq) {
-        case SEQ_INIT:
-            if (c == 0xff) {
-                m_seq = SEQ_SOI;
-            }
-            break;
-        case SEQ_SOI:
-            if (c == MARK_SOI) {
-                outputJPEG(0xff, JPEG_START); // start
-                outputJPEG(c);
-                m_bDHT = false;
-                m_seq = SEQ_FRAME;
-            } else {
-                m_seq = SEQ_INIT;
-            }
-            break;
-        case SEQ_FRAME:
-            if (c == 0xff) {
-                m_seq = SEQ_MARK;
-            } else {
-                m_seq = SEQ_INIT;
-            }
-            break;
-        case SEQ_MARK:
-            if (c == MARK_SOI || c == MARK_EOI || c == 0x00) {
-                m_seq = SEQ_INIT;
-                break;
-            }
-            m_mark = c;
-            m_seq = SEQ_SEG_LEN;
-            break;
-        case SEQ_SEG_LEN:
-            m_seg_len = c;
-            m_seq = SEQ_SEG_LEN2;
-            break;
-        case SEQ_SEG_LEN2:
-            m_seg_len <<= 8;
-            m_seg_len |= c;
-            m_seg_len -= 2;
-            m_seg_pos = 0;
-            m_seq = SEQ_SEG_BODY;
-            if (m_mark == MARK_SOS) {
-                if (m_bDHT == false) {
-                    for(int i = 0; i < sizeof(dht); i++) {
-                        outputJPEG(dht[i]);
-                    }    
-                }
-                m_output_desable = false;
-            } else if (m_mark == MARK_DHT) {
-                m_bDHT = true;
-                m_output_desable = false;
-            } else {
-                m_output_desable = false;
-            }
-            if (!m_output_desable) {
-                outputJPEG(0xff);
-                outputJPEG(m_mark);
-                outputJPEG((m_seg_len+2) >> 8);
-                outputJPEG((m_seg_len+2) & 0xff);
-            } 
-            break;
-        case SEQ_SEG_BODY:
-            if (!m_output_desable) {
-                outputJPEG(c);
-            }
-            if (++m_seg_pos < m_seg_len) {
-                break;
-            }
-            if (m_mark == MARK_SOS) {
-                m_seq = SEQ_SOS;
-                break;
-            }
-            m_seq = SEQ_FRAME;
-            break;
-        case SEQ_SOS:
-            if (c == 0xff) {
-                m_seq = SEQ_SOS2;
-                break;
-            }
-            outputJPEG(c);
-            break;
-        case SEQ_SOS2:
-            if (c == 0x00) {
-                outputJPEG(0xff);
-                outputJPEG(0x00);
-                m_seq = SEQ_SOS;
-                break;
-            } else if (c >= MARK_RST0 && c <= MARK_RST7) {
-                outputJPEG(0xff);
-                outputJPEG(c);
-                m_seq = SEQ_SOS;
-                break;
-            } else if (c == MARK_EOI) {
-                outputJPEG(0xff);
-                outputJPEG(c, JPEG_END);
-                m_seq = SEQ_INIT;
-                break;
-            } else if (c == MARK_SOI) {
-                outputJPEG(0xff);
-                outputJPEG(c);
-                m_seq = SEQ_INIT;
-                break;
-            }
-            m_seq = SEQ_INIT;
-            break;
-        default:
-            m_seq = SEQ_INIT;
-            break;
-    }
-}
--- a/KL46Z-USBHostC270/decodeMJPEG.h	Mon Jan 27 11:07:34 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-// decodeMJPEG.h 2012/12/9
-#ifndef DECODE_MJPEG_H
-#define DECODE_MJPEG_H
-
-#define JPEG_NONE  0
-#define JPEG_START 1
-#define JPEG_END   2
-#define JPEG_ERROR 3
-
-class decodeMJPEG {
-public:
-    decodeMJPEG();
-    void inputPacket(const uint8_t* buf, int len);
-    virtual void outputJPEG(uint8_t c, int status = JPEG_NONE) = 0;
-protected:
-    void input(uint8_t c);
-    int m_seq;
-    uint8_t m_mark;
-    uint16_t m_seg_pos; 
-    uint16_t m_seg_len;
-    bool m_bDHT;
-    bool m_output_desable;
-};
-
-#endif // DECODE_MJPEG_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/KL46Z_USBHostC270/BaseUvc.cpp	Tue Jan 28 06:54:16 2014 +0000
@@ -0,0 +1,56 @@
+// BaseUvc.cpp
+#include "USBHostConf.h"
+#include "USBHost.h"
+//#include "USBIsochronous.h"
+#include "BaseUvc.h"
+
+void BaseUvc::poll()
+{
+    uint8_t buf[ep_iso_in.getSize()];
+    int result = host->IsochronousRead(&ep_iso_in, buf, sizeof(buf));
+    if (result >= 0) {
+        uint16_t frame = 0;
+        onResult(frame, buf, result);
+    }
+}
+
+USB_TYPE BaseUvc::Control(int req, int cs, int index, uint8_t* buf, int size)
+{
+    if (req == SET_CUR) {    
+        return host->controlWrite(dev,
+                    USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, 
+                    req, cs<<8, index, buf, size);
+    }
+    return host->controlRead(dev,
+                USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, 
+                req, cs<<8, index, buf, size);
+}
+
+USB_TYPE BaseUvc::setInterfaceAlternate(uint8_t intf, uint8_t alt)
+{
+    return host->controlWrite(dev, USB_HOST_TO_DEVICE | USB_RECIPIENT_INTERFACE,
+                                   SET_INTERFACE, alt, intf, NULL, 0);
+}
+
+void BaseUvc::onResult(uint16_t frame, uint8_t* buf, int len)
+{
+  if(m_pCbItem && m_pCbMeth)
+    (m_pCbItem->*m_pCbMeth)(frame, buf, len);
+  else if(m_pCb)
+    m_pCb(frame, buf, len);
+}
+
+void BaseUvc::setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) )
+{
+    m_pCb = pMethod;
+    m_pCbItem = NULL;
+    m_pCbMeth = NULL;
+}
+    
+void BaseUvc::clearOnResult()
+{
+    m_pCb = NULL;
+    m_pCbItem = NULL;
+    m_pCbMeth = NULL;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/KL46Z_USBHostC270/BaseUvc.h	Tue Jan 28 06:54:16 2014 +0000
@@ -0,0 +1,51 @@
+// BaseUvc.h
+//#include "USBIsochronous.h"
+#pragma once
+
+// --- UVC --------------------------------------------------
+#define _30FPS  333333
+#define _25FPS  400000
+#define _20FPS  500000
+#define _15FPS  666666
+#define _10FPS 1000000
+#define _5FPS  2000000
+#define _1FPS 10000000
+
+#define SET_CUR  0x01
+#define GET_CUR  0x81
+#define GET_MIN  0x82
+#define GET_MAX  0x83
+#define GET_RES  0x84
+#define GET_LEN  0x85
+#define GET_INFO 0x86
+#define GET_DEF  0x87
+
+#define VS_PROBE_CONTROL  0x01
+#define VS_COMMIT_CONTROL 0x02
+
+class BaseUvc {
+public:
+    void poll();
+    USB_TYPE Control(int req, int cs, int index, uint8_t* buf, int size);
+    USB_TYPE setInterfaceAlternate(uint8_t intf, uint8_t alt);
+    //IsochronousEp* m_isoEp;
+    // callback
+    void onResult(uint16_t frame, uint8_t* buf, int len);
+    void setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) );
+    class CDummy;
+    template<class T> 
+    void setOnResult( T* pItem, void (T::*pMethod)(uint16_t, uint8_t*, int) )
+    {
+        m_pCb = NULL;
+        m_pCbItem = (CDummy*) pItem;
+        m_pCbMeth = (void (CDummy::*)(uint16_t, uint8_t*, int)) pMethod;
+    }
+    void clearOnResult();
+    CDummy* m_pCbItem;
+    void (CDummy::*m_pCbMeth)(uint16_t, uint8_t*, int);
+    void (*m_pCb)(uint16_t, uint8_t*, int);
+protected:
+    USBHost * host;
+    USBDeviceConnected * dev; // dummy
+    USBEndpoint ep_iso_in;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/KL46Z_USBHostC270/CamInfo.cpp	Tue Jan 28 06:54:16 2014 +0000
@@ -0,0 +1,188 @@
+// CamInfo.cpp
+#include "USBHostCam.h"
+
+// Logitech C270
+#define C270_VID 0x046d
+#define C270_PID 0x0825
+#define C270_160x120 2
+#define C270_176x144 3
+#define C270_320x176 4
+#define C270_320x240 5
+#define C270_352x288 6
+#define C270_432x240 7
+#define C270_640x480 1
+#define C270_544x288 8
+#define C270_640x360 9
+#define C270_752x416 10
+#define C270_800x448 11
+#define C270_800x600 12
+
+#define C270_MJPEG 2
+#define C270_YUV2  1
+
+#define C270_EN  0x81
+#define C270_MPS  192
+#define C270_IF_ALT_192 1
+#define C270_IF_ALT(A) C270_IF_ALT_##A
+
+#define C270_INFO(SIZE) {C270_VID, C270_PID, _##SIZE, 0, \
+    "C270", \
+    C270_MJPEG, \
+    C270_##SIZE, \
+    _5FPS, \
+    C270_EN, \
+    192, \
+    C270_IF_ALT(192), \
+    }
+
+#define C210_PID 0x819
+#define C210_INFO(SIZE) {C270_VID, C210_PID, _##SIZE, 0, \
+    "C270", \
+    C270_MJPEG, \
+    C270_##SIZE, \
+    _5FPS, \
+    C270_EN, \
+    192, \
+    C270_IF_ALT(192), \
+    }
+
+// Logitech Qcam Orbit AF QCAM-200R
+#define Q200R_VID 0x046d
+#define Q200R_PID 0x0994
+#define Q200R_160x120 1
+#define Q200R_176x144 2
+#define Q200R_320x240 3
+#define Q200R_352x288 4
+#define Q200R_640x480 5
+#define Q200R_800x600 6
+
+#define Q200R_MJPEG 1
+#define Q200R_YUV2  2
+
+#define Q200R_EN  0x81
+#define Q200R_MPS  192
+#define Q200R_IF_ALT_192 1
+#define Q200R_IF_ALT_384 2
+#define Q200R_IF_ALT_512 3
+#define Q200R_IF_ALT_640 4
+#define Q200R_IF_ALT_800 5
+#define Q200R_IF_ALT_944 6
+#define Q200R_IF_ALT(A) Q200R_IF_ALT_##A
+#define Q200R_INFO(SIZE) {Q200R_VID, Q200R_PID, _##SIZE, 0, \
+    "Q200R", \
+    Q200R_MJPEG, \
+    Q200R_##SIZE, \
+    _5FPS, \
+    Q200R_EN, \
+    192, \
+    Q200R_IF_ALT(192), \
+    }
+
+//LifeCam VX700 / VX500
+#define VX700_VID 0x045e
+#define VX700_PID 0x074a
+
+#define VX700_160x120 5
+#define VX700_176x144 4
+#define VX700_320x240 3
+#define VX700_352x288 2
+#define VX700_640x480 1
+
+#define VX700_MJPEG 1
+
+#define VX700_EN  0x81
+#define VX700_MPS  128
+#define VX700_IF_ALT_128 1 
+#define VX700_IF_ALT(A) VX700_IF_ALT_##A
+#define VX700_INFO(SIZE) {VX700_VID, VX700_PID, _##SIZE, 0, \
+    "VX700", \
+    VX700_MJPEG, \
+    VX700_##SIZE, \
+    _5FPS, \
+    VX700_EN, \
+    128, \
+    VX700_IF_ALT(128), \
+    }
+
+//Sonix USB 2.0 Camera
+#define SONIX_160x120 5
+#define SONIX_176x144 4
+#define SONIX_320x240 3
+#define SONIX_352x288 2
+#define SONIX_640x480 1
+
+#define SONIX_IF_ALT_128 1
+#define SONIX_IF_ALT_256 2
+#define SONIX_IF_ALT_512 3
+#define SONIX_IF_ALT_600 4
+#define SONIX_IF_ALT_800 5
+#define SONIX_IF_ALT_956 6
+#define SONIX_IF_ALT(A) SONIX_IF_ALT_##A
+#define SONIX_INFO(SIZE) {0x0c45, 0x62c0, _##SIZE, 0, \
+    "SONIX", \
+    1, \
+    SONIX_##SIZE, \
+    _5FPS, \
+    0x81, \
+    128, \
+    SONIX_IF_ALT(128), \
+    }
+
+static const CamInfo CamInfoList[] = {
+// Logitech C270
+C270_INFO(160x120),
+C270_INFO(176x144),
+C270_INFO(320x176),
+C270_INFO(320x240),
+C270_INFO(352x288),
+C270_INFO(432x240),
+C270_INFO(640x480),
+C270_INFO(544x288),
+C270_INFO(640x360),
+C270_INFO(752x416),
+C270_INFO(800x448),
+C270_INFO(800x600),
+
+// Logitech C210
+C210_INFO(160x120),
+C210_INFO(176x144),
+C210_INFO(320x176),
+C210_INFO(320x240),
+C210_INFO(352x288),
+C210_INFO(432x240),
+C210_INFO(640x480),
+C210_INFO(544x288),
+C210_INFO(640x360),
+C210_INFO(752x416),
+C210_INFO(800x448),
+C210_INFO(800x600),
+
+// Logitech Qcam Orbit AF QCAM-200R
+Q200R_INFO(160x120),
+Q200R_INFO(176x144),
+Q200R_INFO(320x240),
+Q200R_INFO(352x288),
+Q200R_INFO(640x480),
+Q200R_INFO(800x600),
+
+// LifeCam VX700
+VX700_INFO(160x120),
+VX700_INFO(176x144),
+VX700_INFO(320x240),
+VX700_INFO(352x288),
+VX700_INFO(640x480),
+
+// Sonix USB 2.0 Camera
+SONIX_INFO(160x120),
+SONIX_INFO(176x144),
+SONIX_INFO(320x240),
+SONIX_INFO(352x288),
+SONIX_INFO(640x480),
+
+// Not found
+{0,0,0,0},
+};
+
+CamInfo* getCamInfoList() {
+    return const_cast<CamInfo*>(CamInfoList);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/KL46Z_USBHostC270/USBHostC270.cpp	Tue Jan 28 06:54:16 2014 +0000
@@ -0,0 +1,77 @@
+#include "USBHostC270.h"
+//#include "dbg.h"
+
+#define C270_DEBUG 1
+#ifdef C270_DEBUG
+#define C270_DBG(x, ...) std::printf("[%s:%d]"x"\r\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
+#else
+#define C270_DBG(...)  while(0);
+#endif
+
+USBHostC270::USBHostC270(int formatIndex, int frameIndex, uint32_t interval) {
+    _formatIndex = formatIndex;
+    _frameIndex = frameIndex;
+    _interval = interval;
+    clearOnResult();
+    host = USBHost::getHostInst();
+    report = &host->report;
+    setup();
+}
+
+void USBHostC270::setup() {
+    ep_iso_in.setAddress(C270_EN);
+    ep_iso_in.setSize(C270_MPS);
+    uint8_t buf[26];
+    memset(buf, 0, sizeof(buf));
+    buf[2] = _formatIndex;
+    buf[3] = _frameIndex;
+    *reinterpret_cast<uint32_t*>(buf+4) = _interval;
+    USB_TYPE res = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, sizeof(buf));
+    if (res != USB_TYPE_OK) {
+         C270_DBG("SET_CUR VS_COMMIT_CONTROL FAILED");
+    }
+    res = setInterfaceAlternate(1, C270_IF_ALT); // alt=1 packet size = 192
+    if (res != USB_TYPE_OK) {
+         C270_DBG("SET_INTERFACE FAILED");
+    }
+}
+
+#define SEQ_READ_IDOL 0
+#define SEQ_READ_EXEC 1
+#define SEQ_READ_DONE 2
+
+int USBHostC270::readJPEG(uint8_t* buf, int size, int timeout_ms) {
+    _buf = buf;
+    _pos = 0;
+    _size = size;
+    _seq = SEQ_READ_IDOL;
+    setOnResult(this, &USBHostC270::callback_motion_jpeg);
+    Timer timeout_t;
+    timeout_t.reset();
+    timeout_t.start();
+    while(timeout_t.read_ms() < timeout_ms && _seq != SEQ_READ_DONE) {
+        poll();
+    } 
+    return _pos;
+}
+
+/* virtual */ void USBHostC270::outputJPEG(uint8_t c, int status) { // from decodeMJPEG
+    if (_seq == SEQ_READ_IDOL) {
+        if (status == JPEG_START) {
+            _pos = 0;
+            _seq = SEQ_READ_EXEC;
+        }
+    }
+    if (_seq == SEQ_READ_EXEC) {
+        if (_pos < _size) {
+            _buf[_pos++] = c;  
+        }  
+        if (status == JPEG_END) {
+            _seq = SEQ_READ_DONE;
+        }
+    }
+}
+
+void USBHostC270::callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len) {
+        inputPacket(buf, len);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/KL46Z_USBHostC270/USBHostC270.h	Tue Jan 28 06:54:16 2014 +0000
@@ -0,0 +1,57 @@
+// Simple USBHost Logtigech C270 for FRDM-KL46Z
+#include "USBHost.h"
+#include "BaseUvc.h"
+#include "decodeMJPEG.h"
+
+// Logitech C270
+#define C270_VID 0x046d
+#define C270_PID 0x0825
+#define C270_160x120 2
+#define C270_176x144 3
+#define C270_320x176 4
+#define C270_320x240 5
+#define C270_352x288 6
+#define C270_432x240 7
+#define C270_640x480 1
+#define C270_544x288 8
+#define C270_640x360 9
+#define C270_752x416 10
+#define C270_800x448 11
+#define C270_800x600 12
+
+#define C270_MJPEG 2
+#define C270_YUV2  1
+
+#define C270_EN  0x81
+#define C270_MPS  192
+#define C270_IF_ALT 1
+
+class USBHostC270 : public BaseUvc, public decodeMJPEG {
+public:
+    USBHostC270(int formatIndex = C270_MJPEG, int frameIndex = C270_160x120, uint32_t interval = _5FPS);
+    /**
+     * read jpeg image
+     *
+     * @param buf read buffer 
+     * @param size buffer size 
+     * @param timeout_ms timeout default 15sec
+     * @return jpeg size if read success else -1
+     */
+    int readJPEG(uint8_t* buf, int size, int timeout_ms = 15*1000);
+
+    Report* report;
+
+private:
+    int _formatIndex;
+    int _frameIndex;
+    uint32_t _interval;
+    uint8_t _seq;
+    uint8_t* _buf;
+    int _pos;
+    int _size;
+
+    void setup();
+    virtual void outputJPEG(uint8_t c, int status); // from decodeMJPEG
+    void callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len);
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/KL46Z_USBHostC270/USBHostCam.cpp	Tue Jan 28 06:54:16 2014 +0000
@@ -0,0 +1,101 @@
+// USBHostCam.cpp
+#include "USBHostCam.h"
+
+//#define CAM_DEBUG 1
+#ifdef CAM_DEBUG
+#define CAM_DBG(x, ...) std::printf("[%s:%d]"x"\r\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
+#else
+#define CAM_DBG(...)  while(0);
+#endif
+#define CAM_INFO(...) do{fprintf(stderr,__VA_ARGS__);}while(0);
+
+CamInfo* getCamInfoList(); // CamInfo.cpp
+
+USBHostCam::USBHostCam(uint8_t size, uint8_t option, CamInfo* user_caminfo)
+{
+    CAM_DBG("size: %d, option: %d", size, option);
+    _caminfo_size = size;
+    _caminfo_option = option;
+    if (user_caminfo) {
+        CamInfoList = user_caminfo;
+    } else {
+        CamInfoList = getCamInfoList();
+    }
+    clearOnResult();
+    host = USBHost::getHostInst();
+    setup();
+}
+
+void USBHostCam::setup() {
+    caminfo = CamInfoList;
+    bool found = false;
+    while(caminfo->vid != 0) {
+        if (caminfo->vid == host->dev.vid && caminfo->pid == host->dev.pid && 
+            caminfo->size == _caminfo_size && caminfo->option == _caminfo_option) {
+            found = true;
+            break;
+        }
+        caminfo++;
+    }
+    if (!found) {
+        CAM_INFO("caminfo not found.\n");
+        exit(1);
+    }
+    CAM_INFO("Found: %s\n", caminfo->name);
+
+    ep_iso_in.setAddress(caminfo->en);
+    ep_iso_in.setSize(caminfo->mps);
+    uint8_t buf[26];
+    memset(buf, 0, sizeof(buf));
+    buf[2] = caminfo->formatIndex;
+    buf[3] = caminfo->frameIndex;
+    *reinterpret_cast<uint32_t*>(buf+4) = caminfo->interval;
+    USB_TYPE res = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, sizeof(buf));
+    if (res != USB_TYPE_OK) {
+         CAM_DBG("SET_CUR VS_COMMIT_CONTROL FAILED");
+    }
+    res = setInterfaceAlternate(1, caminfo->if_alt);
+    if (res != USB_TYPE_OK) {
+         CAM_DBG("SET_INTERFACE FAILED");
+    }
+}
+
+#define SEQ_READ_IDOL 0
+#define SEQ_READ_EXEC 1
+#define SEQ_READ_DONE 2
+
+int USBHostCam::readJPEG(uint8_t* buf, int size, int timeout_ms) {
+    _buf = buf;
+    _pos = 0;
+    _size = size;
+    _seq = SEQ_READ_IDOL;
+    setOnResult(this, &USBHostCam::callback_motion_jpeg);
+    Timer timeout_t;
+    timeout_t.reset();
+    timeout_t.start();
+    while(timeout_t.read_ms() < timeout_ms && _seq != SEQ_READ_DONE) {
+        poll();
+    } 
+    return _pos;
+}
+
+/* virtual */ void USBHostCam::outputJPEG(uint8_t c, int status) { // from decodeMJPEG
+    if (_seq == SEQ_READ_IDOL) {
+        if (status == JPEG_START) {
+            _pos = 0;
+            _seq = SEQ_READ_EXEC;
+        }
+    }
+    if (_seq == SEQ_READ_EXEC) {
+        if (_pos < _size) {
+            _buf[_pos++] = c;  
+        }  
+        if (status == JPEG_END) {
+            _seq = SEQ_READ_DONE;
+        }
+    }
+}
+
+void USBHostCam::callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len) {
+        inputPacket(buf, len);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/KL46Z_USBHostC270/USBHostCam.h	Tue Jan 28 06:54:16 2014 +0000
@@ -0,0 +1,72 @@
+// USBHostCam.h
+#include "USBHostConf.h"
+#include "USBHost.h"
+#include "BaseUvc.h"
+#include "decodeMJPEG.h"
+#pragma once
+
+#define _160x120 2
+#define _176x144 3
+#define _320x176 4
+#define _320x240 5
+#define _352x288 6
+#define _432x240 7
+#define _640x480 1
+#define _544x288 8
+#define _640x360 9
+#define _752x416 10
+#define _800x448 11
+#define _800x600 12
+
+#define TEST_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
+
+struct CamInfo {
+    uint16_t vid;
+    uint16_t pid;
+    uint8_t size;
+    uint8_t option;
+//
+    const char* name;
+    uint8_t formatIndex;
+    uint8_t frameIndex;
+    uint32_t interval;
+    uint8_t en;
+    uint8_t mps;
+    uint8_t if_alt;
+};
+
+/** 
+ * A class to communicate a Cam
+ */
+class USBHostCam : public BaseUvc, public decodeMJPEG {
+public:
+    /**
+    * Constructor
+    *
+    */
+    USBHostCam(uint8_t size = _160x120, uint8_t option = 0, CamInfo* user_caminfo = NULL);
+
+    /**
+     * read jpeg image
+     *
+     * @param buf read buffer 
+     * @param size buffer size 
+     * @param timeout_ms timeout default 15sec
+     * @return jpeg size if read success else -1
+     */
+    int readJPEG(uint8_t* buf, int size, int timeout_ms = 15*1000);
+
+private:
+    uint8_t _seq;
+    uint8_t* _buf;
+    int _pos;
+    int _size;
+    CamInfo* CamInfoList;
+    CamInfo* caminfo;
+    uint8_t _caminfo_size;
+    uint8_t _caminfo_option;
+
+    void setup();
+    virtual void outputJPEG(uint8_t c, int status); // from decodeMJPEG
+    void callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len);
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/KL46Z_USBHostC270/decodeMJPEG.cpp	Tue Jan 28 06:54:16 2014 +0000
@@ -0,0 +1,180 @@
+// decodeMJPEG.cpp 2012/12/8
+// decode motion-jpeg to jpeg
+#include "mbed.h"
+#include "decodeMJPEG.h"
+
+#define MARK_SOF0 0xc0
+#define MARK_DHT  0xc4
+#define MARK_RST0 0xd0
+#define MARK_RST7 0xd7
+#define MARK_SOI  0xd8
+#define MARK_EOI  0xd9
+#define MARK_SOS  0xda
+#define MARK_DQT  0xdb
+#define MARK_DRI  0xdd
+#define MARK_APP  0xe0
+ 
+#define SEQ_INIT      0
+#define SEQ_SOI       1
+#define SEQ_FRAME     2
+#define SEQ_MARK      3
+#define SEQ_SEG_LEN   4
+#define SEQ_SEG_LEN2  5
+#define SEQ_SEG_BODY  6
+#define SEQ_SOS       7
+#define SEQ_SOS2      8
+
+static const uint8_t dht[] = {
+0xFF,0xC4,0x01,0xA2,0x00,0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,
+0x0B,0x01,0x00,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,
+0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x10,0x00,
+0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,0x00,0x01,0x7D,0x01,
+0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,
+0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,0x24,
+0x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,0x29,
+0x2A,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,
+0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
+0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,
+0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,
+0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xC2,0xC3,0xC4,0xC5,0xC6,
+0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xE1,0xE2,0xE3,
+0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
+0xFA,0x11,0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,
+0x02,0x77,0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,
+0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,
+0x52,0xF0,0x15,0x62,0x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,
+0x1A,0x26,0x27,0x28,0x29,0x2A,0x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,
+0x47,0x48,0x49,0x4A,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,
+0x67,0x68,0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x82,0x83,0x84,0x85,
+0x86,0x87,0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0xA2,0xA3,
+0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,
+0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,
+0xD9,0xDA,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,
+0xF7,0xF8,0xF9,0xFA,
+};
+
+decodeMJPEG::decodeMJPEG()
+{
+    m_seq = SEQ_INIT;
+}
+
+void decodeMJPEG::inputPacket(const uint8_t* buf, int len)
+{
+    for(int i = 12; i < len; i++) {
+        input(buf[i]);
+    }    
+}
+
+void decodeMJPEG::input(uint8_t c)
+{
+    switch(m_seq) {
+        case SEQ_INIT:
+            if (c == 0xff) {
+                m_seq = SEQ_SOI;
+            }
+            break;
+        case SEQ_SOI:
+            if (c == MARK_SOI) {
+                outputJPEG(0xff, JPEG_START); // start
+                outputJPEG(c);
+                m_bDHT = false;
+                m_seq = SEQ_FRAME;
+            } else {
+                m_seq = SEQ_INIT;
+            }
+            break;
+        case SEQ_FRAME:
+            if (c == 0xff) {
+                m_seq = SEQ_MARK;
+            } else {
+                m_seq = SEQ_INIT;
+            }
+            break;
+        case SEQ_MARK:
+            if (c == MARK_SOI || c == MARK_EOI || c == 0x00) {
+                m_seq = SEQ_INIT;
+                break;
+            }
+            m_mark = c;
+            m_seq = SEQ_SEG_LEN;
+            break;
+        case SEQ_SEG_LEN:
+            m_seg_len = c;
+            m_seq = SEQ_SEG_LEN2;
+            break;
+        case SEQ_SEG_LEN2:
+            m_seg_len <<= 8;
+            m_seg_len |= c;
+            m_seg_len -= 2;
+            m_seg_pos = 0;
+            m_seq = SEQ_SEG_BODY;
+            if (m_mark == MARK_SOS) {
+                if (m_bDHT == false) {
+                    for(int i = 0; i < sizeof(dht); i++) {
+                        outputJPEG(dht[i]);
+                    }    
+                }
+                m_output_desable = false;
+            } else if (m_mark == MARK_DHT) {
+                m_bDHT = true;
+                m_output_desable = false;
+            } else {
+                m_output_desable = false;
+            }
+            if (!m_output_desable) {
+                outputJPEG(0xff);
+                outputJPEG(m_mark);
+                outputJPEG((m_seg_len+2) >> 8);
+                outputJPEG((m_seg_len+2) & 0xff);
+            } 
+            break;
+        case SEQ_SEG_BODY:
+            if (!m_output_desable) {
+                outputJPEG(c);
+            }
+            if (++m_seg_pos < m_seg_len) {
+                break;
+            }
+            if (m_mark == MARK_SOS) {
+                m_seq = SEQ_SOS;
+                break;
+            }
+            m_seq = SEQ_FRAME;
+            break;
+        case SEQ_SOS:
+            if (c == 0xff) {
+                m_seq = SEQ_SOS2;
+                break;
+            }
+            outputJPEG(c);
+            break;
+        case SEQ_SOS2:
+            if (c == 0x00) {
+                outputJPEG(0xff);
+                outputJPEG(0x00);
+                m_seq = SEQ_SOS;
+                break;
+            } else if (c >= MARK_RST0 && c <= MARK_RST7) {
+                outputJPEG(0xff);
+                outputJPEG(c);
+                m_seq = SEQ_SOS;
+                break;
+            } else if (c == MARK_EOI) {
+                outputJPEG(0xff);
+                outputJPEG(c, JPEG_END);
+                m_seq = SEQ_INIT;
+                break;
+            } else if (c == MARK_SOI) {
+                outputJPEG(0xff);
+                outputJPEG(c);
+                m_seq = SEQ_INIT;
+                break;
+            }
+            m_seq = SEQ_INIT;
+            break;
+        default:
+            m_seq = SEQ_INIT;
+            break;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/KL46Z_USBHostC270/decodeMJPEG.h	Tue Jan 28 06:54:16 2014 +0000
@@ -0,0 +1,25 @@
+// decodeMJPEG.h 2012/12/9
+#ifndef DECODE_MJPEG_H
+#define DECODE_MJPEG_H
+
+#define JPEG_NONE  0
+#define JPEG_START 1
+#define JPEG_END   2
+#define JPEG_ERROR 3
+
+class decodeMJPEG {
+public:
+    decodeMJPEG();
+    void inputPacket(const uint8_t* buf, int len);
+    virtual void outputJPEG(uint8_t c, int status = JPEG_NONE) = 0;
+protected:
+    void input(uint8_t c);
+    int m_seq;
+    uint8_t m_mark;
+    uint16_t m_seg_pos; 
+    uint16_t m_seg_len;
+    bool m_bDHT;
+    bool m_output_desable;
+};
+
+#endif // DECODE_MJPEG_H
--- a/main.cpp	Mon Jan 27 11:07:34 2014 +0000
+++ b/main.cpp	Tue Jan 28 06:54:16 2014 +0000
@@ -1,4 +1,4 @@
-#include "USBHostC270.h"
+#include "USBHostCam.h"
 RawSerial pc(USBTX, USBRX);
 DigitalOut led1(LED_GREEN);
 DigitalOut led2(LED_RED);
@@ -16,7 +16,7 @@
     led1 = led2 = LED_OFF;
 
     // Logitech C270
-    USBHostC270* cam = new USBHostC270(C270_MJPEG, C270_320x240, _5FPS);
+    USBHostCam* cam = new USBHostCam(_320x240);
 
     int pos = 0; 
     int size = 0;