Simple USBHost WebCam for EA LPC4088 QSB/LPC1768 test program

Dependencies:   LPC4088-USBHost mbed

EA LPC4088 QSB/LPC1768をUSBホストにしてWebカメラからJPEG画像を読み取るテストプログラムです。

The usage is the same as KL46Z-USBHostC270_example.
使い方はKL46Z-USBHostC270_exampleと同じです。
動作確認: Logitech C270,Logitech Q200R(Qcam Orbit AF)
/media/uploads/va009039/lpc4088-c270-480x360.jpg

Revision:
0:c972ee42b455
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LPC4088-USBHostC270/USBIsochronous.cpp	Thu Apr 24 05:38:45 2014 +0000
@@ -0,0 +1,127 @@
+// USBIsochronous.cpp
+#include "USBHostConf.h"
+#include "USBHost.h"
+#include "USBIsochronous.h"
+
+//#define ISO_DEBUG 1
+#ifdef ISO_DEBUG
+#define ISO_DBG(x, ...) std::printf("[%s:%d]"x"\r\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
+#else
+#define ISO_DBG(...)  while(0);
+#endif
+
+#if 0
+#define TEST_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
+#else
+#define TEST_ASSERT(A) while(0)
+#endif
+
+IsochronousEp::IsochronousEp(USBDeviceConnected* dev):USBEndpoint(dev) {
+}
+
+void IsochronousEp::init2(uint8_t frameCount, uint8_t queueLimit) {
+    m_pED  = new HCED(this);
+    m_pED->setFormat(); // F Format ITD
+    TEST_ASSERT(frameCount >= 1 && frameCount <= 8);
+    m_FrameCount = frameCount;
+    TEST_ASSERT(queueLimit >= 1 && queueLimit <= HCTD_QUEUE_SIZE);
+    m_itd_queue_limit = queueLimit;
+    
+    m_itd_queue_count = 0;
+    reset();
+    HCITD* itd = new_HCITD(this);
+    m_pED->init_queue(reinterpret_cast<HCTD*>(itd)); 
+    HCCA* hcca = reinterpret_cast<HCCA*>(LPC_USB->HcHCCA);
+    hcca->enqueue(m_pED);
+}
+
+void IsochronousEp::reset(int delay_ms) {
+    m_FrameNumber = LPC_USB->HcFmNumber + delay_ms;
+}
+
+HCITD* IsochronousEp::new_HCITD(IsochronousEp* obj) {
+    HCITD* itd = new(getSize() * m_FrameCount)HCITD(obj, m_FrameNumber, m_FrameCount, getSize());
+    m_FrameNumber += m_FrameCount;
+    return itd;
+}
+
+HCITD* IsochronousEp::isochronousReceive(int timeout_ms) {
+    while(m_itd_queue_count < m_itd_queue_limit) {
+        HCITD* blank_itd = new_HCITD(this);
+        if (m_pED->enqueue(reinterpret_cast<HCTD*>(blank_itd))) {
+            m_itd_queue_count++;
+        }
+        enable(); // Enable Periodic
+    }
+    
+    HCITD* itd = get_queue_HCITD(timeout_ms);
+    if (itd) {
+        m_itd_queue_count--;
+    }
+    return itd;
+}
+
+#if 0
+int IsochronousEp::isochronousSend(uint8_t* buf, int len, int timeout_ms)
+{
+    //ISO_DBG("buf: %p, len: %d", buf, len);
+    HCITD* itd = get_queue_HCITD(timeout_ms);
+    if (itd) {
+        delete itd;
+        m_itd_queue_count--;
+        TEST_ASSERT(m_itd_queue_count >= 0);
+    }
+    TEST_ASSERT(m_itd_queue_count >= 0);
+    if(m_itd_queue_count < m_itd_queue_limit) {
+        if (m_pED == NULL) {
+            ISO_DBG("m_pED is NULL");
+            return 0;
+        }
+        if (m_pED->Skip()) {
+            return 0;
+        }
+        itd = new_HCITD(this);
+        TEST_ASSERT(itd);
+        //ISO_DBG("m_pED: %p itd: %p", m_pED, itd);
+        memcpy(const_cast<uint8_t*>(itd->buf), buf, len);
+        if (m_pED->enqueue<HCITD>(itd)) {
+            m_itd_queue_count++;
+        }
+        enable(); // Enable Periodic
+        //ISO_DBG("m_itd_queue_count: %d", m_itd_queue_count);
+        return len;
+    }
+    return 0;
+}
+#endif
+
+HCITD* IsochronousEp::get_queue_HCITD(int timeout_ms)
+{
+    Timer t;
+    t.reset();
+    t.start();
+    do {
+        osEvent evt = m_queue.get(0);
+        if (evt.status == osEventMessage) {
+            HCITD* itd = reinterpret_cast<HCITD*>(evt.value.p);
+            TEST_ASSERT(itd);
+            return itd;
+        } else if (evt.status == osOK) {
+            ;
+        } else if (evt.status == osEventTimeout) {
+            break;
+        } else {
+            ISO_DBG("evt.status: %02x\n", evt.status);
+            TEST_ASSERT(evt.status == osEventMessage);
+            break;
+        }
+    } while(t.read_ms() < timeout_ms);
+    return NULL;
+}
+
+void IsochronousEp::enable()
+{
+    LPC_USB->HcControl |= OR_CONTROL_PLE;
+}
+
+