![](/media/cache/profiles/45ab12afa05e563bb484781693dffc87.50x50_q85.jpg)
modify for C210 webcam and Startboard Orange.
Dependencies: TextLCD USBHost mbed
Fork of USBHostC270_example by
Norimasa Okamoto さんの http://mbed.org/users/va009039/code/USBHostC270_example/ を C210 webcam と StarBoard Orange での SD カード保存用に変更。
Diff: USBHostC270/BaseUvc.cpp
- Revision:
- 10:387c49b2fc7e
- Parent:
- 9:fecabade834a
--- 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); } -