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)
LPC4088-USBHostC270/USBIsochronous.cpp@1:1bb68ef9aa77, 2014-04-25 (annotated)
- Committer:
- va009039
- Date:
- Fri Apr 25 05:55:06 2014 +0000
- Revision:
- 1:1bb68ef9aa77
- Parent:
- 0:c972ee42b455
update LPC4088-USBHost library
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 0:c972ee42b455 | 1 | // USBIsochronous.cpp |
va009039 | 0:c972ee42b455 | 2 | #include "USBHostConf.h" |
va009039 | 0:c972ee42b455 | 3 | #include "USBHost.h" |
va009039 | 0:c972ee42b455 | 4 | #include "USBIsochronous.h" |
va009039 | 0:c972ee42b455 | 5 | |
va009039 | 0:c972ee42b455 | 6 | //#define ISO_DEBUG 1 |
va009039 | 0:c972ee42b455 | 7 | #ifdef ISO_DEBUG |
va009039 | 0:c972ee42b455 | 8 | #define ISO_DBG(x, ...) std::printf("[%s:%d]"x"\r\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); |
va009039 | 0:c972ee42b455 | 9 | #else |
va009039 | 0:c972ee42b455 | 10 | #define ISO_DBG(...) while(0); |
va009039 | 0:c972ee42b455 | 11 | #endif |
va009039 | 0:c972ee42b455 | 12 | |
va009039 | 0:c972ee42b455 | 13 | #if 0 |
va009039 | 0:c972ee42b455 | 14 | #define TEST_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);}; |
va009039 | 0:c972ee42b455 | 15 | #else |
va009039 | 0:c972ee42b455 | 16 | #define TEST_ASSERT(A) while(0) |
va009039 | 0:c972ee42b455 | 17 | #endif |
va009039 | 0:c972ee42b455 | 18 | |
va009039 | 0:c972ee42b455 | 19 | IsochronousEp::IsochronousEp(USBDeviceConnected* dev):USBEndpoint(dev) { |
va009039 | 0:c972ee42b455 | 20 | } |
va009039 | 0:c972ee42b455 | 21 | |
va009039 | 0:c972ee42b455 | 22 | void IsochronousEp::init2(uint8_t frameCount, uint8_t queueLimit) { |
va009039 | 0:c972ee42b455 | 23 | m_pED = new HCED(this); |
va009039 | 0:c972ee42b455 | 24 | m_pED->setFormat(); // F Format ITD |
va009039 | 0:c972ee42b455 | 25 | TEST_ASSERT(frameCount >= 1 && frameCount <= 8); |
va009039 | 0:c972ee42b455 | 26 | m_FrameCount = frameCount; |
va009039 | 0:c972ee42b455 | 27 | TEST_ASSERT(queueLimit >= 1 && queueLimit <= HCTD_QUEUE_SIZE); |
va009039 | 0:c972ee42b455 | 28 | m_itd_queue_limit = queueLimit; |
va009039 | 0:c972ee42b455 | 29 | |
va009039 | 0:c972ee42b455 | 30 | m_itd_queue_count = 0; |
va009039 | 0:c972ee42b455 | 31 | reset(); |
va009039 | 0:c972ee42b455 | 32 | HCITD* itd = new_HCITD(this); |
va009039 | 0:c972ee42b455 | 33 | m_pED->init_queue(reinterpret_cast<HCTD*>(itd)); |
va009039 | 0:c972ee42b455 | 34 | HCCA* hcca = reinterpret_cast<HCCA*>(LPC_USB->HcHCCA); |
va009039 | 0:c972ee42b455 | 35 | hcca->enqueue(m_pED); |
va009039 | 0:c972ee42b455 | 36 | } |
va009039 | 0:c972ee42b455 | 37 | |
va009039 | 0:c972ee42b455 | 38 | void IsochronousEp::reset(int delay_ms) { |
va009039 | 0:c972ee42b455 | 39 | m_FrameNumber = LPC_USB->HcFmNumber + delay_ms; |
va009039 | 0:c972ee42b455 | 40 | } |
va009039 | 0:c972ee42b455 | 41 | |
va009039 | 0:c972ee42b455 | 42 | HCITD* IsochronousEp::new_HCITD(IsochronousEp* obj) { |
va009039 | 0:c972ee42b455 | 43 | HCITD* itd = new(getSize() * m_FrameCount)HCITD(obj, m_FrameNumber, m_FrameCount, getSize()); |
va009039 | 0:c972ee42b455 | 44 | m_FrameNumber += m_FrameCount; |
va009039 | 0:c972ee42b455 | 45 | return itd; |
va009039 | 0:c972ee42b455 | 46 | } |
va009039 | 0:c972ee42b455 | 47 | |
va009039 | 0:c972ee42b455 | 48 | HCITD* IsochronousEp::isochronousReceive(int timeout_ms) { |
va009039 | 0:c972ee42b455 | 49 | while(m_itd_queue_count < m_itd_queue_limit) { |
va009039 | 0:c972ee42b455 | 50 | HCITD* blank_itd = new_HCITD(this); |
va009039 | 0:c972ee42b455 | 51 | if (m_pED->enqueue(reinterpret_cast<HCTD*>(blank_itd))) { |
va009039 | 0:c972ee42b455 | 52 | m_itd_queue_count++; |
va009039 | 0:c972ee42b455 | 53 | } |
va009039 | 0:c972ee42b455 | 54 | enable(); // Enable Periodic |
va009039 | 0:c972ee42b455 | 55 | } |
va009039 | 0:c972ee42b455 | 56 | |
va009039 | 0:c972ee42b455 | 57 | HCITD* itd = get_queue_HCITD(timeout_ms); |
va009039 | 0:c972ee42b455 | 58 | if (itd) { |
va009039 | 0:c972ee42b455 | 59 | m_itd_queue_count--; |
va009039 | 0:c972ee42b455 | 60 | } |
va009039 | 0:c972ee42b455 | 61 | return itd; |
va009039 | 0:c972ee42b455 | 62 | } |
va009039 | 0:c972ee42b455 | 63 | |
va009039 | 0:c972ee42b455 | 64 | #if 0 |
va009039 | 0:c972ee42b455 | 65 | int IsochronousEp::isochronousSend(uint8_t* buf, int len, int timeout_ms) |
va009039 | 0:c972ee42b455 | 66 | { |
va009039 | 0:c972ee42b455 | 67 | //ISO_DBG("buf: %p, len: %d", buf, len); |
va009039 | 0:c972ee42b455 | 68 | HCITD* itd = get_queue_HCITD(timeout_ms); |
va009039 | 0:c972ee42b455 | 69 | if (itd) { |
va009039 | 0:c972ee42b455 | 70 | delete itd; |
va009039 | 0:c972ee42b455 | 71 | m_itd_queue_count--; |
va009039 | 0:c972ee42b455 | 72 | TEST_ASSERT(m_itd_queue_count >= 0); |
va009039 | 0:c972ee42b455 | 73 | } |
va009039 | 0:c972ee42b455 | 74 | TEST_ASSERT(m_itd_queue_count >= 0); |
va009039 | 0:c972ee42b455 | 75 | if(m_itd_queue_count < m_itd_queue_limit) { |
va009039 | 0:c972ee42b455 | 76 | if (m_pED == NULL) { |
va009039 | 0:c972ee42b455 | 77 | ISO_DBG("m_pED is NULL"); |
va009039 | 0:c972ee42b455 | 78 | return 0; |
va009039 | 0:c972ee42b455 | 79 | } |
va009039 | 0:c972ee42b455 | 80 | if (m_pED->Skip()) { |
va009039 | 0:c972ee42b455 | 81 | return 0; |
va009039 | 0:c972ee42b455 | 82 | } |
va009039 | 0:c972ee42b455 | 83 | itd = new_HCITD(this); |
va009039 | 0:c972ee42b455 | 84 | TEST_ASSERT(itd); |
va009039 | 0:c972ee42b455 | 85 | //ISO_DBG("m_pED: %p itd: %p", m_pED, itd); |
va009039 | 0:c972ee42b455 | 86 | memcpy(const_cast<uint8_t*>(itd->buf), buf, len); |
va009039 | 0:c972ee42b455 | 87 | if (m_pED->enqueue<HCITD>(itd)) { |
va009039 | 0:c972ee42b455 | 88 | m_itd_queue_count++; |
va009039 | 0:c972ee42b455 | 89 | } |
va009039 | 0:c972ee42b455 | 90 | enable(); // Enable Periodic |
va009039 | 0:c972ee42b455 | 91 | //ISO_DBG("m_itd_queue_count: %d", m_itd_queue_count); |
va009039 | 0:c972ee42b455 | 92 | return len; |
va009039 | 0:c972ee42b455 | 93 | } |
va009039 | 0:c972ee42b455 | 94 | return 0; |
va009039 | 0:c972ee42b455 | 95 | } |
va009039 | 0:c972ee42b455 | 96 | #endif |
va009039 | 0:c972ee42b455 | 97 | |
va009039 | 0:c972ee42b455 | 98 | HCITD* IsochronousEp::get_queue_HCITD(int timeout_ms) |
va009039 | 0:c972ee42b455 | 99 | { |
va009039 | 0:c972ee42b455 | 100 | Timer t; |
va009039 | 0:c972ee42b455 | 101 | t.reset(); |
va009039 | 0:c972ee42b455 | 102 | t.start(); |
va009039 | 0:c972ee42b455 | 103 | do { |
va009039 | 0:c972ee42b455 | 104 | osEvent evt = m_queue.get(0); |
va009039 | 0:c972ee42b455 | 105 | if (evt.status == osEventMessage) { |
va009039 | 0:c972ee42b455 | 106 | HCITD* itd = reinterpret_cast<HCITD*>(evt.value.p); |
va009039 | 0:c972ee42b455 | 107 | TEST_ASSERT(itd); |
va009039 | 0:c972ee42b455 | 108 | return itd; |
va009039 | 0:c972ee42b455 | 109 | } else if (evt.status == osOK) { |
va009039 | 0:c972ee42b455 | 110 | ; |
va009039 | 0:c972ee42b455 | 111 | } else if (evt.status == osEventTimeout) { |
va009039 | 0:c972ee42b455 | 112 | break; |
va009039 | 0:c972ee42b455 | 113 | } else { |
va009039 | 0:c972ee42b455 | 114 | ISO_DBG("evt.status: %02x\n", evt.status); |
va009039 | 0:c972ee42b455 | 115 | TEST_ASSERT(evt.status == osEventMessage); |
va009039 | 0:c972ee42b455 | 116 | break; |
va009039 | 0:c972ee42b455 | 117 | } |
va009039 | 0:c972ee42b455 | 118 | } while(t.read_ms() < timeout_ms); |
va009039 | 0:c972ee42b455 | 119 | return NULL; |
va009039 | 0:c972ee42b455 | 120 | } |
va009039 | 0:c972ee42b455 | 121 | |
va009039 | 0:c972ee42b455 | 122 | void IsochronousEp::enable() |
va009039 | 0:c972ee42b455 | 123 | { |
va009039 | 0:c972ee42b455 | 124 | LPC_USB->HcControl |= OR_CONTROL_PLE; |
va009039 | 0:c972ee42b455 | 125 | } |
va009039 | 0:c972ee42b455 | 126 | |
va009039 | 0:c972ee42b455 | 127 |