BaseUsbHost example program
Dependencies: BaseUsbHost FATFileSystem mbed mbed-rtos
LogitechC270/LogitechC270.cpp@0:2a9734a95d55, 2012-12-04 (annotated)
- Committer:
- va009039
- Date:
- Tue Dec 04 13:39:57 2012 +0000
- Revision:
- 0:2a9734a95d55
- Child:
- 1:80205a2de336
first commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 0:2a9734a95d55 | 1 | // LogitechC270.cpp 2012/12/4 |
va009039 | 0:2a9734a95d55 | 2 | #include "mbed.h" |
va009039 | 0:2a9734a95d55 | 3 | #include "rtos.h" |
va009039 | 0:2a9734a95d55 | 4 | #include "BaseUsbHost.h" |
va009039 | 0:2a9734a95d55 | 5 | #define DEBUG |
va009039 | 0:2a9734a95d55 | 6 | #include "BaseUsbHostDebug.h" |
va009039 | 0:2a9734a95d55 | 7 | #define TEST |
va009039 | 0:2a9734a95d55 | 8 | #include "BaseUsbHostTest.h" |
va009039 | 0:2a9734a95d55 | 9 | #include "LogitechC270.h" |
va009039 | 0:2a9734a95d55 | 10 | |
va009039 | 0:2a9734a95d55 | 11 | LogitechC270::LogitechC270(int frame, uint32_t interval, ControlEp* ctlEp) |
va009039 | 0:2a9734a95d55 | 12 | { |
va009039 | 0:2a9734a95d55 | 13 | uint8_t buf[26]; |
va009039 | 0:2a9734a95d55 | 14 | |
va009039 | 0:2a9734a95d55 | 15 | if (ctlEp == NULL) { // root hub |
va009039 | 0:2a9734a95d55 | 16 | DBG_OHCI(LPC_USB->HcRhPortStatus1); |
va009039 | 0:2a9734a95d55 | 17 | TEST_ASSERT_FALSE(LPC_USB->HcRhPortStatus1 & 0x200); |
va009039 | 0:2a9734a95d55 | 18 | m_ctlEp = new ControlEp(); |
va009039 | 0:2a9734a95d55 | 19 | TEST_ASSERT_TRUE(m_ctlEp); |
va009039 | 0:2a9734a95d55 | 20 | } else { |
va009039 | 0:2a9734a95d55 | 21 | m_ctlEp = ctlEp; |
va009039 | 0:2a9734a95d55 | 22 | } |
va009039 | 0:2a9734a95d55 | 23 | |
va009039 | 0:2a9734a95d55 | 24 | int r = m_ctlEp->GetDescriptor(1, 0, buf, 18); |
va009039 | 0:2a9734a95d55 | 25 | TEST_ASSERT(r == USB_OK); |
va009039 | 0:2a9734a95d55 | 26 | DBG_HEX(buf, 18); |
va009039 | 0:2a9734a95d55 | 27 | vid = *reinterpret_cast<uint16_t*>(buf+8); |
va009039 | 0:2a9734a95d55 | 28 | pid = *reinterpret_cast<uint16_t*>(buf+10); |
va009039 | 0:2a9734a95d55 | 29 | DBG("VID PID: %04X %04X\n", vid, pid); |
va009039 | 0:2a9734a95d55 | 30 | TEST_ASSERT(vid == 0x046d && pid == 0x0825); |
va009039 | 0:2a9734a95d55 | 31 | int addr = m_ctlEp->GetAddr(); |
va009039 | 0:2a9734a95d55 | 32 | DBG("addr: %d\n", addr); |
va009039 | 0:2a9734a95d55 | 33 | |
va009039 | 0:2a9734a95d55 | 34 | m_isoEp = new IsochronousEp(addr, 0x81, 192); |
va009039 | 0:2a9734a95d55 | 35 | TEST_ASSERT_TRUE(m_isoEp); |
va009039 | 0:2a9734a95d55 | 36 | |
va009039 | 0:2a9734a95d55 | 37 | int rc = Control(GET_INFO, VS_PROBE_CONTROL, 1, buf, 1); |
va009039 | 0:2a9734a95d55 | 38 | TEST_ASSERT(rc == USB_OK); |
va009039 | 0:2a9734a95d55 | 39 | DBG_BYTES("GET_INFO Prob", buf, 1); |
va009039 | 0:2a9734a95d55 | 40 | |
va009039 | 0:2a9734a95d55 | 41 | rc = Control(GET_DEF, VS_PROBE_CONTROL, 1, buf, 26); |
va009039 | 0:2a9734a95d55 | 42 | TEST_ASSERT(rc == USB_OK); |
va009039 | 0:2a9734a95d55 | 43 | DBG_BYTES("GET_DEF Probe", buf, 26); |
va009039 | 0:2a9734a95d55 | 44 | |
va009039 | 0:2a9734a95d55 | 45 | rc = Control(GET_MIN, VS_PROBE_CONTROL, 1, buf, 26); |
va009039 | 0:2a9734a95d55 | 46 | TEST_ASSERT(rc == USB_OK); |
va009039 | 0:2a9734a95d55 | 47 | DBG_BYTES("GET_MIN Probe", buf, 26); |
va009039 | 0:2a9734a95d55 | 48 | |
va009039 | 0:2a9734a95d55 | 49 | rc = Control(GET_MAX, VS_PROBE_CONTROL, 1, buf, 26); |
va009039 | 0:2a9734a95d55 | 50 | TEST_ASSERT(rc == USB_OK); |
va009039 | 0:2a9734a95d55 | 51 | DBG_BYTES("GET_MAX Probe", buf, 26); |
va009039 | 0:2a9734a95d55 | 52 | |
va009039 | 0:2a9734a95d55 | 53 | rc = Control(GET_CUR, VS_PROBE_CONTROL, 1, buf, 26); |
va009039 | 0:2a9734a95d55 | 54 | TEST_ASSERT(rc == USB_OK); |
va009039 | 0:2a9734a95d55 | 55 | DBG_BYTES("GET_CUR Probe", buf, 26); |
va009039 | 0:2a9734a95d55 | 56 | |
va009039 | 0:2a9734a95d55 | 57 | memset(buf, 0, 26); |
va009039 | 0:2a9734a95d55 | 58 | buf[2] = C270_MJPEG; |
va009039 | 0:2a9734a95d55 | 59 | buf[3] = frame; |
va009039 | 0:2a9734a95d55 | 60 | *reinterpret_cast<uint32_t*>(buf+4) = interval; |
va009039 | 0:2a9734a95d55 | 61 | |
va009039 | 0:2a9734a95d55 | 62 | DBG_BYTES("SET_CUR Commit", buf, 26); |
va009039 | 0:2a9734a95d55 | 63 | rc = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, 26); |
va009039 | 0:2a9734a95d55 | 64 | TEST_ASSERT(rc == USB_OK); |
va009039 | 0:2a9734a95d55 | 65 | |
va009039 | 0:2a9734a95d55 | 66 | rc = Control(GET_CUR, VS_COMMIT_CONTROL, 1, buf, 26); |
va009039 | 0:2a9734a95d55 | 67 | TEST_ASSERT(rc == USB_OK); |
va009039 | 0:2a9734a95d55 | 68 | TEST_ASSERT_EQUAL(buf[2], C270_MJPEG); |
va009039 | 0:2a9734a95d55 | 69 | TEST_ASSERT_EQUAL(buf[3], frame); |
va009039 | 0:2a9734a95d55 | 70 | TEST_ASSERT_EQUAL(*reinterpret_cast<uint32_t*>(buf+4), interval); |
va009039 | 0:2a9734a95d55 | 71 | DBG_BYTES("GET_CUR Commit", buf, 26); |
va009039 | 0:2a9734a95d55 | 72 | |
va009039 | 0:2a9734a95d55 | 73 | int cfg; |
va009039 | 0:2a9734a95d55 | 74 | rc = m_ctlEp->GetConfiguration(&cfg); |
va009039 | 0:2a9734a95d55 | 75 | TEST_ASSERT_EQUAL(rc, USB_OK); |
va009039 | 0:2a9734a95d55 | 76 | DBG("config: %d\n", cfg); |
va009039 | 0:2a9734a95d55 | 77 | |
va009039 | 0:2a9734a95d55 | 78 | rc = m_ctlEp->SetConfiguration(1); |
va009039 | 0:2a9734a95d55 | 79 | TEST_ASSERT_EQUAL(rc, USB_OK); |
va009039 | 0:2a9734a95d55 | 80 | |
va009039 | 0:2a9734a95d55 | 81 | rc = m_ctlEp->GetConfiguration(&cfg); |
va009039 | 0:2a9734a95d55 | 82 | TEST_ASSERT_EQUAL(rc, USB_OK); |
va009039 | 0:2a9734a95d55 | 83 | DBG("config: %d\n", cfg); |
va009039 | 0:2a9734a95d55 | 84 | TEST_ASSERT_EQUAL(cfg, 1); |
va009039 | 0:2a9734a95d55 | 85 | |
va009039 | 0:2a9734a95d55 | 86 | int alt; |
va009039 | 0:2a9734a95d55 | 87 | rc = m_ctlEp->GetInterface(1, &alt); |
va009039 | 0:2a9734a95d55 | 88 | TEST_ASSERT_EQUAL(rc, USB_OK); |
va009039 | 0:2a9734a95d55 | 89 | DBG("alt: %d\n", alt); |
va009039 | 0:2a9734a95d55 | 90 | |
va009039 | 0:2a9734a95d55 | 91 | rc = m_ctlEp->SetInterfaceAlternate(1, 1); // alt=1 packet size = 192 |
va009039 | 0:2a9734a95d55 | 92 | TEST_ASSERT_EQUAL(rc, USB_OK); |
va009039 | 0:2a9734a95d55 | 93 | |
va009039 | 0:2a9734a95d55 | 94 | rc = m_ctlEp->GetInterface(1, &alt); |
va009039 | 0:2a9734a95d55 | 95 | TEST_ASSERT_EQUAL(rc, USB_OK); |
va009039 | 0:2a9734a95d55 | 96 | DBG("alt: %d\n", alt); |
va009039 | 0:2a9734a95d55 | 97 | TEST_ASSERT_EQUAL(alt, 1); |
va009039 | 0:2a9734a95d55 | 98 | |
va009039 | 0:2a9734a95d55 | 99 | for(int i = 0; i < 16; i++) { |
va009039 | 0:2a9734a95d55 | 100 | report_cc_count[i] = 0; |
va009039 | 0:2a9734a95d55 | 101 | report_ps_cc_count[i] = 0; |
va009039 | 0:2a9734a95d55 | 102 | } |
va009039 | 0:2a9734a95d55 | 103 | |
va009039 | 0:2a9734a95d55 | 104 | LPC_USB->HcControl |= OR_CONTROL_PLE; // PeriodicListEnable |
va009039 | 0:2a9734a95d55 | 105 | LPC_USB->HcControl |= OR_CONTROL_IE; // IsochronousEnable |
va009039 | 0:2a9734a95d55 | 106 | } |
va009039 | 0:2a9734a95d55 | 107 | |
va009039 | 0:2a9734a95d55 | 108 | void LogitechC270::poll() |
va009039 | 0:2a9734a95d55 | 109 | { |
va009039 | 0:2a9734a95d55 | 110 | HCITD* itd = m_isoEp->read(); |
va009039 | 0:2a9734a95d55 | 111 | if (itd) { |
va009039 | 0:2a9734a95d55 | 112 | uint8_t cc = itd->Control>>28; |
va009039 | 0:2a9734a95d55 | 113 | report_cc_count[cc]++; |
va009039 | 0:2a9734a95d55 | 114 | if (cc == 0) { // ConditionCode |
va009039 | 0:2a9734a95d55 | 115 | //DBG_ITD(itd); |
va009039 | 0:2a9734a95d55 | 116 | uint16_t frame = itd->Control & 0xffff; |
va009039 | 0:2a9734a95d55 | 117 | uint8_t* buf = const_cast<uint8_t*>(itd->buf); |
va009039 | 0:2a9734a95d55 | 118 | int mps = m_isoEp->m_PacketSize; |
va009039 | 0:2a9734a95d55 | 119 | for(int i = 0; i < m_isoEp->m_FrameCount; i++) { |
va009039 | 0:2a9734a95d55 | 120 | uint16_t pswn = itd->OffsetPSW[i]; |
va009039 | 0:2a9734a95d55 | 121 | cc = pswn>>12; |
va009039 | 0:2a9734a95d55 | 122 | if (cc == 0 || cc == 9) { |
va009039 | 0:2a9734a95d55 | 123 | int len = pswn & 0x7ff; |
va009039 | 0:2a9734a95d55 | 124 | onResult(frame, buf, len); |
va009039 | 0:2a9734a95d55 | 125 | } |
va009039 | 0:2a9734a95d55 | 126 | report_ps_cc_count[cc]++; |
va009039 | 0:2a9734a95d55 | 127 | buf += mps; |
va009039 | 0:2a9734a95d55 | 128 | frame++; |
va009039 | 0:2a9734a95d55 | 129 | } |
va009039 | 0:2a9734a95d55 | 130 | } |
va009039 | 0:2a9734a95d55 | 131 | m_isoEp->delete_HCTD(reinterpret_cast<HCTD*>(itd)); |
va009039 | 0:2a9734a95d55 | 132 | } |
va009039 | 0:2a9734a95d55 | 133 | } |
va009039 | 0:2a9734a95d55 | 134 | |
va009039 | 0:2a9734a95d55 | 135 | int LogitechC270::Control(int req, int cs, int index, uint8_t* buf, int size) |
va009039 | 0:2a9734a95d55 | 136 | { |
va009039 | 0:2a9734a95d55 | 137 | TEST_ASSERT(m_ctlEp); |
va009039 | 0:2a9734a95d55 | 138 | int rc; |
va009039 | 0:2a9734a95d55 | 139 | if (req == SET_CUR) { |
va009039 | 0:2a9734a95d55 | 140 | rc = m_ctlEp->controlSend( |
va009039 | 0:2a9734a95d55 | 141 | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, |
va009039 | 0:2a9734a95d55 | 142 | req, cs<<8, index, buf, size); |
va009039 | 0:2a9734a95d55 | 143 | return rc; |
va009039 | 0:2a9734a95d55 | 144 | } |
va009039 | 0:2a9734a95d55 | 145 | rc = m_ctlEp->controlReceive( |
va009039 | 0:2a9734a95d55 | 146 | USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, |
va009039 | 0:2a9734a95d55 | 147 | req, cs<<8, index, buf, size); |
va009039 | 0:2a9734a95d55 | 148 | return rc; |
va009039 | 0:2a9734a95d55 | 149 | } |
va009039 | 0:2a9734a95d55 | 150 | |
va009039 | 0:2a9734a95d55 | 151 | void LogitechC270::onResult(uint16_t frame, uint8_t* buf, int len) |
va009039 | 0:2a9734a95d55 | 152 | { |
va009039 | 0:2a9734a95d55 | 153 | if(m_pCbItem && m_pCbMeth) |
va009039 | 0:2a9734a95d55 | 154 | (m_pCbItem->*m_pCbMeth)(frame, buf, len); |
va009039 | 0:2a9734a95d55 | 155 | else if(m_pCb) |
va009039 | 0:2a9734a95d55 | 156 | m_pCb(frame, buf, len); |
va009039 | 0:2a9734a95d55 | 157 | } |