LogitechC270 webcam class driver alpha version
Fork of USBHostMSD_HelloWorld by
Revision 11:6a8eef89eb22, committed 2013-03-18
- 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
--- 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(); + } } }