LogitechC270 webcam class driver alpha version

Dependencies:   USBHost mbed

Fork of USBHostMSD_HelloWorld by Samuel Mokrani

Files at this revision

API Documentation at this revision

Comitter:
va009039
Date:
Mon Mar 18 12:34:47 2013 +0000
Parent:
10:387c49b2fc7e
Child:
12:ea4badc78215
Commit message:
started detach implementation

Changed in this revision

USBHostC270/BaseUvc.cpp Show annotated file Show diff for this revision Revisions of this file
USBHostC270/BaseUvc.h Show annotated file Show diff for this revision Revisions of this file
USBHostC270/USBHostC270.cpp 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/USBHostC270/BaseUvc.cpp	Sun Mar 17 13:22:13 2013 +0000
+++ b/USBHostC270/BaseUvc.cpp	Mon Mar 18 12:34:47 2013 +0000
@@ -102,12 +102,13 @@
     }
 }
 
-IsochronousEp::IsochronousEp(int addr, uint8_t ep, uint16_t size):BaseEp(addr, ep, size)
+void IsochronousEp::init(int addr, uint8_t ep, uint16_t size)
 {
-    ISO_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);
+    BaseEp::init(addr, ep, size);
     TEST_ASSERT(m_pED);
     
-    m_pED->Control |= (1 << 15); // F Format ITD
+    m_pED->setFormat(); // F Format ITD
 
     TEST_ASSERT(size >= 128 && size <= 1023);
     m_PacketSize = size;
@@ -116,8 +117,7 @@
     m_itd_queue_count = 0;
     reset();
     HCITD* itd = new_HCITD(this);
