BaseUsbHost example program
Dependencies: BaseUsbHost FATFileSystem mbed mbed-rtos
Diff: LogitechC270/LogitechC270.cpp
- Revision:
- 0:2a9734a95d55
- Child:
- 1:80205a2de336
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LogitechC270/LogitechC270.cpp Tue Dec 04 13:39:57 2012 +0000 @@ -0,0 +1,157 @@ +// LogitechC270.cpp 2012/12/4 +#include "mbed.h" +#include "rtos.h" +#include "BaseUsbHost.h" +#define DEBUG +#include "BaseUsbHostDebug.h" +#define TEST +#include "BaseUsbHostTest.h" +#include "LogitechC270.h" + +LogitechC270::LogitechC270(int frame, uint32_t interval, ControlEp* ctlEp) +{ + uint8_t buf[26]; + + if (ctlEp == NULL) { // root hub + DBG_OHCI(LPC_USB->HcRhPortStatus1); + TEST_ASSERT_FALSE(LPC_USB->HcRhPortStatus1 & 0x200); + m_ctlEp = new ControlEp(); + TEST_ASSERT_TRUE(m_ctlEp); + } else { + m_ctlEp = ctlEp; + } + + int r = m_ctlEp->GetDescriptor(1, 0, buf, 18); + TEST_ASSERT(r == USB_OK); + DBG_HEX(buf, 18); + vid = *reinterpret_cast<uint16_t*>(buf+8); + pid = *reinterpret_cast<uint16_t*>(buf+10); + DBG("VID PID: %04X %04X\n", vid, pid); + TEST_ASSERT(vid == 0x046d && pid == 0x0825); + int addr = m_ctlEp->GetAddr(); + DBG("addr: %d\n", addr); + + m_isoEp = new IsochronousEp(addr, 0x81, 192); + TEST_ASSERT_TRUE(m_isoEp); + + int rc = Control(GET_INFO, VS_PROBE_CONTROL, 1, buf, 1); + TEST_ASSERT(rc == USB_OK); + DBG_BYTES("GET_INFO Prob", buf, 1); + + rc = Control(GET_DEF, VS_PROBE_CONTROL, 1, buf, 26); + TEST_ASSERT(rc == USB_OK); + DBG_BYTES("GET_DEF Probe", buf, 26); + + rc = Control(GET_MIN, VS_PROBE_CONTROL, 1, buf, 26); + TEST_ASSERT(rc == USB_OK); + DBG_BYTES("GET_MIN Probe", buf, 26); + + rc = Control(GET_MAX, VS_PROBE_CONTROL, 1, buf, 26); + TEST_ASSERT(rc == USB_OK); + DBG_BYTES("GET_MAX Probe", buf, 26); + + rc = Control(GET_CUR, VS_PROBE_CONTROL, 1, buf, 26); + TEST_ASSERT(rc == USB_OK); + DBG_BYTES("GET_CUR Probe", buf, 26); + + memset(buf, 0, 26); + buf[2] = C270_MJPEG; + buf[3] = frame; + *reinterpret_cast<uint32_t*>(buf+4) = interval; + + DBG_BYTES("SET_CUR Commit", buf, 26); + rc = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, 26); + TEST_ASSERT(rc == USB_OK); + + rc = Control(GET_CUR, VS_COMMIT_CONTROL, 1, buf, 26); + TEST_ASSERT(rc == USB_OK); + TEST_ASSERT_EQUAL(buf[2], C270_MJPEG); + TEST_ASSERT_EQUAL(buf[3], frame); + TEST_ASSERT_EQUAL(*reinterpret_cast<uint32_t*>(buf+4), interval); + DBG_BYTES("GET_CUR Commit", buf, 26); + + int cfg; + rc = m_ctlEp->GetConfiguration(&cfg); + TEST_ASSERT_EQUAL(rc, USB_OK); + DBG("config: %d\n", cfg); + + rc = m_ctlEp->SetConfiguration(1); + TEST_ASSERT_EQUAL(rc, USB_OK); + + rc = m_ctlEp->GetConfiguration(&cfg); + TEST_ASSERT_EQUAL(rc, USB_OK); + DBG("config: %d\n", cfg); + TEST_ASSERT_EQUAL(cfg, 1); + + int alt; + rc = m_ctlEp->GetInterface(1, &alt); + TEST_ASSERT_EQUAL(rc, USB_OK); + DBG("alt: %d\n", alt); + + rc = m_ctlEp->SetInterfaceAlternate(1, 1); // alt=1 packet size = 192 + TEST_ASSERT_EQUAL(rc, USB_OK); + + rc = m_ctlEp->GetInterface(1, &alt); + TEST_ASSERT_EQUAL(rc, USB_OK); + DBG("alt: %d\n", alt); + TEST_ASSERT_EQUAL(alt, 1); + + for(int i = 0; i < 16; i++) { + report_cc_count[i] = 0; + report_ps_cc_count[i] = 0; + } + + LPC_USB->HcControl |= OR_CONTROL_PLE; // PeriodicListEnable + LPC_USB->HcControl |= OR_CONTROL_IE; // IsochronousEnable +} + +void LogitechC270::poll() +{ + HCITD* itd = m_isoEp->read(); + if (itd) { + uint8_t cc = itd->Control>>28; + report_cc_count[cc]++; + if (cc == 0) { // ConditionCode + //DBG_ITD(itd); + uint16_t frame = itd->Control & 0xffff; + uint8_t* buf = const_cast<uint8_t*>(itd->buf); + int mps = m_isoEp->m_PacketSize; + for(int i = 0; i < m_isoEp->m_FrameCount; i++) { + uint16_t pswn = itd->OffsetPSW[i]; + cc = pswn>>12; + if (cc == 0 || cc == 9) { + int len = pswn & 0x7ff; + onResult(frame, buf, len); + } + report_ps_cc_count[cc]++; + buf += mps; + frame++; + } + } + m_isoEp->delete_HCTD(reinterpret_cast<HCTD*>(itd)); + } +} + +int LogitechC270::Control(int req, int cs, int index, uint8_t* buf, int size) +{ + TEST_ASSERT(m_ctlEp); + int rc; + if (req == SET_CUR) { + rc = m_ctlEp->controlSend( + USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, + req, cs<<8, index, buf, size); + return rc; + } + rc = m_ctlEp->controlReceive( + USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, + req, cs<<8, index, buf, size); + return rc; +} + +void LogitechC270::onResult(uint16_t frame, uint8_t* buf, int len) +{ + if(m_pCbItem && m_pCbMeth) + (m_pCbItem->*m_pCbMeth)(frame, buf, len); + else if(m_pCb) + m_pCb(frame, buf, len); +}