testing n-Bed with a Logitech C270 camera

Dependencies:   USBHost mbed

Fork of USBHostC270_example by Norimasa Okamoto

Revision:
10:387c49b2fc7e
Parent:
9:fecabade834a
Child:
11:6a8eef89eb22
--- a/USBHostC270/BaseUvc.cpp	Sat Mar 16 13:07:55 2013 +0000
+++ b/USBHostC270/BaseUvc.cpp	Sun Mar 17 13:22:13 2013 +0000
@@ -1,14 +1,22 @@
+// BaseUvc.cpp
+
 #include "USBHostConf.h"
 #include "USBHost.h"
 
-#include "USBHostC270.h"
 #include "BaseUvc.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
+
 #define TEST_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
 
 void BaseUvc::poll(int millisec)
 {
-    HCITD* itd = m_isoEp->isochronousReveive(millisec);
+    HCITD* itd = m_isoEp->isochronousReceive(millisec);
     if (itd) {
         uint8_t cc = itd->ConditionCode();
         report_cc_count[cc]++;
@@ -33,6 +41,24 @@
     }
 }
 
+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)
@@ -78,7 +104,7 @@
 
 IsochronousEp::IsochronousEp(int addr, uint8_t ep, uint16_t size):BaseEp(addr, ep, size)
 {
-    C270_DBG("%p FA:%d EP:%02X MPS:%d\n", this, addr, ep, size);
+    ISO_DBG("%p FA:%d EP:%02X MPS:%d\n", this, addr, ep, size);
     TEST_ASSERT(m_pED);
     
     m_pED->Control |= (1 << 15); // F Format ITD
@@ -101,18 +127,7 @@
     if (hcca == NULL) {
         return;
     }
-    for(int i = 0; i < 32; i++) {
-        if (hcca->InterruptTable[i] == NULL) {
-            hcca->InterruptTable[i] = m_pED;
-        } else {
-            _HCED* nextEd = hcca->InterruptTable[i];
-            while(nextEd->Next && nextEd->Next != m_pED) {
-                nextEd = nextEd->Next;
-            }
-            nextEd->Next = m_pED;
-        }
-    }
-    //DBG_ED(m_pED);
+    hcca->enqueue(m_pED);
 }
 
 void IsochronousEp::reset(int delay_ms)
@@ -130,7 +145,7 @@
     return itd;
 }
 
-HCITD* IsochronousEp::isochronousReveive(int millisec)
+HCITD* IsochronousEp::isochronousReceive(int millisec)
 {
     TEST_ASSERT(m_itd_queue_count >= 0);
     while(m_itd_queue_count < 3 && m_itd_queue_count < HCTD_QUEUE_SIZE) {
@@ -171,7 +186,7 @@
         } else if (evt.status == osEventTimeout) {
             return NULL;
         } else {
-            //DBG("evt.status: %02x\n", evt.status);
+            ISO_DBG("evt.status: %02x\n", evt.status);
             TEST_ASSERT(evt.status == osEventMessage);
             return NULL;
         }
@@ -184,12 +199,50 @@
     LPC_USB->HcControl |= OR_CONTROL_PLE;
 }
 
+void IsochronousEp::disconnect()
+{
+    m_pED->setSkip();
+    ISO_DBG("m_itd_queue_count: %d", m_itd_queue_count);
+    Timer t;
+    t.reset();
+    t.start();
+    while(m_itd_queue_count > 0 && t.read_ms() <= (8*3)) {
+        HCITD* itd = get_queue_HCITD(0);
+        if (itd) {
+            ISO_DBG("ITD: %p", itd);
+            delete itd;
+            m_itd_queue_count--;
+            t.reset();
+        }
+    }
+    ISO_DBG("m_itd_queue_count: %d, t_ms: %d", m_itd_queue_count, t.read_ms());
+    HCITD* head = reinterpret_cast<HCITD*>(reinterpret_cast<uint32_t>(m_pED->HeadTd)&~3); // delete Halted and Toggle Carry bit
+    TEST_ASSERT(head);
+    HCITD* tail = reinterpret_cast<HCITD*>(m_pED->TailTd);
+    TEST_ASSERT(tail);
+    while(head != tail) {
+        HCITD* next = head->Next;
+        TEST_ASSERT(next);
+        ISO_DBG("ED ITD:%p next:%p", head, next);        
+        delete head;
+        TEST_ASSERT(m_itd_queue_count > 0);
+        m_itd_queue_count--;
+        head = next;
+    }
+    TEST_ASSERT(m_itd_queue_count == 0);
+    delete head;
+    
+    _HCCA* hcca = reinterpret_cast<_HCCA*>(LPC_USB->HcHCCA);
+    TEST_ASSERT(hcca);
+    hcca->dequeue(m_pED);
+    delete m_pED;
+}
+
 BaseEp::BaseEp(int addr, uint8_t ep, uint16_t size, int lowSpeed):m_td_queue_count(0)
 {
-    C270_DBG("%p FA=%d EN=%02x MPS=%d S=%d\n", this, addr, ep, size, lowSpeed);
+    ISO_DBG("%p FA=%d EN=%02x MPS=%d S=%d\n", this, addr, ep, size, lowSpeed);
     TEST_ASSERT(size >= 8 && size <= 1023);    
     TEST_ASSERT(lowSpeed == 0 || lowSpeed == 1);
     m_pED  = new _HCED(addr, ep, size, lowSpeed);
     TEST_ASSERT(m_pED);
 }
-