-    m_pED->TailTd = reinterpret_cast<HCTD*>(itd);
-    m_pED->HeadTd = reinterpret_cast<HCTD*>(itd); 
+    m_pED->init_queue<HCITD>(itd); 
     TEST_ASSERT(itd);
     if (itd == NULL) {
         return;
@@ -149,20 +149,15 @@
 {
     TEST_ASSERT(m_itd_queue_count >= 0);
     while(m_itd_queue_count < 3 && m_itd_queue_count < HCTD_QUEUE_SIZE) {
-        HCITD* itd = reinterpret_cast<HCITD*>(m_pED->TailTd);
-        TEST_ASSERT(itd);
-        if (itd == NULL) {
-            return NULL;
+        TEST_ASSERT(m_pED);
+        if (m_pED->Skip()) {
+            break;
         }
         HCITD* blank_itd = new_HCITD(this);
         TEST_ASSERT(blank_itd);
-        if (blank_itd == NULL) {
-            return NULL;
+        if (m_pED->enqueue<HCITD>(blank_itd)) {
+            m_itd_queue_count++;
         }
-        itd->Next = blank_itd;
-        m_pED->TailTd = reinterpret_cast<HCTD*>(blank_itd);
-        m_itd_queue_count++;
-        //DBG_IED(m_pED);
         enable(); // Enable Periodic
     }
     
@@ -202,47 +197,53 @@
 void IsochronousEp::disconnect()
 {
     m_pED->setSkip();
-    ISO_DBG("m_itd_queue_count: %d", m_itd_queue_count);
+    Thread::wait(50);
+    ISO_DBG("rtos-queue: %d", m_itd_queue_count);
+    int queue_count = 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);
+    while(queue_count > 0 && t.read_ms() < 50) {
+        HCITD* itd = get_queue_HCITD(10);
         if (itd) {
-            ISO_DBG("ITD: %p", itd);
+            ISO_DBG("delete ITD:%p from rtos-queue %d ms", itd, t.read_ms());
             delete itd;
-            m_itd_queue_count--;
+            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);
+    ISO_DBG("rtos-queue: %d, %d ms", queue_count, t.read_ms());
+    while(1) {
+        HCITD* itd = m_pED->dequeue<HCITD>();
+        if (itd == NULL) {
+            break;
+        }
+        ISO_DBG("delete ITD:%p from ED(%p)-queue", itd, m_pED);        
+        delete itd;
+        TEST_ASSERT(queue_count > 0);
+        queue_count--;
+    }            
+    TEST_ASSERT(queue_count == 0);
     HCITD* tail = reinterpret_cast<HCITD*>(m_pED->TailTd);
+    ISO_DBG("delete ITD:%p from ED(%p)-tail", tail, m_pED);
     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;
+    delete tail;
+    m_pED->init_queue<HCITD>(NULL);
     
     _HCCA* hcca = reinterpret_cast<_HCCA*>(LPC_USB->HcHCCA);
     TEST_ASSERT(hcca);
     hcca->dequeue(m_pED);
+    ISO_DBG("delete ED:%p", m_pED);
     delete m_pED;
+    m_pED = NULL;
 }
 
-BaseEp::BaseEp(int addr, uint8_t ep, uint16_t size, int lowSpeed):m_td_queue_count(0)
+void BaseEp::init(int addr, uint8_t ep, uint16_t size, int 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);
+    m_td_queue_count = 0;
 }
--- a/USBHostC270/BaseUvc.h	Sun Mar 17 13:22:13 2013 +0000
+++ b/USBHostC270/BaseUvc.h	Mon Mar 18 12:34:47 2013 +0000
@@ -104,8 +104,45 @@
         Control |= size<<16;
     }
 
-    inline void setSkip() {
-        Control |= 1<<14;
+    int Skip() {
+        return (Control>>14) & 1;
+    }
+
+    void setSkip() {
+        Control |= (1<<14);
+    }
+
+    void setFormat() {
+        Control |= (1<<15);
+    }
+
+    template<typename T>
+    inline bool enqueue(T* td) {
+        if (td) {
+            T* tail = reinterpret_cast<T*>(TailTd);
+            if (tail) {
+                tail->Next = td;
+                TailTd = reinterpret_cast<HCTD*>(td);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    template<typename T>
+    inline T* dequeue() {
+        T* head = reinterpret_cast<T*>(reinterpret_cast<uint32_t>(HeadTd)&~3); // delete Halted and Toggle Carry bit
+        T* tail = reinterpret_cast<T*>(TailTd);
+        if (head == NULL || tail == NULL || head == tail) {
+            return NULL;
+        }
+        HeadTd = reinterpret_cast<HCTD*>(head->Next);
+        return head;
+    }
+    template<typename T>
+    void init_queue(T* td) {
+        TailTd = reinterpret_cast<HCTD*>(td);
+        HeadTd = reinterpret_cast<HCTD*>(td); 
     }
 };
 
@@ -165,7 +202,7 @@
 
 class BaseEp { // endpoint
 public:
-    BaseEp(int addr, uint8_t ep = 0, uint16_t size = 8, int lowSpeed = 0);
+    void init(int addr, uint8_t ep = 0, uint16_t size = 8, int lowSpeed = 0);
     int GetAddr();
     int GetLowSpeed();
     void update_FunctionAddress(int addr);
@@ -189,7 +226,7 @@
 
 class IsochronousEp : public BaseEp {
 public:
-    IsochronousEp(int addr, uint8_t ep, uint16_t size);
+    void init(int addr, uint8_t ep, uint16_t size);
     void reset(int delay_ms = 100);
     HCITD* isochronousReceive(int millisec=osWaitForever);
     int isochronousSend(uint8_t* buf, int len, int millisec=osWaitForever);
--- a/USBHostC270/USBHostC270.cpp	Sun Mar 17 13:22:13 2013 +0000
+++ b/USBHostC270/USBHostC270.cpp	Mon Mar 18 12:34:47 2013 +0000
@@ -17,9 +17,9 @@
     _formatIndex = formatIndex;
     _frameIndex = frameIndex;
     _interval = interval;
-    m_isoEp = NULL;
     clearOnResult();
     host = USBHost::getHostInst();
+    m_isoEp = new IsochronousEp;
     init();
 }
 
@@ -35,13 +35,11 @@
 
 bool USBHostC270::connected()
 {
-    C270_DBG("dev_connected: %d", dev_connected);
     return dev_connected;
 }
 
 bool USBHostC270::connect()
 {
-    C270_DBG("dev_connected: %d", dev_connected);
     if (dev_connected) {
         return true;
     }
@@ -51,15 +49,15 @@
             
             C270_DBG("Trying to connect C270 device\r\n");
             
-            if(host->enumerate(dev, this))
+            if(host->enumerate(dev, this)) {
                 break;
-
+            }
             if (c270_device_found) {
                 USB_INFO("New C270 device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, c270_intf);
                 dev->setName("C270", c270_intf);
                 host->registerDriver(dev, c270_intf, this, &USBHostC270::onDisconnect);
                 int addr = dev->getAddress();
-                m_isoEp = new IsochronousEp(addr, C270_EN, C270_MPS);
+                m_isoEp->init(addr, C270_EN, C270_MPS);
                 uint8_t buf[26];
                 memset(buf, 0, sizeof(buf));
                 buf[2] = _formatIndex;
@@ -92,11 +90,10 @@
 void USBHostC270::onDisconnect()
 {
     C270_DBG("dev_connected: %d", dev_connected);
-    // TODO
-    if (m_isoEp) {
-       m_isoEp->disconnect();
+    if (dev_connected) {
+        m_isoEp->disconnect();
+        init();
     }
-    init();
 }
 
 /*virtual*/ void USBHostC270::setVidPid(uint16_t vid, uint16_t pid)
--- a/main.cpp	Sun Mar 17 13:22:13 2013 +0000
+++ b/main.cpp	Mon Mar 18 12:34:47 2013 +0000
@@ -8,11 +8,7 @@
     pc.baud(921600);
 
     USBHostMSD* msd = new USBHostMSD("usb"); // USB flash drive
-
     USBHostC270* cam = new USBHostC270(C270_MJPEG, C270_160x120, _5FPS); // Logitech C270
-    while(!cam->connect()) {
-        Thread::wait(500);
-    }
 
     uint8_t buf[1024*3];
     Timer interval_t;
@@ -20,7 +16,7 @@
     interval_t.start();
     int shot = 0;
     while(1) {
-        if (interval_t.read() > 10) {
+        if (interval_t.read() > 10 && cam->connected()) {
             int r = cam->readJPEG(buf, sizeof(buf));
             char path[32];
             snprintf(path, sizeof(path), "/usb/image%02d.jpg", shot % 20);
@@ -38,7 +34,13 @@
         }
         if (!msd->connected()) {
             msd->connect();
+            Thread::wait(500);
         }
-        cam->poll();    
+        if (!cam->connected()) {
+            cam->connect();
+            Thread::wait(500);
+        } else {
+            cam->poll();
+        }
     }
 }